Compare commits
123 Commits
targetByte
...
c54e012426
Author | SHA1 | Date | |
---|---|---|---|
|
c54e012426 | ||
|
52f6ebcf3c | ||
|
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 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"
|
||||
|
||||
# mvn clean compile -DskipTests package
|
||||
## prefix each stderr line with " | "
|
||||
# exec 2> >(trap "" INT TERM; sed 's/^/ | /' >&2)
|
||||
# echo -e "\nMatrix test:\n |"
|
||||
# time java -jar target/JavaTXcompiler-0.1-jar-with-dependencies.jar resources/bytecode/javFiles/Matrix.jav >/dev/null;
|
||||
|
||||
|
||||
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 "
|
||||
|
23
pom.xml
23
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,21 @@ 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>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -54,8 +69,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>
|
||||
|
@@ -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,14 +2,9 @@ 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.*;
|
||||
@@ -18,7 +13,6 @@ 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.*;
|
||||
@@ -108,6 +102,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,7 +1292,6 @@ public class Codegen {
|
||||
state.enterScope();
|
||||
// This is the index to start the switch from
|
||||
mv.visitInsn(ICONST_0);
|
||||
if (aSwitch.isExpression())
|
||||
state.pushSwitch();
|
||||
|
||||
// To be able to skip ahead to the next case
|
||||
@@ -1309,16 +1306,17 @@ 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 {
|
||||
} else {
|
||||
System.out.println(label);
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
@@ -1339,11 +1337,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 +1372,18 @@ public class Codegen {
|
||||
if (aSwitch.isExpression()) mv.visitJumpInsn(GOTO, end);
|
||||
}
|
||||
|
||||
if (aSwitch.default_() != null) {
|
||||
mv.visitLabel(defaultLabel);
|
||||
if (aSwitch.default_() != null) {
|
||||
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 +1391,10 @@ public class Codegen {
|
||||
|
||||
state.breakStack.pop();
|
||||
if (aSwitch.isExpression()) {
|
||||
if (aSwitch.type() != null) {
|
||||
mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
|
||||
unboxPrimitive(state, aSwitch.type());
|
||||
}
|
||||
state.popSwitch();
|
||||
}
|
||||
|
||||
@@ -1402,14 +1405,15 @@ 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());
|
||||
|
||||
if (pat.type() instanceof TargetRefType) {
|
||||
state.mv.visitInsn(DUP);
|
||||
state.mv.visitTypeInsn(INSTANCEOF, pat.type().getInternalName());
|
||||
|
||||
@@ -1418,14 +1422,33 @@ public class Codegen {
|
||||
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());
|
||||
}
|
||||
|
||||
if (pat instanceof TargetTypePattern sp) {
|
||||
if (pat instanceof TargetExpressionPattern ep) {
|
||||
var cur = state.createVariable(pat.type());
|
||||
state.mv.visitVarInsn(ASTORE, cur.index);
|
||||
|
||||
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 +1463,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,8 +1556,7 @@ public class Codegen {
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
private int bindLocalVariables(State state, TargetPattern pattern, int offset, int field) {
|
||||
if (pattern instanceof TargetComplexPattern cp) {
|
||||
private void bindLocalVariables(State state, TargetComplexPattern cp, int offset) {
|
||||
state.mv.visitVarInsn(ALOAD, offset);
|
||||
|
||||
var clazz = findClass(new JavaClassName(cp.type().name()));
|
||||
@@ -1530,15 +1569,14 @@ public class Codegen {
|
||||
state.mv.visitInsn(DUP);
|
||||
|
||||
extractField(state, cp.type(), i, clazz);
|
||||
if (subPattern.type() instanceof TargetRefType)
|
||||
state.mv.visitTypeInsn(CHECKCAST, subPattern.type().getInternalName());
|
||||
offset = state.createVariable(subPattern.name(), subPattern.type()).index;
|
||||
state.mv.visitVarInsn(ASTORE, offset);
|
||||
offset = bindLocalVariables(state, subPattern, offset, i);
|
||||
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 +1595,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 +1637,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 +1777,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;
|
||||
}
|
||||
|
||||
|
@@ -5,6 +5,7 @@ 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");
|
||||
|
||||
@@ -13,13 +14,18 @@ public class ConsoleInterface {
|
||||
List<File> classpath = new ArrayList<>();
|
||||
String outputPath = null;
|
||||
Iterator<String> it = Arrays.asList(args).iterator();
|
||||
Optional<Integer> serverPort = Optional.empty();
|
||||
Optional<String> unifyServer = 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");
|
||||
"\t-d\tSet destination directory\n" +
|
||||
"\t[--server-mode <port>]\n" +
|
||||
"\t[--unify-server <url>]\n");
|
||||
System.exit(1);
|
||||
}
|
||||
while (it.hasNext()) {
|
||||
@@ -33,14 +39,27 @@ public class ConsoleInterface {
|
||||
for (String cp : cps) {
|
||||
classpath.add(new File(cp));
|
||||
}
|
||||
} else if (arg.equals("--server-mode")) {
|
||||
serverPort = Optional.of(Integer.parseInt(it.next()));
|
||||
} else if (arg.equals("--unify-server")) {
|
||||
unifyServer = Optional.of(it.next());
|
||||
} else {
|
||||
input.add(new File(arg));
|
||||
}
|
||||
}
|
||||
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath, outputPath != null ? new File(outputPath) : null);
|
||||
|
||||
if (serverPort.isPresent()) {
|
||||
if (unifyServer.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, unifyServer);
|
||||
//compiler.typeInference();
|
||||
compiler.generateBytecode();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ 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.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
@@ -35,10 +36,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;
|
||||
@@ -61,6 +65,9 @@ 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 JavaTXCompiler INSTANCE;
|
||||
final CompilationEnvironment environment;
|
||||
Boolean resultmodel = true;
|
||||
@@ -73,12 +80,14 @@ public class JavaTXCompiler {
|
||||
public final List<File> classPath;
|
||||
private final File outputPath;
|
||||
|
||||
private final Optional<String> unifyServer;
|
||||
|
||||
public DirectoryClassLoader getClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
||||
this(Arrays.asList(sourceFile), List.of(), new File("."));
|
||||
this(Arrays.asList(sourceFile), List.of(), new File("."), Optional.empty());
|
||||
}
|
||||
|
||||
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
|
||||
@@ -87,10 +96,18 @@ public class JavaTXCompiler {
|
||||
}
|
||||
|
||||
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
|
||||
this(sourceFiles, List.of(), new File("."));
|
||||
this(sourceFiles, List.of(), new File("."), Optional.empty());
|
||||
}
|
||||
|
||||
public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath) throws IOException, ClassNotFoundException {
|
||||
this(sources, contextPath, outputPath, Optional.empty());
|
||||
}
|
||||
|
||||
public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath, Optional<String> unifyServer) throws IOException, ClassNotFoundException {
|
||||
// ensure new default placeholder registry for tests
|
||||
defaultClientPlaceholderRegistry = new PlaceholderRegistry();
|
||||
|
||||
this.unifyServer = unifyServer;
|
||||
var path = new ArrayList<>(contextPath);
|
||||
if (contextPath.isEmpty()) {
|
||||
// When no contextPaths are given, the working directory is the sources root
|
||||
@@ -300,13 +317,14 @@ public class JavaTXCompiler {
|
||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||
UnifyResultModel urm = null;
|
||||
// urm.addUnifyResultListener(resultListener);
|
||||
UnifyContext context = new UnifyContext(logFile, log, true, urm, usedTasks, defaultClientPlaceholderRegistry);
|
||||
try {
|
||||
logFile = logFile == null ? new FileWriter(new File("log_" + sourceFiles.keySet().iterator().next().getName())) : logFile;
|
||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, getClassLoader(), this);
|
||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, getClassLoader(), this, context.placeholderRegistry());
|
||||
System.out.println(finiteClosure);
|
||||
urm = new UnifyResultModel(cons, finiteClosure);
|
||||
urm.addUnifyResultListener(resultListener);
|
||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
|
||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons, context.placeholderRegistry());
|
||||
|
||||
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
|
||||
UnifyType lhs, rhs;
|
||||
@@ -320,81 +338,12 @@ public class JavaTXCompiler {
|
||||
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));
|
||||
}
|
||||
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
|
||||
});
|
||||
// logFile.flush();
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||
@@ -410,7 +359,7 @@ public class JavaTXCompiler {
|
||||
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);
|
||||
TypeUnify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
|
||||
} catch (IOException e) {
|
||||
System.err.println("kein LogFile");
|
||||
}
|
||||
@@ -433,13 +382,14 @@ public class JavaTXCompiler {
|
||||
|
||||
final ConstraintSet<Pair> cons = getConstraints(file);
|
||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||
PlaceholderRegistry placeholderRegistry = new PlaceholderRegistry();
|
||||
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);
|
||||
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logFile, classLoader, this, placeholderRegistry);
|
||||
System.out.println(finiteClosure);
|
||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
|
||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons, placeholderRegistry);
|
||||
System.out.println("xxx1");
|
||||
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
|
||||
UnifyType lhs, rhs;
|
||||
@@ -455,91 +405,11 @@ public class JavaTXCompiler {
|
||||
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); } })));
|
||||
*/
|
||||
|
||||
// logFile.flush();
|
||||
System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString());
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||
@@ -557,16 +427,24 @@ public class JavaTXCompiler {
|
||||
/*
|
||||
* Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors.toCollection(ArrayList::new))
|
||||
*/;
|
||||
if (resultmodel) {
|
||||
|
||||
if (unifyServer.isPresent()) {
|
||||
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
||||
UnifyContext context = new UnifyContext(logFile, log, true, urm, usedTasks, placeholderRegistry);
|
||||
SocketClient socketClient = new SocketClient(unifyServer.get());
|
||||
return socketClient.execute(finiteClosure, cons, unifyCons, context);
|
||||
}
|
||||
else 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);
|
||||
UnifyContext context = new UnifyContext(logFile, log, true, urm, usedTasks, placeholderRegistry);
|
||||
TypeUnify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
|
||||
System.out.println("RESULT Final: " + li.getResults());
|
||||
System.out.println("Constraints for Generated Generics: " + " ???");
|
||||
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
|
||||
logFile.flush();
|
||||
// logFile.flush();
|
||||
return li.getResults();
|
||||
}
|
||||
/* UnifyResultModel End */
|
||||
@@ -574,34 +452,35 @@ public class JavaTXCompiler {
|
||||
// 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);
|
||||
UnifyContext context = new UnifyContext(logFile, log, false, new UnifyResultModel(cons, finiteClosure), usedTasks, placeholderRegistry);
|
||||
Set<Set<UnifyPair>> result = TypeUnify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
|
||||
System.out.println("RESULT: " + result);
|
||||
logFile.write("RES: " + result.toString() + "\n");
|
||||
logFile.flush();
|
||||
// logFile.flush();
|
||||
results.addAll(result);
|
||||
|
||||
results = results.stream().map(x -> {
|
||||
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
|
||||
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().applyTypeUnificationRules(res.get(), finiteClosure);
|
||||
return new TypeUnifyTask(context).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();
|
||||
// logFile.flush();
|
||||
logFile.write("PLACEHOLDERS: " + placeholderRegistry);
|
||||
// logFile.flush();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.err.println("kein LogFile");
|
||||
}
|
||||
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList());
|
||||
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons), placeholderRegistry)))).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -733,10 +612,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;
|
||||
|
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);
|
||||
isRunning = true;
|
||||
}
|
||||
|
||||
public void listen() {
|
||||
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 {
|
||||
|
||||
}
|
@@ -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);
|
||||
|
@@ -14,6 +14,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 +103,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 +126,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,7 +148,9 @@ 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);
|
||||
@@ -439,6 +442,7 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
private Pattern convert(PatternContext pattern) {
|
||||
|
||||
return switch (pattern) {
|
||||
case PPatternContext pPattern -> {
|
||||
yield convert(pPattern.primaryPattern());
|
||||
@@ -453,16 +457,19 @@ 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);
|
||||
case Java17Parser.LPatternContext patternContext: return new LiteralPattern(TypePlaceholder.fresh(patternContext.start), convert(patternContext.literal().get(0)), patternContext.start);
|
||||
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
|
||||
@@ -470,13 +477,16 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
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 +593,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 +707,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
|
||||
@@ -780,16 +789,12 @@ public class StatementGenerator {
|
||||
* @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);
|
||||
return new FieldVar(new This(offset), expression, fields.get(expression).type(), offset);
|
||||
} else if (reg.contains(expression)) {
|
||||
return generateStaticClassName(expression, offset);
|
||||
} else {
|
||||
@@ -798,41 +803,6 @@ public class StatementGenerator {
|
||||
return new LocalVar(expression, localVars.get(expression), offset);
|
||||
}
|
||||
}
|
||||
return generateFieldVarOrClassname(expression, offset);
|
||||
}
|
||||
|
||||
private Expression generateFieldVarOrClassname(String expression, Token offset) {
|
||||
String[] parts = expression.split("\\.");
|
||||
String whole = "";
|
||||
Expression receiver = null;
|
||||
for (String part : parts) {
|
||||
whole += part;
|
||||
// Check for Classname:
|
||||
if (reg.contains(whole)) {
|
||||
receiver = generateStaticClassName(whole, offset);
|
||||
break;
|
||||
}
|
||||
whole += ".";
|
||||
}
|
||||
var fieldName = parts[parts.length - 1];
|
||||
|
||||
var isStatic = false;
|
||||
if (parts.length < 2 || parts[0].contentEquals("this")) {
|
||||
receiver = new This(offset);
|
||||
isStatic = Modifier.isStatic(fields.get(fieldName).modifiers());
|
||||
} else if (parts[0].contentEquals("super")) {
|
||||
receiver = new Super(TypePlaceholder.fresh(offset), offset);
|
||||
isStatic = Modifier.isStatic(compiler.getClass(new JavaClassName(superClass.getName().toString())).getField(fieldName).orElseThrow().modifier);
|
||||
} else if (receiver == null) { // Handelt es sich um keinen Statischen Klassennamen:
|
||||
String part = expression.substring(0, expression.length() - (1 + parts[parts.length - 1].length()));
|
||||
receiver = generateLocalOrFieldVarOrClassName(part, offset);
|
||||
} else {
|
||||
StaticClassName cname = (StaticClassName) receiver;
|
||||
var javaClassName = reg.getName(cname.getType().toString());
|
||||
isStatic = Modifier.isStatic(compiler.getClass(javaClassName).getField(fieldName).orElseThrow().modifier);
|
||||
}
|
||||
return new FieldVar(receiver, isStatic, fieldName, TypePlaceholder.fresh(offset), offset);
|
||||
}
|
||||
|
||||
private Expression convert(Java17Parser.ArrayaccessexpressionContext arrayaccess) {
|
||||
throw new NotImplementedException();
|
||||
@@ -867,10 +837,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 +855,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 +1069,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();
|
||||
|
158
src/main/java/de/dhbwstuttgart/server/SocketClient.java
Normal file
158
src/main/java/de/dhbwstuttgart/server/SocketClient.java
Normal file
@@ -0,0 +1,158 @@
|
||||
package de.dhbwstuttgart.server;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
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 java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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 {
|
||||
|
||||
// use a latch to wait until the connection is closed by the remote host
|
||||
private final CountDownLatch closeLatch = new CountDownLatch(1);
|
||||
// temporarily: The received unify result
|
||||
// TODO: replace with uuid and future system, such that responses can be mapped by a uuid to fulfill a Future
|
||||
private UnifyResultPacket unifyResultPacket;
|
||||
|
||||
public SocketClient(String url) {
|
||||
super(URI.create(url), Map.of(
|
||||
"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>");
|
||||
}
|
||||
}
|
||||
|
||||
public SocketClient(String host, int port, boolean secure) {
|
||||
super(URI.create(String.format("%s://%s:%d/", secure ? "wss" : "ws", host, port)));
|
||||
}
|
||||
|
||||
/**
|
||||
* The main method for connecting, requesting and waiting for the server to unify.
|
||||
* This is synchronized to prevent multiple webSockets connections at the moment, but it is not called from any
|
||||
* thread except the main thread right now and is not necessary at all, probably. Maybe remove it later
|
||||
*/
|
||||
synchronized public List<ResultSet> execute(
|
||||
FiniteClosure finiteClosure,
|
||||
ConstraintSet<Pair> constraintSet,
|
||||
ConstraintSet<UnifyPair> unifyConstraintSet,
|
||||
UnifyContext context
|
||||
) throws JsonProcessingException {
|
||||
|
||||
try {
|
||||
// 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);
|
||||
}
|
||||
|
||||
// send the unify task request
|
||||
UnifyRequestPacket packet = new UnifyRequestPacket(finiteClosure, constraintSet, unifyConstraintSet, context.placeholderRegistry());
|
||||
String json = PacketContainer.serialize(packet);
|
||||
this.send(json);
|
||||
|
||||
// block the thread, until the connection is closed by the remote host (usually after sending the results)
|
||||
this.waitUntilClosed();
|
||||
// wait for the connection to fully close
|
||||
this.closeBlocking();
|
||||
} catch (InterruptedException exception) {
|
||||
System.err.println("Server connection interrupted: " + exception);
|
||||
this.notifyAll();
|
||||
throw new RuntimeException("Aborted server connection", exception);
|
||||
}
|
||||
catch (Exception exception) {
|
||||
throw new RuntimeException("Exception occurred in server connection: ", exception);
|
||||
}
|
||||
|
||||
// detect error cases, in which no error was thrown, but also no result was sent back from the server
|
||||
if (this.unifyResultPacket == null) {
|
||||
throw new RuntimeException("Did not receive server response but closed connection already");
|
||||
}
|
||||
|
||||
return unifyResultPacket.getResultSet(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific client-side implementations to handle incoming packets
|
||||
*/
|
||||
protected void handleReceivedPacket(IPacket packet) {
|
||||
if (packet instanceof IServerToClientPacket serverToClientPacket) {
|
||||
|
||||
try {
|
||||
serverToClientPacket.onHandle(this.getConnection(), this);
|
||||
}
|
||||
catch (Exception exception) {
|
||||
this.closeLatch.countDown();
|
||||
this.close();
|
||||
throw exception;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
System.err.println("Received package of invalid type + " + packet.getClass().getName());
|
||||
this.close();
|
||||
}
|
||||
|
||||
public void setUnifyResultSets(UnifyResultPacket unifyResultPacket) {
|
||||
this.unifyResultPacket = unifyResultPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(ServerHandshake handshakedata) {
|
||||
System.out.println("Connected to server with status " + handshakedata.getHttpStatus());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
// System.out.println("received: " + message);
|
||||
IPacket packet = PacketContainer.deserialize(message);
|
||||
this.handleReceivedPacket(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(int code, String reason, boolean remote) {
|
||||
System.out.println(
|
||||
"Disconnected from server " +
|
||||
"with code " + code + " " +
|
||||
(reason.isEmpty() ? "" : "and reason " + reason + " ") +
|
||||
"(closed by remote: " + remote + ")"
|
||||
);
|
||||
this.closeLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception e) {
|
||||
System.out.println("Error: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
public void waitUntilClosed() throws InterruptedException {
|
||||
closeLatch.await();
|
||||
}
|
||||
}
|
203
src/main/java/de/dhbwstuttgart/server/SocketServer.java
Normal file
203
src/main/java/de/dhbwstuttgart/server/SocketServer.java
Normal file
@@ -0,0 +1,203 @@
|
||||
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 java.net.InetSocketAddress;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.java_websocket.WebSocket;
|
||||
import org.java_websocket.handshake.ClientHandshake;
|
||||
import org.java_websocket.server.WebSocketServer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SocketServer extends WebSocketServer {
|
||||
|
||||
/**
|
||||
* Increase this every time a breaking change to the server communication is done.
|
||||
* This will prevent errors when server version and client version do not match.
|
||||
*/
|
||||
public static final String packetProtocolVersion = "1";
|
||||
|
||||
public static final Logger log = LoggerFactory.getLogger(SocketServer.class);
|
||||
|
||||
public SocketServer(int port) {
|
||||
super(new InetSocketAddress(port));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) {
|
||||
String ppv = clientHandshake.getFieldValue("packetProtocolVersion");
|
||||
if (!ppv.equals(packetProtocolVersion)) {
|
||||
try {
|
||||
ErrorPacket errorPacket = ErrorPacket.create(
|
||||
"Mismatch in packet protocol version! Client (you): " + ppv + " and Server (me): " + packetProtocolVersion,
|
||||
true
|
||||
);
|
||||
webSocket.send(PacketContainer.serialize(errorPacket));
|
||||
}
|
||||
catch (JsonProcessingException exception) {
|
||||
System.err.println("Failed to serialize json: " + exception);
|
||||
}
|
||||
webSocket.close(1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SocketData socketData = new SocketData(UUID.randomUUID().toString());
|
||||
webSocket.setAttachment(socketData);
|
||||
System.out.println("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
|
||||
try (ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor()) {
|
||||
Runnable task = () -> {
|
||||
if (webSocket.<SocketData>getAttachment().unhandledTasks.get() == 0 || !webSocket.isOpen()) {
|
||||
return;
|
||||
}
|
||||
sendMessage(webSocket, "No task received after 10 seconds. Closing connection...");
|
||||
webSocket.close();
|
||||
};
|
||||
executor.schedule(task, 10, TimeUnit.SECONDS);
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
// and finally, when your program wants to exit
|
||||
} catch (Exception e) {
|
||||
log.error("e: ", e);
|
||||
webSocket.close(1, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(WebSocket webSocket, int code, String reason, boolean remote) {
|
||||
SocketData socketData = webSocket.getAttachment();
|
||||
System.out.println("Connection closed: " + socketData.id);
|
||||
System.out.println(
|
||||
"Disconnected client " + socketData.id + " " +
|
||||
"with code " + code + " " +
|
||||
(reason.isEmpty() ? "" : "and reason " + reason + " ") +
|
||||
"(closed by client: " + remote + ")"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(WebSocket webSocket, String s) {
|
||||
// System.out.println("Received: " + s.substring(0, 50));
|
||||
IPacket reconstructedPacket = PacketContainer.deserialize(s);
|
||||
try {
|
||||
this.onPacketReceived(webSocket, reconstructedPacket);
|
||||
} catch (JsonProcessingException e) {
|
||||
this.log("Error on processing incoming package: " + e.getMessage(), webSocket);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(WebSocket webSocket, Exception e) {
|
||||
log(e.getMessage(), webSocket);
|
||||
webSocket.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
System.out.println("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 = new MessagePacket();
|
||||
message.message = text;
|
||||
webSocket.send(PacketContainer.serialize(message));
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to send message: " + text);
|
||||
log.error("e: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A shorthand method for sending error messages to the client
|
||||
*/
|
||||
public void sendError(WebSocket webSocket, String text) {
|
||||
try {
|
||||
ErrorPacket error = new ErrorPacket();
|
||||
error.error = text;
|
||||
webSocket.send(PacketContainer.serialize(error));
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to send error: " + text);
|
||||
log.error("e: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 amount of tasks per connection
|
||||
final int maxTasks = 100;
|
||||
if (socketData.totalTasks.get() >= maxTasks) {
|
||||
sendError(webSocket, "Exceeded the maximum amount of " + maxTasks + " tasks per session");
|
||||
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);
|
||||
|
||||
// if the websocket has 0 unhandled Tasks, close the connection
|
||||
int remainingUnhandledTasks = socketData.unhandledTasks.decrementAndGet();
|
||||
if (remainingUnhandledTasks <= 0) {
|
||||
sendMessage(webSocket, "All requested tasks finished! Closing connection...");
|
||||
webSocket.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void log(String msg, WebSocket webSocket) {
|
||||
SocketData socketData = webSocket == null ? new SocketData("???") : webSocket.getAttachment();
|
||||
System.out.println("["+socketData.id+"] " + 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 SocketData(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
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, 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 socketServer) {}
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketServer socketServer) {}
|
||||
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
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 IClientToServerPacket, IServerToClientPacket {
|
||||
|
||||
/**
|
||||
* The error endpoint for messages from the server, that should be logged out outputted
|
||||
*/
|
||||
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) {
|
||||
System.err.println("[socket] " + "ErrorPacket: " + this.error);
|
||||
if (this.isFatal) {
|
||||
throw new RuntimeException("Received fatal error from server: " + this.error);
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
|
||||
socketServer.log("ErrorPacket: " + this.error, webSocket);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.server.SocketServer;
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
public interface IClientToServerPacket extends IPacket {
|
||||
|
||||
@JsonIgnore
|
||||
void onHandle(WebSocket webSocket, SocketServer socketServer);
|
||||
|
||||
}
|
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,29 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
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, IServerToClientPacket {
|
||||
|
||||
/**
|
||||
* If available, the error that caused this package to appear
|
||||
*/
|
||||
public String error = "<unknown error>";
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
|
||||
System.err.println("[socket] " + "InvalidPacket: " + this.error);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
|
||||
socketServer.log("InvalidPacket: " + this.error, webSocket);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import de.dhbwstuttgart.server.SocketClient;
|
||||
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, 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) {
|
||||
System.err.println("[socket] " + this.message);
|
||||
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
|
||||
socketServer.log(this.message, webSocket);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,90 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
// Add new packets here and in the deserialize method
|
||||
|
||||
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;
|
||||
// Add new packets here and in the serialize method
|
||||
|
||||
throw new RuntimeException("Cannot map received json to any known packet class");
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
InvalidPacket packet = new InvalidPacket();
|
||||
packet.error = e.getMessage();
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
package de.dhbwstuttgart.server.packet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
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 java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
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 {
|
||||
|
||||
public SerialMap finiteClosure;
|
||||
public SerialMap constraintSet;
|
||||
public SerialMap unifyConstraintSet;
|
||||
public SerialMap serialKeyStorage;
|
||||
public SerialValue<?> placeholders;
|
||||
public SerialList<SerialMap> factoryplaceholders;
|
||||
|
||||
@JsonIgnore
|
||||
private KeyStorage keyStorage = new KeyStorage();
|
||||
@JsonIgnore
|
||||
private boolean keyStorageLoaded = false;
|
||||
|
||||
public UnifyRequestPacket() {}
|
||||
|
||||
public UnifyRequestPacket(
|
||||
FiniteClosure finiteClosure,
|
||||
ConstraintSet<Pair> constraintSet,
|
||||
ConstraintSet<UnifyPair> unifyConstraintSet,
|
||||
PlaceholderRegistry placeholderRegistry
|
||||
) {
|
||||
// store contraint and finite closure
|
||||
this.finiteClosure = finiteClosure.toSerial(keyStorage);
|
||||
this.constraintSet = constraintSet.toSerial(keyStorage);
|
||||
this.unifyConstraintSet = unifyConstraintSet.toSerial(keyStorage);
|
||||
// store placeholder registry
|
||||
var serialRegistry = placeholderRegistry.toSerial(keyStorage);
|
||||
this.placeholders = serialRegistry.getValue("ph");
|
||||
this.factoryplaceholders = serialRegistry.getList("factoryPh").assertListOfMaps();
|
||||
// store referenced objects separately
|
||||
this.serialKeyStorage = keyStorage.toSerial(keyStorage);
|
||||
}
|
||||
|
||||
|
||||
@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...");
|
||||
System.out.println("Client " + webSocket.<SocketServer.SocketData>getAttachment().id + " requested a unification. Starting now...");
|
||||
|
||||
try {
|
||||
var placeholderRegistry = new PlaceholderRegistry();
|
||||
ArrayList<String> existingPlaceholders = (ArrayList) this.placeholders.getOf(ArrayList.class);
|
||||
existingPlaceholders.forEach(placeholderRegistry::addPlaceholder);
|
||||
|
||||
var unifyContext = new UnifyContext(Writer.nullWriter(), false, true,
|
||||
new UnifyResultModel(new ConstraintSet<>(), new FiniteClosure(new HashSet<>(), null, 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();
|
||||
|
||||
System.out.println("Finished unification for client " + webSocket.<SocketServer.SocketData>getAttachment().id);
|
||||
socketServer.sendMessage(webSocket, "Unification finished. Found " + resultSets.size() + " result sets");
|
||||
|
||||
if (webSocket.isOpen()) {
|
||||
UnifyResultPacket resultPacket = UnifyResultPacket.create(resultSets);
|
||||
webSocket.send(PacketContainer.serialize(resultPacket));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println(e);
|
||||
SocketServer.log.error("e: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
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 static UnifyResultPacket create(List<ResultSet> resultSets) {
|
||||
UnifyResultPacket serialized = new UnifyResultPacket();
|
||||
KeyStorage keyStorage = new KeyStorage();
|
||||
serialized.results = SerialList.fromMapped(resultSets, resultSet -> resultSet.toSerial(keyStorage));
|
||||
serialized.keyStorage = keyStorage.toSerial(keyStorage);
|
||||
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) {
|
||||
System.out.println("[socket] Received unify result");
|
||||
socketClient.setUnifyResultSets(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);
|
||||
|
@@ -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";
|
||||
@@ -27,6 +30,10 @@ 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,6 @@
|
||||
package de.dhbwstuttgart.syntaxtree.factory;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
@@ -31,9 +32,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,
|
||||
Writer logFile,
|
||||
ClassLoader classLoader,
|
||||
JavaTXCompiler compiler,
|
||||
PlaceholderRegistry placeholderRegistry
|
||||
) throws ClassNotFoundException {
|
||||
/*
|
||||
Die transitive Hülle muss funktionieren.
|
||||
Man darf schreiben List<A> extends AL<A>
|
||||
@@ -44,7 +49,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), logFile, compiler, placeholderRegistry);
|
||||
}
|
||||
|
||||
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr, SourceLoc location){
|
||||
@@ -67,23 +72,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 +96,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);
|
||||
}
|
||||
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 +176,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("");
|
||||
// System.out.println("");
|
||||
}
|
||||
((PlaceholderType)rhs).enableWildcardtable();
|
||||
}
|
||||
@@ -202,7 +208,7 @@ public class UnifyTypeFactory {
|
||||
&& ((PlaceholderType)rhs).isWildcardable()
|
||||
&& (lhs = ret.getLhsType()) instanceof PlaceholderType) {
|
||||
if (rhs.getName().equals("AQ")) {
|
||||
System.out.println("");
|
||||
// System.out.println("");
|
||||
}
|
||||
((PlaceholderType)lhs).enableWildcardtable();
|
||||
}
|
||||
@@ -213,16 +219,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 +237,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 +249,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,17 +1,20 @@
|
||||
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
|
||||
{
|
||||
public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric implements ISerializableData {
|
||||
private String name;
|
||||
|
||||
public GenericRefType(String name, Token offset)
|
||||
{
|
||||
public GenericRefType(String name, Token offset) {
|
||||
super(offset);
|
||||
this.name = name;
|
||||
}
|
||||
@@ -49,9 +52,26 @@ public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
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,29 +1,35 @@
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
public RefType(JavaClassName fullyQualifiedName, Token offset) {
|
||||
this(fullyQualifiedName, new ArrayList<>(), offset);
|
||||
}
|
||||
|
||||
@@ -49,10 +55,7 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
|
||||
@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;
|
||||
return this.name.hashCode();//Nur den Name hashen. Sorgt für langsame, aber funktionierende HashMaps
|
||||
}
|
||||
|
||||
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset) {
|
||||
@@ -66,8 +69,7 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
this.primitiveFlag = primitiveFlag;
|
||||
}
|
||||
|
||||
public JavaClassName getName()
|
||||
{
|
||||
public JavaClassName getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -78,40 +80,35 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
|
||||
/**
|
||||
* Author: Jrg Buerle<br/>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if(obj instanceof RefType){
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof RefType refObj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Objects.equals(this.name, refObj.name)) return false;
|
||||
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 &= (refObj.getParaList() == null || refObj.getParaList().isEmpty());
|
||||
} else {
|
||||
if (refObj.getParaList() == null) {
|
||||
ret = false;
|
||||
}
|
||||
else if(parameter.size() != ((RefType)obj).getParaList().size())
|
||||
{
|
||||
} else if (parameter.size() != refObj.getParaList().size()) {
|
||||
ret = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 0; i<parameter.size(); i++)
|
||||
{
|
||||
ret &= parameter.get(i).equals(((RefType)obj).getParaList().get(i));
|
||||
} else {
|
||||
for (int i = 0; i < parameter.size(); i++) {
|
||||
ret &= parameter.get(i).equals(refObj.getParaList().get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -129,5 +126,29 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
public void accept(ResultSetVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@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)));
|
||||
|
||||
// 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 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);
|
||||
}
|
||||
@@ -19,4 +25,25 @@ 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);
|
||||
if (i < subPatterns.size() - 1)
|
||||
out.append(", ");
|
||||
}
|
||||
subPatterns.get(i).accept(this);
|
||||
String name;
|
||||
if ((name = aRecordPattern.getName()) != null)
|
||||
out.append(name);
|
||||
|
@@ -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.*;
|
||||
@@ -33,12 +33,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 +144,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())));
|
||||
|
||||
if (a instanceof TargetRefType ta && b instanceof TargetRefType tb) {
|
||||
var res = new HashSet<ClassOrInterface>();
|
||||
|
||||
var cla = compiler.getClass(new JavaClassName(ta.name()));
|
||||
var clb = compiler.getClass(new JavaClassName(tb.name()));
|
||||
|
||||
if (cla.equals(clb)) return List.of(cla);
|
||||
|
||||
while (!cla.equals(ASTFactory.createObjectClass())) {
|
||||
var clb2 = clb;
|
||||
while (!clb2.equals(ASTFactory.createObjectClass())) {
|
||||
for (var intfa : cla.getSuperInterfaces()) {
|
||||
for (var intfb : clb.getSuperInterfaces()) {
|
||||
if (intfa.equals(intfb)) {
|
||||
var clintf = compiler.getClass(intfa.getName());
|
||||
if (clintf.isSealed()) {
|
||||
res.add(clintf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
clb2 = compiler.getClass(clb2.getSuperClass().getName());
|
||||
}
|
||||
cla = compiler.getClass(cla.getSuperClass().getName());
|
||||
}
|
||||
return res.stream().toList();
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
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;
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
resMethods.add(m1.method);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
res.add(resMethods.stream().toList());
|
||||
}
|
||||
return res;
|
||||
r1.add(r2);
|
||||
}
|
||||
outer: for (var s1 : r1) {
|
||||
for (var s2 : new HashSet<>(r0)) {
|
||||
if (s2.containsAll(s1)) {
|
||||
continue outer;
|
||||
} else if (s1.containsAll(s2)) {
|
||||
r0.remove(s2);
|
||||
r0.add(s1);
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
r0.add(s1);
|
||||
}
|
||||
}
|
||||
|
||||
var result = r0.stream().map(l -> l.stream().toList()).toList();
|
||||
|
||||
System.out.println("============== OUTPUT ==============");
|
||||
for (var l : result) {
|
||||
for (var m : l) System.out.println(m.name() + " " + m.getSignature());
|
||||
System.out.println();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public TargetStructure convert(ClassOrInterface input) {
|
||||
@@ -202,7 +375,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 +390,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 +446,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();
|
||||
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);
|
||||
}
|
||||
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()
|
||||
} 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()
|
||||
);
|
||||
methods.add(newMethod);
|
||||
if (method.signature().returnType() != null) {
|
||||
caseBody = new TargetReturn(caseBody);
|
||||
}
|
||||
return caseBody;
|
||||
}
|
||||
|
||||
// TODO Record overloading
|
||||
/*var template = overloadedMethods.get(0);
|
||||
var cases = new ArrayList<TargetSwitch.Case>();
|
||||
var usedPatterns = new HashSet<TargetPattern>();
|
||||
|
||||
var pParams = new ArrayList<Pattern>();
|
||||
for (var method : methods) {
|
||||
var patternsRec = new ArrayList<>(patterns);
|
||||
|
||||
TargetExpression expr = null;
|
||||
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;
|
||||
});
|
||||
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 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());
|
||||
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
|
||||
|
||||
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);
|
||||
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 +640,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 +687,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 +711,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,10 +1,7 @@
|
||||
package de.dhbwstuttgart.target.generate;
|
||||
|
||||
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;
|
||||
@@ -134,8 +131,8 @@ 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;
|
||||
@@ -154,6 +151,41 @@ public abstract class GenerateGenerics {
|
||||
System.out.println("Simplified constraints: " + simplifiedConstraints);
|
||||
}
|
||||
|
||||
/*public record GenericsState(Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes, Map<TypePlaceholder, TypePlaceholder> equality) {}
|
||||
|
||||
public GenericsState store() {
|
||||
return new GenericsState(new HashMap<>(concreteTypes), new HashMap<>(equality));
|
||||
}
|
||||
|
||||
public void restore(GenericsState state) {
|
||||
this.concreteTypes = state.concreteTypes;
|
||||
this.equality = state.equality;
|
||||
}
|
||||
|
||||
public void addOverlay(TypePlaceholder from, RefTypeOrTPHOrWildcardOrGeneric to) {
|
||||
if (to instanceof TypePlaceholder t) equality.put(from, t);
|
||||
else if (to instanceof RefType t) concreteTypes.put(new TPH(from), t);
|
||||
}*/
|
||||
|
||||
Set<TPH> findTypeVariables(ParameterList params) {
|
||||
var res = new HashSet<TPH>();
|
||||
for (var param : params.getFormalparalist()) {
|
||||
res.addAll(findTypeVariables(param));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
Set<TPH> findTypeVariables(Pattern pattern) {
|
||||
var res = new HashSet<TPH>();
|
||||
if (pattern instanceof RecordPattern rp) {
|
||||
for (var subPattern : rp.getSubPattern()) {
|
||||
res.addAll(findTypeVariables(subPattern));
|
||||
}
|
||||
}
|
||||
res.addAll(findTypeVariables(pattern.getType()));
|
||||
return res;
|
||||
}
|
||||
|
||||
Set<TPH> findTypeVariables(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
var result = new HashSet<TPH>();
|
||||
if (type instanceof TypePlaceholder tph) {
|
||||
@@ -490,9 +522,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() {
|
||||
@@ -556,9 +586,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);
|
||||
@@ -656,11 +684,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) {}
|
||||
|
@@ -1,24 +1,21 @@
|
||||
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.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 {
|
||||
@@ -143,7 +140,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
|
||||
@@ -386,9 +387,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 +568,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);
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -1,12 +1,26 @@
|
||||
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> {
|
||||
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;
|
||||
@@ -64,8 +78,9 @@ public class Constraint<A> extends HashSet<A> {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return super.toString() + "\nisInherited = " + isInherited + " isOveridden = " + isImplemented
|
||||
+ methodSignatureConstraint
|
||||
return super.toString() + "\nisInherited = " + isInherited
|
||||
+ " isOveridden = " + isImplemented
|
||||
+ " msc[" + methodSignatureConstraint.size() + "] = " + methodSignatureConstraint
|
||||
//" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" )
|
||||
+ "\n";
|
||||
}
|
||||
@@ -74,4 +89,71 @@ public class Constraint<A> extends HashSet<A> {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,17 +1,21 @@
|
||||
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> {
|
||||
public class ConstraintSet<A extends IConstraintElement> implements ISerializableData {
|
||||
Constraint<A> undConstraints = new Constraint<>();
|
||||
List<Set<Constraint<A>>> oderConstraints = new ArrayList<>();
|
||||
|
||||
@@ -39,11 +43,24 @@ public class ConstraintSet<A> {
|
||||
@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);
|
||||
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);
|
||||
@@ -53,7 +70,7 @@ public class ConstraintSet<A> {
|
||||
return new GuavaSetOperations().cartesianProduct(allConstraints);
|
||||
}
|
||||
|
||||
public <B> ConstraintSet<B> map(Function<? super A, ? extends B> o) {
|
||||
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));
|
||||
@@ -112,10 +129,9 @@ public class ConstraintSet<A> {
|
||||
}
|
||||
|
||||
public Set<A> getAll() {
|
||||
Set<A> ret = new HashSet<>();
|
||||
ret.addAll(undConstraints);
|
||||
Set<A> ret = new HashSet<>(undConstraints);
|
||||
for (Set<Constraint<A>> oderConstraint : oderConstraints) {
|
||||
oderConstraint.parallelStream().forEach((Constraint<A> as) -> ret.addAll(as));
|
||||
oderConstraint.parallelStream().forEach(ret::addAll);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -127,4 +143,29 @@ public class ConstraintSet<A> {
|
||||
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,18 +1,20 @@
|
||||
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 class Pair implements Serializable, IConstraintElement, ISerializableData {
|
||||
public final RefTypeOrTPHOrWildcardOrGeneric TA1;
|
||||
public final RefTypeOrTPHOrWildcardOrGeneric TA2;
|
||||
|
||||
@@ -22,8 +24,7 @@ public class Pair implements Serializable
|
||||
private Boolean noUnification = false;
|
||||
|
||||
|
||||
private Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2 )
|
||||
{
|
||||
private Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2) {
|
||||
this.TA1 = TA1;
|
||||
this.TA2 = TA2;
|
||||
if (TA1 == null || TA2 == null)
|
||||
@@ -31,8 +32,7 @@ public class Pair implements Serializable
|
||||
eOperator = PairOperator.SMALLER;
|
||||
}
|
||||
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp)
|
||||
{
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp) {
|
||||
// Konstruktor
|
||||
this(TA1, TA2);
|
||||
this.eOperator = eOp;
|
||||
@@ -43,8 +43,7 @@ public class Pair implements Serializable
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, Boolean noUnification)
|
||||
{
|
||||
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, Boolean noUnification) {
|
||||
// Konstruktor
|
||||
this(TA1, TA2);
|
||||
this.eOperator = eOp;
|
||||
@@ -55,8 +54,7 @@ public class Pair implements Serializable
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
public String toString() {
|
||||
// otth: Gibt ein Paar als String aus --> zum Debuggen und Vergleichen
|
||||
String strElement1 = "NULL";
|
||||
String strElement2 = "NULL";
|
||||
@@ -77,32 +75,30 @@ public class Pair implements Serializable
|
||||
Operator = "<?";
|
||||
*/
|
||||
|
||||
return "\n(" + strElement1 + " " + eOperator.toString() + " " + strElement2 + ")";
|
||||
return "\n(P: " + 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;
|
||||
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()
|
||||
{
|
||||
public boolean OperatorEqual() {
|
||||
return eOperator == PairOperator.EQUALSDOT;
|
||||
}
|
||||
|
||||
@@ -110,8 +106,7 @@ public class Pair implements Serializable
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Abfrage, ob Operator vom Typ Smaller ist.
|
||||
*/
|
||||
public boolean OperatorSmaller()
|
||||
{
|
||||
public boolean OperatorSmaller() {
|
||||
return eOperator == PairOperator.SMALLER;
|
||||
}
|
||||
|
||||
@@ -119,8 +114,7 @@ public class Pair implements Serializable
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Abfrage, ob Operator vom Typ SmallerExtends ist.
|
||||
*/
|
||||
public boolean OperatorSmallerExtends()
|
||||
{
|
||||
public boolean OperatorSmallerExtends() {
|
||||
return eOperator == PairOperator.SMALLERDOTWC;
|
||||
}
|
||||
|
||||
@@ -128,8 +122,7 @@ public class Pair implements Serializable
|
||||
* Author: Arne Lüdtke<br/>
|
||||
* Gibt den Operator zurück.
|
||||
*/
|
||||
public PairOperator GetOperator()
|
||||
{
|
||||
public PairOperator GetOperator() {
|
||||
return eOperator;
|
||||
}
|
||||
|
||||
@@ -151,5 +144,34 @@ public class Pair implements Serializable
|
||||
});
|
||||
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
|
||||
|
@@ -1,15 +1,19 @@
|
||||
package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
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.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
|
||||
/**
|
||||
* enthaelt alle Paare, die in einem Ergebnis nicht vorkommen koennen
|
||||
* sie sind noetig fuer origPairs in PairTPHsmallerTPH, da hier auch
|
||||
* Paare vorkommen koennen die keine Result sind (z.B. bei FunN$$)
|
||||
*/
|
||||
public class PairNoResult extends ResultPair<RefTypeOrTPHOrWildcardOrGeneric, RefTypeOrTPHOrWildcardOrGeneric>{
|
||||
public class PairNoResult extends ResultPair<RefTypeOrTPHOrWildcardOrGeneric, RefTypeOrTPHOrWildcardOrGeneric>
|
||||
implements ISerializableData {
|
||||
//public final TypePlaceholder left;
|
||||
//public final TypePlaceholder right;
|
||||
|
||||
@@ -17,7 +21,7 @@ public class PairNoResult extends ResultPair<RefTypeOrTPHOrWildcardOrGeneric, Re
|
||||
* urspruengliches Paar aus diesem dieses Resultpair erzeugt wurde
|
||||
* wichtig fuer generated Generics
|
||||
*/
|
||||
ResultPair origPair;
|
||||
ResultPair<?,?> origPair;
|
||||
|
||||
public PairNoResult(RefTypeOrTPHOrWildcardOrGeneric left, RefTypeOrTPHOrWildcardOrGeneric right){
|
||||
super(left, right);
|
||||
@@ -29,4 +33,24 @@ public class PairNoResult extends ResultPair<RefTypeOrTPHOrWildcardOrGeneric, Re
|
||||
throw new NotImplementedException();
|
||||
//visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
SerialMap serialized = new SerialMap();
|
||||
serialized.put("left", this.getLeft().toSerial(keyStorage));
|
||||
serialized.put("right", this.getRight().toSerial(keyStorage));
|
||||
// create the wrapper and put this as the object
|
||||
var serializedWrapper = super.toSerial(keyStorage);
|
||||
serializedWrapper.put("object", serialized);
|
||||
return serializedWrapper;
|
||||
}
|
||||
|
||||
public static PairNoResult fromSerial2(SerialMap data, UnifyContext context) {
|
||||
SerialMap left = data.getMap("left");
|
||||
SerialMap right = data.getMap("right");
|
||||
return new PairNoResult(
|
||||
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(left, context),
|
||||
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(right, context)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,13 @@
|
||||
package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
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.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
|
||||
public class PairTPHEqualTPH extends ResultPair<TypePlaceholder, TypePlaceholder> {
|
||||
public class PairTPHEqualTPH extends ResultPair<TypePlaceholder, TypePlaceholder> implements ISerializableData {
|
||||
public PairTPHEqualTPH(TypePlaceholder tl, TypePlaceholder tr) {
|
||||
super(tl, tr);
|
||||
}
|
||||
@@ -12,4 +16,24 @@ public class PairTPHEqualTPH extends ResultPair<TypePlaceholder, TypePlaceholder
|
||||
public void accept(ResultPairVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
SerialMap serialized = new SerialMap();
|
||||
serialized.put("left", this.getLeft().toSerial(keyStorage));
|
||||
serialized.put("right", this.getRight().toSerial(keyStorage));
|
||||
// create the wrapper and put this as the object
|
||||
var serializedWrapper = super.toSerial(keyStorage);
|
||||
serializedWrapper.put("object", serialized);
|
||||
return serializedWrapper;
|
||||
}
|
||||
|
||||
public static PairTPHEqualTPH fromSerial2(SerialMap data, UnifyContext context) {
|
||||
SerialMap left = data.getMap("left");
|
||||
SerialMap right = data.getMap("right");
|
||||
return new PairTPHEqualTPH(
|
||||
(TypePlaceholder) RefTypeOrTPHOrWildcardOrGeneric.fromSerial(left, context),
|
||||
(TypePlaceholder) RefTypeOrTPHOrWildcardOrGeneric.fromSerial(right, context)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,17 @@
|
||||
package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
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.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
|
||||
/**
|
||||
* Steht für A =. RefType
|
||||
*/
|
||||
public class PairTPHequalRefTypeOrWildcardType extends ResultPair{
|
||||
public class PairTPHequalRefTypeOrWildcardType extends ResultPair<TypePlaceholder, RefTypeOrTPHOrWildcardOrGeneric>
|
||||
implements ISerializableData {
|
||||
public final TypePlaceholder left;
|
||||
public final RefTypeOrTPHOrWildcardOrGeneric right;
|
||||
|
||||
@@ -26,4 +30,24 @@ public class PairTPHequalRefTypeOrWildcardType extends ResultPair{
|
||||
public String toString() {
|
||||
return "(" + left.toString() + " = " + right.toString() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
SerialMap serialized = new SerialMap();
|
||||
serialized.put("left", this.getLeft().toSerial(keyStorage));
|
||||
serialized.put("right", this.getRight().toSerial(keyStorage));
|
||||
// create the wrapper and put this as the object
|
||||
var serializedWrapper = super.toSerial(keyStorage);
|
||||
serializedWrapper.put("object", serialized);
|
||||
return serializedWrapper;
|
||||
}
|
||||
|
||||
public static PairTPHequalRefTypeOrWildcardType fromSerial2(SerialMap data, UnifyContext context) {
|
||||
SerialMap left = data.getMap("left");
|
||||
SerialMap right = data.getMap("right");
|
||||
return new PairTPHequalRefTypeOrWildcardType(
|
||||
(TypePlaceholder)RefTypeOrTPHOrWildcardOrGeneric.fromSerial(left, context),
|
||||
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(right, context)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,12 +1,17 @@
|
||||
package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
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.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
|
||||
/**
|
||||
* Steht für: A <. B
|
||||
*/
|
||||
public class PairTPHsmallerTPH extends ResultPair{
|
||||
public class PairTPHsmallerTPH extends ResultPair<TypePlaceholder,TypePlaceholder>
|
||||
implements ISerializableData {
|
||||
public final TypePlaceholder left;
|
||||
public final TypePlaceholder right;
|
||||
|
||||
@@ -14,7 +19,7 @@ public class PairTPHsmallerTPH extends ResultPair{
|
||||
* urspruengliches Paar aus diesem dieses Resultpair erzeugt wurde
|
||||
* wichtig fuer generated Generics
|
||||
*/
|
||||
ResultPair origPair;
|
||||
ResultPair<?,?> origPair;
|
||||
|
||||
public PairTPHsmallerTPH(TypePlaceholder left, TypePlaceholder right){
|
||||
super(left, right);
|
||||
@@ -22,7 +27,7 @@ public class PairTPHsmallerTPH extends ResultPair{
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public PairTPHsmallerTPH(TypePlaceholder left, TypePlaceholder right, ResultPair origPair){
|
||||
public PairTPHsmallerTPH(TypePlaceholder left, TypePlaceholder right, ResultPair<?,?> origPair){
|
||||
this(left, right);
|
||||
this.origPair = origPair;
|
||||
}
|
||||
@@ -36,4 +41,24 @@ public class PairTPHsmallerTPH extends ResultPair{
|
||||
public String toString() {
|
||||
return "(" + left.toString() + " < " + right.toString() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
SerialMap serialized = new SerialMap();
|
||||
serialized.put("left", this.getLeft().toSerial(keyStorage));
|
||||
serialized.put("right", this.getRight().toSerial(keyStorage));
|
||||
// create the wrapper and put this as the object
|
||||
var serializedWrapper = super.toSerial(keyStorage);
|
||||
serializedWrapper.put("object", serialized);
|
||||
return serializedWrapper;
|
||||
}
|
||||
|
||||
public static PairTPHsmallerTPH fromSerial2(SerialMap data, UnifyContext context) {
|
||||
SerialMap left = data.getMap("left");
|
||||
SerialMap right = data.getMap("right");
|
||||
return new PairTPHsmallerTPH(
|
||||
(TypePlaceholder) RefTypeOrTPHOrWildcardOrGeneric.fromSerial(left, context),
|
||||
(TypePlaceholder) RefTypeOrTPHOrWildcardOrGeneric.fromSerial(right, context)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,17 @@
|
||||
package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
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.server.packet.dataContainers.serialized.SerialValue;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
|
||||
|
||||
/**
|
||||
* Paare, welche das Unifikationsergebnis darstellen
|
||||
*/
|
||||
public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B extends RefTypeOrTPHOrWildcardOrGeneric> {
|
||||
public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B extends RefTypeOrTPHOrWildcardOrGeneric>
|
||||
implements ISerializableData {
|
||||
private final A left;
|
||||
private final B right;
|
||||
|
||||
@@ -59,4 +65,34 @@ public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B ext
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
SerialMap serialized = new SerialMap();
|
||||
String type = switch (this) {
|
||||
case PairNoResult _ -> "pnr";
|
||||
case PairTPHEqualTPH _ -> "ptet";
|
||||
case PairTPHsmallerTPH _ -> "ptst";
|
||||
case PairTPHequalRefTypeOrWildcardType _ -> "ptertwt";
|
||||
default -> throw new RuntimeException("No type defined for ResultPair of class " + this.getClass().getName());
|
||||
};
|
||||
serialized.put("type", type);
|
||||
// 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 <A extends RefTypeOrTPHOrWildcardOrGeneric,B extends RefTypeOrTPHOrWildcardOrGeneric> ResultPair<A,B>
|
||||
fromSerial(SerialMap data, UnifyContext context) {
|
||||
String type = data.getValue("type").getOf(String.class);
|
||||
SerialMap object = data.getMap("object");
|
||||
|
||||
return switch (type) {
|
||||
case "pnr" -> (ResultPair) PairNoResult.fromSerial2(object, context);
|
||||
case "ptet" -> (ResultPair) PairTPHEqualTPH.fromSerial2(object, context);
|
||||
case "ptst" -> (ResultPair) PairTPHsmallerTPH.fromSerial2(object, context);
|
||||
case "ptertwt" -> (ResultPair) PairTPHequalRefTypeOrWildcardType.fromSerial2(object, context);
|
||||
default -> throw new RuntimeException("Could not unserialize class of unhandled type " + type);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,13 @@
|
||||
package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
import com.google.common.collect.Ordering;
|
||||
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.UnifyContext;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -10,9 +18,10 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class ResultSet {
|
||||
public class ResultSet implements ISerializableData {
|
||||
|
||||
public final Set<ResultPair> results;
|
||||
public Set<ResultPair<TypePlaceholder, TypePlaceholder>> genIns;
|
||||
@@ -20,7 +29,11 @@ public class ResultSet {
|
||||
public ResultSet(Set<ResultPair> set) {
|
||||
this.results = set;
|
||||
this.genIns = new HashSet<>();
|
||||
results.forEach(x -> { if (x instanceof PairTPHsmallerTPH) { this.genIns.add(x);}} );
|
||||
results.forEach(x -> {
|
||||
if (x instanceof PairTPHsmallerTPH) {
|
||||
this.genIns.add(x);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean contains(ResultPair toCheck) {
|
||||
@@ -46,14 +59,27 @@ public class ResultSet {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var results = new ArrayList<>(this.results);
|
||||
results.sort(
|
||||
Comparator
|
||||
.comparingInt((ResultPair o) -> o.getLeft().toString().length())
|
||||
.thenComparing(o -> o.getLeft().toString())
|
||||
.thenComparingInt(o -> o.getRight().toString().length())
|
||||
.thenComparing(o -> o.getRight().toString())
|
||||
);
|
||||
return results.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof ResultSet) {
|
||||
ResultSet other = (ResultSet)o;
|
||||
return this.results.equals(other.results);
|
||||
if (o instanceof ResultSet other) {
|
||||
// sort both result lists
|
||||
var thisElements = new ArrayList<>(this.results);
|
||||
thisElements.sort(Ordering.usingToString());
|
||||
var otherElements = new ArrayList<>(other.results);
|
||||
otherElements.sort(Ordering.usingToString());
|
||||
|
||||
return thisElements.equals(otherElements);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -63,6 +89,18 @@ public class ResultSet {
|
||||
public int hashCode() {
|
||||
return results.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerialMap toSerial(KeyStorage keyStorage) {
|
||||
SerialMap serialized = new SerialMap();;
|
||||
serialized.put("results", SerialList.fromMapped(results, result -> result.toSerial(keyStorage)));
|
||||
return serialized;
|
||||
}
|
||||
|
||||
public static ResultSet fromSerial(SerialMap data, UnifyContext context) {
|
||||
var resultsData = data.getList("results").assertListOfMaps();
|
||||
return new ResultSet(resultsData.stream().map(resultData -> ResultPair.fromSerial(resultData, context)).collect(Collectors.toSet()));
|
||||
}
|
||||
}
|
||||
|
||||
class Resolver implements ResultSetVisitor {
|
||||
@@ -152,7 +190,6 @@ class Resolver implements ResultSetVisitor {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,6 +273,7 @@ class RelatedTypeWalker implements ResultSetVisitor {
|
||||
|
||||
/**
|
||||
* Läuft über das resultSet und speichert alle TPHs, welche mit start in Verbindung stehen
|
||||
*
|
||||
* @param start - kann null sein, wenn der Walker für einen RefType benutzt wird
|
||||
* @param resultSet
|
||||
*/
|
||||
|
@@ -1,15 +1,22 @@
|
||||
package de.dhbwstuttgart.typeinference.typeAlgo;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.parser.SourceLoc;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
import de.dhbwstuttgart.util.BiRelation;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -79,8 +86,53 @@ public class TYPE {
|
||||
if(m.block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints
|
||||
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
|
||||
TYPEStmt methodScope = new TYPEStmt(blockInfo);
|
||||
ConstraintSet constraintSet = new ConstraintSet();
|
||||
m.getParameterList().getFormalparalist().forEach(el -> {
|
||||
if(el instanceof RecordPattern){
|
||||
constraintSet.addAll(addRecursiveParameterConstraints((RecordPattern) el, blockInfo));
|
||||
|
||||
}
|
||||
});
|
||||
m.block.accept(methodScope);
|
||||
return methodScope.getConstraints();
|
||||
constraintSet.addAll(methodScope.getConstraints());
|
||||
return constraintSet;
|
||||
}
|
||||
|
||||
public ConstraintSet addRecursiveParameterConstraints(RecordPattern recordPattern, TypeInferenceBlockInformation blockInformation){
|
||||
ConstraintSet constraintSet = new ConstraintSet();
|
||||
|
||||
var subPatternList = recordPattern.getSubPattern();
|
||||
var resolver = new GenericsResolverSameName();
|
||||
var refType = (RefType) recordPattern.getType();
|
||||
|
||||
var allClasses = blockInformation.getAvailableClasses();
|
||||
var typename = refType.getName().getClassName();
|
||||
|
||||
ClassOrInterface allClass = allClasses.stream().filter(c -> c.getClassName().getClassName().equals(typename)).findFirst().orElseThrow();
|
||||
|
||||
int counter = 0;
|
||||
for (Pattern el : subPatternList){
|
||||
if (el instanceof RecordPattern){
|
||||
constraintSet.addAll(addRecursiveParameterConstraints((RecordPattern) el, blockInformation));
|
||||
} else {
|
||||
FormalParameter param = (FormalParameter) allClass.getConstructors().getFirst().getParameterList().getParameterAt(counter);
|
||||
FieldAssumption assumption = new FieldAssumption(param.getName(), allClass, param.getType(), blockInformation.getCurrentTypeScope());
|
||||
|
||||
var fieldCons = new Pair(el.getType(), assumption.getType(resolver), PairOperator.SMALLERDOT);
|
||||
var recvCons = new Pair(refType, assumption.getReceiverType(resolver), PairOperator.EQUALSDOT);
|
||||
constraintSet.addUndConstraint(fieldCons);
|
||||
constraintSet.addUndConstraint(recvCons);
|
||||
|
||||
for (var i = 0; i < refType.getParaList().size(); i++) {
|
||||
constraintSet.addUndConstraint(new Pair(refType.getParaList().get(i),
|
||||
((RefType)assumption.getReceiverType(resolver)).getParaList().get(i),
|
||||
PairOperator.EQUALSDOT));
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
return constraintSet;
|
||||
}
|
||||
|
||||
private ConstraintSet getConstraintsConstructor(Constructor m, TypeInferenceInformation info, ClassOrInterface currentClass) {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
//PL 2018-12-19: Merge chekcen
|
||||
package de.dhbwstuttgart.typeinference.typeAlgo;
|
||||
|
||||
import java.sql.Ref;
|
||||
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -48,7 +48,9 @@ public class TYPEStmt implements StatementVisitor {
|
||||
|
||||
private SourceLoc loc(Token token) {
|
||||
return new SourceLoc(info.getCurrentClass().getFileName(), token.getLine());
|
||||
};
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* Erstellt einen neuen GenericResolver Die Idee dieser Datenstruktur ist es, GTVs einen eindeutigen TPH zuzuweisen. Bei Methodenaufrufen oder anderen Zugriffen, bei denen alle benutzten GTVs jeweils einen einheitlichen TPH bekommen müssen kann diese Klasse eingesetzt werden. Wichtig ist, dass hierfür jeweils eine frische Instanz benutzt wird.
|
||||
@@ -116,6 +118,8 @@ public class TYPEStmt implements StatementVisitor {
|
||||
public void visit(FieldVar fieldVar) {
|
||||
fieldVar.receiver.accept(this);
|
||||
Set<Constraint> oderConstraints = new HashSet<>();
|
||||
|
||||
|
||||
for (FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)) {
|
||||
Constraint constraint = new Constraint();
|
||||
GenericsResolver resolver = getResolverInstance();
|
||||
@@ -127,7 +131,6 @@ public class TYPEStmt implements StatementVisitor {
|
||||
throw new TypeinferenceException("Kein Feld " + fieldVar.fieldVarName + " gefunden", fieldVar.getOffset());
|
||||
constraintsSet.addOderConstraint(oderConstraints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ForStmt forStmt) {
|
||||
forStmt.initializer.forEach(s -> s.accept(this));
|
||||
@@ -821,6 +824,10 @@ public class TYPEStmt implements StatementVisitor {
|
||||
public void visit(Switch switchStmt) {
|
||||
switchStack.push(switchStmt);
|
||||
|
||||
if(switchStmt.getSwitch().getType() instanceof TypePlaceholder){
|
||||
((TypePlaceholder) switchStmt.getSwitch().getType()).setVariance(-1);
|
||||
}
|
||||
|
||||
RefTypeOrTPHOrWildcardOrGeneric caseExpressionType = null;
|
||||
for (var child : switchStmt.getBlocks()) {
|
||||
for (var label : child.getLabels()) {
|
||||
@@ -834,7 +841,34 @@ public class TYPEStmt implements StatementVisitor {
|
||||
if (caseExpressionType == null) {
|
||||
for (var child : switchStmt.getBlocks()) {
|
||||
for (var label : child.getLabels()) {
|
||||
if (label.getPattern() instanceof FormalParameter) {
|
||||
if (label.getPattern() == null) {
|
||||
//System.out.println("DefaultCase");
|
||||
} else {
|
||||
constraintsSet.addUndConstraint(
|
||||
new Pair(
|
||||
label.getPattern().getType(),
|
||||
switchStmt.getSwitch().getType(),
|
||||
PairOperator.SMALLERDOT,
|
||||
loc(label.getOffset())
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
constraintsSet.addUndConstraint(new Pair(caseExpressionType, switchStmt.getSwitch().getType(), PairOperator.EQUALSDOT, loc(switchStmt.getSwitch().getOffset())));
|
||||
}
|
||||
|
||||
if (caseExpressionType == null) {
|
||||
for (var child : switchStmt.getBlocks()) {
|
||||
for (var label : child.getLabels()) {
|
||||
if (label.getPattern() == null) {
|
||||
constraintsSet.addUndConstraint(new Pair(new RefType(new JavaClassName("java.lang.Object"), new NullToken()), switchStmt.getSwitch().getType(), PairOperator.SMALLERDOT, loc(label.getOffset())));
|
||||
}
|
||||
if (label.getPattern() instanceof RecordPattern) {
|
||||
RecordPattern recordPattern = (RecordPattern) label.getPattern();
|
||||
//constraintsSet.addUndConstraint(new Pair(label.getPattern().getType(), switchStmt.getSwitch().getType(), PairOperator.SMALLERDOT, loc(label.getOffset())));
|
||||
} else if (label.getPattern() instanceof FormalParameter) {
|
||||
constraintsSet.addUndConstraint(new Pair(label.getPattern().getType(), switchStmt.getSwitch().getType(), PairOperator.SMALLERDOT, loc(label.getOffset())));
|
||||
}
|
||||
}
|
||||
@@ -843,14 +877,50 @@ public class TYPEStmt implements StatementVisitor {
|
||||
constraintsSet.addUndConstraint(new Pair(caseExpressionType, switchStmt.getSwitch().getType(), PairOperator.EQUALSDOT, loc(switchStmt.getSwitch().getOffset())));
|
||||
}
|
||||
|
||||
|
||||
for (var child : switchStmt.getBlocks()) {
|
||||
child.accept(this);
|
||||
constraintsSet.addUndConstraint(new Pair(child.getType(), switchStmt.getType(), PairOperator.SMALLERDOT, loc(switchStmt.getOffset())));
|
||||
|
||||
|
||||
child.getLabels().forEach(el -> {
|
||||
if (el.getType() instanceof RefType) {
|
||||
var recType = el;
|
||||
|
||||
if (el.getPattern() instanceof RecordPattern) {
|
||||
var pattern = (RecordPattern) recType.getPattern();
|
||||
recursivelyAddRecordConstraints(pattern);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
constraintsSet.addUndConstraint(new Pair(child.getType(), switchStmt.getType(), PairOperator.SMALLERDOT, loc(switchStmt.getOffset())));
|
||||
child.accept(this);
|
||||
}
|
||||
|
||||
|
||||
switchStack.pop();
|
||||
}
|
||||
|
||||
public void recursivelyAddRecordConstraints(RecordPattern pattern) {
|
||||
|
||||
var allClasses = info.getAvailableClasses();
|
||||
var interestingClasses = allClasses.stream().filter(as -> as.getClassName().equals(((RefType) pattern.getType()).getName())).toList();
|
||||
var constructors = interestingClasses.get(0).getConstructors();
|
||||
|
||||
int counter = 0;
|
||||
|
||||
for (var subPattern : pattern.getSubPattern()) {
|
||||
for (Constructor con : constructors) {
|
||||
//System.out.println("----------------------\n" + subPattern.getType() + " | " + con.getParameterList().getParameterAt(counter).getType() + "\n----------------------\n");
|
||||
constraintsSet.addUndConstraint(new Pair(subPattern.getType(), con.getParameterList().getParameterAt(counter).getType(), PairOperator.SMALLERDOT, loc(con.getParameterList().getParameterAt(counter).getOffset())));
|
||||
}
|
||||
if (subPattern instanceof RecordPattern) recursivelyAddRecordConstraints((RecordPattern) subPattern);
|
||||
else if (subPattern instanceof LiteralPattern lp) lp.value.accept(this);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(SwitchBlock switchBlock) {
|
||||
for (var stmt : switchBlock.statements) {
|
||||
@@ -860,7 +930,6 @@ public class TYPEStmt implements StatementVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(SwitchLabel switchLabel) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -0,0 +1,62 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.RecursiveTask;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* An intermediate class for the recursive steps of the TypeUnifyTask:
|
||||
* This allows to cancel parts of the recursion tree, instead of only the whole execution as before. But in
|
||||
* order for that to work, all cancellable child tasks must be added when they are created
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class CancellableTask<T> extends RecursiveTask<T> {
|
||||
|
||||
private final AtomicBoolean executionCancelled = new AtomicBoolean(false);
|
||||
private final List<CancellableTask<?>> childTasks = new ArrayList<>();
|
||||
private CancellableTask<?> parentTask = null;
|
||||
|
||||
/**
|
||||
* Set the execution for this task and all its (recursive) children to be cancelled
|
||||
*/
|
||||
protected void cancelExecution() {
|
||||
// is this branch already cancelled? Then do nothing
|
||||
if (this.executionCancelled.get()) return;
|
||||
executionCancelled.set(true);
|
||||
this.cancelChildExecution();
|
||||
}
|
||||
|
||||
public void cancelChildExecution() {
|
||||
for (var childTask : childTasks) {
|
||||
// no need to cancel a branch that is already finished
|
||||
if (!childTask.isDone()) {
|
||||
childTask.cancelExecution();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void cancelSiblingTasks() {
|
||||
if (this.parentTask != null) {
|
||||
boolean thisWasCancelledBefore = this.executionCancelled.get();
|
||||
this.parentTask.cancelChildExecution();
|
||||
this.executionCancelled.set(thisWasCancelledBefore);
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean isExecutionCancelled() {
|
||||
return executionCancelled.get();
|
||||
}
|
||||
|
||||
public void addChildTask(CancellableTask<?> childTask) {
|
||||
this.childTasks.add(childTask);
|
||||
childTask.setParentTask(this);
|
||||
}
|
||||
|
||||
private void setParentTask(CancellableTask<?> parentTask) {
|
||||
this.parentTask = parentTask;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
package de.dhbwstuttgart.typeinference.unify;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.RecursiveTask;
|
||||
|
||||
public class ConcurrentSetMergeTask<T> extends RecursiveTask<Set<T>> {
|
||||
|
||||
public static <E> Set<E> merge(List<Set<E>> list) {
|
||||
if (list.isEmpty()) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
var task = new ConcurrentSetMergeTask<>(list, 0, list.size());
|
||||
return task.compute();
|
||||
}
|
||||
|
||||
private static final int LIST_THRESHOLD = 3;
|
||||
private static final int ELEMENT_THRESHOLD = 1000;
|
||||
|
||||
private final List<Set<T>> list;
|
||||
private final int start;
|
||||
private final int end;
|
||||
|
||||
private ConcurrentSetMergeTask(List<Set<T>> list, int start, int end) {
|
||||
this.list = list;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<T> compute() {
|
||||
int size = end - start;
|
||||
|
||||
int totalElements = 0;
|
||||
for (int i = start+1; i < end; i++) {
|
||||
totalElements += list.get(i).size();
|
||||
}
|
||||
|
||||
System.out.println("ConcurrentSetMerge? -> " + (size <= LIST_THRESHOLD || totalElements < ELEMENT_THRESHOLD ? "true" : "false"));
|
||||
|
||||
|
||||
// size will always be at least one
|
||||
if (true || size <= LIST_THRESHOLD || totalElements < ELEMENT_THRESHOLD) {
|
||||
Set<T> result = this.list.get(start);
|
||||
for (int i = start+1; i < end; i++) {
|
||||
result.addAll(list.get(i));
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
int mid = start + (size / 2);
|
||||
ConcurrentSetMergeTask<T> leftTask = new ConcurrentSetMergeTask<>(list, start, mid);
|
||||
ConcurrentSetMergeTask<T> rightTask = new ConcurrentSetMergeTask<>(list, mid, end);
|
||||
|
||||
leftTask.fork();
|
||||
Set<T> rightResult = rightTask.compute();
|
||||
Set<T> leftResult = leftTask.join();
|
||||
|
||||
// Merge results
|
||||
leftResult.addAll(rightResult);
|
||||
return leftResult;
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user