Compare commits
141 Commits
targetByte
...
feat/unify
Author | SHA1 | Date | |
---|---|---|---|
|
79658c181d | ||
|
f396189a4b | ||
|
e7f4a94908 | ||
|
ce49a4b9a5 | ||
|
03b3692724 | ||
|
f0022d2b6f | ||
|
b1015cfa82 | ||
|
b63a27a0a0 | ||
|
3b0a53d3c4 | ||
|
50dbbf5f86 | ||
|
130c491ac0 | ||
|
9f9b264ac4 | ||
|
1393db05c2 | ||
|
93e1a8787c | ||
|
0129d7540f | ||
|
7ea8337aee | ||
|
28458d405f | ||
|
1b905cb3e2 | ||
|
d02c3583e9 | ||
|
ca98e83fd2 | ||
|
c80a0c8596 | ||
|
2278fb1b91 | ||
|
32b16cd5fd | ||
|
fd30c5f63f | ||
|
8bfd6ae255 | ||
|
ad2dfb13bd | ||
|
501633a90c | ||
|
4defa50ca2 | ||
|
d65e90536a | ||
|
3de7f1aa61 | ||
|
029e40b775 | ||
|
459bfcdd5f | ||
|
02886c38ea | ||
|
57ffae0481 | ||
|
d084d74a25 | ||
|
cd15016f61 | ||
|
b0e5eee25c | ||
|
d1bd285be7 | ||
|
a902fd5bee | ||
|
ced9fdc9f7 | ||
|
53417bf298 | ||
|
2d4da03f00 | ||
|
f7a13f5faa | ||
|
8fe80b4396 | ||
|
eb1201ae5e | ||
|
963ad76593 | ||
|
1eba09e3b0 | ||
|
fc82125d14 | ||
|
dad468368b | ||
|
fdd4f3aa59 | ||
|
a0c11b60e8 | ||
|
4cddf73e6d | ||
|
5024a02447 | ||
|
6c2d97b770 | ||
|
426c2916d3 | ||
|
f722a00fbb | ||
|
32797c9b9f | ||
|
87f655c85a | ||
|
613dceae1d | ||
|
81cac06e16 | ||
|
a47d5bc024 | ||
|
e5916d455a | ||
|
ebb639e72e | ||
|
f0a4a51ce6 | ||
|
7442880452 | ||
|
c4dc3b4245 | ||
1391206dfe | |||
659bf6b500 | |||
33ed22c06a | |||
70f7857661 | |||
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 | ||
|
96eb504174 | ||
|
4f0162ba64 | ||
|
6e1198ab3d | ||
|
cc8f36d3ec | ||
|
139325e78f | ||
|
b18b0a38cf | ||
|
be60261795 | ||
|
c7f4a2d4c1 | ||
|
5f944e441c | ||
|
0d572ed9b6 |
@@ -15,7 +15,7 @@ jobs:
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '21'
|
||||
java-version: '23'
|
||||
cache: 'maven'
|
||||
- name: Compile project
|
||||
run: |
|
||||
|
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
40
independentTest.sh
Executable file
40
independentTest.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
REPO="https://gitea.hb.dhbw-stuttgart.de/f.holzwarth/JavaCompilerCore.git"
|
||||
TDIR="./testBuild"
|
||||
|
||||
rm -rf "$TDIR" 2>/dev/null
|
||||
mkdir $TDIR
|
||||
|
||||
cd $TDIR
|
||||
git clone $REPO .
|
||||
git checkout feat/unify-server
|
||||
# git checkout 93e1a8787cd94c73f4538f6a348f58613893a584
|
||||
# git checkout dad468368b86bdd5a3d3b2754b17617cee0a9107 # 1:55
|
||||
# git checkout a0c11b60e8c9d7addcbe0d3a09c9ce2924e9d5c0 # 2:25
|
||||
# git checkout 4cddf73e6d6c9116d3e1705c4b27a8e7f18d80c3 # 2:27
|
||||
# git checkout 6c2d97b7703d954e4a42eef3ec374bcf313af75c # 2:13
|
||||
# git checkout f722a00fbb6e69423d48a890e4a6283471763e64 # 1:35
|
||||
# git checkout f0a4a51ce65639ce9a9470ff0fdb538fdf9c02cc # 2:19
|
||||
# git checkout 1391206dfe59263cdb22f93371cfd1dd5465d97f # 1:29
|
||||
|
||||
date "+%Y.%m.%d %H:%M:%S"
|
||||
# sed -i -e 's/source>21/source>23/g' pom.xml
|
||||
# sed -i -e 's/target>21/target>23/g' pom.xml
|
||||
|
||||
|
||||
mvn clean compile -DskipTests package
|
||||
time java -jar target/JavaTXcompiler-0.1-jar-with-dependencies.jar resources/bytecode/javFiles/Matrix.jav;
|
||||
|
||||
# mvn clean compile test
|
||||
|
||||
|
||||
echo -e "\nCleanup... "
|
||||
cd -
|
||||
rm -rf "$TDIR" 2>/dev/null
|
||||
|
||||
echo -e "\nFinished "
|
||||
date "+%Y.%m.%d %H:%M:%S"
|
||||
echo -e "\n "
|
||||
|
30
pom.xml
30
pom.xml
@@ -14,7 +14,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<version>4.13.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4 -->
|
||||
@@ -26,7 +26,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.6</version>
|
||||
<version>2.16.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.classgraph</groupId>
|
||||
@@ -44,6 +44,26 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<artifactId>asm</artifactId>
|
||||
<version>9.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.java-websocket</groupId>
|
||||
<artifactId>Java-WebSocket</artifactId>
|
||||
<version>1.5.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.25</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.17.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.diogonunes</groupId>
|
||||
<artifactId>JColor</artifactId>
|
||||
<version>5.5.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -54,8 +74,8 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<compilerArgs>--enable-preview</compilerArgs>
|
||||
<source>21</source>
|
||||
<target>21</target>
|
||||
<source>23</source>
|
||||
<target>23</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
@@ -138,4 +158,4 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<url>file:///${project.basedir}/maven-repository/</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</project>
|
||||
</project>
|
||||
|
@@ -1,9 +1,12 @@
|
||||
public class Box<A> {
|
||||
public class Box {
|
||||
|
||||
A a;
|
||||
a;
|
||||
|
||||
public Box() { }
|
||||
public Box(A a) {
|
||||
public Box(a) {
|
||||
//this.a = a;
|
||||
}
|
||||
set(x) {
|
||||
a = x;
|
||||
}
|
||||
}
|
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
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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
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.Float;
|
||||
|
||||
record Point(Number x, Number y) {}
|
||||
public record Point(Number x, Number y) {}
|
||||
|
||||
public class OverloadPattern {
|
||||
public m(Point(Integer x, Integer y)) {
|
||||
return x + y;
|
||||
public Number m(Point(Integer x, Integer y), Point(Float a, Float b)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public m(Point(Float x, Float y)) {
|
||||
return x * y;
|
||||
public Number m(Point(Integer x, Integer y), Point(Integer a, Integer b)) {
|
||||
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) {
|
||||
|
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, Rec(Integer b, Integer c)) -> a + b + c;
|
||||
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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -654,14 +654,17 @@ primaryPattern
|
||||
: typePattern #tPattern
|
||||
| recordPattern #rPattern
|
||||
| '(' pattern ')' #enclosedPattern
|
||||
| literal (',' literal)* #lPattern
|
||||
;
|
||||
|
||||
recordPattern
|
||||
: typeType recordStructurePattern identifier?
|
||||
//| recordStructurePattern identifier?
|
||||
;
|
||||
|
||||
typePattern
|
||||
: variableModifier* typeType identifier
|
||||
| variableModifier* identifier
|
||||
;
|
||||
|
||||
recordStructurePattern
|
||||
@@ -717,10 +720,10 @@ switchLabeledRule
|
||||
;
|
||||
|
||||
switchLabelCase
|
||||
: CASE expressionList (ARROW | COLON) #labeledRuleExprList
|
||||
| CASE NULL_LITERAL (ARROW | COLON) #labeledRuleNull
|
||||
: CASE NULL_LITERAL (ARROW | COLON) #labeledRuleNull
|
||||
| CASE pattern (ARROW | COLON) #labeledRulePattern
|
||||
| DEFAULT (ARROW | COLON) #labeledRuleDefault
|
||||
| CASE expressionList (ARROW | COLON) #labeledRuleExprList
|
||||
;
|
||||
|
||||
// Java20
|
||||
|
@@ -2,29 +2,26 @@ package de.dhbwstuttgart.bytecode;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.Pattern;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||
import de.dhbwstuttgart.target.generate.StatementToTargetExpression;
|
||||
import de.dhbwstuttgart.target.tree.*;
|
||||
import de.dhbwstuttgart.target.tree.expression.*;
|
||||
import de.dhbwstuttgart.target.tree.type.*;
|
||||
import de.dhbwstuttgart.util.Logger;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
import java.lang.invoke.*;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.*;
|
||||
import static de.dhbwstuttgart.target.tree.expression.TargetBinaryOp.*;
|
||||
import static de.dhbwstuttgart.target.tree.expression.TargetLiteral.*;
|
||||
|
||||
public class Codegen {
|
||||
public static Logger logger = new Logger("codegen");
|
||||
|
||||
private final TargetStructure clazz;
|
||||
private final ClassWriter cw;
|
||||
public final String className;
|
||||
@@ -108,6 +105,10 @@ public class Codegen {
|
||||
this.scope = this.scope.parent;
|
||||
}
|
||||
|
||||
LocalVar createVariable(TargetType type) {
|
||||
return createVariable("__var" + this.localCounter, type);
|
||||
}
|
||||
|
||||
LocalVar createVariable(String name, TargetType type) {
|
||||
var local = new LocalVar(localCounter, name, type);
|
||||
scope.add(local);
|
||||
@@ -1294,8 +1295,7 @@ public class Codegen {
|
||||
state.enterScope();
|
||||
// This is the index to start the switch from
|
||||
mv.visitInsn(ICONST_0);
|
||||
if (aSwitch.isExpression())
|
||||
state.pushSwitch();
|
||||
state.pushSwitch();
|
||||
|
||||
// To be able to skip ahead to the next case
|
||||
var start = new Label();
|
||||
@@ -1309,17 +1309,18 @@ public class Codegen {
|
||||
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 types = new ArrayList<Object>(aSwitch.cases().size());
|
||||
var types = new ArrayList<>(aSwitch.cases().size());
|
||||
for (var cse : aSwitch.cases()) for (var label : cse.labels()) {
|
||||
if (label instanceof TargetTypePattern || label instanceof TargetComplexPattern)
|
||||
types.add(Type.getObjectType(label.type().getInternalName()));
|
||||
else if (label instanceof TargetLiteral lit)
|
||||
if (label instanceof TargetTypePattern || label instanceof TargetComplexPattern) {
|
||||
if (label.type() instanceof TargetGenericType) types.add(Type.getType(Object.class));
|
||||
else types.add(Type.getObjectType(label.type().getInternalName()));
|
||||
} else if (label instanceof TargetLiteral lit) {
|
||||
types.add(lit.value());
|
||||
else if (label instanceof TargetGuard guard)
|
||||
} else if (label instanceof TargetGuard guard) {
|
||||
types.add(Type.getObjectType(guard.inner().type().getInternalName()));
|
||||
// TODO Same here we need to evaluate constant;
|
||||
else {
|
||||
System.out.println(label);
|
||||
// TODO Same here we need to evaluate constant;
|
||||
} else {
|
||||
logger.info(label);
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -1339,11 +1340,7 @@ public class Codegen {
|
||||
}
|
||||
}
|
||||
|
||||
var defaultLabel = end;
|
||||
if (aSwitch.default_() != null) {
|
||||
defaultLabel = new Label();
|
||||
}
|
||||
|
||||
var defaultLabel = new Label();
|
||||
mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);
|
||||
|
||||
for (var i = 0; i < aSwitch.cases().size(); i++) {
|
||||
@@ -1378,11 +1375,18 @@ public class Codegen {
|
||||
if (aSwitch.isExpression()) mv.visitJumpInsn(GOTO, end);
|
||||
}
|
||||
|
||||
mv.visitLabel(defaultLabel);
|
||||
if (aSwitch.default_() != null) {
|
||||
mv.visitLabel(defaultLabel);
|
||||
generate(state, aSwitch.default_().body());
|
||||
if (aSwitch.default_().isSingleExpression() && aSwitch.isExpression())
|
||||
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);
|
||||
@@ -1390,8 +1394,10 @@ public class Codegen {
|
||||
|
||||
state.breakStack.pop();
|
||||
if (aSwitch.isExpression()) {
|
||||
mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
|
||||
unboxPrimitive(state, aSwitch.type());
|
||||
if (aSwitch.type() != null) {
|
||||
mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
|
||||
unboxPrimitive(state, aSwitch.type());
|
||||
}
|
||||
state.popSwitch();
|
||||
}
|
||||
|
||||
@@ -1402,30 +1408,50 @@ public class Codegen {
|
||||
if (i >= clazz.getFieldDecl().size())
|
||||
throw new CodeGenException("Couldn't find suitable field accessor for '" + type.name() + "'");
|
||||
var field = clazz.getFieldDecl().get(i);
|
||||
var fieldType = new TargetRefType(((RefType) field.getType()).getName().toString());
|
||||
state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toDescriptor(), false);
|
||||
var fieldType = converter.convert(field.getType());
|
||||
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) {
|
||||
if (pat.type() instanceof TargetPrimitiveType)
|
||||
boxPrimitive(state, pat.type());
|
||||
|
||||
state.mv.visitInsn(DUP);
|
||||
state.mv.visitTypeInsn(INSTANCEOF, pat.type().getInternalName());
|
||||
if (pat.type() instanceof TargetRefType) {
|
||||
state.mv.visitInsn(DUP);
|
||||
state.mv.visitTypeInsn(INSTANCEOF, pat.type().getInternalName());
|
||||
|
||||
var cont = new Label();
|
||||
state.mv.visitJumpInsn(IFNE, cont);
|
||||
for (var i = 0; i < depth; i++) {
|
||||
state.mv.visitInsn(POP);
|
||||
var cont = new Label();
|
||||
state.mv.visitJumpInsn(IFNE, cont);
|
||||
for (var i = 0; i < depth; 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);
|
||||
|
||||
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());
|
||||
state.mv.visitVarInsn(ASTORE, local.index);
|
||||
} else if (pat instanceof TargetComplexPattern cp) {
|
||||
@@ -1440,10 +1466,27 @@ public class Codegen {
|
||||
// TODO Check if class is a Record
|
||||
|
||||
for (var i = 0; i < cp.subPatterns().size(); i++) {
|
||||
state.mv.visitInsn(DUP);
|
||||
|
||||
var subPattern = cp.subPatterns().get(i);
|
||||
|
||||
state.mv.visitInsn(DUP);
|
||||
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);
|
||||
}
|
||||
state.mv.visitInsn(POP);
|
||||
@@ -1516,29 +1559,27 @@ public class Codegen {
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
private int bindLocalVariables(State state, TargetPattern pattern, int offset, int field) {
|
||||
if (pattern instanceof TargetComplexPattern cp) {
|
||||
state.mv.visitVarInsn(ALOAD, offset);
|
||||
private void bindLocalVariables(State state, TargetComplexPattern cp, int offset) {
|
||||
state.mv.visitVarInsn(ALOAD, offset);
|
||||
|
||||
var clazz = findClass(new JavaClassName(cp.type().name()));
|
||||
if (clazz == null) throw new CodeGenException("Class definition for '" + cp.type().name() + "' not found");
|
||||
var clazz = findClass(new JavaClassName(cp.type().name()));
|
||||
if (clazz == null) throw new CodeGenException("Class definition for '" + cp.type().name() + "' not found");
|
||||
|
||||
for (var i = 0; i < cp.subPatterns().size(); i++) {
|
||||
var subPattern = cp.subPatterns().get(i);
|
||||
for (var i = 0; i < cp.subPatterns().size(); i++) {
|
||||
var subPattern = cp.subPatterns().get(i);
|
||||
|
||||
if (i < cp.subPatterns().size() - 1)
|
||||
state.mv.visitInsn(DUP);
|
||||
if (i < cp.subPatterns().size() - 1)
|
||||
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.visitVarInsn(ASTORE, offset);
|
||||
offset = bindLocalVariables(state, subPattern, offset, i);
|
||||
offset = state.createVariable(subPattern.name(), subPattern.type()).index;
|
||||
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());
|
||||
} else throw new NotImplementedException();
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
private void generateMethod(TargetMethod method) {
|
||||
@@ -1557,8 +1598,14 @@ public class Codegen {
|
||||
if (method.block() != null) {
|
||||
mv.visitCode();
|
||||
var state = new State(method.signature().returnType(), mv, method.isStatic() ? 0 : 1);
|
||||
var offset = 1;
|
||||
for (var param : method.signature().parameters()) {
|
||||
bindLocalVariables(state, param.pattern(), 1, 0);
|
||||
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++;
|
||||
}
|
||||
generate(state, method.block());
|
||||
if (method.signature().returnType() == null)
|
||||
@@ -1593,13 +1640,26 @@ public class Codegen {
|
||||
if (!(clazz instanceof TargetInterface))
|
||||
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 interfaces = clazz.implementingInterfaces().stream().map(TargetType::getInternalName).toArray(String[]::new);
|
||||
var superType = clazz.superType() != null ? clazz.superType().getInternalName() : "java/lang/Object";
|
||||
|
||||
cw.visit(V1_8, access, clazz.qualifiedName().toString().replaceAll("\\.", "/"), signature, superType, interfaces);
|
||||
if (clazz.txGenerics() != null && signature != null)
|
||||
cw.visitAttribute(new JavaTXSignatureAttribute(generateSignature(clazz, clazz.txGenerics())));
|
||||
if (clazz.txGenerics() != null && signature != null) {
|
||||
var txSignature = generateSignature(clazz, clazz.txGenerics());
|
||||
if (txSignature != null)
|
||||
cw.visitAttribute(new JavaTXSignatureAttribute(txSignature));
|
||||
}
|
||||
|
||||
clazz.fields().forEach(this::generateField);
|
||||
clazz.constructors().forEach(this::generateConstructor);
|
||||
@@ -1720,7 +1780,7 @@ public class Codegen {
|
||||
bootstrapArgs[1] = String.join(";", clazz.fields().stream().map(TargetField::name).toArray(String[]::new));
|
||||
for (var i = 0; i < clazz.fields().size(); 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;
|
||||
}
|
||||
|
||||
|
@@ -120,7 +120,7 @@ public class FunNGenerator {
|
||||
superFunNMethodDescriptor.append(")V");
|
||||
}
|
||||
|
||||
System.out.println(superFunNMethodSignature);
|
||||
Codegen.logger.info(superFunNMethodSignature);
|
||||
|
||||
ClassWriter classWriter = new ClassWriter(0);
|
||||
MethodVisitor methodVisitor;
|
||||
|
@@ -1,46 +1,81 @@
|
||||
package de.dhbwstuttgart.core;
|
||||
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
import de.dhbwstuttgart.util.Logger;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.*;
|
||||
public class ConsoleInterface {
|
||||
private static final String directory = System.getProperty("user.dir");
|
||||
|
||||
public static void main(String[] args) throws IOException, ClassNotFoundException {
|
||||
List<File> input = new ArrayList<>();
|
||||
List<File> classpath = new ArrayList<>();
|
||||
String outputPath = null;
|
||||
Iterator<String> it = Arrays.asList(args).iterator();
|
||||
if(args.length == 0){
|
||||
System.out.println("No input files given. Get help with --help");
|
||||
System.exit(1);
|
||||
}else if(args.length == 1 && args[0].equals("--help")){
|
||||
System.out.println("Usage: javatx [OPTION]... [FILE]...\n" +
|
||||
"\t-cp\tSet Classpath\n" +
|
||||
"\t-d\tSet destination directory");
|
||||
System.exit(1);
|
||||
public class ConsoleInterface {
|
||||
|
||||
/**
|
||||
* Leave the argument configurations here for the rest of the code to read
|
||||
*/
|
||||
public static Logger.LogLevel logLevel = Logger.LogLevel.ERROR;
|
||||
public static boolean writeLogFiles = false;
|
||||
public static Optional<String> unifyServerUrl = Optional.empty();
|
||||
|
||||
public static void main(String[] args) throws IOException, ClassNotFoundException {
|
||||
List<File> input = new ArrayList<>();
|
||||
List<File> classpath = new ArrayList<>();
|
||||
String outputPath = null;
|
||||
Iterator<String> it = Arrays.asList(args).iterator();
|
||||
Optional<Integer> serverPort = Optional.empty();
|
||||
|
||||
if (args.length == 0) {
|
||||
System.out.println("No input files given. Get help with --help");
|
||||
System.exit(1);
|
||||
} else if (args.length == 1 && args[0].equals("--help")) {
|
||||
System.out.println("Usage: javatx [OPTION]... [FILE]...\n" +
|
||||
"\t-cp\tSet Classpath\n" +
|
||||
"\t-d\tSet destination directory\n" +
|
||||
"\t[--server-mode <port>]\n" +
|
||||
"\t[--unify-server <url>]\n" +
|
||||
"\t[--write-logs]\n" +
|
||||
"\t[-v|-vv-|-vvv]");
|
||||
System.exit(1);
|
||||
}
|
||||
while (it.hasNext()) {
|
||||
String arg = it.next();
|
||||
if (arg.equals("-d")) {
|
||||
outputPath = it.next();
|
||||
} else if (arg.startsWith("-d")) {
|
||||
outputPath = arg.substring(2);
|
||||
} else if (arg.equals("-cp") || arg.equals("-classpath")) {
|
||||
String[] cps = it.next().split(":");
|
||||
for (String cp : cps) {
|
||||
classpath.add(new File(cp));
|
||||
}
|
||||
while(it.hasNext()){
|
||||
String arg = it.next();
|
||||
if(arg.equals("-d")){
|
||||
outputPath = it.next();
|
||||
}else if(arg.startsWith("-d")) {
|
||||
outputPath = arg.substring(2);
|
||||
}else if(arg.equals("-cp") || arg.equals("-classpath")){
|
||||
String[] cps = it.next().split(":");
|
||||
for(String cp : cps){
|
||||
classpath.add(new File(cp));
|
||||
}
|
||||
}else{
|
||||
input.add(new File(arg));
|
||||
}
|
||||
}
|
||||
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath, outputPath != null ? new File(outputPath) : null);
|
||||
//compiler.typeInference();
|
||||
compiler.generateBytecode();
|
||||
}
|
||||
} else if (arg.equals("--server-mode")) {
|
||||
serverPort = Optional.of(Integer.parseInt(it.next()));
|
||||
} else if (arg.equals("--unify-server")) {
|
||||
unifyServerUrl = Optional.of(it.next());
|
||||
} else if (arg.equals("--write-logs")) {
|
||||
ConsoleInterface.writeLogFiles = true;
|
||||
} else if (arg.startsWith("-v")) {
|
||||
logLevel = switch (arg) {
|
||||
case "-v" -> Logger.LogLevel.WARNING;
|
||||
case "-vv" -> Logger.LogLevel.INFO;
|
||||
case "-vvv" -> Logger.LogLevel.DEBUG;
|
||||
default -> throw new IllegalArgumentException("Argument " + arg + " is not a valid verbosity level");
|
||||
};
|
||||
} else {
|
||||
input.add(new File(arg));
|
||||
}
|
||||
}
|
||||
|
||||
if (serverPort.isPresent()) {
|
||||
if (unifyServerUrl.isPresent()) throw new RuntimeException("Cannot use unifyServer when in server mode!");
|
||||
JavaTXServer server = new JavaTXServer(serverPort.get());
|
||||
server.listen();
|
||||
}
|
||||
else {
|
||||
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath, outputPath != null ? new File(outputPath) : null);
|
||||
//compiler.typeInference();
|
||||
compiler.generateBytecode();
|
||||
SocketClient.closeIfOpen();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -12,6 +12,11 @@ import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
import de.dhbwstuttgart.server.SocketFuture;
|
||||
import de.dhbwstuttgart.server.packet.SetAutoclosePacket;
|
||||
import de.dhbwstuttgart.server.packet.UnifyRequestPacket;
|
||||
import de.dhbwstuttgart.server.packet.UnifyResultPacket;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
@@ -35,10 +40,13 @@ import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
|
||||
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||
import de.dhbwstuttgart.typeinference.unify.RuleSet;
|
||||
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
@@ -49,6 +57,7 @@ import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel;
|
||||
|
||||
import de.dhbwstuttgart.util.Logger;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.file.Path;
|
||||
@@ -61,14 +70,17 @@ import org.apache.commons.io.output.NullOutputStream;
|
||||
|
||||
public class JavaTXCompiler {
|
||||
|
||||
// do not use this in any code, that can be executed serverside!
|
||||
public static PlaceholderRegistry defaultClientPlaceholderRegistry = new PlaceholderRegistry();
|
||||
public static Logger defaultLogger = new Logger();
|
||||
|
||||
// public static JavaTXCompiler INSTANCE;
|
||||
final CompilationEnvironment environment;
|
||||
Boolean resultmodel = true;
|
||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
||||
|
||||
Boolean log = false; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
|
||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||
public final DirectoryClassLoader classLoader;
|
||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||
public final DirectoryClassLoader classLoader;
|
||||
|
||||
public final List<File> classPath;
|
||||
private final File outputPath;
|
||||
@@ -76,14 +88,9 @@ public class JavaTXCompiler {
|
||||
public DirectoryClassLoader getClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
||||
this(Arrays.asList(sourceFile), List.of(), new File("."));
|
||||
}
|
||||
|
||||
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
|
||||
this(sourceFile);
|
||||
this.log = log;
|
||||
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
||||
this(Collections.singletonList(sourceFile), List.of(), new File("."));
|
||||
}
|
||||
|
||||
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
|
||||
@@ -91,6 +98,9 @@ public class JavaTXCompiler {
|
||||
}
|
||||
|
||||
public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath) throws IOException, ClassNotFoundException {
|
||||
// ensure new default placeholder registry for tests
|
||||
defaultClientPlaceholderRegistry = new PlaceholderRegistry();
|
||||
|
||||
var path = new ArrayList<>(contextPath);
|
||||
if (contextPath.isEmpty()) {
|
||||
// When no contextPaths are given, the working directory is the sources root
|
||||
@@ -300,120 +310,51 @@ public class JavaTXCompiler {
|
||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||
UnifyResultModel urm = null;
|
||||
// urm.addUnifyResultListener(resultListener);
|
||||
try {
|
||||
logFile = logFile == null ? new FileWriter(new File("log_" + sourceFiles.keySet().iterator().next().getName())) : logFile;
|
||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, getClassLoader(), this);
|
||||
System.out.println(finiteClosure);
|
||||
urm = new UnifyResultModel(cons, finiteClosure);
|
||||
urm.addUnifyResultListener(resultListener);
|
||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
|
||||
logFile = logFile == null ? new FileWriter("log_" + sourceFiles.keySet().iterator().next().getName()) : logFile;
|
||||
Logger logger = new Logger(logFile, "TypeInferenceAsync");
|
||||
UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, defaultClientPlaceholderRegistry);
|
||||
|
||||
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;
|
||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logger, getClassLoader(), this, context.placeholderRegistry());
|
||||
logger.info(finiteClosure.toString());
|
||||
urm = new UnifyResultModel(cons, finiteClosure);
|
||||
urm.addUnifyResultListener(resultListener);
|
||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons, context.placeholderRegistry());
|
||||
|
||||
};
|
||||
logFile.write(unifyCons.toString());
|
||||
unifyCons = unifyCons.map(distributeInnerVars);
|
||||
logFile.write(unifyCons.toString());
|
||||
TypeUnify unify = new TypeUnify();
|
||||
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
|
||||
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
|
||||
for (SourceFile f : this.sourceFiles.values()) {
|
||||
logFile.write(ASTTypePrinter.print(f));
|
||||
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);
|
||||
}
|
||||
logFile.flush();
|
||||
return x;
|
||||
|
||||
Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
}, (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
})).reduce(new HashSet<String>(), (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
});
|
||||
|
||||
Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
}, (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
})).reduce(new HashSet<String>(), (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
});
|
||||
|
||||
Set<String> paraTypeVarNames = methodParaTypeVarNames;
|
||||
paraTypeVarNames.addAll(constructorParaTypeVarNames);
|
||||
|
||||
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
}).get();
|
||||
|
||||
Set<String> fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
}).get();
|
||||
|
||||
returnTypeVarNames.addAll(fieldTypeVarNames);
|
||||
|
||||
unifyCons = unifyCons.map(x -> {
|
||||
// Hier muss ueberlegt werden, ob
|
||||
// 1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs
|
||||
// mit disableWildcardtable() werden.
|
||||
// 2. alle Typvariablen mit Argument- oder Retuntyp-Variablen
|
||||
// in Beziehung auch auf disableWildcardtable() gesetzt werden muessen
|
||||
// PL 2018-04-23
|
||||
if ((x.getLhsType() instanceof PlaceholderType)) {
|
||||
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
|
||||
((PlaceholderType) x.getLhsType()).setVariance((byte) 1);
|
||||
((PlaceholderType) x.getLhsType()).disableWildcardtable();
|
||||
}
|
||||
if (returnTypeVarNames.contains(x.getLhsType().getName())) {
|
||||
((PlaceholderType) x.getLhsType()).setVariance((byte) -1);
|
||||
((PlaceholderType) x.getLhsType()).disableWildcardtable();
|
||||
}
|
||||
}
|
||||
if ((x.getRhsType() instanceof PlaceholderType)) {
|
||||
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
|
||||
((PlaceholderType) x.getRhsType()).setVariance((byte) 1);
|
||||
((PlaceholderType) x.getRhsType()).disableWildcardtable();
|
||||
}
|
||||
if (returnTypeVarNames.contains(x.getRhsType().getName())) {
|
||||
((PlaceholderType) x.getRhsType()).setVariance((byte) -1);
|
||||
((PlaceholderType) x.getRhsType()).disableWildcardtable();
|
||||
}
|
||||
}
|
||||
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
|
||||
// JEWEILS ANDERE SEITE
|
||||
});
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||
|
||||
/*
|
||||
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
|
||||
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
|
||||
*/
|
||||
|
||||
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
|
||||
// logFile, log);
|
||||
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()/*
|
||||
* .stream().map(x -> { Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors. toCollection(ArrayList::new))
|
||||
*/;
|
||||
unify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
|
||||
} catch (IOException e) {
|
||||
System.err.println("kein LogFile");
|
||||
};
|
||||
logger.debug(unifyCons.toString());
|
||||
unifyCons = unifyCons.map(distributeInnerVars);
|
||||
logger.debug(unifyCons.toString());
|
||||
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
|
||||
logger.debug("FC:\\" + finiteClosure.toString() + "\n");
|
||||
for (SourceFile f : this.sourceFiles.values()) {
|
||||
logger.debug(ASTTypePrinter.print(f));
|
||||
}
|
||||
// logFile.flush();
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||
|
||||
/*
|
||||
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
|
||||
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
|
||||
*/
|
||||
|
||||
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
|
||||
// logFile, log);
|
||||
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()/*
|
||||
* .stream().map(x -> { Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors. toCollection(ArrayList::new))
|
||||
*/;
|
||||
TypeUnify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
|
||||
|
||||
return urm;
|
||||
}
|
||||
|
||||
@@ -433,175 +374,108 @@ public class JavaTXCompiler {
|
||||
|
||||
final ConstraintSet<Pair> cons = getConstraints(file);
|
||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||
try {
|
||||
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/");
|
||||
if (log) logFolder.mkdirs();
|
||||
Writer logFile = log ? new FileWriter(new File(logFolder, "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
|
||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logFile, classLoader, this);
|
||||
System.out.println(finiteClosure);
|
||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
|
||||
System.out.println("xxx1");
|
||||
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
|
||||
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;
|
||||
PlaceholderRegistry placeholderRegistry = new PlaceholderRegistry();
|
||||
|
||||
};
|
||||
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/");
|
||||
if (ConsoleInterface.writeLogFiles && !logFolder.mkdirs()) throw new RuntimeException("Could not creat directoy for log files: " + logFolder);
|
||||
Writer logFile = ConsoleInterface.writeLogFiles ? new FileWriter(new File(logFolder, "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
|
||||
Logger logger = new Logger(logFile, "TypeInference");
|
||||
|
||||
logFile.write("Unify:" + unifyCons.toString());
|
||||
System.out.println("Unify:" + unifyCons.toString());
|
||||
unifyCons = unifyCons.map(distributeInnerVars);
|
||||
logFile.write("\nUnify_distributeInnerVars: " + unifyCons.toString());
|
||||
TypeUnify unify = new TypeUnify();
|
||||
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
|
||||
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
|
||||
logFile.write(ASTTypePrinter.print(sf));
|
||||
System.out.println(ASTTypePrinter.print(sf));
|
||||
logFile.flush();
|
||||
|
||||
Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
}, (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
})).reduce(new HashSet<String>(), (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
});
|
||||
|
||||
Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
}, (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
})).reduce(new HashSet<String>(), (a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
});
|
||||
|
||||
Set<String> paraTypeVarNames = methodParaTypeVarNames;
|
||||
paraTypeVarNames.addAll(constructorParaTypeVarNames);
|
||||
|
||||
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
}).get();
|
||||
|
||||
Set<String> fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
|
||||
a.addAll(b);
|
||||
return a;
|
||||
}).get();
|
||||
|
||||
returnTypeVarNames.addAll(fieldTypeVarNames);
|
||||
|
||||
unifyCons = unifyCons.map(x -> {
|
||||
// Hier muss ueberlegt werden, ob
|
||||
// 1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs
|
||||
// mit disableWildcardtable() werden.
|
||||
// 2. alle Typvariablen mit Argument- oder Retuntyp-Variablen
|
||||
// in Beziehung auch auf disableWildcardtable() gesetzt werden muessen
|
||||
// PL 2018-04-23
|
||||
if ((x.getLhsType() instanceof PlaceholderType)) {
|
||||
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
|
||||
((PlaceholderType) x.getLhsType()).setVariance((byte) 1);
|
||||
((PlaceholderType) x.getLhsType()).disableWildcardtable();
|
||||
}
|
||||
if (returnTypeVarNames.contains(x.getLhsType().getName())) {
|
||||
((PlaceholderType) x.getLhsType()).setVariance((byte) -1);
|
||||
((PlaceholderType) x.getLhsType()).disableWildcardtable();
|
||||
}
|
||||
}
|
||||
if ((x.getRhsType() instanceof PlaceholderType)) {
|
||||
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
|
||||
((PlaceholderType) x.getRhsType()).setVariance((byte) 1);
|
||||
((PlaceholderType) x.getRhsType()).disableWildcardtable();
|
||||
}
|
||||
if (returnTypeVarNames.contains(x.getRhsType().getName())) {
|
||||
((PlaceholderType) x.getRhsType()).setVariance((byte) -1);
|
||||
((PlaceholderType) x.getRhsType()).disableWildcardtable();
|
||||
}
|
||||
}
|
||||
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
|
||||
// JEWEILS ANDERE SEITE
|
||||
});
|
||||
|
||||
// PL 2020-02-05 alle Oder-Constraints Receiver und Parameter werden auf
|
||||
// variance 1 gesetzt
|
||||
// Es wird davon ausgegangen, dass in OderConstraints in Bedingungen für
|
||||
// Parameter die Typen der Argumente links stehen
|
||||
// und die Typen der Rückgabewerte immer rechts stehen
|
||||
|
||||
/*
|
||||
* unifyCons.getOderConstraints().forEach(z -> z.forEach(y -> y.forEach(x -> { if ((x.getLhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.SMALLERDOT) == 0) { ((PlaceholderType) x.getLhsType()).setVariance((byte)1); } else if ((x.getRhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.EQUALSDOT) == 0) { ((PlaceholderType) x.getRhsType()).setVariance((byte)-1); } })));
|
||||
*/
|
||||
|
||||
System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString());
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||
|
||||
/*
|
||||
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
|
||||
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
|
||||
*/
|
||||
|
||||
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
|
||||
// logFile, log);
|
||||
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()// .stream().map(x -> {
|
||||
/*
|
||||
* Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors.toCollection(ArrayList::new))
|
||||
*/;
|
||||
if (resultmodel) {
|
||||
/* UnifyResultModel Anfang */
|
||||
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
||||
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
|
||||
urm.addUnifyResultListener(li);
|
||||
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
|
||||
System.out.println("RESULT Final: " + li.getResults());
|
||||
System.out.println("Constraints for Generated Generics: " + " ???");
|
||||
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
|
||||
logFile.flush();
|
||||
return li.getResults();
|
||||
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logger, classLoader, this, placeholderRegistry);
|
||||
logger.info(finiteClosure.toString());
|
||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons, placeholderRegistry);
|
||||
logger.info("xxx1");
|
||||
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
|
||||
UnifyType lhs, rhs;
|
||||
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
|
||||
((PlaceholderType) lhs).setInnerType(true);
|
||||
((PlaceholderType) rhs).setInnerType(true);
|
||||
}
|
||||
/* UnifyResultModel End */
|
||||
else {
|
||||
// Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(),
|
||||
// oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons,
|
||||
// finiteClosure));
|
||||
Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure), usedTasks);
|
||||
System.out.println("RESULT: " + result);
|
||||
logFile.write("RES: " + result.toString() + "\n");
|
||||
logFile.flush();
|
||||
results.addAll(result);
|
||||
return x;
|
||||
|
||||
results = results.stream().map(x -> {
|
||||
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
|
||||
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
|
||||
y.setPairOp(PairOperator.EQUALSDOT);
|
||||
return y; // alle Paare a <.? b erden durch a =. b ersetzt
|
||||
}).collect(Collectors.toCollection(HashSet::new)));
|
||||
if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert
|
||||
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure);
|
||||
} else
|
||||
return x; // wenn nichts veraendert wurde wird x zurueckgegeben
|
||||
}).collect(Collectors.toCollection(HashSet::new));
|
||||
System.out.println("RESULT Final: " + results);
|
||||
System.out.println("Constraints for Generated Generics: " + " ???");
|
||||
logFile.write("RES_FINAL: " + results.toString() + "\n");
|
||||
logFile.flush();
|
||||
logFile.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS);
|
||||
logFile.flush();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.err.println("kein LogFile");
|
||||
};
|
||||
|
||||
logger.debug("Unify:" + unifyCons.toString());
|
||||
logger.info("Unify:" + unifyCons.toString());
|
||||
unifyCons = unifyCons.map(distributeInnerVars);
|
||||
logger.debug("\nUnify_distributeInnerVars: " + unifyCons.toString());
|
||||
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
|
||||
logger.debug("FC:\\" + finiteClosure.toString() + "\n");
|
||||
logger.debug(ASTTypePrinter.print(sf));
|
||||
logger.info(ASTTypePrinter.print(sf));
|
||||
// logFile.flush();
|
||||
logger.info("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString());
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||
|
||||
/*
|
||||
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
|
||||
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
|
||||
*/
|
||||
|
||||
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
|
||||
// logFile, log);
|
||||
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()// .stream().map(x -> {
|
||||
/*
|
||||
* Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors.toCollection(ArrayList::new))
|
||||
*/;
|
||||
|
||||
if (ConsoleInterface.unifyServerUrl.isPresent()) {
|
||||
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
||||
UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, placeholderRegistry);
|
||||
SocketFuture<UnifyResultPacket> future = SocketClient.execute(
|
||||
UnifyRequestPacket.create(finiteClosure, cons, unifyCons, context.placeholderRegistry())
|
||||
);
|
||||
SocketClient.execute(SetAutoclosePacket.create());
|
||||
return future.get().getResultSet(context);
|
||||
}
|
||||
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList());
|
||||
else if (resultmodel) {
|
||||
/* UnifyResultModel Anfang */
|
||||
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
||||
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
|
||||
urm.addUnifyResultListener(li);
|
||||
UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, placeholderRegistry);
|
||||
TypeUnify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
|
||||
logger.info("RESULT Final: " + li.getResults());
|
||||
logger.info("Constraints for Generated Generics: " + " ???");
|
||||
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
|
||||
// logFile.flush();
|
||||
return li.getResults();
|
||||
}
|
||||
/* UnifyResultModel End */
|
||||
else {
|
||||
// Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(),
|
||||
// oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons,
|
||||
// finiteClosure));
|
||||
UnifyContext context = new UnifyContext(logger, false, new UnifyResultModel(cons, finiteClosure), usedTasks, placeholderRegistry);
|
||||
Set<Set<UnifyPair>> result = TypeUnify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
|
||||
logger.info("RESULT: " + result);
|
||||
logFile.write("RES: " + result.toString() + "\n");
|
||||
// logFile.flush();
|
||||
results.addAll(result);
|
||||
|
||||
results = results.stream().map(x -> {
|
||||
Optional<Set<UnifyPair>> res = new RuleSet(placeholderRegistry).subst(x.stream().map(y -> {
|
||||
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
|
||||
y.setPairOp(PairOperator.EQUALSDOT);
|
||||
return y; // alle Paare a <.? b erden durch a =. b ersetzt
|
||||
}).collect(Collectors.toCollection(HashSet::new)));
|
||||
if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert
|
||||
return new TypeUnifyTask(context).applyTypeUnificationRules(res.get(), finiteClosure);
|
||||
} else
|
||||
return x; // wenn nichts veraendert wurde wird x zurueckgegeben
|
||||
}).collect(Collectors.toCollection(HashSet::new));
|
||||
logger.info("RESULT Final: " + results);
|
||||
logger.info("Constraints for Generated Generics: " + " ???");
|
||||
logger.debug("RES_FINAL: " + results.toString() + "\n");
|
||||
// logFile.flush();
|
||||
logger.debug("PLACEHOLDERS: " + placeholderRegistry);
|
||||
// logFile.flush();
|
||||
}
|
||||
|
||||
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons), placeholderRegistry)))).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -733,10 +607,6 @@ public class JavaTXCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path - output-Directory can be null, then class file output is in the same directory as the parsed source files
|
||||
* @return
|
||||
*/
|
||||
public Map<JavaClassName, byte[]> generateBytecode(File sourceFile) throws ClassNotFoundException, IOException {
|
||||
var sf = sourceFiles.get(sourceFile);
|
||||
if (sf.isGenerated()) return null;
|
||||
@@ -791,15 +661,15 @@ public class JavaTXCompiler {
|
||||
FileOutputStream output;
|
||||
for (JavaClassName name : classFiles.keySet()) {
|
||||
byte[] bytecode = classFiles.get(name);
|
||||
System.out.println("generating " + name + ".class file ...");
|
||||
defaultLogger.info("generating " + name + ".class file ...");
|
||||
var subPath = preserveHierarchy ? path : Path.of(path.toString(), name.getPackageName().split("\\.")).toFile();
|
||||
File outputFile = new File(subPath, name.getClassName() + ".class");
|
||||
outputFile.getAbsoluteFile().getParentFile().mkdirs();
|
||||
System.out.println(outputFile);
|
||||
defaultLogger.info(outputFile.toString());
|
||||
output = new FileOutputStream(outputFile);
|
||||
output.write(bytecode);
|
||||
output.close();
|
||||
System.out.println(name + ".class file generated");
|
||||
defaultLogger.success(name + ".class file generated");
|
||||
}
|
||||
}
|
||||
|
||||
|
31
src/main/java/de/dhbwstuttgart/core/JavaTXServer.java
Normal file
31
src/main/java/de/dhbwstuttgart/core/JavaTXServer.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package de.dhbwstuttgart.core;
|
||||
|
||||
import de.dhbwstuttgart.server.SocketServer;
|
||||
|
||||
public class JavaTXServer {
|
||||
|
||||
public static boolean isRunning = false;
|
||||
|
||||
final SocketServer socketServer;
|
||||
|
||||
public JavaTXServer(int port) {
|
||||
this.socketServer = new SocketServer(port);
|
||||
}
|
||||
|
||||
public void listen() {
|
||||
isRunning = true;
|
||||
socketServer.start();
|
||||
}
|
||||
|
||||
public void forceStop() {
|
||||
try {
|
||||
socketServer.stop();
|
||||
}
|
||||
catch (InterruptedException exception) {
|
||||
System.err.println("Interrupted socketServer: " + exception);
|
||||
}
|
||||
isRunning = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
package de.dhbwstuttgart.exceptions;
|
||||
|
||||
|
||||
/**
|
||||
* Eine Runtime Exception, die für den Fall genutzt wird, dass eine Unifikation abgebrochen wird.
|
||||
* Durch das Werfen einer Exception können Abbrüche auch aus Methodenaufrufen heraus
|
||||
* geprüft werden, da zuvor nur ein return X; stattfinden würde.
|
||||
*/
|
||||
public class UnifyCancelException extends RuntimeException {
|
||||
|
||||
}
|
@@ -7,6 +7,7 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
|
||||
import de.dhbwstuttgart.util.Logger;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
@@ -17,6 +18,9 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class JavaTXParser {
|
||||
|
||||
public static Logger logger = new Logger("Parser");
|
||||
|
||||
public static Java17Parser.SourceFileContext parse(File source) throws IOException, java.lang.ClassNotFoundException {
|
||||
InputStream stream = new FileInputStream(source);
|
||||
// DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream);
|
||||
|
@@ -1,4 +1,25 @@
|
||||
package de.dhbwstuttgart.parser;
|
||||
|
||||
public record SourceLoc(String file, int line) {
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
|
||||
public record SourceLoc(String file, int line) implements ISerializableData {
|
||||
|
||||
|
||||
@Override
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
var serialized = new SerialMap();
|
||||
serialized.put("file", file);
|
||||
serialized.put("line", line);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
public static SourceLoc fromSerial(SerialMap data) {
|
||||
return new SourceLoc(
|
||||
data.getValue("file").getOf(String.class),
|
||||
data.getValue("line").getOf(Integer.class)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.*;
|
||||
|
||||
import java.util.*;
|
||||
@@ -26,16 +27,21 @@ public class FCGenerator {
|
||||
*
|
||||
* @param availableClasses - Alle geparsten Klassen
|
||||
*/
|
||||
public static Set<UnifyPair> toUnifyFC(JavaTXCompiler compiler, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
|
||||
return toFC(availableClasses, classLoader).stream().map(t -> UnifyTypeFactory.convert(compiler, t)).collect(Collectors.toSet());
|
||||
public static Set<UnifyPair> toUnifyFC(JavaTXCompiler compiler, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader, PlaceholderRegistry placeholderRegistry) throws ClassNotFoundException {
|
||||
return toFC(
|
||||
availableClasses,
|
||||
classLoader,
|
||||
placeholderRegistry
|
||||
).stream().map(t -> UnifyTypeFactory.convert(compiler, t, placeholderRegistry))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
|
||||
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses, ClassLoader classLoader, PlaceholderRegistry placeholderRegistry) throws ClassNotFoundException {
|
||||
HashSet<Pair> pairs = new HashSet<>();
|
||||
//PL 2018-09-18: gtvs vor die for-Schleife gezogen, damit immer die gleichen Typeplaceholder eingesetzt werden.
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
|
||||
for(ClassOrInterface cly : availableClasses){
|
||||
List<Pair> newPairs = getSuperTypes(cly, availableClasses, gtvs, classLoader);
|
||||
List<Pair> newPairs = getSuperTypes(cly, availableClasses, gtvs, classLoader, placeholderRegistry);
|
||||
pairs.addAll(newPairs);
|
||||
|
||||
//For all Functional Interfaces FI: FunN$$<... args auf dem Functional Interface ...> <. FI is added to FC
|
||||
@@ -75,8 +81,13 @@ public class FCGenerator {
|
||||
* @param forType
|
||||
* @return
|
||||
*/
|
||||
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
|
||||
return getSuperTypes(forType, availableClasses, new HashMap<>(), classLoader);
|
||||
private static List<Pair> getSuperTypes(
|
||||
ClassOrInterface forType,
|
||||
Collection<ClassOrInterface> availableClasses,
|
||||
ClassLoader classLoader,
|
||||
PlaceholderRegistry placeholderRegistry
|
||||
) throws ClassNotFoundException {
|
||||
return getSuperTypes(forType, availableClasses, new HashMap<>(), classLoader, placeholderRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,8 +98,13 @@ public class FCGenerator {
|
||||
* @return
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses,
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs, ClassLoader classLoader) throws ClassNotFoundException {
|
||||
private static List<Pair> getSuperTypes(
|
||||
ClassOrInterface forType,
|
||||
Collection<ClassOrInterface> availableClasses,
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs,
|
||||
ClassLoader classLoader,
|
||||
PlaceholderRegistry placeholderRegistry
|
||||
) throws ClassNotFoundException {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
//Die GTVs, die in forType hinzukommen:
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> newGTVs = new HashMap<>();
|
||||
@@ -147,7 +163,7 @@ public class FCGenerator {
|
||||
if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){
|
||||
superTypes = Arrays.asList(new Pair(ASTFactory.createObjectType(), ASTFactory.createObjectType(), PairOperator.SMALLER));
|
||||
}else{
|
||||
superTypes = getSuperTypes(superClass, availableClasses, newGTVs, classLoader);
|
||||
superTypes = getSuperTypes(superClass, availableClasses, newGTVs, classLoader, placeholderRegistry);
|
||||
}
|
||||
|
||||
retList.add(ret);
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
||||
|
||||
import de.dhbwstuttgart.parser.JavaTXParser;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -14,6 +15,8 @@ import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
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 de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
@@ -101,7 +104,6 @@ import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import org.stringtemplate.v4.ST;
|
||||
|
||||
public class StatementGenerator {
|
||||
|
||||
@@ -125,7 +127,7 @@ public class StatementGenerator {
|
||||
this.superClass = superType;
|
||||
}
|
||||
|
||||
public ParameterList convert(Java17Parser.FormalParameterListContext formalParameterListContext) {
|
||||
public ParameterList convert(Java17Parser.FormalParameterListContext formalParameterListContext, boolean methodparameters) {
|
||||
List<Pattern> ret = new ArrayList<>();
|
||||
List<Java17Parser.FormalParameterContext> fps = new ArrayList<>();
|
||||
if (Objects.isNull(formalParameterListContext))
|
||||
@@ -147,10 +149,12 @@ public class StatementGenerator {
|
||||
if (fp.typeType() != null) {
|
||||
type = TypeGenerator.convert(fp.typeType(), reg, generics);
|
||||
} 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()));
|
||||
localVars.put(paramName, type);
|
||||
localVars.put(paramName, type);
|
||||
}
|
||||
}
|
||||
return new ParameterList(ret, ret.get(0).getOffset());
|
||||
@@ -256,7 +260,7 @@ public class StatementGenerator {
|
||||
ret.setStatement();
|
||||
return ret;
|
||||
default:
|
||||
System.out.println(stmt.getClass());
|
||||
JavaTXParser.logger.info(stmt.getClass());
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -439,6 +443,7 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
private Pattern convert(PatternContext pattern) {
|
||||
|
||||
return switch (pattern) {
|
||||
case PPatternContext pPattern -> {
|
||||
yield convert(pPattern.primaryPattern());
|
||||
@@ -453,30 +458,36 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
private FormalParameter convert(PrimaryPatternContext pPattern) {
|
||||
|
||||
switch (pPattern) {
|
||||
case TPatternContext tPattern:
|
||||
TypePatternContext typePattern = tPattern.typePattern();
|
||||
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);
|
||||
return new FormalParameter(text, type, typePattern.getStart());
|
||||
case RPatternContext rPattern:
|
||||
RecordPatternContext recordPattern = rPattern.recordPattern();
|
||||
return convert(recordPattern);
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
case Java17Parser.LPatternContext patternContext: return new LiteralPattern(TypePlaceholder.fresh(patternContext.start), convert(patternContext.literal().get(0)), patternContext.start);
|
||||
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
IdentifierContext identifierCtx = recordPatternCtx.identifier();
|
||||
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);
|
||||
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) {
|
||||
@@ -583,7 +594,7 @@ public class StatementGenerator {
|
||||
initValue = convert(varDecl.variableInitializer().expression());
|
||||
}
|
||||
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) {
|
||||
@@ -697,8 +708,7 @@ public class StatementGenerator {
|
||||
if (!Objects.isNull(expr.methodCall())) {
|
||||
return convert(expr.methodCall(), expr.expression(), offset);
|
||||
} else if (!Objects.isNull(expr.identifier())) {
|
||||
// FIXME This is not the right way of handling any of this
|
||||
return generateLocalOrFieldVarOrClassName(expr.getText(), offset);
|
||||
return new FieldVar(convert(expr.expression()), expr.identifier().getText(), TypePlaceholder.fresh(expr.identifier().start), offset);
|
||||
} else {
|
||||
// Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite
|
||||
// generische Invokationen
|
||||
@@ -774,64 +784,25 @@ public class StatementGenerator {
|
||||
|
||||
/**
|
||||
* Der Parser kann nicht zwischen einer lokalen Variable, einem Feldzugriff und einer Klassenangabe unterscheiden.
|
||||
*
|
||||
*
|
||||
* @param expression
|
||||
* @param offset
|
||||
* @return
|
||||
*/
|
||||
private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) {
|
||||
// FIXME Why does this take a String argument???
|
||||
String[] parts = expression.split("\\.");
|
||||
if (parts.length < 2) {
|
||||
// Check for localVar:
|
||||
if (localVars.get(expression) != null) {
|
||||
return new LocalVar(expression, localVars.get(expression), offset);
|
||||
} else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die
|
||||
// gleiche TPH bekommen
|
||||
var field = fields.get(expression);
|
||||
return new FieldVar(new This(offset), Modifier.isStatic(field.modifiers()), expression, fields.get(expression).type(), offset);
|
||||
} else if (reg.contains(expression)) {
|
||||
return generateStaticClassName(expression, offset);
|
||||
} else {
|
||||
// lokale Variable wurde ohne "var"-Keyword deklariert und direkt mit Wert versehen
|
||||
localVars.put(expression, TypePlaceholder.fresh(offset));
|
||||
return new LocalVar(expression, localVars.get(expression), offset);
|
||||
}
|
||||
}
|
||||
return generateFieldVarOrClassname(expression, offset);
|
||||
}
|
||||
|
||||
private Expression generateFieldVarOrClassname(String expression, Token offset) {
|
||||
String[] parts = expression.split("\\.");
|
||||
String whole = "";
|
||||
Expression receiver = null;
|
||||
for (String part : parts) {
|
||||
whole += part;
|
||||
// Check for Classname:
|
||||
if (reg.contains(whole)) {
|
||||
receiver = generateStaticClassName(whole, offset);
|
||||
break;
|
||||
}
|
||||
whole += ".";
|
||||
}
|
||||
var fieldName = parts[parts.length - 1];
|
||||
|
||||
var isStatic = false;
|
||||
if (parts.length < 2 || parts[0].contentEquals("this")) {
|
||||
receiver = new This(offset);
|
||||
isStatic = Modifier.isStatic(fields.get(fieldName).modifiers());
|
||||
} else if (parts[0].contentEquals("super")) {
|
||||
receiver = new Super(TypePlaceholder.fresh(offset), offset);
|
||||
isStatic = Modifier.isStatic(compiler.getClass(new JavaClassName(superClass.getName().toString())).getField(fieldName).orElseThrow().modifier);
|
||||
} else if (receiver == null) { // Handelt es sich um keinen Statischen Klassennamen:
|
||||
String part = expression.substring(0, expression.length() - (1 + parts[parts.length - 1].length()));
|
||||
receiver = generateLocalOrFieldVarOrClassName(part, offset);
|
||||
// Check for localVar:
|
||||
if (localVars.get(expression) != null) {
|
||||
return new LocalVar(expression, localVars.get(expression), offset);
|
||||
} else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die
|
||||
// gleiche TPH bekommen
|
||||
return new FieldVar(new This(offset), expression, fields.get(expression).type(), offset);
|
||||
} else if (reg.contains(expression)) {
|
||||
return generateStaticClassName(expression, offset);
|
||||
} else {
|
||||
StaticClassName cname = (StaticClassName) receiver;
|
||||
var javaClassName = reg.getName(cname.getType().toString());
|
||||
isStatic = Modifier.isStatic(compiler.getClass(javaClassName).getField(fieldName).orElseThrow().modifier);
|
||||
// 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 new FieldVar(receiver, isStatic, fieldName, TypePlaceholder.fresh(offset), offset);
|
||||
}
|
||||
|
||||
private Expression convert(Java17Parser.ArrayaccessexpressionContext arrayaccess) {
|
||||
@@ -867,10 +838,8 @@ public class StatementGenerator {
|
||||
private Statement convert(AssignexpressionContext expr) {
|
||||
switch (expr.bop.getText()) {
|
||||
case "=":
|
||||
ExpressionContext leftside = expr.expression(0);
|
||||
AssignLeftSide leftHandSide = convert(leftside.getText(), leftside.getStart());
|
||||
Statement ret = new Assign(leftHandSide, convert(expr.expression(1)), expr.getStart());
|
||||
return ret;
|
||||
AssignLeftSide leftHandSide = convertAssignLHS(convert(expr.expression(0)));
|
||||
return new Assign(leftHandSide, convert(expr.expression(1)), expr.getStart());
|
||||
case "+=":
|
||||
case "-=":
|
||||
case "*=":
|
||||
@@ -887,8 +856,8 @@ public class StatementGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
private AssignLeftSide convert(String leftHandSide, Token start) {
|
||||
Expression leftSide = generateLocalOrFieldVarOrClassName(leftHandSide, start);
|
||||
private AssignLeftSide convertAssignLHS(Expression expr) {
|
||||
Expression leftSide = expr;
|
||||
if (leftSide instanceof FieldVar)
|
||||
return new AssignToField((FieldVar) leftSide);
|
||||
else if (leftSide instanceof LocalVar)
|
||||
@@ -1101,7 +1070,7 @@ public class StatementGenerator {
|
||||
}
|
||||
params = new ParameterList(parameterList, lambdaParams.getStart());
|
||||
} else if (lambdaParams.formalParameterList() != null) {
|
||||
params = convert(lambdaParams.formalParameterList());
|
||||
params = convert(lambdaParams.formalParameterList(), false);
|
||||
// }else if( lambdaParams.inferredFormalParameterList != null){
|
||||
} else if (!Objects.isNull(lambdaParams.lambdaLVTIList())) {
|
||||
List<Pattern> parameterList = new ArrayList<>();
|
||||
|
@@ -269,7 +269,7 @@ public class SyntaxTreeGenerator {
|
||||
}
|
||||
fielddecl.add(new Field(fieldname, fieldtype, fieldmodifiers, fieldoffset));
|
||||
constructorParameters.add(new FormalParameter(fieldname, fieldtype, fieldoffset));
|
||||
FieldVar fieldvar = new FieldVar(new This(offset), false, fieldname, fieldtype, fieldoffset);
|
||||
FieldVar fieldvar = new FieldVar(new This(offset), fieldname, fieldtype, fieldoffset);
|
||||
constructorStatements.add(new Assign(new AssignToField(fieldvar), new LocalVar(fieldname, fieldtype, fieldoffset), offset));
|
||||
Statement returnStatement = new Return(fieldvar, offset);
|
||||
methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset));
|
||||
@@ -393,12 +393,12 @@ public class SyntaxTreeGenerator {
|
||||
if (!Objects.isNull(ctx.EXTENDS())) {
|
||||
extendedInterfaces.addAll(convert(ctx.typeList(0), generics));
|
||||
}
|
||||
List<RefType> permittedSubtypes = new ArrayList<>();
|
||||
List<RefType> permittedSubtypes = null;
|
||||
// Ist Bit für 'sealed'-Modifier gesetzt
|
||||
if ((modifiers & 4096) != 0) {
|
||||
if (!Objects.isNull(ctx.PERMITS())) {
|
||||
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
|
||||
permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
|
||||
permittedSubtypes = new ArrayList<>(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
|
||||
} else {
|
||||
// falls sealed modifier ohne 'permits'-List oder umgekehrt
|
||||
throw new NotImplementedException("Invalid sealed class declaration");
|
||||
@@ -435,7 +435,7 @@ public class SyntaxTreeGenerator {
|
||||
}
|
||||
}
|
||||
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();
|
||||
Block block = null;
|
||||
if (!(body instanceof EmptymethodContext)) {
|
||||
@@ -532,7 +532,7 @@ public class SyntaxTreeGenerator {
|
||||
|
||||
RefTypeOrTPHOrWildcardOrGeneric retType;
|
||||
if (Objects.isNull(header.refType())) {
|
||||
retType = TypePlaceholder.fresh(header.getStart());
|
||||
retType = TypePlaceholder.fresh(header.getStart(), -1, false);
|
||||
} else {
|
||||
if (header.refType() instanceof RefType2Context reftype) {
|
||||
retType = TypeGenerator.convert(reftype.typeType(), reg, generics);
|
||||
@@ -541,7 +541,7 @@ public class SyntaxTreeGenerator {
|
||||
}
|
||||
}
|
||||
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();
|
||||
Block block = null;
|
||||
if (body instanceof EmptymethodContext emptymethod) {
|
||||
@@ -581,7 +581,7 @@ public class SyntaxTreeGenerator {
|
||||
}
|
||||
RefTypeOrTPHOrWildcardOrGeneric retType = TypeGenerator.convertTypeName(name, constructordeclaration.getStart(), reg, localgenerics);
|
||||
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
|
||||
ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList());
|
||||
ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList(), true);
|
||||
Block block = prepareBlock(stmtgen.convert(constructordeclaration.constructorBody, true), superClass);
|
||||
return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart());
|
||||
}
|
||||
@@ -594,7 +594,7 @@ public class SyntaxTreeGenerator {
|
||||
} else {
|
||||
// PL 2019-12-06: variableDeclaratorList() eingefuegt, um als Token nicht die
|
||||
// Modifier zu bekommen
|
||||
fieldType = TypePlaceholder.fresh(fieldDeclContext.variableDeclarators().getStart());
|
||||
fieldType = TypePlaceholder.fresh(fieldDeclContext.variableDeclarators().getStart(), -1, false);
|
||||
}
|
||||
for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) {
|
||||
String fieldName = varDecl.variableDeclaratorId().getText();
|
||||
|
@@ -74,7 +74,7 @@ public class TypeGenerator {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
} else if (!typeContext.LBRACK().isEmpty()) { // ArrayType über eckige Klammer prüfen
|
||||
// System.out.println(unannTypeContext.getText());
|
||||
// JavaTXParser.logger.info(unannTypeContext.getText());
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
/*
|
||||
|
41
src/main/java/de/dhbwstuttgart/server/ServerTaskLogger.java
Normal file
41
src/main/java/de/dhbwstuttgart/server/ServerTaskLogger.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package de.dhbwstuttgart.server;
|
||||
|
||||
import de.dhbwstuttgart.util.Logger;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
public class ServerTaskLogger extends Logger {
|
||||
|
||||
private final WebSocket webSocket;
|
||||
private final SocketServer socketServer;
|
||||
private final LogLevel customLogLevel;
|
||||
|
||||
public ServerTaskLogger(WebSocket webSocket, SocketServer socketServer, LogLevel customLogLevel) {
|
||||
this.webSocket = webSocket;
|
||||
this.socketServer = socketServer;
|
||||
this.customLogLevel = customLogLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogLevelActive(LogLevel logLevel) {
|
||||
return logLevel.isHigherOrEqualTo(customLogLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void print(String s, LogLevel logLevel) {
|
||||
String coloredPrefix = this.getPrefix(logLevel);
|
||||
if (logLevel.isHigherOrEqualTo(LogLevel.ERROR)) {
|
||||
socketServer.sendError(webSocket, coloredPrefix + s, false);
|
||||
}
|
||||
else {
|
||||
socketServer.sendMessage(webSocket, coloredPrefix + s);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void write(String s) {
|
||||
// under no circumstances write anything to a file
|
||||
}
|
||||
|
||||
}
|
202
src/main/java/de/dhbwstuttgart/server/SocketClient.java
Normal file
202
src/main/java/de/dhbwstuttgart/server/SocketClient.java
Normal file
@@ -0,0 +1,202 @@
|
||||
package de.dhbwstuttgart.server;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.dhbwstuttgart.core.ConsoleInterface;
|
||||
import de.dhbwstuttgart.server.packet.IClientToServerPacket;
|
||||
import de.dhbwstuttgart.server.packet.IPacket;
|
||||
import de.dhbwstuttgart.server.packet.IServerToClientPacket;
|
||||
import de.dhbwstuttgart.server.packet.PacketContainer;
|
||||
import de.dhbwstuttgart.server.packet.UnifyRequestPacket;
|
||||
import de.dhbwstuttgart.server.packet.UnifyResultPacket;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
import de.dhbwstuttgart.util.Logger;
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.java_websocket.client.WebSocketClient;
|
||||
import org.java_websocket.enums.ReadyState;
|
||||
import org.java_websocket.handshake.ServerHandshake;
|
||||
|
||||
|
||||
/**
|
||||
* The Client-side of the websocket
|
||||
*/
|
||||
public class SocketClient extends WebSocketClient {
|
||||
|
||||
public static Logger logger = new Logger("SocketClient");
|
||||
|
||||
/**
|
||||
* The singleton object
|
||||
*/
|
||||
private static SocketClient socketClient = null;
|
||||
|
||||
/**
|
||||
* List of futures that are still waiting to be fulfilled
|
||||
*/
|
||||
private final Map<String, SocketFuture<?>> responseFutures = new HashMap<>();
|
||||
|
||||
private SocketClient(String url) {
|
||||
super(
|
||||
URI.create(url), // target url
|
||||
//SocketServer.perMessageDeflateDraft, // enable compression
|
||||
Map.of( // headers
|
||||
"packetProtocolVersion", SocketServer.packetProtocolVersion
|
||||
)
|
||||
);
|
||||
|
||||
// make sure the url is in a valid format
|
||||
final String regex = "^wss?://(\\w+(\\.\\w+)?)*:(\\d+)$";
|
||||
final Matcher matcher = Pattern.compile(regex).matcher(url);
|
||||
if (!matcher.find()) {
|
||||
throw new RuntimeException("Provided string \"" + url + "\" is not a valid server URL! Use pattern ws(s?)://<host.name>:<port>");
|
||||
}
|
||||
|
||||
try {
|
||||
// wait for the connection to be set up
|
||||
this.connectBlocking();
|
||||
// make sure the connection has been established successfully
|
||||
if (this.getReadyState() != ReadyState.OPEN) {
|
||||
throw new RuntimeException("WebSocket Client could not connect to remote host at " + this.uri);
|
||||
}
|
||||
} catch (InterruptedException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
|
||||
// add a shutdown hook to close the connection when the process ends or is stopped by a SIGINT signal
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(this::close));
|
||||
}
|
||||
|
||||
private SocketClient(String host, int port, boolean secure) throws InterruptedException {
|
||||
this(String.format("%s://%s:%d/", secure ? "wss" : "ws", host, port));
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton access method, creates one if none is available
|
||||
*
|
||||
* @return The one and only socketClient
|
||||
*/
|
||||
private static SocketClient initializeClient() {
|
||||
if (socketClient == null) {
|
||||
socketClient = new SocketClient(ConsoleInterface.unifyServerUrl.get());
|
||||
}
|
||||
return socketClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a packet to the server (connection will be created, if none is found) and return a future
|
||||
* for the response packet
|
||||
*/
|
||||
synchronized public static <T extends IServerToClientPacket> SocketFuture<T> execute(IClientToServerPacket<T> packet) {
|
||||
SocketClient client = initializeClient();
|
||||
|
||||
/*
|
||||
* Create a future that will be associated with the packet and eventually completed
|
||||
*/
|
||||
SocketFuture<T> future = packet.getFuture();
|
||||
if (!future.isDone()) {
|
||||
client.responseFutures.put(future.futureId, future);
|
||||
}
|
||||
|
||||
/*
|
||||
* Establish connection, if not already done.
|
||||
* Serialize the packet and send it to the server.
|
||||
* Return the future to be handled by the caller.
|
||||
*/
|
||||
try {
|
||||
String json = PacketContainer.serialize(packet);
|
||||
client.send(json);
|
||||
} catch (Exception exception) {
|
||||
logger.exception(exception);
|
||||
throw new RuntimeException("Exception occurred in server connection: ", exception);
|
||||
}
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for waiting and retrieving the response immediately
|
||||
*
|
||||
* @param packet The packet to send
|
||||
* @param <T> The type of response packet to await
|
||||
* @return The response packet, once it is received
|
||||
*/
|
||||
public static <T extends IServerToClientPacket> T executeAndGet(IClientToServerPacket<T> packet) {
|
||||
return SocketClient.execute(packet).get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific client-side implementations to handle incoming packets
|
||||
*/
|
||||
protected void handleReceivedPacket(IPacket packet) {
|
||||
if (!(packet instanceof IServerToClientPacket serverToClientPacket)) {
|
||||
System.err.println("Received package of invalid type + " + packet.getClass().getName());
|
||||
this.close();
|
||||
return;
|
||||
}
|
||||
|
||||
serverToClientPacket.onHandle(this.getConnection(), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete a registered future, so it can be handled by whoever executed the creator task
|
||||
*
|
||||
* @param id The associated id for this future
|
||||
* @param trigger The object triggering the completion
|
||||
*/
|
||||
public void completeResponseFuture(String id, IServerToClientPacket trigger) {
|
||||
SocketFuture<?> future = this.responseFutures.remove(id);
|
||||
if (future == null) return;
|
||||
if (!future.accept(trigger)) {
|
||||
throw new RuntimeException("Packet " + trigger.getClass().getName() + " tried to complete future, but was not allowed to");
|
||||
}
|
||||
}
|
||||
|
||||
public static void closeIfOpen() {
|
||||
if (socketClient != null && socketClient.isOpen()) {
|
||||
socketClient.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(ServerHandshake handshakedata) {
|
||||
logger.success("Connected to server with status " + handshakedata.getHttpStatus());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
// logger.info("received: " + message);
|
||||
IPacket packet = PacketContainer.deserialize(message);
|
||||
this.handleReceivedPacket(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(int code, String reason, boolean remote) {
|
||||
logger.info(
|
||||
"Disconnected from server " +
|
||||
"with code " + code + " " +
|
||||
(reason.isEmpty() ? "" : "and reason " + reason + " ") +
|
||||
"(closed by remote: " + remote + ")"
|
||||
);
|
||||
|
||||
if (!this.responseFutures.isEmpty()) {
|
||||
throw new RuntimeException("Server closed before all required tasks were answered");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception e) {
|
||||
logger.exception(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
48
src/main/java/de/dhbwstuttgart/server/SocketFuture.java
Normal file
48
src/main/java/de/dhbwstuttgart/server/SocketFuture.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package de.dhbwstuttgart.server;
|
||||
|
||||
import de.dhbwstuttgart.server.packet.IServerToClientPacket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class SocketFuture<T extends IServerToClientPacket> extends CompletableFuture<T> {
|
||||
|
||||
public final String futureId = UUID.randomUUID().toString();
|
||||
|
||||
public final List<Class<T>> allowedTriggers;
|
||||
|
||||
public SocketFuture(List<Class<T>> allowedTriggers) {
|
||||
this.allowedTriggers = allowedTriggers;
|
||||
}
|
||||
|
||||
public boolean accept(IServerToClientPacket trigger) {
|
||||
if (this.allowedTriggers.contains(trigger.getClass())) {
|
||||
this.complete((T)trigger);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
try {
|
||||
return super.get();
|
||||
}
|
||||
catch (InterruptedException | ExecutionException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Special case where the future is immediately fulfilled without a response package similar to
|
||||
* <code>CompletableFuture.completedFuture()</code> but without a value
|
||||
*/
|
||||
public static <R extends IServerToClientPacket> SocketFuture<R> completedFuture() {
|
||||
SocketFuture<R> dummyFuture = new SocketFuture<>(new ArrayList<>(0));
|
||||
dummyFuture.complete(null);
|
||||
return dummyFuture;
|
||||
}
|
||||
|
||||
}
|
235
src/main/java/de/dhbwstuttgart/server/SocketServer.java
Normal file
235
src/main/java/de/dhbwstuttgart/server/SocketServer.java
Normal file
@@ -0,0 +1,235 @@
|
||||
package de.dhbwstuttgart.server;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.dhbwstuttgart.server.packet.ErrorPacket;
|
||||
import de.dhbwstuttgart.server.packet.IClientToServerPacket;
|
||||
import de.dhbwstuttgart.server.packet.IPacket;
|
||||
import de.dhbwstuttgart.server.packet.MessagePacket;
|
||||
import de.dhbwstuttgart.server.packet.PacketContainer;
|
||||
import de.dhbwstuttgart.util.Logger;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.java_websocket.WebSocket;
|
||||
import org.java_websocket.drafts.Draft;
|
||||
import org.java_websocket.drafts.Draft_6455;
|
||||
import org.java_websocket.extensions.permessage_deflate.PerMessageDeflateExtension;
|
||||
import org.java_websocket.handshake.ClientHandshake;
|
||||
import org.java_websocket.server.WebSocketServer;
|
||||
|
||||
public class SocketServer extends WebSocketServer {
|
||||
|
||||
public static Logger logger = new Logger("SocketServer");
|
||||
public static final int maxTasksPerSession = 100;
|
||||
private static boolean serverRunning = false;
|
||||
|
||||
/**
|
||||
* Increase this every time a breaking change to the server communication is done.
|
||||
* This will prevent errors when the server version and client version do not match.
|
||||
*/
|
||||
public static final String packetProtocolVersion = "1";
|
||||
|
||||
// create an executor for tasks that will always keep at least one task around
|
||||
private final ThreadPoolExecutor taskExecutor = new ThreadPoolExecutor(1, Integer.MAX_VALUE,60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
||||
// create an executor for scheduling timeouts
|
||||
private final ScheduledExecutorService timeoutExecutor = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
public SocketServer(int port) {
|
||||
super(new InetSocketAddress(port));
|
||||
this.setConnectionLostTimeout(30);
|
||||
|
||||
serverRunning = true;
|
||||
// add a shutdown hook to close all connections when the process ends or is stopped by a SIGINT signal
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(this::onShutdown));
|
||||
}
|
||||
|
||||
public static boolean isServerRunning() {
|
||||
return serverRunning;
|
||||
}
|
||||
|
||||
private void onShutdown() {
|
||||
serverRunning = false;
|
||||
try {
|
||||
for (var webSocket : this.getConnections()) {
|
||||
this.sendError(webSocket, "Sorry, i am shutting down. You are now on your own, good Luck!", true);
|
||||
webSocket.close();
|
||||
}
|
||||
this.stop();
|
||||
taskExecutor.shutdown();
|
||||
timeoutExecutor.shutdown();
|
||||
} catch (InterruptedException exception) {
|
||||
// we are shutting down anyway
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) {
|
||||
String ppv = clientHandshake.getFieldValue("packetProtocolVersion");
|
||||
if (!ppv.equals(packetProtocolVersion)) {
|
||||
this.sendError(webSocket,
|
||||
"Mismatch in packet protocol version! Client (you): \"" + ppv + "\" and Server (me): \"" + packetProtocolVersion + "\"",
|
||||
true
|
||||
);
|
||||
webSocket.close(1);
|
||||
return;
|
||||
}
|
||||
|
||||
SocketData socketData = new SocketData(webSocket);
|
||||
logger.info("New connection: " + socketData.id + " (with ppv " + ppv + ")");
|
||||
|
||||
try {
|
||||
sendMessage(webSocket, "Welcome to the server!");
|
||||
|
||||
// wait 10 seconds for the client to send a task and close the connection if nothing has been received until then
|
||||
final int secondsUntilTimeout = 10;
|
||||
timeoutExecutor.schedule(() -> {
|
||||
if (webSocket.<SocketData>getAttachment().totalTasks.get() > 0 || !webSocket.isOpen()) {
|
||||
return;
|
||||
}
|
||||
sendMessage(webSocket, "No task received after " + secondsUntilTimeout + " seconds. Closing connection...");
|
||||
webSocket.close();
|
||||
},
|
||||
secondsUntilTimeout,
|
||||
TimeUnit.SECONDS
|
||||
);
|
||||
|
||||
// and finally, when your program wants to exit
|
||||
} catch (Exception e) {
|
||||
logger.exception(e);
|
||||
webSocket.close(1, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(WebSocket webSocket, int code, String reason, boolean remote) {
|
||||
SocketData socketData = webSocket.getAttachment();
|
||||
logger.info("Connection closed: " + socketData.id);
|
||||
logger.info(
|
||||
"Disconnected client " + socketData.id + " " +
|
||||
"with code " + code + " " +
|
||||
(reason.isEmpty() ? "" : "and reason " + reason + " ") +
|
||||
"(closed by client: " + remote + ")"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(WebSocket webSocket, String s) {
|
||||
// logger.info("Received: " + s.substring(0, 50));
|
||||
IPacket reconstructedPacket = PacketContainer.deserialize(s);
|
||||
try {
|
||||
this.onPacketReceived(webSocket, reconstructedPacket);
|
||||
} catch (JsonProcessingException e) {
|
||||
logger.exception(e);
|
||||
this.log(webSocket, "Error on processing incoming package: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(WebSocket webSocket, Exception e) {
|
||||
if (webSocket != null) {
|
||||
log(webSocket, e.getMessage());
|
||||
webSocket.close();
|
||||
}
|
||||
logger.exception(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
logger.success("Websocket server started on port " + this.getPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* A shorthand method for sending informational messages to the client
|
||||
*/
|
||||
public void sendMessage(WebSocket webSocket, String text) {
|
||||
try {
|
||||
MessagePacket message = MessagePacket.create(text);
|
||||
webSocket.send(PacketContainer.serialize(message));
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to send message: " + text);
|
||||
logger.exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A shorthand method for sending error messages to the client
|
||||
*/
|
||||
public void sendError(WebSocket webSocket, String text, boolean isFatal) {
|
||||
try {
|
||||
ErrorPacket error = ErrorPacket.create(text, isFatal);
|
||||
webSocket.send(PacketContainer.serialize(error));
|
||||
} catch (Exception e) {
|
||||
logger.exception(e);
|
||||
log(webSocket, "Failed to send error: " + text);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The server-side implementation on how to handle certain packets when received
|
||||
*/
|
||||
private void onPacketReceived(WebSocket webSocket, IPacket packet) throws JsonProcessingException {
|
||||
SocketData socketData = webSocket.getAttachment();
|
||||
|
||||
// limit the number of tasks per connection
|
||||
if (socketData.totalTasks.get() >= maxTasksPerSession) {
|
||||
sendError(webSocket, "Exceeded the maximum amount of " + maxTasksPerSession + " tasks per session", true);
|
||||
webSocket.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// only allow packets that are meant to be handled by the server
|
||||
if (!(packet instanceof IClientToServerPacket<?> clientToServerPacket)) {
|
||||
sendMessage(webSocket, "The package of type " + packet.getClass().getName() + " is not handled by the server!");
|
||||
return;
|
||||
}
|
||||
|
||||
// update the socket data
|
||||
socketData.unhandledTasks.incrementAndGet();
|
||||
socketData.totalTasks.incrementAndGet();
|
||||
|
||||
// add the packet to the queue so it can be started by the worker
|
||||
CompletableFuture.runAsync(() -> {
|
||||
clientToServerPacket.onHandle(webSocket, this);
|
||||
int remainingUnhandledTasks = socketData.unhandledTasks.decrementAndGet();
|
||||
|
||||
if (socketData.closeIfNoTasksLeft) {
|
||||
// if the websocket has 0 unhandled Tasks, close the connection
|
||||
if (remainingUnhandledTasks <= 0) {
|
||||
sendMessage(webSocket, "All requested tasks finished! Closing connection...");
|
||||
webSocket.close();
|
||||
}
|
||||
}
|
||||
}, taskExecutor);
|
||||
}
|
||||
|
||||
public void log(WebSocket webSocket, String msg) {
|
||||
String socketId = (webSocket == null) ? "???" : webSocket.<SocketData>getAttachment().id;
|
||||
logger.info("[" + socketId + "] " + msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* The data that is associated server-side with any connected client.
|
||||
* This makes it possible to store information that can be mapped to any existing connection.
|
||||
*/
|
||||
public static class SocketData {
|
||||
|
||||
public final String id;
|
||||
public final AtomicInteger unhandledTasks = new AtomicInteger(0);
|
||||
public final AtomicInteger totalTasks = new AtomicInteger(0);
|
||||
public boolean closeIfNoTasksLeft = false;
|
||||
|
||||
public SocketData(WebSocket webSocket) {
|
||||
this.id = UUID.randomUUID().toString();
|
||||
webSocket.setAttachment(this);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
import de.dhbwstuttgart.server.SocketFuture;
|
||||
import de.dhbwstuttgart.server.SocketServer;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialUUID;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue;
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
public class DebugPacket implements IClientToServerPacket.Void, IServerToClientPacket {
|
||||
|
||||
public SerialUUID a1;
|
||||
public SerialUUID a2;
|
||||
public SerialMap b1;
|
||||
public SerialMap b2;
|
||||
public SerialList<? extends ISerialNode> c1;
|
||||
public SerialList<? extends ISerialNode> c2;
|
||||
public SerialValue<?> d1;
|
||||
public SerialValue<?> d2;
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketClient socketClient) {}
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketServer socketServer) {}
|
||||
|
||||
@JsonIgnore
|
||||
public SocketFuture<IServerToClientPacket> getFuture() {
|
||||
return SocketFuture.completedFuture();
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
import de.dhbwstuttgart.server.SocketFuture;
|
||||
import de.dhbwstuttgart.server.SocketServer;
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
/**
|
||||
* A packet to send simple error messages between the client and the server
|
||||
*/
|
||||
public class ErrorPacket implements IServerToClientPacket {
|
||||
|
||||
/**
|
||||
* The error endpoint for messages from the server that should be logged out as errors and possibly abort the process
|
||||
*/
|
||||
public String error;
|
||||
public boolean isFatal;
|
||||
|
||||
@JsonIgnore
|
||||
public static ErrorPacket create(String error, boolean isFatal) {
|
||||
ErrorPacket packet = new ErrorPacket();
|
||||
packet.error = error;
|
||||
packet.isFatal = isFatal;
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
|
||||
SocketClient.logger.exception(new RuntimeException(this.error));
|
||||
if (this.isFatal) {
|
||||
socketClient.close(1, "Received fatal error from server");
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.server.SocketFuture;
|
||||
import de.dhbwstuttgart.server.SocketServer;
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
/**
|
||||
* A packet that will be sent to the server. Use <code>Void</code> Sub-Interface for packets without response
|
||||
*
|
||||
* @param <T> The response packet that will fulfill the future.
|
||||
*/
|
||||
public interface IClientToServerPacket<T extends IServerToClientPacket> extends IPacket {
|
||||
|
||||
@JsonIgnore
|
||||
void onHandle(WebSocket webSocket, SocketServer socketServer);
|
||||
|
||||
@JsonIgnore
|
||||
SocketFuture<T> getFuture();
|
||||
|
||||
/**
|
||||
* Special case, where the packet will remain unanswered by the server
|
||||
*/
|
||||
interface Void extends IClientToServerPacket<IServerToClientPacket> {}
|
||||
}
|
||||
|
12
src/main/java/de/dhbwstuttgart/server/packet/IPacket.java
Normal file
12
src/main/java/de/dhbwstuttgart/server/packet/IPacket.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
/**
|
||||
* The shared interface for all packet of the client-server connection.
|
||||
* A packet must always:
|
||||
* - Have a default / no-parameter constructor
|
||||
* - Have only serializable public properties (or disable them via jackson annotations)
|
||||
*
|
||||
*/
|
||||
public interface IPacket {
|
||||
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
public interface IServerToClientPacket extends IPacket {
|
||||
|
||||
@JsonIgnore
|
||||
void onHandle(WebSocket webSocket, SocketClient socketClient);
|
||||
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
import de.dhbwstuttgart.server.SocketFuture;
|
||||
import de.dhbwstuttgart.server.SocketServer;
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
/**
|
||||
* A fallback packet that is generated if the received JSON could not be mapped to an existing package
|
||||
*/
|
||||
public class InvalidPacket implements IClientToServerPacket.Void, IServerToClientPacket {
|
||||
|
||||
/**
|
||||
* If available, the error that caused this package to appear
|
||||
*/
|
||||
public String error = "<unknown error>";
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
|
||||
SocketClient.logger.error("InvalidPacket: " + this.error);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
|
||||
socketServer.log(webSocket, "InvalidPacket: " + this.error);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public SocketFuture<IServerToClientPacket> getFuture() {
|
||||
return SocketFuture.completedFuture();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
import de.dhbwstuttgart.server.SocketFuture;
|
||||
import de.dhbwstuttgart.server.SocketServer;
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
/**
|
||||
* A packet to send simple informational messages between the client and the server
|
||||
*/
|
||||
public class MessagePacket implements IClientToServerPacket.Void, IServerToClientPacket {
|
||||
|
||||
/**
|
||||
* The informational message from the server that should be logged out outputted
|
||||
*/
|
||||
public String message;
|
||||
|
||||
@JsonIgnore
|
||||
public static MessagePacket create(String message) {
|
||||
MessagePacket packet = new MessagePacket();
|
||||
packet.message = message;
|
||||
return packet;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
|
||||
SocketClient.logger.info("SocketMessage: " + this.message);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
|
||||
socketServer.log(webSocket, this.message);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public SocketFuture<IServerToClientPacket> getFuture() {
|
||||
return SocketFuture.completedFuture();
|
||||
}
|
||||
}
|
@@ -0,0 +1,98 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import de.dhbwstuttgart.util.Logger;
|
||||
|
||||
/**
|
||||
* A wrapper for the packet to ensure correct serialization/deserialization and make it possible to detect the matching
|
||||
* packet type for deserialization.
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class PacketContainer {
|
||||
|
||||
// The jackson serializer / deserializer tool
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
/*
|
||||
* The available packet types. The one type that is represented in the JSON should always be the ONLY non-null value.
|
||||
* They have to be public (for the moment) to let jackson fill them in while deserializing
|
||||
*/
|
||||
public ErrorPacket errorPacket = null;
|
||||
public MessagePacket messagePacket = null;
|
||||
public InvalidPacket invalidPacket = null;
|
||||
public UnifyRequestPacket unifyRequestPacket = null;
|
||||
public UnifyResultPacket unifyResultPacket = null;
|
||||
public DebugPacket debugPacket = null;
|
||||
public SetAutoclosePacket setAutoclosePacket = null;
|
||||
|
||||
|
||||
/**
|
||||
* Generate the JSON string for the given packet
|
||||
*
|
||||
* @param packet The packet to serialize
|
||||
* @return The JSON representation of the packet
|
||||
*/
|
||||
public static String serialize(IPacket packet) throws JsonProcessingException {
|
||||
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
PacketContainer container = new PacketContainer();
|
||||
|
||||
if (packet instanceof ErrorPacket)
|
||||
container.errorPacket = (ErrorPacket) packet;
|
||||
else if (packet instanceof MessagePacket)
|
||||
container.messagePacket = (MessagePacket) packet;
|
||||
else if (packet instanceof UnifyRequestPacket)
|
||||
container.unifyRequestPacket = (UnifyRequestPacket) packet;
|
||||
else if (packet instanceof UnifyResultPacket)
|
||||
container.unifyResultPacket = (UnifyResultPacket) packet;
|
||||
else if (packet instanceof DebugPacket)
|
||||
container.debugPacket = (DebugPacket) packet;
|
||||
else if (packet instanceof SetAutoclosePacket)
|
||||
container.setAutoclosePacket = (SetAutoclosePacket) packet;
|
||||
// Add new packets here and in the deserialize method
|
||||
else
|
||||
throw new RuntimeException("Cannot map packet to any known packet class");
|
||||
|
||||
return objectMapper.writeValueAsString(container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the JSON string to generate the matching packet object
|
||||
*
|
||||
* @param json The serialized representation of a packet container
|
||||
* @return The deserialized Packet object
|
||||
*/
|
||||
public static IPacket deserialize(String json) {
|
||||
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
|
||||
try {
|
||||
PacketContainer container = objectMapper.readValue(json, PacketContainer.class);
|
||||
|
||||
if (container.errorPacket != null)
|
||||
return container.errorPacket;
|
||||
if (container.messagePacket != null)
|
||||
return container.messagePacket;
|
||||
if (container.invalidPacket != null)
|
||||
return container.invalidPacket;
|
||||
if (container.unifyRequestPacket != null)
|
||||
return container.unifyRequestPacket;
|
||||
if (container.unifyResultPacket != null)
|
||||
return container.unifyResultPacket;
|
||||
if (container.debugPacket != null)
|
||||
return container.debugPacket;
|
||||
if (container.setAutoclosePacket != null)
|
||||
return container.setAutoclosePacket;
|
||||
// Add new packets here and in the serialize method
|
||||
|
||||
throw new RuntimeException("Cannot map received json to any known packet class");
|
||||
} catch (Exception e) {
|
||||
(new Logger()).exception(e);
|
||||
InvalidPacket packet = new InvalidPacket();
|
||||
packet.error = e.getMessage();
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
import de.dhbwstuttgart.server.SocketFuture;
|
||||
import de.dhbwstuttgart.server.SocketServer;
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
/**
|
||||
* Normally, a connection stays open until either the client or the server process ends.
|
||||
* Send this packet to inform the server that the connection can be closed once all tasks are done
|
||||
*/
|
||||
public class SetAutoclosePacket implements IClientToServerPacket.Void {
|
||||
|
||||
public int dummyProperty = 1;
|
||||
|
||||
@JsonIgnore
|
||||
public static SetAutoclosePacket create() {
|
||||
return new SetAutoclosePacket();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
|
||||
webSocket.<SocketServer.SocketData>getAttachment().closeIfNoTasksLeft = true;
|
||||
socketServer.log(webSocket, "Marked connection as autoclose");
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public SocketFuture<IServerToClientPacket> getFuture() {
|
||||
return SocketFuture.completedFuture();
|
||||
}
|
||||
}
|
@@ -0,0 +1,164 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.core.ConsoleInterface;
|
||||
import de.dhbwstuttgart.server.ServerTaskLogger;
|
||||
import de.dhbwstuttgart.server.SocketFuture;
|
||||
import de.dhbwstuttgart.server.SocketServer;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel;
|
||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
||||
import de.dhbwstuttgart.util.Logger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
/**
|
||||
* A packet to send all required data for the unification algorithm to the server and request the unification
|
||||
*/
|
||||
public class UnifyRequestPacket implements IClientToServerPacket<UnifyResultPacket> {
|
||||
|
||||
public SerialMap finiteClosure;
|
||||
public SerialMap constraintSet;
|
||||
public SerialMap unifyConstraintSet;
|
||||
public SerialMap serialKeyStorage;
|
||||
public SerialValue<?> placeholders;
|
||||
public SerialList<SerialMap> factoryplaceholders;
|
||||
public String futureId;
|
||||
public int logLevel;
|
||||
|
||||
@JsonIgnore
|
||||
private KeyStorage keyStorage = new KeyStorage();
|
||||
@JsonIgnore
|
||||
private boolean keyStorageLoaded = false;
|
||||
|
||||
public static UnifyRequestPacket create(
|
||||
FiniteClosure finiteClosure,
|
||||
ConstraintSet<Pair> constraintSet,
|
||||
ConstraintSet<UnifyPair> unifyConstraintSet,
|
||||
PlaceholderRegistry placeholderRegistry
|
||||
) {
|
||||
UnifyRequestPacket packet = new UnifyRequestPacket();
|
||||
// store constraint and finite closure
|
||||
packet.finiteClosure = finiteClosure.toSerial(packet.keyStorage);
|
||||
packet.constraintSet = constraintSet.toSerial(packet.keyStorage);
|
||||
packet.unifyConstraintSet = unifyConstraintSet.toSerial(packet.keyStorage);
|
||||
// store placeholder registry
|
||||
var serialRegistry = placeholderRegistry.toSerial(packet.keyStorage);
|
||||
packet.placeholders = serialRegistry.getValue("ph");
|
||||
packet.factoryplaceholders = serialRegistry.getList("factoryPh").assertListOfMaps();
|
||||
// store referenced objects separately
|
||||
packet.serialKeyStorage = packet.keyStorage.toSerial(packet.keyStorage);
|
||||
packet.logLevel = ConsoleInterface.logLevel.getValue();
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
public void loadKeyStorage(UnifyContext context) {
|
||||
if (!keyStorageLoaded) {
|
||||
keyStorageLoaded = true;
|
||||
keyStorage = KeyStorage.fromSerial(this.serialKeyStorage, context);
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
private FiniteClosure retrieveFiniteClosure(UnifyContext context) {
|
||||
this.loadKeyStorage(context);
|
||||
return FiniteClosure.fromSerial(this.finiteClosure, context, keyStorage);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
private ConstraintSet<Pair> retrieveConstraintSet(UnifyContext context) {
|
||||
this.loadKeyStorage(context);
|
||||
return ConstraintSet.fromSerial(this.constraintSet, context, Pair.class, keyStorage);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
private ConstraintSet<UnifyPair> retrieveUnifyConstraintSet(UnifyContext context) {
|
||||
this.loadKeyStorage(context);
|
||||
return ConstraintSet.fromSerial(this.unifyConstraintSet, context, UnifyPair.class, keyStorage);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
|
||||
socketServer.sendMessage(webSocket, "You requested a unify! Please wait until I calculated everything...");
|
||||
socketServer.log(webSocket, "Client requested a unification. Starting now...");
|
||||
|
||||
try {
|
||||
var placeholderRegistry = new PlaceholderRegistry();
|
||||
ArrayList<String> existingPlaceholders = (ArrayList) this.placeholders.getOf(ArrayList.class);
|
||||
existingPlaceholders.forEach(placeholderRegistry::addPlaceholder);
|
||||
|
||||
Logger logger = new ServerTaskLogger(
|
||||
webSocket,
|
||||
socketServer,
|
||||
Logger.LogLevel.fromValue(
|
||||
Math.max(this.logLevel, Logger.LogLevel.INFO.getValue())
|
||||
)
|
||||
);
|
||||
var unifyContext = new UnifyContext(logger, true,
|
||||
new UnifyResultModel(new ConstraintSet<>(), new FiniteClosure(new HashSet<>(), logger, placeholderRegistry)),
|
||||
new UnifyTaskModel(), ForkJoinPool.commonPool(), placeholderRegistry
|
||||
);
|
||||
|
||||
this.factoryplaceholders.stream()
|
||||
.map(p -> (PlaceholderType)UnifyType.fromSerial(p, unifyContext))
|
||||
.forEach(placeholderRegistry.UnifyTypeFactory_PLACEHOLDERS::add);
|
||||
|
||||
|
||||
// start the unification algorithm from the received data
|
||||
IFiniteClosure finiteClosure = this.retrieveFiniteClosure(unifyContext);
|
||||
ConstraintSet<Pair> constraintSet = this.retrieveConstraintSet(unifyContext);
|
||||
ConstraintSet<UnifyPair> unifyConstraintSet = this.retrieveUnifyConstraintSet(unifyContext);
|
||||
|
||||
var resultModel = new UnifyResultModel(constraintSet, finiteClosure);
|
||||
UnifyResultListenerImpl resultListener = new UnifyResultListenerImpl();
|
||||
resultModel.addUnifyResultListener(resultListener);
|
||||
|
||||
TypeUnify.unifyParallel(
|
||||
unifyConstraintSet.getUndConstraints(),
|
||||
unifyConstraintSet.getOderConstraints(),
|
||||
finiteClosure,
|
||||
unifyContext.newWithResultModel(resultModel)
|
||||
);
|
||||
|
||||
var resultSets = resultListener.getResults();
|
||||
|
||||
socketServer.log(webSocket, "Finished unification");
|
||||
socketServer.sendMessage(webSocket, "Unification finished. Found " + resultSets.size() + " result sets");
|
||||
|
||||
if (webSocket.isOpen()) {
|
||||
UnifyResultPacket resultPacket = UnifyResultPacket.create(resultSets, futureId);
|
||||
webSocket.send(PacketContainer.serialize(resultPacket));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SocketServer.logger.exception(e);
|
||||
socketServer.log(webSocket, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public SocketFuture<UnifyResultPacket> getFuture() {
|
||||
var future = new SocketFuture<>(List.of(UnifyResultPacket.class));
|
||||
futureId = future.futureId;
|
||||
return future;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import java.util.List;
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
/**
|
||||
* A packet to send all calculated data from the unification algorithm back to the client
|
||||
*/
|
||||
public class UnifyResultPacket implements IServerToClientPacket {
|
||||
|
||||
public SerialList<ISerialNode> results;
|
||||
public SerialMap keyStorage;
|
||||
public String futureId;
|
||||
|
||||
public static UnifyResultPacket create(List<ResultSet> resultSets, String futureId) {
|
||||
UnifyResultPacket serialized = new UnifyResultPacket();
|
||||
KeyStorage keyStorage = new KeyStorage();
|
||||
serialized.results = SerialList.fromMapped(resultSets, resultSet -> resultSet.toSerial(keyStorage));
|
||||
serialized.keyStorage = keyStorage.toSerial(keyStorage);
|
||||
serialized.futureId = futureId;
|
||||
return serialized;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public List<ResultSet> getResultSet(UnifyContext context) {
|
||||
return this.results.assertListOfMaps().stream()
|
||||
.map(resultData -> ResultSet.fromSerial(resultData, context)).toList();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
|
||||
SocketClient.logger.info("Received unify result");
|
||||
socketClient.completeResponseFuture(futureId, this);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
package de.dhbwstuttgart.server.packet.dataContainers;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
|
||||
public interface ISerializableData {
|
||||
|
||||
public abstract ISerialNode toSerial(KeyStorage keyStorage);
|
||||
|
||||
public static Object fromSerial(SerialMap data, UnifyContext context) {
|
||||
throw new NotImplementedException("Missing implementation of \"fromSerial\" for a serializable element");
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
package de.dhbwstuttgart.server.packet.dataContainers;
|
||||
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class KeyStorage implements ISerializableData {
|
||||
|
||||
/**
|
||||
* Store a unique identifier for every element, so it can be referenced in the json
|
||||
*/
|
||||
protected AtomicInteger identifierCount = new AtomicInteger();
|
||||
/**
|
||||
* Store the serialized element per identifier when serializing
|
||||
*/
|
||||
protected SerialMap serializedElements = new SerialMap();
|
||||
/**
|
||||
* Store the unserialized element per identifier when unserializing
|
||||
*/
|
||||
protected Map<String, ISerializableData> unserializedElements = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve or generate a new identifier for a constraint
|
||||
*/
|
||||
public String getIdentifier() {
|
||||
return this.identifierCount.incrementAndGet() + "_";
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given element identifier belongs to an element that was already serialized
|
||||
*/
|
||||
public boolean isAlreadySerialized(String identifier) {
|
||||
return this.serializedElements.containsKey(identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given element identifier belongs to a element that was already unserialized
|
||||
*/
|
||||
public boolean isAlreadyUnserialized(String identifier) {
|
||||
return this.unserializedElements.containsKey(identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a serialized element to prevent it from being serialized again
|
||||
*/
|
||||
public void putSerialized(String identifier, SerialMap serializedElement) {
|
||||
this.serializedElements.put(identifier, serializedElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a serialized element
|
||||
*/
|
||||
public SerialMap getSerialized(String identifier) {
|
||||
if (!this.serializedElements.containsKey(identifier)) {
|
||||
throw new RuntimeException("No serialized element of identifier " + identifier + " available to get");
|
||||
}
|
||||
return this.serializedElements.getMap(identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an unserialized element to prevent it from being unserialized again
|
||||
*/
|
||||
public void putUnserialized(String identifier, ISerializableData element) {
|
||||
this.unserializedElements.put(identifier, element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an unserialized element
|
||||
*/
|
||||
public <T extends ISerializableData> T getUnserialized(String identifier, Class<T> target) {
|
||||
if (!this.unserializedElements.containsKey(identifier)) {
|
||||
throw new RuntimeException("No unserialized element of identifier " + identifier + " available to get");
|
||||
}
|
||||
var element = this.unserializedElements.get(identifier);
|
||||
if (target.isInstance(element)) {
|
||||
return (T) element;
|
||||
}
|
||||
throw new RuntimeException("Failed to get unserialized element from KeyStorage. Expected instance of " +
|
||||
target.getName() + " but found " + element.getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
SerialMap serialized = new SerialMap();
|
||||
serialized.put("serializedElements", this.serializedElements);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
public static KeyStorage fromSerial(SerialMap data, UnifyContext context) {
|
||||
var serializedConstraintsData = data.getMap("serializedElements");
|
||||
var constraintContext = new KeyStorage();
|
||||
for (var entry : serializedConstraintsData.entrySet()) {
|
||||
if (entry.getValue() instanceof SerialMap valueMap) {
|
||||
constraintContext.putSerialized(entry.getKey(), valueMap);
|
||||
}
|
||||
}
|
||||
return constraintContext;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
|
||||
|
||||
/**
|
||||
* Use the following classes for an intermediate serialized tree structure
|
||||
*/
|
||||
@JsonTypeInfo(
|
||||
use = JsonTypeInfo.Id.NAME,
|
||||
include = JsonTypeInfo.As.PROPERTY,
|
||||
property = "_t"
|
||||
)
|
||||
@JsonSubTypes({
|
||||
@JsonSubTypes.Type(value = SerialMap.class, name = "m"),
|
||||
@JsonSubTypes.Type(value = SerialList.class, name = "l"),
|
||||
@JsonSubTypes.Type(value = SerialValue.class, name = "v"),
|
||||
@JsonSubTypes.Type(value = SerialUUID.class, name = "u")
|
||||
})
|
||||
public interface ISerialNode {
|
||||
|
||||
default <T extends ISerialNode> T assertType(Class<T> type) {
|
||||
if (type.isInstance(this)) {
|
||||
return (T) this;
|
||||
}
|
||||
throw new RuntimeException("Expected ISerialNode to be of type " + type.getName()
|
||||
+ " but found " + this.getClass().getName() + " instead");
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SerialList<I extends ISerialNode> extends ArrayList<I> implements ISerialNode {
|
||||
public SerialList() {}
|
||||
public SerialList(Collection<I> data) {
|
||||
this.addAll(data);
|
||||
}
|
||||
public SerialList(Stream<I> data) {
|
||||
this(data.toList());
|
||||
}
|
||||
public SerialList(I[] data) {
|
||||
this(Arrays.stream(data).toList());
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
@JsonIgnore
|
||||
public static <A extends ISerialNode> ArrayList<A> from(A ...values) {
|
||||
ArrayList<A> list = new SerialList<>();
|
||||
Collections.addAll(list, values);
|
||||
return list;
|
||||
}
|
||||
@JsonIgnore
|
||||
public static <A,B extends ISerialNode> SerialList<B> fromMapped(Stream<A> data, Function<A,B> mapper) {
|
||||
return new SerialList<>(data.map(mapper).toList());
|
||||
}
|
||||
@JsonIgnore
|
||||
public static <A,B extends ISerialNode> SerialList<B> fromMapped(Collection<A> data, Function<A,B> mapper) {
|
||||
return SerialList.fromMapped(data.stream(), mapper);
|
||||
}
|
||||
@JsonIgnore
|
||||
public static <A,B extends ISerialNode> SerialList<B> fromMapped(A[] data, Function<A,B> mapper) {
|
||||
return SerialList.fromMapped(Arrays.stream(data), mapper);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public SerialList<SerialMap> assertListOfMaps() {
|
||||
if (this.isEmpty() || this.get(0) instanceof SerialMap) {
|
||||
return (SerialList<SerialMap>) this;
|
||||
}
|
||||
throw new RuntimeException("Required List to contain SerialMap elements but condition failed");
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public SerialList<SerialList<?>> assertListOfLists() {
|
||||
if (this.isEmpty() || this.get(0) instanceof SerialList) {
|
||||
return (SerialList<SerialList<?>>) this;
|
||||
}
|
||||
throw new RuntimeException("Required List to contain SerialList elements but condition failed");
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public SerialList<SerialValue<?>> assertListOfValues() {
|
||||
if (this.isEmpty() || this.get(0) instanceof SerialValue) {
|
||||
return (SerialList<SerialValue<?>>) this;
|
||||
}
|
||||
throw new RuntimeException("Required List to contain SerialValue elements but condition failed");
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public SerialList<SerialUUID> assertListOfUUIDs() {
|
||||
if (this.isEmpty() || this.get(0) instanceof SerialUUID) {
|
||||
return (SerialList<SerialUUID>) this;
|
||||
}
|
||||
throw new RuntimeException("Required List to contain SerialUUID elements but condition failed");
|
||||
}
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class SerialMap extends HashMap<String, ISerialNode> implements ISerialNode {
|
||||
|
||||
public SerialMap() {
|
||||
super();
|
||||
}
|
||||
|
||||
public SerialMap(Map<String, ISerialNode> data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void put(String key, Boolean value) {
|
||||
this.put(key, new SerialValue<>(value));
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void put(String key, String value) {
|
||||
this.put(key, new SerialValue<>(value));
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void put(String key, Number value) {
|
||||
this.put(key, new SerialValue<>(value));
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
private <T> T get(String key, Class<T> expectedType) {
|
||||
if (!this.containsKey(key)) {
|
||||
throw new RuntimeException("Missing required value " + key + " in ObjectMap");
|
||||
}
|
||||
var element = this.get(key);
|
||||
if (element != null && element.getClass() != expectedType) {
|
||||
throw new RuntimeException(
|
||||
"Required value " + key + " to be of type " + expectedType.getName() + " but found " + element.getClass().getName()
|
||||
);
|
||||
}
|
||||
return (T)element;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public SerialList<?> getList(String key) {
|
||||
return this.get(key, SerialList.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@JsonIgnore
|
||||
public SerialList<?> getListOrNull(String key) {
|
||||
return this.containsKey(key) ? this.getList(key) : null;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public SerialMap getMap(String key) {
|
||||
return this.get(key, SerialMap.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@JsonIgnore
|
||||
public SerialMap getMapOrNull(String key) {
|
||||
return this.containsKey(key) ? this.getMap(key) : null;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public SerialValue<?> getValue(String key) {
|
||||
return this.get(key, SerialValue.class);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public SerialUUID getUUID(String key) {
|
||||
return this.get(key, SerialUUID.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@JsonIgnore
|
||||
public SerialUUID getUUIDOrNull(String key) {
|
||||
return this.containsKey(key) ? this.getUUID(key) : null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
|
||||
|
||||
public class SerialUUID implements ISerialNode {
|
||||
|
||||
public String uuid;
|
||||
|
||||
public SerialUUID() {}
|
||||
|
||||
public SerialUUID(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package de.dhbwstuttgart.server.packet.dataContainers.serialized;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
public class SerialValue<T> implements ISerialNode {
|
||||
public T value;
|
||||
public static final SerialValue<Object> NULL = new SerialValue<>(null);
|
||||
|
||||
public SerialValue() {}
|
||||
|
||||
public SerialValue(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public <A> SerialValue<A> assertValueOf(Class<A> targetClass) {
|
||||
if (this.value == null || targetClass.isInstance(this.value)) {
|
||||
return (SerialValue<A>) this;
|
||||
}
|
||||
throw new RuntimeException("Required Value to contain " + targetClass.getName() + " value but condition failed on" +
|
||||
" type " + this.value.getClass().getName());
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public <A> A getOf(Class<A> targetClass) {
|
||||
return this.assertValueOf(targetClass).value;
|
||||
}
|
||||
}
|
@@ -10,6 +10,8 @@ public interface ASTVisitor extends StatementVisitor{
|
||||
|
||||
void visit(FormalParameter formalParameter);
|
||||
|
||||
void visit(LiteralPattern literalPattern);
|
||||
|
||||
void visit(GenericDeclarationList genericTypeVars);
|
||||
|
||||
void visit(Field field);
|
||||
|
@@ -37,6 +37,11 @@ public abstract class AbstractASTWalker implements ASTVisitor {
|
||||
formalParameter.getType().accept((ASTVisitor) this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LiteralPattern literalPattern) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(GenericDeclarationList genericTypeVars) {
|
||||
Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator();
|
||||
|
@@ -86,6 +86,9 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
||||
return staticInitializer;
|
||||
}
|
||||
|
||||
public boolean isSealed() { return permittedSubtypes != null; }
|
||||
public List<RefType> getPermittedSubtypes() { return permittedSubtypes != null ? permittedSubtypes : List.of(); }
|
||||
|
||||
public boolean isInterface() {
|
||||
return (Modifier.INTERFACE & this.getModifiers()) != 0;
|
||||
}
|
||||
|
@@ -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.syntaxtree.statement.*;
|
||||
|
||||
|
||||
public interface StatementVisitor {
|
||||
|
||||
void visit(ArgumentList argumentList);
|
||||
|
@@ -0,0 +1,8 @@
|
||||
package de.dhbwstuttgart.syntaxtree;
|
||||
|
||||
import de.dhbwstuttgart.util.Logger;
|
||||
|
||||
public class SyntaxTree {
|
||||
|
||||
public static Logger logger = new Logger("SyntaxTree");
|
||||
}
|
@@ -34,7 +34,6 @@ public class ASTFactory {
|
||||
private static final HashMap<java.lang.Class, ClassOrInterface> cache = new HashMap<>();
|
||||
|
||||
public static ClassOrInterface createClass(java.lang.Class jreClass) {
|
||||
System.out.println(jreClass);
|
||||
if (cache.containsKey(jreClass))
|
||||
return cache.get(jreClass);
|
||||
|
||||
@@ -174,12 +173,12 @@ public class ASTFactory {
|
||||
superClass = (RefType) createType(java.lang.Object.class);
|
||||
}
|
||||
List<RefType> implementedInterfaces = new ArrayList<>();
|
||||
System.out.println(jreClass);
|
||||
for (Type jreInterface : jreClass.getGenericInterfaces()) {
|
||||
implementedInterfaces.add((RefType) createType(jreInterface));
|
||||
}
|
||||
List<RefType> permittedSubtypes = new ArrayList<>();
|
||||
List<RefType> permittedSubtypes = null;
|
||||
if (jreClass.isSealed()) {
|
||||
permittedSubtypes = new ArrayList<>();
|
||||
for (Class subclass : jreClass.getPermittedSubclasses()) {
|
||||
permittedSubtypes.add((RefType) createType(subclass));
|
||||
}
|
||||
|
@@ -1,5 +1,8 @@
|
||||
package de.dhbwstuttgart.syntaxtree.factory;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.core.JavaTXServer;
|
||||
|
||||
public class NameGenerator {
|
||||
|
||||
private static String strNextName = "A";
|
||||
@@ -26,7 +29,11 @@ public class NameGenerator {
|
||||
|
||||
// n�chster Name berechnen und in strNextName speichern
|
||||
inc( strNextName.length() - 1 );
|
||||
|
||||
|
||||
if (JavaTXServer.isRunning) {
|
||||
throw new RuntimeException("Using the NameGenerator on a server is not allowed");
|
||||
}
|
||||
JavaTXCompiler.defaultClientPlaceholderRegistry.addPlaceholder(strReturn);
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,8 @@
|
||||
package de.dhbwstuttgart.syntaxtree.factory;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.SyntaxTree;
|
||||
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||
import de.dhbwstuttgart.util.Logger;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
@@ -31,9 +34,13 @@ import org.antlr.v4.runtime.Token;
|
||||
|
||||
public class UnifyTypeFactory {
|
||||
|
||||
private static ArrayList<PlaceholderType> PLACEHOLDERS = new ArrayList<>();
|
||||
|
||||
public static FiniteClosure generateFC(List<ClassOrInterface> fromClasses, Writer logFile, ClassLoader classLoader, JavaTXCompiler compiler) throws ClassNotFoundException {
|
||||
public static FiniteClosure generateFC(
|
||||
List<ClassOrInterface> fromClasses,
|
||||
Logger logger,
|
||||
ClassLoader classLoader,
|
||||
JavaTXCompiler compiler,
|
||||
PlaceholderRegistry placeholderRegistry
|
||||
) throws ClassNotFoundException {
|
||||
/*
|
||||
Die transitive Hülle muss funktionieren.
|
||||
Man darf schreiben List<A> extends AL<A>
|
||||
@@ -44,7 +51,7 @@ public class UnifyTypeFactory {
|
||||
Generell dürfen sie immer die gleichen Namen haben.
|
||||
TODO: die transitive Hülle bilden
|
||||
*/
|
||||
return new FiniteClosure(FCGenerator.toUnifyFC(compiler, fromClasses, classLoader), logFile, compiler);
|
||||
return new FiniteClosure(FCGenerator.toUnifyFC(compiler, fromClasses, classLoader, placeholderRegistry), logger, compiler, placeholderRegistry);
|
||||
}
|
||||
|
||||
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr, SourceLoc location){
|
||||
@@ -67,23 +74,23 @@ public class UnifyTypeFactory {
|
||||
* Convert from
|
||||
* ASTType -> UnifyType
|
||||
*/
|
||||
public static UnifyType convert(JavaTXCompiler compiler, RefTypeOrTPHOrWildcardOrGeneric t, Boolean innerType){
|
||||
public static UnifyType convert(JavaTXCompiler compiler, RefTypeOrTPHOrWildcardOrGeneric t, Boolean innerType, PlaceholderRegistry placeholderRegistry){
|
||||
if (t instanceof GenericRefType){
|
||||
return UnifyTypeFactory.convert(compiler, (GenericRefType)t, innerType);
|
||||
return UnifyTypeFactory.convert(compiler, (GenericRefType)t, innerType, placeholderRegistry);
|
||||
} else if (t instanceof TypePlaceholder){
|
||||
return UnifyTypeFactory.convert(compiler, (TypePlaceholder)t, innerType);
|
||||
return UnifyTypeFactory.convert(compiler, (TypePlaceholder)t, innerType, placeholderRegistry);
|
||||
} else if (t instanceof ExtendsWildcardType){
|
||||
return UnifyTypeFactory.convert(compiler, (ExtendsWildcardType)t, innerType);
|
||||
return UnifyTypeFactory.convert(compiler, (ExtendsWildcardType)t, innerType, placeholderRegistry);
|
||||
} else if (t instanceof SuperWildcardType) {
|
||||
return UnifyTypeFactory.convert(compiler, (SuperWildcardType) t, innerType);
|
||||
return UnifyTypeFactory.convert(compiler, (SuperWildcardType) t, innerType, placeholderRegistry);
|
||||
} else if (t instanceof RefType){
|
||||
return UnifyTypeFactory.convert(compiler, (RefType)t, innerType);
|
||||
return UnifyTypeFactory.convert(compiler, (RefType)t, innerType, placeholderRegistry);
|
||||
}
|
||||
//Es wurde versucht ein Typ umzuwandeln, welcher noch nicht von der Factory abgedeckt ist
|
||||
throw new NotImplementedException("Der Typ "+t+" kann nicht umgewandelt werden");
|
||||
}
|
||||
|
||||
public static UnifyType convert(JavaTXCompiler compiler, RefType t, Boolean innerType){
|
||||
public static UnifyType convert(JavaTXCompiler compiler, RefType t, Boolean innerType, PlaceholderRegistry placeholderRegistry){
|
||||
//Check if it is a FunN Type:
|
||||
Pattern p = Pattern.compile("Fun(\\d+)[$][$]");
|
||||
Matcher m = p.matcher(t.getName().toString());
|
||||
@@ -91,75 +98,76 @@ public class UnifyTypeFactory {
|
||||
if(b){
|
||||
Integer N = Integer.valueOf(m.group(1));
|
||||
if((N + 1) == t.getParaList().size()){
|
||||
return convertFunN(compiler, t.getParaList(), false);
|
||||
return convertFunN(compiler, t.getParaList(), false, placeholderRegistry);
|
||||
}
|
||||
}
|
||||
UnifyType ret;
|
||||
List<UnifyType> params = new ArrayList<>();
|
||||
if (t.getParaList() != null) {
|
||||
for (RefTypeOrTPHOrWildcardOrGeneric pT : t.getParaList()) {
|
||||
params.add(UnifyTypeFactory.convert(compiler, pT, true));
|
||||
params.add(UnifyTypeFactory.convert(compiler, pT, true, placeholderRegistry));
|
||||
}
|
||||
}
|
||||
|
||||
var clazz = compiler.getClass(t.getName());
|
||||
if (clazz != null && clazz.isInterface() && clazz.isFunctionalInterface()) {
|
||||
var method = clazz.getMethods().stream().filter(x -> Modifier.isAbstract(x.modifier)).findFirst().orElseThrow();
|
||||
var methodParams = method.getParameterList().getFormalparalist().stream().map(x -> convert(compiler, x.getType(), true)).toList();
|
||||
var methodParams = method.getParameterList().getFormalparalist().stream().map(x -> convert(compiler, x.getType(), true, placeholderRegistry)).toList();
|
||||
var generics = StreamSupport.stream(clazz.getGenerics().spliterator(), false).map(GenericTypeVar::getName).toList();
|
||||
return new FunInterfaceType(t.getName().toString(), new TypeParams(params), methodParams, convert(compiler, method.getReturnType(), true), generics);
|
||||
return new FunInterfaceType(t.getName().toString(), new TypeParams(params), methodParams, convert(compiler, method.getReturnType(), true, placeholderRegistry), generics);
|
||||
}
|
||||
|
||||
return new ReferenceType(t.getName().toString(),new TypeParams(params));
|
||||
}
|
||||
|
||||
public static UnifyType convertFunN(JavaTXCompiler compiler, List<RefTypeOrTPHOrWildcardOrGeneric> paraList, Boolean innerType){
|
||||
public static UnifyType convertFunN(JavaTXCompiler compiler, List<RefTypeOrTPHOrWildcardOrGeneric> paraList, Boolean innerType, PlaceholderRegistry placeholderRegistry){
|
||||
UnifyType ret;
|
||||
List<UnifyType> params = new ArrayList<>();
|
||||
if(paraList != null && paraList.size() > 0){
|
||||
for(RefTypeOrTPHOrWildcardOrGeneric pT : paraList){
|
||||
params.add(UnifyTypeFactory.convert(compiler, pT, false));
|
||||
params.add(UnifyTypeFactory.convert(compiler, pT, false, placeholderRegistry));
|
||||
}
|
||||
}
|
||||
ret = FunNType.getFunNType(new TypeParams(params));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static UnifyType convert(JavaTXCompiler compiler, TypePlaceholder tph, Boolean innerType){
|
||||
public static UnifyType convert(JavaTXCompiler compiler, TypePlaceholder tph, Boolean innerType, PlaceholderRegistry placeholderRegistry) {
|
||||
if (tph.getName().equals("AFR")) {
|
||||
System.out.println("XXX"+innerType);
|
||||
SyntaxTree.logger.info("XXX"+innerType);
|
||||
}
|
||||
PlaceholderType ntph = new PlaceholderType(tph.getName());
|
||||
PlaceholderType ntph = new PlaceholderType(tph.getName(), tph.getVariance(), placeholderRegistry);
|
||||
ntph.setVariance(tph.getVariance());
|
||||
ntph.setOrCons(tph.getOrCons());
|
||||
int in = PLACEHOLDERS.indexOf(ntph);
|
||||
ntph.setWildcardtable(tph.getWildcardtable());
|
||||
int in = placeholderRegistry.UnifyTypeFactory_PLACEHOLDERS.indexOf(ntph);
|
||||
if (in == -1) {
|
||||
PLACEHOLDERS.add(ntph);
|
||||
placeholderRegistry.UnifyTypeFactory_PLACEHOLDERS.add(ntph);
|
||||
ntph.setInnerType(innerType);
|
||||
return ntph;
|
||||
}
|
||||
else {
|
||||
PlaceholderType oldpht = PLACEHOLDERS.get(in);
|
||||
PlaceholderType oldpht = placeholderRegistry.UnifyTypeFactory_PLACEHOLDERS.get(in);
|
||||
oldpht.setInnerType(oldpht.isInnerType() || innerType);
|
||||
return oldpht;
|
||||
}
|
||||
}
|
||||
|
||||
public static UnifyType convert(JavaTXCompiler compiler, GenericRefType t, Boolean innerType){
|
||||
public static UnifyType convert(JavaTXCompiler compiler, GenericRefType t, Boolean innerType, PlaceholderRegistry placeholderRegistry){
|
||||
return new ReferenceType(t.getParsedName(), true);
|
||||
}
|
||||
|
||||
public static UnifyType convert(JavaTXCompiler compiler, WildcardType t, Boolean innerType){
|
||||
public static UnifyType convert(JavaTXCompiler compiler, WildcardType t, Boolean innerType, PlaceholderRegistry placeholderRegistry){
|
||||
if(t.isExtends())
|
||||
return new ExtendsType(UnifyTypeFactory.convert(compiler, t.getInnerType(), false));
|
||||
return new ExtendsType(UnifyTypeFactory.convert(compiler, t.getInnerType(), false, placeholderRegistry));
|
||||
else if(t.isSuper())
|
||||
return new SuperType(UnifyTypeFactory.convert(compiler, t.getInnerType(), false));
|
||||
return new SuperType(UnifyTypeFactory.convert(compiler, t.getInnerType(), false, placeholderRegistry));
|
||||
else throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
public static ConstraintSet<UnifyPair> convert(JavaTXCompiler compiler, ConstraintSet<Pair> constraints) {
|
||||
return constraints.map(c -> UnifyTypeFactory.convert(compiler, c));
|
||||
public static ConstraintSet<UnifyPair> convert(JavaTXCompiler compiler, ConstraintSet<Pair> constraints, PlaceholderRegistry placeholderRegistry) {
|
||||
return constraints.map(c -> UnifyTypeFactory.convert(compiler, c, placeholderRegistry));
|
||||
}
|
||||
|
||||
//NEVER USED
|
||||
@@ -170,30 +178,30 @@ public class UnifyTypeFactory {
|
||||
// return unifyPairConstraint;
|
||||
//}
|
||||
|
||||
public static UnifyPair convert(JavaTXCompiler compiler, Pair p) {
|
||||
public static UnifyPair convert(JavaTXCompiler compiler, Pair p, PlaceholderRegistry placeholderRegistry) {
|
||||
UnifyPair ret = null;
|
||||
if(p.GetOperator().equals(PairOperator.SMALLERDOT)) {
|
||||
ret = generateSmallerDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false)
|
||||
, UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
|
||||
ret = generateSmallerDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false, placeholderRegistry)
|
||||
, UnifyTypeFactory.convert(compiler, p.TA2, false, placeholderRegistry), p.getLocation());
|
||||
//return ret;
|
||||
}else if(p.GetOperator().equals(PairOperator.SMALLERNEQDOT)) {
|
||||
ret = generateSmallNotEqualDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false)
|
||||
, UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
|
||||
ret = generateSmallNotEqualDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false, placeholderRegistry)
|
||||
, UnifyTypeFactory.convert(compiler, p.TA2, false, placeholderRegistry), p.getLocation());
|
||||
//return ret;
|
||||
}else if(p.GetOperator().equals(PairOperator.EQUALSDOT)) {
|
||||
ret = generateEqualDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false)
|
||||
, UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
|
||||
ret = generateEqualDotPair(UnifyTypeFactory.convert(compiler, p.TA1, false, placeholderRegistry)
|
||||
, UnifyTypeFactory.convert(compiler, p.TA2, false, placeholderRegistry), p.getLocation());
|
||||
//return ret;
|
||||
}else if(p.GetOperator().equals(PairOperator.SMALLER)){
|
||||
ret = generateSmallerPair(UnifyTypeFactory.convert(compiler, p.TA1, false),
|
||||
UnifyTypeFactory.convert(compiler, p.TA2, false), p.getLocation());
|
||||
ret = generateSmallerPair(UnifyTypeFactory.convert(compiler, p.TA1, false, placeholderRegistry),
|
||||
UnifyTypeFactory.convert(compiler, p.TA2, false, placeholderRegistry), p.getLocation());
|
||||
}else throw new NotImplementedException();
|
||||
UnifyType lhs, rhs;
|
||||
if (((lhs = ret.getLhsType()) instanceof PlaceholderType)
|
||||
&& ((PlaceholderType)lhs).isWildcardable()
|
||||
&& (rhs = ret.getLhsType()) instanceof PlaceholderType) {
|
||||
if (lhs.getName().equals("AQ")) {
|
||||
System.out.println("");
|
||||
// SyntaxTree.logger.info("");
|
||||
}
|
||||
((PlaceholderType)rhs).enableWildcardtable();
|
||||
}
|
||||
@@ -202,7 +210,7 @@ public class UnifyTypeFactory {
|
||||
&& ((PlaceholderType)rhs).isWildcardable()
|
||||
&& (lhs = ret.getLhsType()) instanceof PlaceholderType) {
|
||||
if (rhs.getName().equals("AQ")) {
|
||||
System.out.println("");
|
||||
// SyntaxTree.logger.info("");
|
||||
}
|
||||
((PlaceholderType)lhs).enableWildcardtable();
|
||||
}
|
||||
@@ -213,16 +221,16 @@ public class UnifyTypeFactory {
|
||||
* Convert from
|
||||
* UnifyType -> ASTType
|
||||
*/
|
||||
public static Set<ResultPair> convert(Set<UnifyPair> unifyPairSet, Map<String,TypePlaceholder> tphs) {
|
||||
public static Set<ResultPair> convert(Set<UnifyPair> unifyPairSet, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||
return unifyPairSet.stream().map(
|
||||
unifyPair -> convert(unifyPair, tphs))
|
||||
unifyPair -> convert(unifyPair, tphs, placeholderRegistry))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static ResultPair convert(UnifyPair mp, Map<String,TypePlaceholder> tphs) {
|
||||
public static ResultPair convert(UnifyPair mp, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||
if (mp == null) { return null;} //kann bei basePairs passieren
|
||||
RefTypeOrTPHOrWildcardOrGeneric tl = UnifyTypeFactory.convert(mp.getLhsType(), tphs);
|
||||
RefTypeOrTPHOrWildcardOrGeneric tr = UnifyTypeFactory.convert(mp.getRhsType(), tphs);
|
||||
RefTypeOrTPHOrWildcardOrGeneric tl = UnifyTypeFactory.convert(mp.getLhsType(), tphs, placeholderRegistry);
|
||||
RefTypeOrTPHOrWildcardOrGeneric tr = UnifyTypeFactory.convert(mp.getRhsType(), tphs, placeholderRegistry);
|
||||
if(tl instanceof TypePlaceholder){
|
||||
if(tr instanceof TypePlaceholder) {
|
||||
|
||||
@@ -231,7 +239,7 @@ public class UnifyTypeFactory {
|
||||
//Einfach ignorieren TODO: Das hier muss ausgebessert werden:
|
||||
//return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, ASTFactory.createObjectType());
|
||||
}else{
|
||||
return new PairTPHsmallerTPH((TypePlaceholder)tl, (TypePlaceholder)tr, convert(mp.getBasePair(), tphs));
|
||||
return new PairTPHsmallerTPH((TypePlaceholder)tl, (TypePlaceholder)tr, convert(mp.getBasePair(), tphs, placeholderRegistry));
|
||||
}
|
||||
}else if(tr instanceof RefType){
|
||||
return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (RefType) tr);
|
||||
@@ -243,51 +251,51 @@ public class UnifyTypeFactory {
|
||||
}else return new PairNoResult(tl, tr);//throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(ReferenceType t, Map<String,TypePlaceholder> tphs) {
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(ReferenceType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||
if(JavaClassName.Void.equals(t.getName()))return new Void(new NullToken());
|
||||
if (t.isGenTypeVar()) return new GenericRefType(t.getName(),new NullToken());
|
||||
RefType ret = new RefType(new JavaClassName(t.getName()),convert(t.getTypeParams(), tphs),new NullToken());
|
||||
RefType ret = new RefType(new JavaClassName(t.getName()),convert(t.getTypeParams(), tphs, placeholderRegistry),new NullToken());
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(FunNType t, Map<String,TypePlaceholder> tphs) {
|
||||
RefType ret = new RefType(new JavaClassName(t.getName()), convert(t.getTypeParams(), tphs), new NullToken());
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(FunNType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||
RefType ret = new RefType(new JavaClassName(t.getName()), convert(t.getTypeParams(), tphs, placeholderRegistry), new NullToken());
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(SuperType t, Map<String,TypePlaceholder> tphs) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric innerType = convert(t.getSuperedType(), tphs);
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(SuperType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric innerType = convert(t.getSuperedType(), tphs, placeholderRegistry);
|
||||
return new SuperWildcardType(innerType, new NullToken());
|
||||
}
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(ExtendsType t, Map<String,TypePlaceholder> tphs) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric innerType = convert(t.getExtendedType(), tphs);
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(ExtendsType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric innerType = convert(t.getExtendedType(), tphs, placeholderRegistry);
|
||||
return new ExtendsWildcardType(innerType, new NullToken());
|
||||
}
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(PlaceholderType t, Map<String,TypePlaceholder> tphs) {
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(PlaceholderType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||
TypePlaceholder ret = tphs.get(t.getName());
|
||||
if(ret == null){ //Dieser TPH wurde vom Unifikationsalgorithmus erstellt
|
||||
ret = TypePlaceholder.fresh(new NullToken());
|
||||
ret = TypePlaceholder.fresh(new NullToken(), placeholderRegistry);
|
||||
tphs.put(t.getName(), ret);
|
||||
}
|
||||
ret.setVariance(t.getVariance());
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(UnifyType t, Map<String,TypePlaceholder> tphs) {
|
||||
if(t instanceof FunNType)return convert((FunNType) t, tphs);
|
||||
if(t instanceof ReferenceType)return convert((ReferenceType) t, tphs);
|
||||
if(t instanceof SuperType)return convert((SuperType) t, tphs);
|
||||
if(t instanceof ExtendsType)return convert((ExtendsType) t, tphs);
|
||||
if(t instanceof PlaceholderType)return convert((PlaceholderType) t, tphs);
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(UnifyType t, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||
if(t instanceof FunNType)return convert((FunNType) t, tphs, placeholderRegistry);
|
||||
if(t instanceof ReferenceType)return convert((ReferenceType) t, tphs, placeholderRegistry);
|
||||
if(t instanceof SuperType)return convert((SuperType) t, tphs, placeholderRegistry);
|
||||
if(t instanceof ExtendsType)return convert((ExtendsType) t, tphs, placeholderRegistry);
|
||||
if(t instanceof PlaceholderType)return convert((PlaceholderType) t, tphs, placeholderRegistry);
|
||||
throw new NotImplementedException("Der Typ "+t+" kann nicht umgewandelt werden");
|
||||
}
|
||||
|
||||
private static List<RefTypeOrTPHOrWildcardOrGeneric> convert(TypeParams typeParams, Map<String,TypePlaceholder> tphs) {
|
||||
private static List<RefTypeOrTPHOrWildcardOrGeneric> convert(TypeParams typeParams, Map<String,TypePlaceholder> tphs, PlaceholderRegistry placeholderRegistry) {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
|
||||
for(UnifyType uT : typeParams){
|
||||
RefTypeOrTPHOrWildcardOrGeneric toAdd = convert(uT, tphs);
|
||||
RefTypeOrTPHOrWildcardOrGeneric toAdd = convert(uT, tphs, placeholderRegistry);
|
||||
ret.add(toAdd);
|
||||
}
|
||||
return ret;
|
||||
|
@@ -17,13 +17,11 @@ public class FieldVar extends Expression {
|
||||
|
||||
public final String fieldVarName;
|
||||
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);
|
||||
this.fieldVarName = fieldVarName;
|
||||
this.receiver = receiver;
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,8 +1,13 @@
|
||||
package de.dhbwstuttgart.syntaxtree.type;
|
||||
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -15,7 +20,7 @@ import java.util.Objects;
|
||||
*
|
||||
*/
|
||||
|
||||
public class ExtendsWildcardType extends WildcardType{
|
||||
public class ExtendsWildcardType extends WildcardType implements ISerializableData {
|
||||
|
||||
/**
|
||||
* Author: Arne Lüdtke<br/>
|
||||
@@ -68,4 +73,22 @@ public class ExtendsWildcardType extends WildcardType{
|
||||
ExtendsWildcardType that = (ExtendsWildcardType) o;
|
||||
return that.innerType.equals(this.innerType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
SerialMap serialized = new SerialMap();
|
||||
serialized.put("innerType", this.innerType.toSerial(keyStorage));
|
||||
|
||||
// create the wrapper and put this as the object
|
||||
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
|
||||
serializedWrapper.put("object", serialized);
|
||||
return serializedWrapper;
|
||||
}
|
||||
|
||||
public static ExtendsWildcardType fromSerial(SerialMap data, UnifyContext context) {
|
||||
return new ExtendsWildcardType(
|
||||
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(data.getMap("innerType"), context),
|
||||
new NullToken()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,57 +1,77 @@
|
||||
package de.dhbwstuttgart.syntaxtree.type;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
{
|
||||
private String name;
|
||||
public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric implements ISerializableData {
|
||||
private String name;
|
||||
|
||||
public GenericRefType(String name, Token offset)
|
||||
{
|
||||
super(offset);
|
||||
this.name = name;
|
||||
}
|
||||
public GenericRefType(String name, Token offset) {
|
||||
super(offset);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getParsedName(){
|
||||
return name.toString();
|
||||
}
|
||||
public String getParsedName() {
|
||||
return name.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
@Override
|
||||
public void accept(ASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A> A acceptTV(TypeVisitor<A> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
@Override
|
||||
public <A> A acceptTV(TypeVisitor<A> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ResultSetVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
@Override
|
||||
public void accept(ResultSetVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
GenericRefType that = (GenericRefType) o;
|
||||
return name.equals(that.name);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
GenericRefType that = (GenericRefType) o;
|
||||
return name.equals(that.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name);
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "GTV " + this.name;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GTV " + this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
SerialMap serialized = new SerialMap();
|
||||
serialized.put("name", this.name);
|
||||
|
||||
// create the wrapper and put this as the object
|
||||
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
|
||||
serializedWrapper.put("object", serialized);
|
||||
return serializedWrapper;
|
||||
}
|
||||
|
||||
public static GenericRefType fromSerial(SerialMap data, UnifyContext context) {
|
||||
return new GenericRefType(
|
||||
data.getValue("name").getOf(String.class),
|
||||
new NullToken()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,133 +1,154 @@
|
||||
package de.dhbwstuttgart.syntaxtree.type;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
{
|
||||
protected final JavaClassName name;
|
||||
protected final List<RefTypeOrTPHOrWildcardOrGeneric> parameter;
|
||||
/**
|
||||
* Ist primitiveFlag auf true, muss beim Codegen dieser Reftype durch
|
||||
* den primitiven Datentyp ersetzt werden
|
||||
*
|
||||
* Bsp: java.lang.Integer mit Flag wird dann zu [int]
|
||||
*/
|
||||
boolean primitiveFlag = false; // TODO Should be final
|
||||
public class RefType extends RefTypeOrTPHOrWildcardOrGeneric implements ISerializableData {
|
||||
protected final JavaClassName name;
|
||||
protected final List<RefTypeOrTPHOrWildcardOrGeneric> parameter;
|
||||
/**
|
||||
* Ist primitiveFlag auf true, muss beim Codegen dieser Reftype durch
|
||||
* den primitiven Datentyp ersetzt werden
|
||||
* <p>
|
||||
* Bsp: java.lang.Integer mit Flag wird dann zu [int]
|
||||
*/
|
||||
boolean primitiveFlag = false; // TODO Should be final
|
||||
|
||||
public RefType(JavaClassName fullyQualifiedName, Token offset)
|
||||
{
|
||||
this(fullyQualifiedName, new ArrayList<>(), offset);
|
||||
public RefType(JavaClassName fullyQualifiedName, Token offset) {
|
||||
this(fullyQualifiedName, new ArrayList<>(), offset);
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return primitiveFlag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String params = "";
|
||||
if (parameter.size() > 0) {
|
||||
params += "<";
|
||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = parameter.iterator();
|
||||
while (it.hasNext()) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric param = it.next();
|
||||
params += param.toString();
|
||||
if (it.hasNext()) params += ", ";
|
||||
}
|
||||
params += ">";
|
||||
}
|
||||
return this.name.toString() + params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.name.hashCode();//Nur den Name hashen. Sorgt für langsame, aber funktionierende HashMaps
|
||||
}
|
||||
|
||||
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset) {
|
||||
this(fullyQualifiedName, parameter, offset, false);
|
||||
}
|
||||
|
||||
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset, boolean primitiveFlag) {
|
||||
super(offset);
|
||||
this.name = (fullyQualifiedName);
|
||||
this.parameter = parameter;
|
||||
this.primitiveFlag = primitiveFlag;
|
||||
}
|
||||
|
||||
public JavaClassName getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<RefTypeOrTPHOrWildcardOrGeneric> getParaList() {
|
||||
if (this.parameter == null) return new ArrayList<>();
|
||||
return this.parameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Author: Jrg Buerle<br/>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof RefType refObj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return primitiveFlag;
|
||||
}
|
||||
if (!Objects.equals(this.name, refObj.name)) return false;
|
||||
boolean ret = true;
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
String params = "";
|
||||
if(parameter.size()>0){
|
||||
params += "<";
|
||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = parameter.iterator();
|
||||
while(it.hasNext()){
|
||||
RefTypeOrTPHOrWildcardOrGeneric param = it.next();
|
||||
params += param.toString();
|
||||
if(it.hasNext())params += ", ";
|
||||
}
|
||||
params += ">";
|
||||
//if(!(super.equals(obj))) PL 2020-03-12 muss vll. einkommentiert werden
|
||||
// return false;
|
||||
|
||||
if (parameter == null || parameter.size() == 0) {
|
||||
ret &= (refObj.getParaList() == null || refObj.getParaList().isEmpty());
|
||||
} else {
|
||||
if (refObj.getParaList() == null) {
|
||||
ret = false;
|
||||
} else if (parameter.size() != refObj.getParaList().size()) {
|
||||
ret = false;
|
||||
} else {
|
||||
for (int i = 0; i < parameter.size(); i++) {
|
||||
ret &= parameter.get(i).equals(refObj.getParaList().get(i));
|
||||
}
|
||||
return this.name.toString() + params;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 0;
|
||||
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) {
|
||||
this(fullyQualifiedName, parameter, offset, false);
|
||||
}
|
||||
|
||||
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset, boolean primitiveFlag) {
|
||||
super(offset);
|
||||
this.name = (fullyQualifiedName);
|
||||
this.parameter = parameter;
|
||||
this.primitiveFlag = primitiveFlag;
|
||||
}
|
||||
@Override
|
||||
public void accept(ASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
public JavaClassName getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
@Override
|
||||
public <A> A acceptTV(TypeVisitor<A> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
public List<RefTypeOrTPHOrWildcardOrGeneric> getParaList(){
|
||||
if(this.parameter==null)return new ArrayList<>();
|
||||
return this.parameter;
|
||||
}
|
||||
@Override
|
||||
public void accept(ResultSetVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Author: Jrg Buerle<br/>
|
||||
* @return
|
||||
*/
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if(obj instanceof RefType){
|
||||
boolean ret = true;
|
||||
|
||||
//if(!(super.equals(obj))) PL 2020-03-12 muss vll. einkommentiert werden
|
||||
// return false;
|
||||
|
||||
if(parameter==null || parameter.size()==0){
|
||||
ret &= (((RefType)obj).getParaList()==null || ((RefType)obj).getParaList().size()==0);
|
||||
}
|
||||
else{
|
||||
if(((RefType)obj).getParaList()==null){
|
||||
ret = false;
|
||||
}
|
||||
else if(parameter.size() != ((RefType)obj).getParaList().size())
|
||||
{
|
||||
ret = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 0; i<parameter.size(); i++)
|
||||
{
|
||||
ret &= parameter.get(i).equals(((RefType)obj).getParaList().get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISerialNode toSerial(KeyStorage keyStorage) {
|
||||
SerialMap serialized = new SerialMap();
|
||||
serialized.put("isPrimitive", this.primitiveFlag);
|
||||
serialized.put("name", this.name.toString());
|
||||
serialized.put("parameters", SerialList.fromMapped(this.parameter, param -> param.toSerial(keyStorage)));
|
||||
|
||||
@Override
|
||||
public void accept(ASTVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
// create the wrapper and put this as the object
|
||||
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
|
||||
serializedWrapper.put("object", serialized);
|
||||
return serializedWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A> A acceptTV(TypeVisitor<A> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ResultSetVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
public static RefType fromSerial(SerialMap data, UnifyContext context) {
|
||||
return new RefType(
|
||||
new JavaClassName(data.getValue("name").getOf(String.class)),
|
||||
data.getList("parameters").assertListOfMaps().stream()
|
||||
.map(param -> RefTypeOrTPHOrWildcardOrGeneric.fromSerial(param, context))
|
||||
.toList(),
|
||||
new NullToken(),
|
||||
data.getValue("isPrimitive").getOf(Boolean.class)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,11 +1,17 @@
|
||||
package de.dhbwstuttgart.syntaxtree.type;
|
||||
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue;
|
||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
public abstract class RefTypeOrTPHOrWildcardOrGeneric extends SyntaxTreeNode{
|
||||
public abstract class RefTypeOrTPHOrWildcardOrGeneric extends SyntaxTreeNode implements ISerializableData {
|
||||
public RefTypeOrTPHOrWildcardOrGeneric(Token offset) {
|
||||
super(offset);
|
||||
}
|
||||
@@ -18,5 +24,26 @@ public abstract class RefTypeOrTPHOrWildcardOrGeneric extends SyntaxTreeNode{
|
||||
|
||||
@Override
|
||||
public abstract boolean equals(Object o);
|
||||
|
||||
|
||||
@Override
|
||||
public ISerialNode toSerial(KeyStorage keyStorage) {
|
||||
SerialMap serialized = new SerialMap();
|
||||
serialized.put("type", this.getClass().getSimpleName());
|
||||
// we only insert null for the object and expect the child classes to call this and override the value with themselves
|
||||
serialized.put("object", SerialValue.NULL);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric fromSerial(SerialMap data, UnifyContext context) {
|
||||
String type = data.getValue("type").getOf(String.class);
|
||||
SerialMap object = data.getMap("object");
|
||||
|
||||
if (type.equals(ExtendsWildcardType.class.getSimpleName())) return ExtendsWildcardType.fromSerial(object, context);
|
||||
else if (type.equals(GenericRefType.class.getSimpleName())) return GenericRefType.fromSerial(object, context);
|
||||
else if (type.equals(SuperWildcardType.class.getSimpleName())) return SuperWildcardType.fromSerial(object, context);
|
||||
else if (type.equals(RefType.class.getSimpleName())) return RefType.fromSerial(object, context);
|
||||
else if (type.equals(Void.class.getSimpleName())) return Void.fromSerial(object, context);
|
||||
else if (type.equals(TypePlaceholder.class.getSimpleName())) return TypePlaceholder.fromSerial(object, context);
|
||||
else throw new RuntimeException("Could not unserialize class of unhandled type " + type);
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,13 @@
|
||||
package de.dhbwstuttgart.syntaxtree.type;
|
||||
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -16,7 +20,7 @@ import java.util.Objects;
|
||||
*
|
||||
*/
|
||||
|
||||
public class SuperWildcardType extends WildcardType{
|
||||
public class SuperWildcardType extends WildcardType implements ISerializableData {
|
||||
|
||||
/**
|
||||
* Author: Arne Lüdtke<br/>
|
||||
@@ -80,4 +84,22 @@ public class SuperWildcardType extends WildcardType{
|
||||
SuperWildcardType that = (SuperWildcardType) o;
|
||||
return that.innerType.equals(this.innerType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
SerialMap serialized = new SerialMap();
|
||||
serialized.put("innerType", this.innerType.toSerial(keyStorage));
|
||||
|
||||
// create the wrapper and put this as the object
|
||||
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
|
||||
serializedWrapper.put("object", serialized);
|
||||
return serializedWrapper;
|
||||
}
|
||||
|
||||
public static SuperWildcardType fromSerial(SerialMap data, UnifyContext context) {
|
||||
return new SuperWildcardType(
|
||||
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(data.getMap("innerType"), context),
|
||||
new NullToken()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,12 @@
|
||||
package de.dhbwstuttgart.syntaxtree.type;
|
||||
import java.util.Hashtable;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
@@ -16,15 +19,23 @@ import org.antlr.v4.runtime.Token;
|
||||
* @author J�rg B�uerle
|
||||
* @version $Date: 2013/06/19 12:45:37 $
|
||||
*/
|
||||
public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric implements ISerializableData
|
||||
{
|
||||
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;
|
||||
|
||||
/**
|
||||
* isWildcardable gibt an, ob ein Wildcardtyp dem PlaceholderType zugeordnet werden darf
|
||||
*/
|
||||
private boolean wildcardable = true;
|
||||
|
||||
/*
|
||||
* Fuer Oder-Constraints:
|
||||
* orCons = 1: Receiver
|
||||
@@ -39,10 +50,12 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
* Factory-Methode <code>fresh()</code> erzeugt.
|
||||
* <br>Author: J�rg B�uerle
|
||||
*/
|
||||
private TypePlaceholder(String name, Token offset)
|
||||
private TypePlaceholder(String name, Token offset, int variance, boolean wildcardable)
|
||||
{
|
||||
super(offset);
|
||||
this.name = name;
|
||||
this.variance = variance;
|
||||
this.wildcardable = wildcardable;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,11 +66,20 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
* @return
|
||||
*/
|
||||
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, PlaceholderRegistry placeholderRegistry){
|
||||
String newName = placeholderRegistry.generateFreshPlaceholderName();
|
||||
return new TypePlaceholder(newName, 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) {
|
||||
return new TypePlaceholder(name, new NullToken());
|
||||
return new TypePlaceholder(name, new NullToken(),0, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -120,4 +142,31 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
public byte getOrCons() {
|
||||
return orCons;
|
||||
}
|
||||
|
||||
|
||||
public Boolean getWildcardtable() {
|
||||
return wildcardable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
SerialMap serialized = new SerialMap();
|
||||
serialized.put("name", this.name);
|
||||
serialized.put("variance", this.variance);
|
||||
serialized.put("wildcardable", this.wildcardable);
|
||||
|
||||
// create the wrapper and put this as the object
|
||||
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
|
||||
serializedWrapper.put("object", serialized);
|
||||
return serializedWrapper;
|
||||
}
|
||||
|
||||
public static TypePlaceholder fromSerial(SerialMap data, UnifyContext context) {
|
||||
return new TypePlaceholder(
|
||||
data.getValue("name").getOf(String.class),
|
||||
new NullToken(),
|
||||
data.getValue("variance").getOf(Integer.class),
|
||||
data.getValue("wildcardable").getOf(Boolean.class)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,14 +1,32 @@
|
||||
package de.dhbwstuttgart.syntaxtree.type;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
|
||||
|
||||
public class Void extends RefType
|
||||
public class Void extends RefType implements ISerializableData
|
||||
{
|
||||
public Void(Token offset) {
|
||||
super(JavaClassName.Void, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISerialNode toSerial(KeyStorage keyStorage) {
|
||||
// create the wrapper and put this as the object
|
||||
var serializedWrapper = super.toSerial(keyStorage).assertType(SerialMap.class);
|
||||
serializedWrapper.put("object", new SerialMap());
|
||||
return serializedWrapper;
|
||||
}
|
||||
|
||||
public static Void fromSerial(SerialMap data, UnifyContext context) {
|
||||
return new Void(new NullToken());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -57,6 +57,11 @@ public class OutputGenerator implements ASTVisitor {
|
||||
out.append(formalParameter.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LiteralPattern literalPattern) {
|
||||
literalPattern.value.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(GenericDeclarationList genericTypeVars) {
|
||||
Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator();
|
||||
@@ -508,12 +513,11 @@ public class OutputGenerator implements ASTVisitor {
|
||||
aRecordPattern.getType().accept(this);
|
||||
out.append("(");
|
||||
List<Pattern> subPatterns = aRecordPattern.getSubPattern();
|
||||
int i;
|
||||
for (i = 0; i < subPatterns.size() - 1; i++) {
|
||||
for (var i = 0; i < subPatterns.size(); i++) {
|
||||
subPatterns.get(i).accept(this);
|
||||
out.append(", ");
|
||||
if (i < subPatterns.size() - 1)
|
||||
out.append(", ");
|
||||
}
|
||||
subPatterns.get(i).accept(this);
|
||||
String name;
|
||||
if ((name = aRecordPattern.getName()) != null)
|
||||
out.append(name);
|
||||
|
8
src/main/java/de/dhbwstuttgart/target/Target.java
Normal file
8
src/main/java/de/dhbwstuttgart/target/Target.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package de.dhbwstuttgart.target;
|
||||
|
||||
import de.dhbwstuttgart.util.Logger;
|
||||
|
||||
public class Target {
|
||||
public static Logger logger = new Logger("Target");
|
||||
|
||||
}
|
@@ -1,10 +1,10 @@
|
||||
package de.dhbwstuttgart.target.generate;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.CodeGenException;
|
||||
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
@@ -12,6 +12,7 @@ import de.dhbwstuttgart.syntaxtree.Record;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.target.Target;
|
||||
import de.dhbwstuttgart.target.tree.*;
|
||||
import de.dhbwstuttgart.target.tree.expression.*;
|
||||
import de.dhbwstuttgart.target.tree.type.*;
|
||||
@@ -33,12 +34,18 @@ public class ASTToTargetAST {
|
||||
|
||||
protected List<Generics> all;
|
||||
public Generics generics;
|
||||
public List<Generics> currentMethodOverloads;
|
||||
|
||||
final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>();
|
||||
final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>();
|
||||
private Method currentMethod;
|
||||
|
||||
public final JavaTXCompiler compiler;
|
||||
|
||||
public List<RefTypeOrTPHOrWildcardOrGeneric> findAllVariants(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
return javaGenerics().stream().map(generics -> generics.resolve(type)).distinct().toList();
|
||||
}
|
||||
|
||||
public List<GenericsResult> txGenerics() {
|
||||
return all.stream().map(generics -> new GenericsResult(generics.txGenerics)).toList();
|
||||
}
|
||||
@@ -138,38 +145,205 @@ public class ASTToTargetAST {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<List<TargetMethod>> groupOverloads(ClassOrInterface input, List<Method> methods) {
|
||||
var res = new ArrayList<List<TargetMethod>>();
|
||||
for (var method : methods) {
|
||||
// Convert all methods
|
||||
var methodsWithTphs = convert(input, method);
|
||||
// Then check for methods with the same signature
|
||||
var mapOfSignatures = new HashMap<TargetMethod.Signature, List<MethodWithTphs>>();
|
||||
for (var m : methodsWithTphs) {
|
||||
var methodsWithSameSignature = mapOfSignatures.getOrDefault(m.method.signature(), new ArrayList<>());
|
||||
methodsWithSameSignature.add(m);
|
||||
mapOfSignatures.put(m.method.signature(), methodsWithSameSignature);
|
||||
}
|
||||
// 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())));
|
||||
|
||||
var resMethods = new HashSet<TargetMethod>();
|
||||
for (var methodsWithSignature : mapOfSignatures.values()) {
|
||||
outer: for (var m1 : methodsWithSignature) {
|
||||
for (var m2 : methodsWithSignature) {
|
||||
for (var i = 0; i < m1.args.size(); i++) {
|
||||
var arg1 = m1.args.get(i);
|
||||
var arg2 = m2.args.get(i);
|
||||
if (arg1.parameter.equals(arg2.parameter)) {
|
||||
if (isSupertype(arg1.signature, arg2.signature) &&
|
||||
!arg1.signature.equals(arg2.signature)) continue outer;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resMethods.add(m1.method);
|
||||
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);
|
||||
}
|
||||
}
|
||||
res.add(resMethods.stream().toList());
|
||||
}
|
||||
return res;
|
||||
|
||||
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();
|
||||
|
||||
Target.logger.info("============== OUTPUT ==============");
|
||||
for (var l : result) {
|
||||
for (var m : l) Target.logger.info(m.name() + " " + m.getSignature());
|
||||
Target.logger.info("");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public TargetStructure convert(ClassOrInterface input) {
|
||||
@@ -202,7 +376,8 @@ public class ASTToTargetAST {
|
||||
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 fields = input.getFieldDecl().stream().map(this::convert).toList();
|
||||
var methods = groupOverloads(input, input.getMethods()).stream().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;
|
||||
if (input.getStaticInitializer().isPresent())
|
||||
@@ -216,9 +391,14 @@ public class ASTToTargetAST {
|
||||
}
|
||||
|
||||
public List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) {
|
||||
return input.getFormalparalist().stream().map(param ->
|
||||
new MethodParameter((TargetPattern) convert(param))
|
||||
).toList();
|
||||
var res = new ArrayList<MethodParameter>();
|
||||
for (var i = 0; i < input.getFormalparalist().size(); i++) {
|
||||
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) {
|
||||
@@ -267,69 +447,156 @@ public class ASTToTargetAST {
|
||||
return result;
|
||||
}
|
||||
|
||||
private String encodeName(String name, ParameterList params) {
|
||||
private String encodeName(String name, TargetMethod.Signature params) {
|
||||
var res = new StringBuilder();
|
||||
res.append(name);
|
||||
res.append('$');
|
||||
for (var param : params.getFormalparalist()) {
|
||||
if (param instanceof RecordPattern rp) {
|
||||
res.append(FunNGenerator.encodeType(convert(param.getType())));
|
||||
for (var pattern : rp.getSubPattern()) {
|
||||
res.append(FunNGenerator.encodeType(convert(pattern.getType())));
|
||||
}
|
||||
}
|
||||
for (var param : params.parameters()) {
|
||||
encodeName(param.pattern(), res);
|
||||
}
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
private List<TargetMethod> convert(ClassOrInterface clazz, List<Method> overloadedMethods) {
|
||||
if (overloadedMethods.size() == 1) {
|
||||
return convert(clazz, overloadedMethods.getFirst()).stream().map(m -> m.method()).toList();
|
||||
}
|
||||
var methods = new ArrayList<Method>();
|
||||
for (var method : overloadedMethods) {
|
||||
var newMethod = new Method(
|
||||
method.modifier,
|
||||
method.name,
|
||||
//encodeName(method.name, method.getParameterList()),
|
||||
method.getReturnType(),
|
||||
method.getParameterList(),
|
||||
method.block,
|
||||
method.getGenerics(),
|
||||
method.getOffset()
|
||||
);
|
||||
methods.add(newMethod);
|
||||
}
|
||||
|
||||
// TODO Record overloading
|
||||
/*var template = overloadedMethods.get(0);
|
||||
|
||||
var pParams = new ArrayList<Pattern>();
|
||||
var i = 0;
|
||||
for (var par : template.getParameterList()) {
|
||||
pParams.add(switch (par) {
|
||||
case RecordPattern rp -> new RecordPattern(rp.getSubPattern(), "par" + i, rp.getType(), new NullToken());
|
||||
default -> par;
|
||||
});
|
||||
i++;
|
||||
}
|
||||
var params = new ParameterList(pParams, new NullToken());
|
||||
|
||||
var statements = new ArrayList<Statement>();
|
||||
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*/
|
||||
var res = new ArrayList<TargetMethod>();
|
||||
for (var method : methods) {
|
||||
var overloads = convert(clazz, method);
|
||||
for (var m : overloads) {
|
||||
var overload = m.method;
|
||||
if (res.contains(overload)) throw new CodeGenException("Duplicate method found: " + overload.name() + " with signature " + overload.signature().getSignature());
|
||||
res.add(overload);
|
||||
private void encodeName(TargetPattern pattern, StringBuilder res) {
|
||||
if (pattern instanceof TargetComplexPattern cp) {
|
||||
res.append(FunNGenerator.encodeType(cp.type()));
|
||||
for (var pat : cp.subPatterns()) {
|
||||
encodeName(pat, res);
|
||||
}
|
||||
} else {
|
||||
res.append(FunNGenerator.encodeType(pattern.type()));
|
||||
}
|
||||
}
|
||||
|
||||
private TargetType unwrap(TargetType type) {
|
||||
if (type instanceof TargetRefType ref) {
|
||||
if (!ref.params().isEmpty()) return new TargetRefType(ref.name());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private TargetExpression generatePatternOverloadsRec(int offset, TargetExpression switchExpr, List<TargetLocalVar> params, List<TargetPattern> patterns, List<TargetMethod> methods, TargetType classType) {
|
||||
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()
|
||||
);
|
||||
if (method.signature().returnType() != null) {
|
||||
caseBody = new TargetReturn(caseBody);
|
||||
}
|
||||
return caseBody;
|
||||
}
|
||||
|
||||
var cases = new ArrayList<TargetSwitch.Case>();
|
||||
var usedPatterns = new HashSet<TargetPattern>();
|
||||
|
||||
for (var method : methods) {
|
||||
var patternsRec = new ArrayList<>(patterns);
|
||||
|
||||
TargetExpression expr = null;
|
||||
var i = 0;
|
||||
for (var param : method.signature().parameters()) {
|
||||
if (i == offset) {
|
||||
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_);
|
||||
}
|
||||
|
||||
return new TargetSwitch(switchExpr, cases, null, true);
|
||||
}
|
||||
|
||||
private List<TargetMethod> generatePatternOverloads(ClassOrInterface clazz, List<TargetMethod> overloadedMethods) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -374,13 +641,30 @@ public class ASTToTargetAST {
|
||||
}).findFirst();
|
||||
}
|
||||
|
||||
record MethodWithTphs(TargetMethod method, List<SignaturePairTarget> args) {}
|
||||
record MethodWithTphs(TargetMethod method, Generics generics, List<SignaturePairTarget> args) {
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
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) {
|
||||
generics = s;
|
||||
var javaGenerics = this.generics.javaGenerics.generics(currentClass, method);
|
||||
@@ -404,11 +688,21 @@ public class ASTToTargetAST {
|
||||
|
||||
var javaSignature = new TargetMethod.Signature(javaMethodGenerics, params, returnType);
|
||||
var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), this.generics.txGenerics));
|
||||
var newMethod = new TargetMethod(method.modifier, method.name, convert(method.block), javaSignature, txSignature);
|
||||
|
||||
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, concreteParams));
|
||||
result.add(new MethodWithTphs(newMethod, generics, concreteParams));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -418,7 +712,9 @@ public class ASTToTargetAST {
|
||||
var list = new ArrayList<MethodParameter>();
|
||||
for (var i = 0; i < paraList.getFormalparalist().size(); 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;
|
||||
}
|
||||
|
@@ -1,13 +1,12 @@
|
||||
package de.dhbwstuttgart.target.generate;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import de.dhbwstuttgart.target.Target;
|
||||
import de.dhbwstuttgart.target.tree.type.TargetGenericType;
|
||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||
import de.dhbwstuttgart.typeinference.result.PairTPHEqualTPH;
|
||||
@@ -134,24 +133,59 @@ public abstract class GenerateGenerics {
|
||||
final Map<Method, Set<Pair>> familyOfMethods = new HashMap<>();
|
||||
|
||||
final Set<PairLT> simplifiedConstraints = new HashSet<>();
|
||||
final Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
|
||||
final Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>();
|
||||
Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
|
||||
Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>();
|
||||
|
||||
GenerateGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
|
||||
this.astToTargetAST = astToTargetAST;
|
||||
for (var constraint : constraints.results) {
|
||||
if (constraint instanceof PairTPHsmallerTPH p) {
|
||||
System.out.println(p.left + " " + p.left.getVariance());
|
||||
Target.logger.info(p.left + " " + p.left.getVariance());
|
||||
simplifiedConstraints.add(new PairLT(new TPH(p.left), new TPH(p.right)));
|
||||
} else if (constraint instanceof PairTPHEqualTPH p) {
|
||||
equality.put(p.getLeft(), p.getRight());
|
||||
} else if (constraint instanceof PairTPHequalRefTypeOrWildcardType p) {
|
||||
System.out.println(p.left + " = " + p.right);
|
||||
Target.logger.info(p.left + " = " + p.right);
|
||||
concreteTypes.put(new TPH(p.left), p.right);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Simplified constraints: " + simplifiedConstraints);
|
||||
Target.logger.info("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) {
|
||||
@@ -216,7 +250,7 @@ public abstract class GenerateGenerics {
|
||||
equality.put(entry.getKey(), to);
|
||||
}
|
||||
}
|
||||
System.out.println(from + " -> " + to + " " + from.getVariance());
|
||||
Target.logger.info(from + " -> " + to + " " + from.getVariance());
|
||||
//from.setVariance(to.getVariance());
|
||||
equality.put(from, to);
|
||||
referenced.remove(new TPH(from));
|
||||
@@ -285,7 +319,7 @@ public abstract class GenerateGenerics {
|
||||
Set<TPH> T2s = new HashSet<>();
|
||||
findTphs(superType, T2s);
|
||||
|
||||
System.out.println("T1s: " + T1s + " T2s: " + T2s);
|
||||
Target.logger.info("T1s: " + T1s + " T2s: " + T2s);
|
||||
//Ende
|
||||
|
||||
superType = methodCall.receiverType;
|
||||
@@ -300,7 +334,7 @@ public abstract class GenerateGenerics {
|
||||
var optMethod = astToTargetAST.findMethod(owner, methodCall.name, methodCall.signatureArguments().stream().map(astToTargetAST::convert).toList());
|
||||
if (optMethod.isEmpty()) return;
|
||||
var method2 = optMethod.get();
|
||||
System.out.println("In: " + method.getName() + " Method: " + method2.getName());
|
||||
Target.logger.info("In: " + method.getName() + " Method: " + method2.getName());
|
||||
var generics = family(owner, method2);
|
||||
|
||||
// transitive and
|
||||
@@ -333,7 +367,7 @@ public abstract class GenerateGenerics {
|
||||
if (!T1s.contains(R1) || !T2s.contains(R2)) continue;
|
||||
|
||||
var newPair = new PairLT(R1, R2);
|
||||
System.out.println("New pair: " + newPair);
|
||||
Target.logger.info("New pair: " + newPair);
|
||||
newPairs.add(newPair);
|
||||
|
||||
if (!containsRelation(result, newPair))
|
||||
@@ -490,9 +524,7 @@ public abstract class GenerateGenerics {
|
||||
|
||||
if (!(method instanceof Constructor))
|
||||
typeVariables.addAll(findTypeVariables(method.getReturnType()));
|
||||
for (var arg : method.getParameterList().getFormalparalist()) {
|
||||
typeVariables.addAll(findTypeVariables(arg.getType()));
|
||||
}
|
||||
typeVariables.addAll(findTypeVariables(method.getParameterList()));
|
||||
|
||||
if (method.block != null)
|
||||
method.block.accept(new TracingStatementVisitor() {
|
||||
@@ -537,7 +569,7 @@ public abstract class GenerateGenerics {
|
||||
Set<Pair> generics(ClassOrInterface owner, Method method) {
|
||||
if (computedGenericsOfMethods.containsKey(method)) {
|
||||
var cached = computedGenericsOfMethods.get(method);
|
||||
System.out.println("Cached " + method.getName() + ": " + cached);
|
||||
Target.logger.info("Cached " + method.getName() + ": " + cached);
|
||||
return cached;
|
||||
}
|
||||
|
||||
@@ -556,9 +588,7 @@ public abstract class GenerateGenerics {
|
||||
|
||||
var usedTphs = new HashSet<TPH>();
|
||||
// For eliminating inner type variables we need to figure out which ones are actually used
|
||||
for (var param : method.getParameterList().getFormalparalist()) {
|
||||
usedTphs.addAll(findTypeVariables(param.getType()));
|
||||
}
|
||||
usedTphs.addAll(findTypeVariables(method.getParameterList()));
|
||||
usedTphs.addAll(findTypeVariables(method.getReturnType()));
|
||||
referenced.addAll(usedTphs);
|
||||
referenced.addAll(typeVariablesOfClass);
|
||||
@@ -568,7 +598,7 @@ public abstract class GenerateGenerics {
|
||||
|
||||
normalize(result, classGenerics, usedTphs);
|
||||
|
||||
System.out.println(this.getClass().getSimpleName() + " " + method.name + ": " + result);
|
||||
Target.logger.info(this.getClass().getSimpleName() + " " + method.name + ": " + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -647,7 +677,7 @@ public abstract class GenerateGenerics {
|
||||
|
||||
normalize(javaResult, null, referencedByClass);
|
||||
|
||||
System.out.println(this.getClass().getSimpleName() + " Class " + classOrInterface.getClassName().getClassName() + ": " + javaResult);
|
||||
Target.logger.info(this.getClass().getSimpleName() + " Class " + classOrInterface.getClassName().getClassName() + ": " + javaResult);
|
||||
return javaResult;
|
||||
}
|
||||
|
||||
@@ -656,11 +686,21 @@ public abstract class GenerateGenerics {
|
||||
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) {
|
||||
if (classGenerics == null || classGenerics.stream().noneMatch((pair) -> pair.left.equals(tph)))
|
||||
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) {}
|
||||
@@ -688,7 +728,7 @@ public abstract class GenerateGenerics {
|
||||
if (!added) break;
|
||||
}
|
||||
|
||||
System.out.println(chain + " " + chain.stream().map(e -> e.resolve().getVariance()).toList());
|
||||
Target.logger.info(chain + " " + chain.stream().map(e -> e.resolve().getVariance()).toList());
|
||||
var variance = chain.get(0).resolve().getVariance();
|
||||
if (variance != 1) continue;
|
||||
var index = 0;
|
||||
@@ -726,7 +766,7 @@ public abstract class GenerateGenerics {
|
||||
}
|
||||
|
||||
for (var pair : elementsToAddToEquality) {
|
||||
System.out.println(pair);
|
||||
Target.logger.info(pair);
|
||||
addToEquality(pair.left, pair.right, referenced);
|
||||
}
|
||||
}
|
||||
@@ -879,11 +919,11 @@ public abstract class GenerateGenerics {
|
||||
}
|
||||
}
|
||||
if (infima.size() > 1) {
|
||||
System.out.println(infima);
|
||||
Target.logger.info(infima);
|
||||
for (var pair : infima) {
|
||||
var returnTypes = findTypeVariables(method.getReturnType());
|
||||
var chain = findConnectionToReturnType(returnTypes, input, new HashSet<>(), pair.left);
|
||||
System.out.println("Find: " + pair.left + " " + chain);
|
||||
Target.logger.info("Find: " + pair.left + " " + chain);
|
||||
chain.remove(pair.left);
|
||||
if (chain.size() > 0) {
|
||||
for (var tph : chain)
|
||||
@@ -921,8 +961,8 @@ public abstract class GenerateGenerics {
|
||||
}
|
||||
}
|
||||
newTph.setVariance(variance);
|
||||
System.out.println(infima + " " + infima.stream().map(i -> i.right.resolve().getVariance()).toList());
|
||||
System.out.println("Infima new TPH " + newTph + " variance " + variance);
|
||||
Target.logger.info(infima + " " + infima.stream().map(i -> i.right.resolve().getVariance()).toList());
|
||||
Target.logger.info("Infima new TPH " + newTph + " variance " + variance);
|
||||
|
||||
//referenced.add(newTph);
|
||||
addToPairs(input, new PairLT(left, new TPH(newTph)));
|
||||
|
@@ -1,24 +1,22 @@
|
||||
package de.dhbwstuttgart.target.generate;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.PrimitiveMethodsGenerator;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.target.Target;
|
||||
import de.dhbwstuttgart.target.tree.MethodParameter;
|
||||
import de.dhbwstuttgart.target.tree.TargetGeneric;
|
||||
import de.dhbwstuttgart.target.tree.TargetMethod;
|
||||
import de.dhbwstuttgart.target.tree.expression.*;
|
||||
import de.dhbwstuttgart.target.tree.type.*;
|
||||
|
||||
import javax.swing.text.html.Option;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
public class StatementToTargetExpression implements ASTVisitor {
|
||||
@@ -123,7 +121,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(BoolExpression bool) {
|
||||
System.out.println("BoolExpression");
|
||||
Target.logger.info("BoolExpression");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -143,7 +141,11 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
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
|
||||
@@ -233,7 +235,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
isInterface = receiverClass.isInterface();
|
||||
}
|
||||
|
||||
System.out.println(argList);
|
||||
Target.logger.info(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);
|
||||
}
|
||||
|
||||
@@ -386,9 +388,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));
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
for (var block : switchStmt.getBlocks()) {
|
||||
@@ -482,6 +569,11 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
result = new TargetTypePattern(converter.convert(aPattern.getType()), aPattern.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LiteralPattern literalPattern) {
|
||||
result = new TargetExpressionPattern(converter.convert(literalPattern.value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ExpressionPattern aPattern) {
|
||||
result = converter.convert(aPattern.getExpression());
|
||||
|
@@ -11,4 +11,8 @@ public record MethodParameter(TargetPattern pattern) {
|
||||
public MethodParameter withType(TargetType type) {
|
||||
return new MethodParameter(pattern.withType(type));
|
||||
}
|
||||
|
||||
public MethodParameter withName(String name) {
|
||||
return new MethodParameter(pattern.withName(name));
|
||||
}
|
||||
}
|
||||
|
@@ -18,6 +18,19 @@ public record TargetMethod(int access, String name, TargetBlock block, Signature
|
||||
public String getDescriptor() {
|
||||
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) {
|
||||
@@ -66,6 +79,10 @@ public record TargetMethod(int access, String name, TargetBlock block, Signature
|
||||
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;
|
||||
|
@@ -9,4 +9,9 @@ public record TargetComplexPattern(TargetType type, String name, List<TargetPatt
|
||||
public TargetComplexPattern withType(TargetType type) {
|
||||
return new TargetComplexPattern(type, name, subPatterns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetComplexPattern withName(String name) {
|
||||
return new TargetComplexPattern(type, name, subPatterns);
|
||||
}
|
||||
}
|
||||
|
@@ -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() {
|
||||
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;
|
||||
|
||||
public sealed interface TargetPattern extends TargetExpression permits TargetComplexPattern, TargetGuard, TargetTypePattern {
|
||||
public sealed interface TargetPattern extends TargetExpression permits TargetComplexPattern, TargetExpressionPattern, TargetGuard, TargetTypePattern {
|
||||
default String name() {
|
||||
return null;
|
||||
}
|
||||
@@ -10,4 +10,6 @@ public sealed interface TargetPattern extends TargetExpression permits TargetCom
|
||||
TargetPattern withType(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) {
|
||||
return new TargetTypePattern(type, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetTypePattern withName(String name) {
|
||||
return new TargetTypePattern(type, name);
|
||||
}
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class TypeInsertPlacer extends AbstractASTWalker{
|
||||
public class TypeInsertPlacer extends AbstractASTWalker {
|
||||
Set<TypeInsert> inserts = new HashSet<>();
|
||||
private ResultSet withResults;
|
||||
String pkgName;
|
||||
|
@@ -9,13 +9,8 @@ import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import javax.swing.text.html.Option;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
@@ -19,11 +19,11 @@ public class MethodAssumption extends Assumption{
|
||||
private ClassOrInterface receiver;
|
||||
private RefTypeOrTPHOrWildcardOrGeneric retType;
|
||||
List<? extends RefTypeOrTPHOrWildcardOrGeneric> params;
|
||||
private final Boolean isInherited;
|
||||
private final Boolean isOverridden;
|
||||
private final boolean isInherited;
|
||||
private final boolean isOverridden;
|
||||
|
||||
public MethodAssumption(ClassOrInterface receiver, RefTypeOrTPHOrWildcardOrGeneric retType,
|
||||
List<? extends RefTypeOrTPHOrWildcardOrGeneric> params, TypeScope scope, Boolean isInherited, Boolean isOverridden){
|
||||
List<? extends RefTypeOrTPHOrWildcardOrGeneric> params, TypeScope scope, boolean isInherited, boolean isOverridden){
|
||||
super(scope);
|
||||
this.receiver = receiver;
|
||||
this.retType = retType;
|
||||
@@ -73,11 +73,11 @@ public class MethodAssumption extends Assumption{
|
||||
return TYPEStmt.getReceiverType(receiver, resolver);
|
||||
}
|
||||
|
||||
public Boolean isInherited() {
|
||||
public boolean isInherited() {
|
||||
return isInherited;
|
||||
}
|
||||
|
||||
public Boolean isOverridden() {
|
||||
public boolean isOverridden() {
|
||||
return isOverridden;
|
||||
}
|
||||
}
|
||||
|
@@ -1,77 +1,171 @@
|
||||
package de.dhbwstuttgart.typeinference.constraints;
|
||||
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialUUID;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class Constraint<A> extends HashSet<A> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Boolean isInherited = false;//wird beides nur für die Method-Constraints benoetigt
|
||||
private Boolean isImplemented = false;
|
||||
|
||||
/*
|
||||
* wird verwendet um bei der Codegenerierung die richtige Methoden - Signatur
|
||||
* auszuwaehlen
|
||||
*/
|
||||
/*private*/ Set<A> methodSignatureConstraint = new HashSet<>();
|
||||
|
||||
private Constraint<A> extendConstraint = null;
|
||||
|
||||
public Constraint() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Constraint(Boolean isInherited, Boolean isImplemented) {
|
||||
this.isInherited = isInherited;
|
||||
this.isImplemented = isImplemented;
|
||||
}
|
||||
|
||||
public Constraint(Boolean isInherited, Boolean isImplemented, Constraint<A> extendConstraint, Set<A> methodSignatureConstraint) {
|
||||
this.isInherited = isInherited;
|
||||
this.isImplemented = isImplemented;
|
||||
this.extendConstraint = extendConstraint;
|
||||
this.methodSignatureConstraint = methodSignatureConstraint;
|
||||
}
|
||||
|
||||
public void setIsInherited(Boolean isInherited) {
|
||||
this.isInherited = isInherited;
|
||||
}
|
||||
|
||||
public Boolean isInherited() {
|
||||
return isInherited;
|
||||
}
|
||||
|
||||
public Boolean isImplemented() {
|
||||
return isImplemented;
|
||||
}
|
||||
|
||||
public Constraint<A> getExtendConstraint() {
|
||||
return extendConstraint;
|
||||
}
|
||||
|
||||
public void setExtendConstraint(Constraint<A> c) {
|
||||
extendConstraint = c;
|
||||
}
|
||||
|
||||
public Set<A> getmethodSignatureConstraint() {
|
||||
return methodSignatureConstraint;
|
||||
}
|
||||
|
||||
public void setmethodSignatureConstraint(Set<A> c) {
|
||||
methodSignatureConstraint = c;
|
||||
}
|
||||
public class Constraint<A extends IConstraintElement> extends HashSet<A> implements ISerializableData {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private boolean isInherited = false;//wird beides nur für die Method-Constraints benoetigt
|
||||
private boolean isImplemented = false;
|
||||
|
||||
/*
|
||||
* wird verwendet um bei der Codegenerierung die richtige Methoden - Signatur
|
||||
* auszuwaehlen
|
||||
*/
|
||||
/*private*/ Set<A> methodSignatureConstraint = new HashSet<>();
|
||||
|
||||
private Constraint<A> extendConstraint = null;
|
||||
|
||||
public Constraint() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Constraint(int initialCapacity) {
|
||||
super(initialCapacity);
|
||||
}
|
||||
|
||||
public Constraint(boolean isInherited, boolean isImplemented) {
|
||||
this.isInherited = isInherited;
|
||||
this.isImplemented = isImplemented;
|
||||
}
|
||||
|
||||
public Constraint(boolean isInherited, boolean isImplemented, Constraint<A> extendConstraint, Set<A> methodSignatureConstraint) {
|
||||
this.isInherited = isInherited;
|
||||
this.isImplemented = isImplemented;
|
||||
this.extendConstraint = extendConstraint;
|
||||
this.methodSignatureConstraint = methodSignatureConstraint;
|
||||
}
|
||||
|
||||
public void setIsInherited(boolean isInherited) {
|
||||
this.isInherited = isInherited;
|
||||
}
|
||||
|
||||
public boolean isInherited() {
|
||||
return isInherited;
|
||||
}
|
||||
|
||||
public boolean isImplemented() {
|
||||
return isImplemented;
|
||||
}
|
||||
|
||||
public Constraint<A> getExtendConstraint() {
|
||||
return extendConstraint;
|
||||
}
|
||||
|
||||
public void setExtendConstraint(Constraint<A> c) {
|
||||
extendConstraint = c;
|
||||
}
|
||||
|
||||
public Set<A> getmethodSignatureConstraint() {
|
||||
return methodSignatureConstraint;
|
||||
}
|
||||
|
||||
public void setmethodSignatureConstraint(Set<A> c) {
|
||||
methodSignatureConstraint = c;
|
||||
}
|
||||
|
||||
public <B extends IConstraintElement> Constraint<B> createdMapped(Function<A,B> mapper) {
|
||||
Constraint<B> result = new Constraint<>(this.size());
|
||||
for (A element : this) {
|
||||
result.add(mapper.apply(element));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return super.toString() + "\nisInherited = " + isInherited
|
||||
+ " isOveridden = " + isImplemented
|
||||
+ " msc[" + methodSignatureConstraint.size() + "] = " + methodSignatureConstraint
|
||||
//" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" )
|
||||
+ "\n";
|
||||
}
|
||||
|
||||
public String toStringBase() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
private String serialUUID = null;
|
||||
|
||||
@Override
|
||||
public SerialUUID toSerial(KeyStorage keyStorage) {
|
||||
final String uuid = serialUUID == null ? keyStorage.getIdentifier() : serialUUID;
|
||||
if (serialUUID == null) serialUUID = uuid;
|
||||
|
||||
if (!keyStorage.isAlreadySerialized(uuid)) {
|
||||
SerialMap serialized = new SerialMap();
|
||||
keyStorage.putSerialized(uuid, serialized);
|
||||
serialized.put("isInherited", isInherited);
|
||||
serialized.put("isImplemented", isImplemented);
|
||||
serialized.put("extendedConstraint", extendConstraint == null ? null :
|
||||
extendConstraint.toSerial(keyStorage));
|
||||
Function<A, ISerialNode> pairMapper = pair -> {
|
||||
if (pair instanceof Pair simplePair) return simplePair.toSerial(keyStorage);
|
||||
if (pair instanceof UnifyPair unifyPair) return unifyPair.toSerial(keyStorage);
|
||||
throw new RuntimeException("No serialization is supported for type " + pair.getClass().getName());
|
||||
};
|
||||
serialized.put("methodSignatureConstraint", methodSignatureConstraint == null ? null :
|
||||
SerialList.fromMapped(methodSignatureConstraint, pairMapper));
|
||||
serialized.put("setElements", SerialList.fromMapped(this, pairMapper));
|
||||
}
|
||||
|
||||
// return only the unique key
|
||||
return new SerialUUID(uuid);
|
||||
}
|
||||
|
||||
public static <T extends IConstraintElement> Constraint<T> fromSerial(SerialUUID serialUUID, UnifyContext context, Class<T> target, KeyStorage keyStorage) {
|
||||
String uuid = serialUUID.uuid;
|
||||
|
||||
if (!keyStorage.isAlreadyUnserialized(uuid)) {
|
||||
Constraint<T> constraint = new Constraint<>();
|
||||
// immediately add the object to the context to prevent infinite recursion
|
||||
keyStorage.putUnserialized(uuid, constraint);
|
||||
|
||||
// retrieve the serialized data und start unserializing it
|
||||
SerialMap data = keyStorage.getSerialized(uuid);
|
||||
constraint.isInherited = data.getValue("isInherited").getOf(Boolean.class);
|
||||
constraint.isImplemented = data.getValue("isImplemented").getOf(Boolean.class);
|
||||
constraint.extendConstraint = Optional.ofNullable(data.getUUIDOrNull("extendedConstraint"))
|
||||
.map(v -> Constraint.fromSerial(v, context, target, keyStorage))
|
||||
.orElse(null);
|
||||
|
||||
// to convert the maps back to elements, we sadly have to do some assumptions about the generic types...
|
||||
Function<ISerialNode, T> pairUnmapper = pairData -> {
|
||||
if (target == Pair.class && pairData instanceof SerialMap pairMap) {
|
||||
return (T) Pair.fromSerial(pairMap, context);
|
||||
}
|
||||
if (target == UnifyPair.class && pairData instanceof SerialUUID pairUUID) {
|
||||
return (T) UnifyPair.fromSerial(pairUUID, context, keyStorage);
|
||||
}
|
||||
throw new RuntimeException("No serialization is supported for target type " + target.getName());
|
||||
};
|
||||
|
||||
constraint.methodSignatureConstraint =
|
||||
Optional.ofNullable(data.getListOrNull("methodSignatureConstraint"))
|
||||
.map(l -> l.stream().map(pairUnmapper).collect(Collectors.toSet()))
|
||||
.orElse(null);
|
||||
constraint.addAll(
|
||||
data.getList("setElements")
|
||||
.stream().map(pairUnmapper).toList());
|
||||
}
|
||||
|
||||
return keyStorage.getUnserialized(uuid, Constraint.class);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return super.toString() + "\nisInherited = " + isInherited + " isOveridden = " + isImplemented
|
||||
+ methodSignatureConstraint
|
||||
//" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" )
|
||||
+ "\n" ;
|
||||
}
|
||||
|
||||
public String toStringBase() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,63 +1,80 @@
|
||||
package de.dhbwstuttgart.typeinference.constraints;
|
||||
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.typeinference.unify.GuavaSetOperations;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
||||
import java.util.*;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ConstraintSet<A> {
|
||||
Constraint<A> undConstraints = new Constraint<>();
|
||||
List<Set<Constraint<A>>> oderConstraints = new ArrayList<>();
|
||||
public class ConstraintSet<A extends IConstraintElement> implements ISerializableData {
|
||||
Constraint<A> undConstraints = new Constraint<>();
|
||||
List<Set<Constraint<A>>> oderConstraints = new ArrayList<>();
|
||||
|
||||
public void addUndConstraint(A p){
|
||||
undConstraints.add(p);
|
||||
}
|
||||
public void addUndConstraint(A p) {
|
||||
undConstraints.add(p);
|
||||
}
|
||||
|
||||
public void addOderConstraint(Set<Constraint<A>> methodConstraints) {
|
||||
oderConstraints.add(methodConstraints);
|
||||
}
|
||||
public void addOderConstraint(Set<Constraint<A>> methodConstraints) {
|
||||
oderConstraints.add(methodConstraints);
|
||||
}
|
||||
|
||||
public void addAllUndConstraint(Constraint<A> allUndConstraints){
|
||||
undConstraints.addAll(allUndConstraints);
|
||||
}
|
||||
|
||||
public void addAllOderConstraint(List<Set<Constraint<A>>> allOderConstraints){
|
||||
this.oderConstraints.addAll(allOderConstraints);
|
||||
}
|
||||
|
||||
public void addAll(ConstraintSet constraints) {
|
||||
this.addAllUndConstraint(constraints.undConstraints);
|
||||
this.addAllOderConstraint(constraints.oderConstraints);
|
||||
}
|
||||
public void addAllUndConstraint(Constraint<A> allUndConstraints) {
|
||||
undConstraints.addAll(allUndConstraints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
BinaryOperator<String> b = (x,y) -> x+y;
|
||||
return "\nUND:" + this.undConstraints.toString() + "\n" +
|
||||
"ODER:" + this.oderConstraints.stream().reduce("", (x,y) -> x.toString()+ "\n" +y, b);
|
||||
//cartesianProduct().toString();
|
||||
}
|
||||
public void addAllOderConstraint(List<Set<Constraint<A>>> allOderConstraints) {
|
||||
this.oderConstraints.addAll(allOderConstraints);
|
||||
}
|
||||
|
||||
public Set<List<Constraint<A>>> cartesianProduct(){
|
||||
Set<Constraint<A>> toAdd = new HashSet<>();
|
||||
toAdd.add(undConstraints);
|
||||
List<Set<Constraint<A>>> allConstraints = new ArrayList<>();
|
||||
allConstraints.add(toAdd);
|
||||
allConstraints.addAll(oderConstraints);
|
||||
return new GuavaSetOperations().cartesianProduct(allConstraints);
|
||||
}
|
||||
public void addAll(ConstraintSet constraints) {
|
||||
this.addAllUndConstraint(constraints.undConstraints);
|
||||
this.addAllOderConstraint(constraints.oderConstraints);
|
||||
}
|
||||
|
||||
public <B> ConstraintSet<B> map(Function<? super A, ? extends B> o) {
|
||||
Hashtable<Constraint<A>,Constraint<B>> CSA2CSB = new Hashtable<>();
|
||||
ConstraintSet<B> ret = new ConstraintSet<>();
|
||||
ret.undConstraints = undConstraints.stream().map(o).collect(Collectors.toCollection(Constraint<B>::new));
|
||||
List<Set<Constraint<B>>> newOder = new ArrayList<>();
|
||||
@Override
|
||||
public String toString() {
|
||||
BinaryOperator<String> b = (x, y) -> x + y;
|
||||
return "\nUND:\n" + this.undConstraints.toString() +
|
||||
"ODER:" + this.oderConstraints.stream().reduce("", (x, y) -> x + "\n\t" + y, b) +
|
||||
"\n";
|
||||
//cartesianProduct().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof ConstraintSet<?> other)) return false;
|
||||
return Objects.equals(undConstraints, other.undConstraints)
|
||||
&& Objects.equals(oderConstraints, other.oderConstraints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(undConstraints, oderConstraints);
|
||||
}
|
||||
|
||||
public Set<List<Constraint<A>>> cartesianProduct() {
|
||||
Set<Constraint<A>> toAdd = new HashSet<>();
|
||||
toAdd.add(undConstraints);
|
||||
List<Set<Constraint<A>>> allConstraints = new ArrayList<>();
|
||||
allConstraints.add(toAdd);
|
||||
allConstraints.addAll(oderConstraints);
|
||||
return new GuavaSetOperations().cartesianProduct(allConstraints);
|
||||
}
|
||||
|
||||
public <B extends IConstraintElement> ConstraintSet<B> map(Function<? super A, ? extends B> o) {
|
||||
Hashtable<Constraint<A>, Constraint<B>> CSA2CSB = new Hashtable<>();
|
||||
ConstraintSet<B> ret = new ConstraintSet<>();
|
||||
ret.undConstraints = undConstraints.stream().map(o).collect(Collectors.toCollection(Constraint<B>::new));
|
||||
List<Set<Constraint<B>>> newOder = new ArrayList<>();
|
||||
/*
|
||||
for(Set<Constraint<A>> oderConstraint : oderConstraints){
|
||||
oderConstraint.forEach(as -> {
|
||||
@@ -68,25 +85,25 @@ public class ConstraintSet<A> {
|
||||
CSA2CSB.put(as, newConst);} );
|
||||
}
|
||||
*/
|
||||
|
||||
for(Set<Constraint<A>> oderConstraint : oderConstraints){
|
||||
newOder.add(
|
||||
oderConstraint.stream().map((Constraint<A> as) -> {
|
||||
|
||||
Constraint<B> newConst = as.stream()
|
||||
.map(o)
|
||||
.collect(Collectors.toCollection((
|
||||
() -> new Constraint<B> (as.isInherited(),
|
||||
as.isImplemented(),
|
||||
(as.getExtendConstraint() != null)
|
||||
? as.getExtendConstraint().stream().map(o).collect(Collectors.toCollection(Constraint::new))
|
||||
: null,
|
||||
as.getmethodSignatureConstraint().stream().map(o).collect(Collectors.toCollection(HashSet::new))))
|
||||
));
|
||||
|
||||
//CSA2CSB.put(as, newConst);
|
||||
|
||||
return newConst;
|
||||
|
||||
for (Set<Constraint<A>> oderConstraint : oderConstraints) {
|
||||
newOder.add(
|
||||
oderConstraint.stream().map((Constraint<A> as) -> {
|
||||
|
||||
Constraint<B> newConst = as.stream()
|
||||
.map(o)
|
||||
.collect(Collectors.toCollection((
|
||||
() -> new Constraint<B>(as.isInherited(),
|
||||
as.isImplemented(),
|
||||
(as.getExtendConstraint() != null)
|
||||
? as.getExtendConstraint().stream().map(o).collect(Collectors.toCollection(Constraint::new))
|
||||
: null,
|
||||
as.getmethodSignatureConstraint().stream().map(o).collect(Collectors.toCollection(HashSet::new))))
|
||||
));
|
||||
|
||||
//CSA2CSB.put(as, newConst);
|
||||
|
||||
return newConst;
|
||||
|
||||
/*
|
||||
Constraint<B> bs = CSA2CSB.get(as);
|
||||
@@ -95,36 +112,60 @@ public class ConstraintSet<A> {
|
||||
}
|
||||
return bs;
|
||||
*/
|
||||
}).collect(Collectors.toSet())
|
||||
);
|
||||
}
|
||||
|
||||
ret.oderConstraints = newOder;
|
||||
return ret;
|
||||
}).collect(Collectors.toSet())
|
||||
);
|
||||
}
|
||||
|
||||
public void forEach (Consumer<? super A> c) {
|
||||
undConstraints.stream().forEach(c);
|
||||
for(Set<Constraint<A>> oderConstraint : oderConstraints){
|
||||
oderConstraint.parallelStream().forEach((Constraint<A> as) ->
|
||||
as.stream().forEach(c));
|
||||
}
|
||||
|
||||
ret.oderConstraints = newOder;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void forEach(Consumer<? super A> c) {
|
||||
undConstraints.stream().forEach(c);
|
||||
for (Set<Constraint<A>> oderConstraint : oderConstraints) {
|
||||
oderConstraint.parallelStream().forEach((Constraint<A> as) ->
|
||||
as.stream().forEach(c));
|
||||
}
|
||||
|
||||
public Set<A> getAll () {
|
||||
Set<A> ret = new HashSet<>();
|
||||
ret.addAll(undConstraints);
|
||||
for(Set<Constraint<A>> oderConstraint : oderConstraints){
|
||||
oderConstraint.parallelStream().forEach((Constraint<A> as) -> ret.addAll(as));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<Set<Constraint<A>>> getOderConstraints() {
|
||||
return oderConstraints;
|
||||
}
|
||||
|
||||
public Set<A> getUndConstraints() {
|
||||
return undConstraints;
|
||||
}
|
||||
|
||||
public Set<A> getAll() {
|
||||
Set<A> ret = new HashSet<>(undConstraints);
|
||||
for (Set<Constraint<A>> oderConstraint : oderConstraints) {
|
||||
oderConstraint.parallelStream().forEach(ret::addAll);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<Set<Constraint<A>>> getOderConstraints() {
|
||||
return oderConstraints;
|
||||
}
|
||||
|
||||
public Set<A> getUndConstraints() {
|
||||
return undConstraints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
SerialMap serialized = new SerialMap();
|
||||
serialized.put("undConstraints", undConstraints.toSerial(keyStorage));
|
||||
serialized.put("oderConstraints", SerialList.fromMapped(oderConstraints, oderConstraintSet ->
|
||||
SerialList.fromMapped(oderConstraintSet, oderConstraint ->
|
||||
oderConstraint.toSerial(keyStorage))
|
||||
));
|
||||
return serialized;
|
||||
}
|
||||
|
||||
public static <T extends IConstraintElement> ConstraintSet<T> fromSerial(SerialMap data, UnifyContext context, Class<T> target, KeyStorage keyStorage) {
|
||||
ConstraintSet<T> constraintSet = new ConstraintSet<>();
|
||||
|
||||
constraintSet.undConstraints = Constraint.fromSerial(data.getUUID("undConstraints"), context, target, keyStorage);
|
||||
constraintSet.oderConstraints = data.getList("oderConstraints").assertListOfLists().stream()
|
||||
.map(oderConstraintSetData -> oderConstraintSetData.assertListOfUUIDs().stream()
|
||||
.map(oderConstraintData -> Constraint.fromSerial(oderConstraintData, context, target, keyStorage))
|
||||
.collect(Collectors.toSet())
|
||||
).toList();
|
||||
|
||||
return constraintSet;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,4 @@
|
||||
package de.dhbwstuttgart.typeinference.constraints;
|
||||
|
||||
public interface IConstraintElement {
|
||||
}
|
@@ -1,72 +1,70 @@
|
||||
package de.dhbwstuttgart.typeinference.constraints;
|
||||
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
|
||||
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.SourceLoc;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
|
||||
public class Pair implements Serializable
|
||||
{
|
||||
public final RefTypeOrTPHOrWildcardOrGeneric TA1;
|
||||
public final RefTypeOrTPHOrWildcardOrGeneric TA2;
|
||||
public class Pair implements Serializable, IConstraintElement, ISerializableData {
|
||||
public final RefTypeOrTPHOrWildcardOrGeneric TA1;
|
||||
public final RefTypeOrTPHOrWildcardOrGeneric TA2;
|
||||
|
||||
private SourceLoc location;
|
||||
private SourceLoc location;
|
||||
|
||||
private PairOperator eOperator = PairOperator.SMALLER;
|
||||
private Boolean noUnification = false;
|
||||
|
||||
private PairOperator eOperator = PairOperator.SMALLER;
|
||||
private boolean noUnification = false;
|
||||
|
||||
private Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2 )
|
||||
{
|
||||
this.TA1 = TA1;
|
||||
this.TA2 = TA2;
|
||||
if(TA1 == null || TA2 == null)
|
||||
throw new NullPointerException();
|
||||
eOperator = PairOperator.SMALLER;
|
||||
}
|
||||
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp)
|
||||
{
|
||||
// Konstruktor
|
||||
this(TA1,TA2);
|
||||
this.eOperator = eOp;
|
||||
}
|
||||
private Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2) {
|
||||
this.TA1 = TA1;
|
||||
this.TA2 = TA2;
|
||||
if (TA1 == null || TA2 == null)
|
||||
throw new NullPointerException();
|
||||
eOperator = PairOperator.SMALLER;
|
||||
}
|
||||
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator e0p, SourceLoc location) {
|
||||
this(TA1, TA2, e0p);
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, Boolean noUnification)
|
||||
{
|
||||
// Konstruktor
|
||||
this(TA1,TA2);
|
||||
this.eOperator = eOp;
|
||||
this.noUnification = noUnification;
|
||||
}
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp) {
|
||||
// Konstruktor
|
||||
this(TA1, TA2);
|
||||
this.eOperator = eOp;
|
||||
}
|
||||
|
||||
public SourceLoc getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
// otth: Gibt ein Paar als String aus --> zum Debuggen und Vergleichen
|
||||
String strElement1 = "NULL";
|
||||
String strElement2 = "NULL";
|
||||
String Operator = "<.";
|
||||
|
||||
if( TA1 != null )
|
||||
strElement1 = TA1.toString();
|
||||
|
||||
if( TA2 != null )
|
||||
strElement2 = TA2.toString();
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator e0p, SourceLoc location) {
|
||||
this(TA1, TA2, e0p);
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, boolean noUnification) {
|
||||
// Konstruktor
|
||||
this(TA1, TA2);
|
||||
this.eOperator = eOp;
|
||||
this.noUnification = noUnification;
|
||||
}
|
||||
|
||||
public SourceLoc getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
// otth: Gibt ein Paar als String aus --> zum Debuggen und Vergleichen
|
||||
String strElement1 = "NULL";
|
||||
String strElement2 = "NULL";
|
||||
String Operator = "<.";
|
||||
|
||||
if (TA1 != null)
|
||||
strElement1 = TA1.toString();
|
||||
|
||||
if (TA2 != null)
|
||||
strElement2 = TA2.toString();
|
||||
|
||||
/* PL ausskommentiert 2018-05-24
|
||||
if(OperatorEqual())
|
||||
@@ -76,80 +74,104 @@ public class Pair implements Serializable
|
||||
if(OperatorSmallerExtends())
|
||||
Operator = "<?";
|
||||
*/
|
||||
|
||||
return "\n(" + strElement1 + " " + eOperator.toString() + " " + strElement2 + ")";
|
||||
|
||||
/*- Equals: " + bEqual*/
|
||||
}
|
||||
|
||||
/**
|
||||
* <br/>Author: J�rg B�uerle
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
boolean ret = true;
|
||||
ret &= (obj instanceof Pair);
|
||||
if(!ret)return ret;
|
||||
ret &= ((Pair)obj).TA1.equals(this.TA1);
|
||||
ret &= ((Pair)obj).TA2.equals(this.TA2);
|
||||
return ret;
|
||||
}
|
||||
return "\n(P: " + strElement1 + " " + eOperator.toString() + " " + strElement2 + ")";
|
||||
|
||||
/**
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Abfrage, ob Operator vom Typ Equal ist.
|
||||
*/
|
||||
public boolean OperatorEqual()
|
||||
{
|
||||
return eOperator == PairOperator.EQUALSDOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Abfrage, ob Operator vom Typ Smaller ist.
|
||||
*/
|
||||
public boolean OperatorSmaller()
|
||||
{
|
||||
return eOperator == PairOperator.SMALLER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Abfrage, ob Operator vom Typ SmallerExtends ist.
|
||||
*/
|
||||
public boolean OperatorSmallerExtends()
|
||||
{
|
||||
return eOperator == PairOperator.SMALLERDOTWC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Gibt den Operator zurück.
|
||||
*/
|
||||
public PairOperator GetOperator()
|
||||
{
|
||||
return eOperator;
|
||||
}
|
||||
/*- Equals: " + bEqual*/
|
||||
}
|
||||
|
||||
public boolean OperatorSmallerDot() {
|
||||
return eOperator == PairOperator.SMALLERDOT;
|
||||
}
|
||||
|
||||
|
||||
static public Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
|
||||
HashMap<String, TypePlaceholder> ret = new HashMap<>();
|
||||
constraints.map((Pair p) -> {
|
||||
if (p.TA1 instanceof TypePlaceholder) {
|
||||
ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1);
|
||||
}
|
||||
if (p.TA2 instanceof TypePlaceholder) {
|
||||
ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* <br/>Author: J�rg B�uerle
|
||||
*
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
return (
|
||||
(obj instanceof Pair pairObj) &&
|
||||
pairObj.TA1.equals(this.TA1) &&
|
||||
pairObj.TA2.equals(this.TA2)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Abfrage, ob Operator vom Typ Equal ist.
|
||||
*/
|
||||
public boolean OperatorEqual() {
|
||||
return eOperator == PairOperator.EQUALSDOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Abfrage, ob Operator vom Typ Smaller ist.
|
||||
*/
|
||||
public boolean OperatorSmaller() {
|
||||
return eOperator == PairOperator.SMALLER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Abfrage, ob Operator vom Typ SmallerExtends ist.
|
||||
*/
|
||||
public boolean OperatorSmallerExtends() {
|
||||
return eOperator == PairOperator.SMALLERDOTWC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Gibt den Operator zurück.
|
||||
*/
|
||||
public PairOperator GetOperator() {
|
||||
return eOperator;
|
||||
}
|
||||
|
||||
public boolean OperatorSmallerDot() {
|
||||
return eOperator == PairOperator.SMALLERDOT;
|
||||
}
|
||||
|
||||
|
||||
static public Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
|
||||
HashMap<String, TypePlaceholder> ret = new HashMap<>();
|
||||
constraints.map((Pair p) -> {
|
||||
if (p.TA1 instanceof TypePlaceholder) {
|
||||
ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1);
|
||||
}
|
||||
if (p.TA2 instanceof TypePlaceholder) {
|
||||
ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
// because toString() will output TA1 and TA2 recursively, we can ignore potential infinite recursion here too
|
||||
SerialMap serialized = new SerialMap();
|
||||
serialized.put("ta1", this.TA1.toSerial(keyStorage));
|
||||
serialized.put("ta2", this.TA2.toSerial(keyStorage));
|
||||
serialized.put("op", this.eOperator.toString());
|
||||
serialized.put("noUnification", this.noUnification ? 1 : 0);
|
||||
serialized.put("location", this.location == null ? null : this.location.toSerial(keyStorage));
|
||||
return serialized;
|
||||
}
|
||||
|
||||
public static Pair fromSerial(SerialMap data, UnifyContext context) {
|
||||
String op = data.getValue("op").getOf(String.class);
|
||||
SerialMap ta1 = data.getMap("ta1");
|
||||
SerialMap ta2 = data.getMap("ta2");
|
||||
boolean noUnification = data.getValue("noUnification").getOf(Integer.class) == 1;
|
||||
SerialMap location = data.getMapOrNull("location");
|
||||
|
||||
var pair = new Pair(
|
||||
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(ta1, context),
|
||||
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(ta2, context),
|
||||
PairOperator.fromString(op),
|
||||
noUnification
|
||||
);
|
||||
if (location != null) pair.location = SourceLoc.fromSerial(location);
|
||||
return pair;
|
||||
}
|
||||
}
|
||||
// ino.end
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user