Compare commits

..

5 Commits

94 changed files with 938 additions and 28232 deletions
.gitea/workflows
README.md
gen
pom.xml
resources
src

@ -15,7 +15,7 @@ jobs:
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '22'
java-version: '21'
cache: 'maven'
- name: Compile project
run: |

9
README.md Normal file

@ -0,0 +1,9 @@
Prototype
run with:
mvn test -Dtest="TestComplete#matrixTest"
mvn test -Dtest="typeinference.JavaTXCompilerTest#importTest"
then the output is in: /tmp/output

File diff suppressed because one or more lines are too long

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

@ -1,242 +0,0 @@
ABSTRACT=1
ASSERT=2
BOOLEAN=3
BREAK=4
BYTE=5
CASE=6
CATCH=7
CHAR=8
CLASS=9
CONST=10
CONTINUE=11
DEFAULT=12
DO=13
DOUBLE=14
ELSE=15
ENUM=16
EXTENDS=17
FINAL=18
FINALLY=19
FLOAT=20
FOR=21
IF=22
GOTO=23
IMPLEMENTS=24
IMPORT=25
INSTANCEOF=26
INT=27
INTERFACE=28
LONG=29
NATIVE=30
NEW=31
PACKAGE=32
PRIVATE=33
PROTECTED=34
PUBLIC=35
RETURN=36
SHORT=37
STATIC=38
STRICTFP=39
SUPER=40
SWITCH=41
SYNCHRONIZED=42
THIS=43
THROW=44
THROWS=45
TRANSIENT=46
TRY=47
VOID=48
VOLATILE=49
WHILE=50
MODULE=51
OPEN=52
REQUIRES=53
EXPORTS=54
OPENS=55
TO=56
USES=57
PROVIDES=58
WITH=59
TRANSITIVE=60
VAR=61
YIELD=62
RECORD=63
SEALED=64
PERMITS=65
NON_SEALED=66
DECIMAL_LITERAL=67
HEX_LITERAL=68
OCT_LITERAL=69
BINARY_LITERAL=70
FLOAT_LITERAL=71
HEX_FLOAT_LITERAL=72
BOOL_LITERAL=73
CHAR_LITERAL=74
STRING_LITERAL=75
TEXT_BLOCK=76
NULL_LITERAL=77
LPAREN=78
RPAREN=79
LBRACE=80
RBRACE=81
LBRACK=82
RBRACK=83
SEMI=84
COMMA=85
DOT=86
ASSIGN=87
GT=88
LT=89
BANG=90
TILDE=91
QUESTION=92
COLON=93
EQUAL=94
LE=95
GE=96
NOTEQUAL=97
AND=98
OR=99
INC=100
DEC=101
ADD=102
SUB=103
MUL=104
DIV=105
BITAND=106
BITOR=107
CARET=108
MOD=109
ADD_ASSIGN=110
SUB_ASSIGN=111
MUL_ASSIGN=112
DIV_ASSIGN=113
AND_ASSIGN=114
OR_ASSIGN=115
XOR_ASSIGN=116
MOD_ASSIGN=117
LSHIFT_ASSIGN=118
RSHIFT_ASSIGN=119
URSHIFT_ASSIGN=120
ARROW=121
COLONCOLON=122
AT=123
ELLIPSIS=124
WS=125
COMMENT=126
LINE_COMMENT=127
IDENTIFIER=128
'abstract'=1
'assert'=2
'boolean'=3
'break'=4
'byte'=5
'case'=6
'catch'=7
'char'=8
'class'=9
'const'=10
'continue'=11
'default'=12
'do'=13
'double'=14
'else'=15
'enum'=16
'extends'=17
'final'=18
'finally'=19
'float'=20
'for'=21
'if'=22
'goto'=23
'implements'=24
'import'=25
'instanceof'=26
'int'=27
'interface'=28
'long'=29
'native'=30
'new'=31
'package'=32
'private'=33
'protected'=34
'public'=35
'return'=36
'short'=37
'static'=38
'strictfp'=39
'super'=40
'switch'=41
'synchronized'=42
'this'=43
'throw'=44
'throws'=45
'transient'=46
'try'=47
'void'=48
'volatile'=49
'while'=50
'module'=51
'open'=52
'requires'=53
'exports'=54
'opens'=55
'to'=56
'uses'=57
'provides'=58
'with'=59
'transitive'=60
'var'=61
'yield'=62
'record'=63
'sealed'=64
'permits'=65
'non-sealed'=66
'null'=77
'('=78
')'=79
'{'=80
'}'=81
'['=82
']'=83
';'=84
','=85
'.'=86
'='=87
'>'=88
'<'=89
'!'=90
'~'=91
'?'=92
':'=93
'=='=94
'<='=95
'>='=96
'!='=97
'&&'=98
'||'=99
'++'=100
'--'=101
'+'=102
'-'=103
'*'=104
'/'=105
'&'=106
'|'=107
'^'=108
'%'=109
'+='=110
'-='=111
'*='=112
'/='=113
'&='=114
'|='=115
'^='=116
'%='=117
'<<='=118
'>>='=119
'>>>='=120
'->'=121
'::'=122
'@'=123
'...'=124

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -1,242 +0,0 @@
ABSTRACT=1
ASSERT=2
BOOLEAN=3
BREAK=4
BYTE=5
CASE=6
CATCH=7
CHAR=8
CLASS=9
CONST=10
CONTINUE=11
DEFAULT=12
DO=13
DOUBLE=14
ELSE=15
ENUM=16
EXTENDS=17
FINAL=18
FINALLY=19
FLOAT=20
FOR=21
IF=22
GOTO=23
IMPLEMENTS=24
IMPORT=25
INSTANCEOF=26
INT=27
INTERFACE=28
LONG=29
NATIVE=30
NEW=31
PACKAGE=32
PRIVATE=33
PROTECTED=34
PUBLIC=35
RETURN=36
SHORT=37
STATIC=38
STRICTFP=39
SUPER=40
SWITCH=41
SYNCHRONIZED=42
THIS=43
THROW=44
THROWS=45
TRANSIENT=46
TRY=47
VOID=48
VOLATILE=49
WHILE=50
MODULE=51
OPEN=52
REQUIRES=53
EXPORTS=54
OPENS=55
TO=56
USES=57
PROVIDES=58
WITH=59
TRANSITIVE=60
VAR=61
YIELD=62
RECORD=63
SEALED=64
PERMITS=65
NON_SEALED=66
DECIMAL_LITERAL=67
HEX_LITERAL=68
OCT_LITERAL=69
BINARY_LITERAL=70
FLOAT_LITERAL=71
HEX_FLOAT_LITERAL=72
BOOL_LITERAL=73
CHAR_LITERAL=74
STRING_LITERAL=75
TEXT_BLOCK=76
NULL_LITERAL=77
LPAREN=78
RPAREN=79
LBRACE=80
RBRACE=81
LBRACK=82
RBRACK=83
SEMI=84
COMMA=85
DOT=86
ASSIGN=87
GT=88
LT=89
BANG=90
TILDE=91
QUESTION=92
COLON=93
EQUAL=94
LE=95
GE=96
NOTEQUAL=97
AND=98
OR=99
INC=100
DEC=101
ADD=102
SUB=103
MUL=104
DIV=105
BITAND=106
BITOR=107
CARET=108
MOD=109
ADD_ASSIGN=110
SUB_ASSIGN=111
MUL_ASSIGN=112
DIV_ASSIGN=113
AND_ASSIGN=114
OR_ASSIGN=115
XOR_ASSIGN=116
MOD_ASSIGN=117
LSHIFT_ASSIGN=118
RSHIFT_ASSIGN=119
URSHIFT_ASSIGN=120
ARROW=121
COLONCOLON=122
AT=123
ELLIPSIS=124
WS=125
COMMENT=126
LINE_COMMENT=127
IDENTIFIER=128
'abstract'=1
'assert'=2
'boolean'=3
'break'=4
'byte'=5
'case'=6
'catch'=7
'char'=8
'class'=9
'const'=10
'continue'=11
'default'=12
'do'=13
'double'=14
'else'=15
'enum'=16
'extends'=17
'final'=18
'finally'=19
'float'=20
'for'=21
'if'=22
'goto'=23
'implements'=24
'import'=25
'instanceof'=26
'int'=27
'interface'=28
'long'=29
'native'=30
'new'=31
'package'=32
'private'=33
'protected'=34
'public'=35
'return'=36
'short'=37
'static'=38
'strictfp'=39
'super'=40
'switch'=41
'synchronized'=42
'this'=43
'throw'=44
'throws'=45
'transient'=46
'try'=47
'void'=48
'volatile'=49
'while'=50
'module'=51
'open'=52
'requires'=53
'exports'=54
'opens'=55
'to'=56
'uses'=57
'provides'=58
'with'=59
'transitive'=60
'var'=61
'yield'=62
'record'=63
'sealed'=64
'permits'=65
'non-sealed'=66
'null'=77
'('=78
')'=79
'{'=80
'}'=81
'['=82
']'=83
';'=84
','=85
'.'=86
'='=87
'>'=88
'<'=89
'!'=90
'~'=91
'?'=92
':'=93
'=='=94
'<='=95
'>='=96
'!='=97
'&&'=98
'||'=99
'++'=100
'--'=101
'+'=102
'-'=103
'*'=104
'/'=105
'&'=106
'|'=107
'^'=108
'%'=109
'+='=110
'-='=111
'*='=112
'/='=113
'&='=114
'|='=115
'^='=116
'%='=117
'<<='=118
'>>='=119
'>>>='=120
'->'=121
'::'=122
'@'=123
'...'=124

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

21
pom.xml

@ -14,7 +14,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4 -->
@ -26,17 +26,17 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.16.1</version>
</dependency>
<dependency>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
<version>4.8.172</version>
<version>2.6</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.2.0-jre</version>
<version>22.0</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
<dependency>
@ -53,9 +53,8 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<compilerArgs>--enable-preview</compilerArgs>
<source>23</source>
<target>23</target>
<source>22</source>
<target>22</target>
</configuration>
</plugin>
<plugin>

@ -1,10 +0,0 @@
public class Bar{
void visit(Object o){
System.out.println("Object");
}
void visit(Bla f){
System.out.println("Foo");
}
}

@ -1,12 +1,10 @@
public class Box {
class Box<A> {
a;
A a;
public Box() { }
public Box(a) {
//this.a = a;
Box(A a) {
this.a = a;
}
set(x) {
a = x;
}
}
}

@ -1,6 +0,0 @@
public class Foo{
public accept(Bar b){
b.visit(this);
}
}

@ -1,15 +0,0 @@
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,9 +1,7 @@
public class Box<A> {
A a;
public Box() { }
public Box(A a) {
//this.a = a;
}
}
class B { }
class Box_Main extends B {
m(b) {
b.m(new Box_Main());
b.m(new B());
}
}

@ -0,0 +1,3 @@
class Box<A> {
void m(A a) { }
}

@ -1,15 +0,0 @@
import java.lang.Object;
interface Visitor {
public void visit(Object obj);
public void visit(ClassA a);
}
class ClassA {
void accept(Visitor v) {
v.visit(this);
}
}
public class Bug332 {
}

@ -1,11 +0,0 @@
import java.lang.String;
public class Bug333 {
public static String Bar = "Bar";
}
class Bar {
public bar() {
String s = Bug333.Bar;
}
}

@ -1,10 +0,0 @@
import java.lang.Integer;
import java.lang.Number;
import java.lang.Object;
public class Bug337 {
public void main() {
Fun1$$<Object, Integer> fun1 = x -> x.hashCode() + 1;
Fun1$$<Number, Number> fun2 = fun1;
}
}

@ -1,11 +0,0 @@
import java.util.List;
import java.lang.Integer;
import java.lang.String;
import java.lang.Object;
import java.util.List;
public class Bug338 {
public hashCode() {
return List.of(42);
}
}

@ -1,2 +0,0 @@
public record Bug343() {
}

@ -1 +0,0 @@
public record GenericRecord<T>(T a) {}

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

@ -1,5 +0,0 @@
import java.lang.*;
public class ImportWildcard {
m(a, b) { return a * b; }
}

@ -0,0 +1,16 @@
import java.lang.Runnable;
import java.lang.System;
import java.lang.String;
import java.io.PrintStream;
public class LamRunnable {
public LamRunnable() {
Runnable lam = () -> {
System.out.println("lambda");
};
lam.run();
}
}

@ -1,20 +0,0 @@
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,31 +2,15 @@ import java.lang.Integer;
import java.lang.Number;
import java.lang.Float;
public record Point(Number x, Number y) {}
record Point(Number x, Number y) {}
public class OverloadPattern {
public Number m(Point(Integer x, Integer y), Point(Float a, Float b)) {
return 1;
public m(Point(Integer x, Integer 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(Point(Float x, Float y)) {
return x * y;
}
public m(Integer x) {

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

@ -1,26 +0,0 @@
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() ->
}
}*/
}

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

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

@ -1,22 +0,0 @@
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";
};
}
}

@ -1,17 +0,0 @@
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";
};
}
}

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

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

@ -1,27 +0,0 @@
import java.lang.Integer;
import java.lang.Object;
import java.lang.Float;
import java.lang.String;
sealed interface List permits LinkedElem, Elem {}
public record LinkedElem(Integer a,List l) implements List{} //Implementiert List und wird auch permittet
public record Elem(Integer c) implements List{} //Implementiert List, wird aber nicht permittet
public class SwitchCaseHeritageDetection {
public main(o) {
return switch(o) {
case LinkedElem(a, Elem(e)) -> a + e;
case LinkedElem(a, LinkedElem(e, Elem(f))) -> a + e + f;
default -> 0;
};
}
}

@ -9,13 +9,4 @@ public class While {
}
return x;
}
public m2() {
int i = 0;
do {
++i;
} while(i < 10);
return i;
}
}

@ -2,21 +2,41 @@ import java.lang.Integer;
public class Y {
y;
//factorial;
public Y() {
y = f -> t -> f.apply(y.apply(f)).apply(t);
y = f -> t -> f.apply(y.apply(f)).apply(t);
//factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
}
/*
getY() {
return y;
}
*/
}
/*
class fac1 {
factorial;
fac1() {
var y;
y = new Y<Integer,Integer,Integer,Integer,Integer>().getY();
factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
}
}
public class Fac1 {
public factorial;
public Fac1() {
ergibt Parse-Error
class fac1 {
factorial;
fac1() {
var y;
var tmp = new Y<>(); // TODO Having new Y<>().y on one line doesn't work, see FIXME in StatementGenerator
y = tmp.y;
y = new Y<>().y;
factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
}
public fac(v) {
return factorial.apply(v);
public static void main(String args[]) {
System.out.println(new fac1().factorial.apply(3));
}
}
}
*/

@ -654,17 +654,14 @@ primaryPattern
: typePattern #tPattern
| recordPattern #rPattern
| '(' pattern ')' #enclosedPattern
| literal (',' literal)* #lPattern
;
recordPattern
: typeType recordStructurePattern identifier?
//| recordStructurePattern identifier?
;
typePattern
: variableModifier* typeType identifier
| variableModifier* identifier
;
recordStructurePattern
@ -720,10 +717,10 @@ switchLabeledRule
;
switchLabelCase
: CASE NULL_LITERAL (ARROW | COLON) #labeledRuleNull
: CASE expressionList (ARROW | COLON) #labeledRuleExprList
| CASE NULL_LITERAL (ARROW | COLON) #labeledRuleNull
| CASE pattern (ARROW | COLON) #labeledRulePattern
| DEFAULT (ARROW | COLON) #labeledRuleDefault
| CASE expressionList (ARROW | COLON) #labeledRuleExprList
;
// Java20

@ -2,9 +2,12 @@ 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.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.*;
@ -13,6 +16,7 @@ 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.*;
@ -27,21 +31,15 @@ public class Codegen {
private final JavaTXCompiler compiler;
private final ASTToTargetAST converter;
private class CustomClassWriter extends ClassWriter {
public CustomClassWriter() {
super(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
}
@Override
protected ClassLoader getClassLoader() {
return compiler.getClassLoader();
}
}
public Codegen(TargetStructure clazz, JavaTXCompiler compiler, ASTToTargetAST converter) {
this.clazz = clazz;
this.className = clazz.qualifiedName().getClassName();
this.cw = new CustomClassWriter();
this.cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
@Override
protected ClassLoader getClassLoader() {
return compiler.getClassLoader();
}
};
this.compiler = compiler;
this.converter = converter;
}
@ -84,6 +82,8 @@ public class Codegen {
int localCounter;
MethodVisitor mv;
TargetType returnType;
// This is used to remember the type from lambda expressions
TargetType contextType;
Stack<BreakEnv> breakStack = new Stack<>();
Stack<Integer> switchResultValue = new Stack<>();
@ -102,10 +102,6 @@ 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);
@ -274,43 +270,13 @@ public class Codegen {
mv.visitInsn(I2F);
else if (dest.equals(TargetType.Double))
mv.visitInsn(I2D);
} else if (isFunctionalInterface(source) && isFunctionalInterface(dest) &&
!(source instanceof TargetFunNType && dest instanceof TargetFunNType)) {
boxFunctionalInterface(state, source, dest);
} else if (!(dest instanceof TargetGenericType)) {
//boxPrimitive(state, source);
boxPrimitive(state, source);
mv.visitTypeInsn(CHECKCAST, dest.getInternalName());
unboxPrimitive(state, dest);
}
}
record TypePair(TargetType from, TargetType to) {}
private Map<TypePair, String> funWrapperClasses = new HashMap<>();
private void boxFunctionalInterface(State state, TargetType source, TargetType dest) {
var mv = state.mv;
var className = "FunWrapper$$" +
source.name().replaceAll("\\.", "\\$") +
"$_$" +
dest.name().replaceAll("\\.", "\\$");
funWrapperClasses.put(new TypePair(source, dest), className);
mv.visitTypeInsn(NEW, className);
mv.visitInsn(DUP_X1);
mv.visitInsn(SWAP);
mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "(" + source.toDescriptor() + ")V", false);
}
private boolean isFunctionalInterface(TargetType type) {
if (type instanceof TargetFunNType) return true;
if (type instanceof TargetRefType) {
var clazz = compiler.getClass(new JavaClassName(type.name()));
return (clazz.getModifiers() & Modifier.INTERFACE) != 0 && clazz.isFunctionalInterface();
}
return false;
}
private TargetType largerType(TargetType left, TargetType right) {
if (left.equals(TargetType.String) || right.equals(TargetType.String)) {
return TargetType.String;
@ -761,15 +727,41 @@ public class Codegen {
var mv = state.mv;
String methodName = "apply";
TargetMethod.Signature signature = new TargetMethod.Signature(Set.of(),
lambda.signature().parameters().stream().map(
par -> par.withType(TargetType.Object)).toList(),
lambda.signature().returnType() != null ? TargetType.Object : null);
TargetMethod.Signature signature = null;
if (!(state.contextType instanceof TargetFunNType ctx)) {
var intf = compiler.getClass(new JavaClassName(state.contextType.name()));
if (intf != null) {
var method = intf.getMethods().stream().filter(m -> Modifier.isAbstract(m.modifier)).findFirst().orElseThrow();
methodName = method.getName();
var methodParams = new ArrayList<MethodParameter>();
for (var i = 0; i < lambda.signature().parameters().size(); i++) {
var param = lambda.signature().parameters().get(i);
var tpe = converter.convert(method.getParameterList().getParameterAt(i).getType());
methodParams.add(param.withType(tpe));
}
var retType = converter.convert(method.getReturnType());
signature = new TargetMethod.Signature(Set.of(), methodParams, retType);
}
}
if (signature == null) {
signature = new TargetMethod.Signature(Set.of(), lambda.signature().parameters().stream().map(par -> par.withType(TargetType.Object)).toList(), TargetType.Object);
}
signature = new TargetMethod.Signature(
signature.generics(),
signature.parameters().stream().map(par ->
par.withType(par.pattern().type() instanceof TargetGenericType ? TargetType.Object : par.pattern().type())
).toList(),
signature.returnType() instanceof TargetGenericType ? TargetType.Object : signature.returnType()
);
var parameters = new ArrayList<>(lambda.captures());
parameters.addAll(signature.parameters());
var implSignature = new TargetMethod.Signature(Set.of(), parameters, lambda.signature().returnType());
// Normalize
TargetMethod impl;
if (lambdas.containsKey(lambda)) {
impl = lambdas.get(lambda);
@ -790,6 +782,7 @@ public class Codegen {
params.add(new TargetRefType(clazz.qualifiedName().getClassName()));
params.addAll(lambda.captures().stream().map(mp -> mp.pattern().type()).toList());
var descriptor = TargetMethod.getDescriptor(state.contextType, params.toArray(TargetType[]::new));
mv.visitVarInsn(ALOAD, 0);
for (var index = 0; index < lambda.captures().size(); index++) {
var capture = lambda.captures().get(index);
@ -799,42 +792,9 @@ public class Codegen {
mv.visitTypeInsn(CHECKCAST, capture.pattern().type().getInternalName());
}
var descriptor = TargetMethod.getDescriptor(lambda.type(), params.toArray(TargetType[]::new));
mv.visitInvokeDynamicInsn(methodName, descriptor, bootstrap, Type.getType(signature.getSignature()), handle, Type.getType(signature.getDescriptor()));
}
private int findReturnCode(TargetType returnType) {
if (returnType.equals(TargetType.boolean_)
|| returnType.equals(TargetType.char_)
|| returnType.equals(TargetType.int_)
|| returnType.equals(TargetType.short_)
|| returnType.equals(TargetType.byte_))
return IRETURN;
else if (returnType.equals(TargetType.long_))
return LRETURN;
else if (returnType.equals(TargetType.float_))
return FRETURN;
else if (returnType.equals(TargetType.double_))
return DRETURN;
return ARETURN;
}
private int findLoadCode(TargetType loadType) {
if (loadType.equals(TargetType.boolean_)
|| loadType.equals(TargetType.char_)
|| loadType.equals(TargetType.int_)
|| loadType.equals(TargetType.short_)
|| loadType.equals(TargetType.byte_))
return ILOAD;
else if (loadType.equals(TargetType.long_))
return LLOAD;
else if (loadType.equals(TargetType.float_))
return FLOAD;
else if (loadType.equals(TargetType.double_))
return DLOAD;
return ALOAD;
}
private void generate(State state, TargetExpression expr) {
var mv = state.mv;
switch (expr) {
@ -859,7 +819,10 @@ public class Codegen {
break;
}
case TargetCast cast:
var ctx = state.contextType;
state.contextType = cast.type();
generate(state, cast.expr());
state.contextType = ctx;
convertTo(state, cast.expr().type(), cast.type());
break;
case TargetInstanceOf instanceOf:
@ -904,7 +867,10 @@ public class Codegen {
case TargetAssign assign: {
switch (assign.left()) {
case TargetLocalVar localVar -> {
var ctype = state.contextType;
state.contextType = localVar.type();
generate(state, assign.right());
state.contextType = ctype;
convertTo(state, assign.right().type(), localVar.type());
boxPrimitive(state, localVar.type());
@ -917,7 +883,10 @@ public class Codegen {
if (!(dot.left() instanceof TargetThis && dot.isStatic()))
generate(state, dot.left());
var ctype = state.contextType;
state.contextType = fieldType;
generate(state, assign.right());
state.contextType = ctype;
convertTo(state, assign.right().type(), fieldType);
boxPrimitive(state, fieldType);
@ -1009,27 +978,6 @@ public class Codegen {
mv.visitLabel(end);
break;
}
case TargetDo _do: {
Label start = new Label();
Label end = new Label();
Label check = new Label();
var env = new BreakEnv();
env.startLabel = check;
env.endLabel = end;
mv.visitLabel(start);
state.breakStack.push(env);
generate(state, _do.body());
state.breakStack.pop();
mv.visitLabel(check);
generate(state, _do.cond());
mv.visitJumpInsn(IFEQ, end);
mv.visitJumpInsn(GOTO, start);
mv.visitLabel(end);
break;
}
case TargetIf _if: {
generate(state, _if.cond());
Label _else = new Label();
@ -1047,12 +995,29 @@ public class Codegen {
case TargetReturn ret: {
if (ret.expression() != null && state.returnType != null) {
if (state.returnType instanceof TargetPrimitiveType) {
var ctype = state.contextType;
state.contextType = state.returnType;
generate(state, ret.expression());
state.contextType = ctype;
unboxPrimitive(state, state.returnType);
mv.visitInsn(findReturnCode(state.returnType));
if (state.returnType.equals(TargetType.boolean_)
|| state.returnType.equals(TargetType.char_)
|| state.returnType.equals(TargetType.int_)
|| state.returnType.equals(TargetType.short_)
|| state.returnType.equals(TargetType.byte_))
mv.visitInsn(IRETURN);
else if (state.returnType.equals(TargetType.long_))
mv.visitInsn(LRETURN);
else if (state.returnType.equals(TargetType.float_))
mv.visitInsn(FRETURN);
else if (state.returnType.equals(TargetType.double_))
mv.visitInsn(DRETURN);
} else {
var ctype = state.contextType;
state.contextType = state.returnType;
generate(state, ret.expression());
state.contextType = ctype;
boxPrimitive(state, ret.expression().type());
convertTo(state, ret.expression().type(), state.returnType);
mv.visitInsn(ARETURN);
@ -1103,10 +1068,12 @@ public class Codegen {
for (var i = 0; i < call.args().size(); i++) {
var e = call.args().get(i);
var arg = call.parameterTypes().get(i);
var ctype = state.contextType;
state.contextType = arg;
generate(state, e);
convertTo(state, e.type(), arg);
if (!(arg instanceof TargetPrimitiveType))
boxPrimitive(state, e.type());
state.contextType = ctype;
}
var descriptor = call.getDescriptor();
if (call.owner() instanceof TargetFunNType) // Decay FunN
@ -1292,7 +1259,8 @@ public class Codegen {
state.enterScope();
// This is the index to start the switch from
mv.visitInsn(ICONST_0);
state.pushSwitch();
if (aSwitch.isExpression())
state.pushSwitch();
// To be able to skip ahead to the next case
var start = new Label();
@ -1306,17 +1274,16 @@ 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<>(aSwitch.cases().size());
var types = new ArrayList<Object>(aSwitch.cases().size());
for (var cse : aSwitch.cases()) for (var label : cse.labels()) {
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) {
if (label instanceof TargetTypePattern || label instanceof TargetComplexPattern)
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 {
// TODO Same here we need to evaluate constant;
else {
System.out.println(label);
throw new NotImplementedException();
}
@ -1337,7 +1304,11 @@ public class Codegen {
}
}
var defaultLabel = new Label();
var defaultLabel = end;
if (aSwitch.default_() != null) {
defaultLabel = new Label();
}
mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);
for (var i = 0; i < aSwitch.cases().size(); i++) {
@ -1372,18 +1343,11 @@ public class Codegen {
if (aSwitch.isExpression()) mv.visitJumpInsn(GOTO, end);
}
mv.visitLabel(defaultLabel);
if (aSwitch.default_() != null) {
mv.visitLabel(defaultLabel);
generate(state, aSwitch.default_().body());
if (aSwitch.default_().isSingleExpression() && aSwitch.isExpression())
yieldValue(state, aSwitch.default_().body().statements().get(0).type());
} else {
// throw illegal argument exception on missing default case
mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
mv.visitInsn(DUP);
mv.visitLdcInsn("Unhandled case value");
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V", false);
mv.visitInsn(ATHROW);
}
mv.visitLabel(end);
@ -1391,10 +1355,8 @@ public class Codegen {
state.breakStack.pop();
if (aSwitch.isExpression()) {
if (aSwitch.type() != null) {
mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
unboxPrimitive(state, aSwitch.type());
}
mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
unboxPrimitive(state, aSwitch.type());
state.popSwitch();
}
@ -1405,50 +1367,30 @@ 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 = converter.convert(field.getType());
state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toSignature(), false);
var fieldType = new TargetRefType(((RefType) field.getType()).getName().toString());
state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toDescriptor(), 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());
state.mv.visitInsn(DUP);
state.mv.visitTypeInsn(INSTANCEOF, pat.type().getInternalName());
var cont = new Label();
state.mv.visitJumpInsn(IFNE, cont);
for (var i = 0; i < depth; i++) {
state.mv.visitInsn(POP);
}
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());
var cont = new Label();
state.mv.visitJumpInsn(IFNE, cont);
for (var i = 0; i < depth; i++) {
state.mv.visitInsn(POP);
}
state.mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
state.mv.visitLdcInsn(index + 1);
state.mv.visitJumpInsn(GOTO, start);
state.mv.visitLabel(cont);
if (pat instanceof TargetExpressionPattern ep) {
var cur = state.createVariable(pat.type());
state.mv.visitVarInsn(ASTORE, cur.index);
state.mv.visitTypeInsn(CHECKCAST, pat.type().getInternalName());
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) {
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) {
@ -1463,27 +1405,10 @@ public class Codegen {
// TODO Check if class is a Record
for (var i = 0; i < cp.subPatterns().size(); i++) {
var subPattern = cp.subPatterns().get(i);
state.mv.visitInsn(DUP);
var subPattern = cp.subPatterns().get(i);
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);
@ -1556,27 +1481,29 @@ public class Codegen {
mv.visitEnd();
}
private void bindLocalVariables(State state, TargetComplexPattern cp, int offset) {
state.mv.visitVarInsn(ALOAD, offset);
private int bindLocalVariables(State state, TargetPattern pattern, int offset, int field) {
if (pattern instanceof TargetComplexPattern cp) {
state.mv.visitVarInsn(ALOAD, offset);
var clazz = findClass(new JavaClassName(cp.type().name()));
if (clazz == null) throw new CodeGenException("Class definition for '" + cp.type().name() + "' not found");
var clazz = findClass(new JavaClassName(cp.type().name()));
if (clazz == null) throw new CodeGenException("Class definition for '" + cp.type().name() + "' not found");
for (var i = 0; i < cp.subPatterns().size(); i++) {
var subPattern = cp.subPatterns().get(i);
for (var i = 0; i < cp.subPatterns().size(); i++) {
var subPattern = cp.subPatterns().get(i);
if (i < cp.subPatterns().size() - 1)
state.mv.visitInsn(DUP);
if (i < cp.subPatterns().size() - 1)
state.mv.visitInsn(DUP);
extractField(state, cp.type(), i, clazz);
if (subPattern.type() instanceof TargetRefType)
extractField(state, cp.type(), i, clazz);
state.mv.visitTypeInsn(CHECKCAST, subPattern.type().getInternalName());
offset = state.createVariable(subPattern.name(), subPattern.type()).index;
state.mv.visitVarInsn(ASTORE, offset);
if (subPattern instanceof TargetComplexPattern cp2) {
bindLocalVariables(state, cp2, offset);
state.mv.visitVarInsn(ASTORE, offset);
offset = bindLocalVariables(state, subPattern, offset, i);
}
}
} else if (pattern instanceof TargetTypePattern tp) {
offset++;
state.createVariable(tp.name(), tp.type());
} else throw new NotImplementedException();
return offset;
}
private void generateMethod(TargetMethod method) {
@ -1595,14 +1522,8 @@ 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()) {
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++;
bindLocalVariables(state, param.pattern(), 1, 0);
}
generate(state, method.block());
if (method.signature().returnType() == null)
@ -1637,26 +1558,13 @@ 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) {
var txSignature = generateSignature(clazz, clazz.txGenerics());
if (txSignature != null)
cw.visitAttribute(new JavaTXSignatureAttribute(txSignature));
}
if (clazz.txGenerics() != null && signature != null)
cw.visitAttribute(new JavaTXSignatureAttribute(generateSignature(clazz, clazz.txGenerics())));
clazz.fields().forEach(this::generateField);
clazz.constructors().forEach(this::generateConstructor);
@ -1668,85 +1576,6 @@ public class Codegen {
if (clazz instanceof TargetRecord)
generateRecordMethods();
// Generate wrapper classes for function types
for (var pair : funWrapperClasses.keySet()) {
var className = funWrapperClasses.get(pair);
ClassWriter cw2 = new CustomClassWriter();
cw2.visit(V1_8, ACC_PUBLIC, className, null, "java/lang/Object", new String[] { pair.to.getInternalName() });
cw2.visitField(ACC_PRIVATE, "wrapped", pair.from.toDescriptor(), null, null).visitEnd();
// Generate constructor
var ctor = cw2.visitMethod(ACC_PUBLIC, "<init>", "(" + pair.from.toDescriptor() + ")V", null, null);
ctor.visitVarInsn(ALOAD, 0);
ctor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
ctor.visitVarInsn(ALOAD, 0);
ctor.visitVarInsn(ALOAD, 1);
ctor.visitFieldInsn(PUTFIELD, className, "wrapped", pair.from.toDescriptor());
ctor.visitInsn(RETURN);
ctor.visitMaxs(0, 0);
ctor.visitEnd();
String methodName = "apply";
String fromDescriptor = null;
TargetType fromReturn = null;
if (!(pair.from instanceof TargetFunNType funNType)) {
var fromClass = compiler.getClass(new JavaClassName(pair.from.name()));
var fromMethod = fromClass.getMethods().stream().filter(m -> (m.modifier & ACC_ABSTRACT) != 0).findFirst().orElseThrow();
methodName = fromMethod.name;
fromReturn = converter.convert(fromMethod.getReturnType());
var fromParams = converter.convert(fromMethod.getParameterList(), converter.generics.javaGenerics()).stream().map(m -> m.pattern().type()).toArray(TargetType[]::new);
fromDescriptor = TargetMethod.getDescriptor(fromReturn, fromParams);
} else {
fromReturn = funNType.returnArguments() > 0 ? TargetType.Object : null;
fromDescriptor = funNType.toMethodDescriptor();
}
var toClass = compiler.getClass(new JavaClassName(pair.to.name()));
var toMethod = toClass.getMethods().stream().filter(m -> (m.modifier & ACC_ABSTRACT) != 0).findFirst().orElseThrow();
var toReturn = converter.convert(toMethod.getReturnType());
var toParams = converter.convert(toMethod.getParameterList(), converter.generics.javaGenerics()).stream().map(m -> m.pattern().type()).toArray(TargetType[]::new);
var toDescriptor = TargetMethod.getDescriptor(toReturn, toParams);
// Generate wrapper method
var mv = cw2.visitMethod(ACC_PUBLIC, toMethod.name, toDescriptor, null, null);
var state = new State(null, mv, 0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, className, "wrapped", pair.from.toDescriptor());
for (var i = 0; i < toParams.length; i++) {
var arg = toParams[i];
mv.visitVarInsn(findLoadCode(arg), i + 1);
}
mv.visitMethodInsn(INVOKEINTERFACE, pair.from.getInternalName(), methodName, fromDescriptor, true);
if (fromReturn != null) {
if (toReturn instanceof TargetPrimitiveType) {
convertTo(state, fromReturn, TargetType.toWrapper(toReturn));
} else convertTo(state, fromReturn, toReturn);
}
if (toReturn != null)
mv.visitInsn(findReturnCode(toReturn));
else mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
cw2.visitEnd();
var bytes = cw2.toByteArray();
converter.auxiliaries.put(className, bytes);
// TODO These class loading shenanigans happen in a few places, the tests load the classes individually.
// Instead we should just look at the folder.
try {
converter.classLoader.findClass(className);
} catch (ClassNotFoundException e) {
try {
converter.classLoader.loadClass(bytes);
} catch (LinkageError ignored) {}
}
}
cw.visitEnd();
return cw.toByteArray();
}
@ -1777,7 +1606,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().toSignature(), false);
var fieldRef = new Handle(H_GETFIELD, clazz.getName(), field.name(), field.type().toDescriptor(), false);
bootstrapArgs[i + 2] = fieldRef;
}

@ -1,13 +1,11 @@
package de.dhbwstuttgart.bytecode;
import de.dhbwstuttgart.syntaxtree.statement.Break;
import de.dhbwstuttgart.target.tree.TargetGeneric;
import de.dhbwstuttgart.target.tree.type.*;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import java.sql.Array;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -35,36 +33,6 @@ public class FunNGenerator {
public static class GenericParameters {
int start;
public List<TargetType> parameters = new ArrayList<>();
final String descriptor;
public final List<TargetType> inParams;
public final List<TargetType> realParams;
public GenericParameters(List<TargetType> params, int numReturns) {
this.realParams = params;
this.inParams = flattenTypeParams(params);
var type = new TargetRefType(FunNGenerator.getSuperClassName(params.size() - 1, numReturns), params);
descriptor = applyDescriptor(type, this);
}
private static List<TargetType> flattenTypeParams(List<TargetType> params) {
var res = new ArrayList<TargetType>();
for (var param : params) {
if (param instanceof TargetSpecializedType tspec) {
res.addAll(flattenTypeParams(tspec.params()));
} else {
res.add(param);
}
}
return res;
}
public TargetType getReturnType() {
return FunNGenerator.getReturnType(realParams);
}
public List<TargetType> getArguments() {
return FunNGenerator.getArguments(realParams);
}
}
private static String applyDescriptor(TargetType type, GenericParameters gep) {
@ -101,7 +69,7 @@ public class FunNGenerator {
return applyNameDescriptor(type).replace("/", "$").replace(";", "$_$");
}
public static byte[] generateSuperBytecode(int numberArguments, int numReturnTypes) {
public static byte[] generateSuperBytecode(int numberArguments) {
StringBuilder superFunNClassSignature = new StringBuilder("<");
StringBuilder superFunNMethodSignature = new StringBuilder("(");
StringBuilder superFunNMethodDescriptor = new StringBuilder("(");
@ -112,34 +80,30 @@ public class FunNGenerator {
superFunNMethodDescriptor.append(objectSignature);
}
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
if (numReturnTypes > 0) {
superFunNMethodSignature.append(String.format(")T%s;", returnGeneric));
superFunNMethodDescriptor.append(String.format(")%s", objectSignature));
} else {
superFunNMethodSignature.append(")V");
superFunNMethodDescriptor.append(")V");
}
superFunNMethodSignature.append(String.format(")T%s;", returnGeneric));
superFunNMethodDescriptor.append(String.format(")%s", objectSignature));
System.out.println(superFunNMethodSignature);
ClassWriter classWriter = new ClassWriter(0);
MethodVisitor methodVisitor;
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSuperClassName(numberArguments, numReturnTypes), superFunNClassSignature.toString(), objectSuperType, null);
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSuperClassName(numberArguments), superFunNClassSignature.toString(), objectSuperType, null);
methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, methodName, superFunNMethodDescriptor.toString(), superFunNMethodSignature.toString(), null);
methodVisitor.visitEnd();
classWriter.visitEnd();
return classWriter.toByteArray();
}
public static String getSuperClassName(int numberArguments, int returnArguments) {
return returnArguments > 0 ? String.format("Fun%d$$", numberArguments) : String.format("FunVoid%d$$", numberArguments);
public static String getSuperClassName(int numberArguments) {
return String.format("Fun%d$$", numberArguments);
}
public static byte[] generateSpecializedBytecode(GenericParameters gep, List<String> superInterfaces) {
var argumentTypes = gep.getArguments();
var returnType = gep.getReturnType();
public static byte[] generateSpecializedBytecode(List<TargetType> argumentTypes, TargetType returnType, GenericParameters gep) {
List<TargetType> parameters = Stream
.concat(argumentTypes.stream(), Stream.of(returnType))
.toList();
StringBuilder funNClassSignature = new StringBuilder(objectSignature + gep.descriptor);
StringBuilder funNClassSignature = new StringBuilder(objectSignature + applyDescriptor(new TargetRefType(getSuperClassName(argumentTypes.size()), parameters), gep));
boolean containsGeneric = false;
String genericSignature = "<";
@ -150,18 +114,10 @@ public class FunNGenerator {
genericSignature += ">";
if (containsGeneric) funNClassSignature.insert(0, genericSignature);
for (var superInterface : superInterfaces) {
funNClassSignature.append('L');
funNClassSignature.append(superInterface);
funNClassSignature.append(';');
}
var interfaces = new ArrayList<>(superInterfaces);
interfaces.add(getSuperClassName(argumentTypes.size(), returnType != null ? 1 : 0));
System.out.println(funNClassSignature.toString());
ClassWriter classWriter = new ClassWriter(0);
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSpecializedClassName(argumentTypes, returnType), funNClassSignature.toString(), objectSuperType, interfaces.toArray(String[]::new));
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSpecializedClassName(argumentTypes, returnType), funNClassSignature.toString(), objectSuperType, new String[]{getSuperClassName(argumentTypes.size())});
classWriter.visitEnd();
return classWriter.toByteArray();
}
@ -177,24 +133,14 @@ public class FunNGenerator {
}
}
public static String getSpecializedClassName(GenericParameters gep) {
return getSpecializedClassName(gep.getArguments(), gep.getReturnType());
}
public static String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType) {
var arguments = argumentTypes
.stream()
.map(FunNGenerator::encodeType)
.collect(Collectors.joining());
if (returnType != null)
return String.format("Fun%d$$%s%s",
argumentTypes.size(),
arguments,
encodeType(returnType));
else return String.format("FunVoidImpl%d$$%s",
return String.format("Fun%d$$%s%s",
argumentTypes.size(),
arguments);
argumentTypes
.stream()
.map(FunNGenerator::encodeType)
.collect(Collectors.joining()),
encodeType(returnType));
}
public static List<TargetType> getArguments(List<TargetType> list) {
@ -205,8 +151,8 @@ public class FunNGenerator {
}
public static TargetType getReturnType(List<TargetType> list) {
if(list.isEmpty())
if(list.size() == 0)
throw new IndexOutOfBoundsException();
return list.getLast();
return list.get(list.size() - 1);
}
}

@ -66,7 +66,7 @@ public class JavaTXCompiler {
Boolean resultmodel = true;
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
Boolean log = false; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
public final DirectoryClassLoader classLoader;
@ -98,7 +98,7 @@ public class JavaTXCompiler {
}
if (outputPath != null) path.add(outputPath);
classLoader = new DirectoryClassLoader(path, ClassLoader.getSystemClassLoader());
environment = new CompilationEnvironment(sources, classLoader);
environment = new CompilationEnvironment(sources);
classPath = path;
this.outputPath = outputPath;
@ -327,6 +327,74 @@ public class JavaTXCompiler {
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
});
Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>();
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
@ -393,6 +461,85 @@ public class JavaTXCompiler {
logFile.write(ASTTypePrinter.print(sf));
System.out.println(ASTTypePrinter.print(sf));
logFile.flush();
Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
});
Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
});
Set<String> paraTypeVarNames = methodParaTypeVarNames;
paraTypeVarNames.addAll(constructorParaTypeVarNames);
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
a.addAll(b);
return a;
}).get();
Set<String> fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
a.addAll(b);
return a;
}).get();
returnTypeVarNames.addAll(fieldTypeVarNames);
unifyCons = unifyCons.map(x -> {
// Hier muss ueberlegt werden, ob
// 1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs
// mit disableWildcardtable() werden.
// 2. alle Typvariablen mit Argument- oder Retuntyp-Variablen
// in Beziehung auch auf disableWildcardtable() gesetzt werden muessen
// PL 2018-04-23
if ((x.getLhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) 1);
((PlaceholderType) x.getLhsType()).disableWildcardtable();
}
if (returnTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) -1);
((PlaceholderType) x.getLhsType()).disableWildcardtable();
}
}
if ((x.getRhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) 1);
((PlaceholderType) x.getRhsType()).disableWildcardtable();
}
if (returnTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) -1);
((PlaceholderType) x.getRhsType()).disableWildcardtable();
}
}
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
// JEWEILS ANDERE SEITE
});
// PL 2020-02-05 alle Oder-Constraints Receiver und Parameter werden auf
// variance 1 gesetzt
// Es wird davon ausgegangen, dass in OderConstraints in Bedingungen für
// Parameter die Typen der Argumente links stehen
// und die Typen der Rückgabewerte immer rechts stehen
/*
* unifyCons.getOderConstraints().forEach(z -> z.forEach(y -> y.forEach(x -> { if ((x.getLhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.SMALLERDOT) == 0) { ((PlaceholderType) x.getLhsType()).setVariance((byte)1); } else if ((x.getRhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.EQUALSDOT) == 0) { ((PlaceholderType) x.getRhsType()).setVariance((byte)-1); } })));
*/
System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString());
Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>();
@ -636,7 +783,6 @@ public class JavaTXCompiler {
});
}
generatedGenerics.put(sf, converter.javaGenerics());
converter.generateFunNTypes();
return generatedClasses;
}

@ -34,7 +34,7 @@ public class CompilationEnvironment {
*
* @param sourceFiles die zu kompilierenden Dateien
*/
public CompilationEnvironment(List<File> sourceFiles, DirectoryClassLoader classLoader) {
public CompilationEnvironment(List<File> sourceFiles) {
/**
* Java 9 bringt einige Änderungen am Classloader So funktioniert der BootClassLoader nicht mehr. hier gibts ein paar Quellen zum nachlesen: http://java9.wtf/class-loading/ https://stackoverflow.com/questions/46494112/classloaders-hierarchy-in-java-9
*
@ -54,7 +54,7 @@ public class CompilationEnvironment {
// librarys = Arrays.asList(loader.getURLs());
this.sourceFiles = sourceFiles;
this.packageCrawler = new PackageCrawler(classLoader);
this.packageCrawler = new PackageCrawler(librarys);
}
public void addClassesToRegistry(JavaClassRegistry registry, SourceFileContext tree, File sourceFile, JavaTXCompiler compiler) throws ClassNotFoundException, IOException {
@ -104,4 +104,12 @@ public class CompilationEnvironment {
return packageName;
}
public List<ClassOrInterface> getAllAvailableClasses() {
List<ClassOrInterface> ret = new ArrayList<>();
for (Class c : new PackageCrawler(librarys).getAllAvailableClasses()) {
ret.add(ASTFactory.createClass(c));
}
return ret;
}
}

@ -5,61 +5,31 @@ import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.*;
import java.util.ArrayList;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Collectors;
public class DirectoryClassLoader extends URLClassLoader implements IByteArrayClassLoader {
// public DirectoryClassLoader(File directory, java.lang.ClassLoader parent) {
// super(generateURLArray(dirToURL(directory)), parent);
// }
public DirectoryClassLoader(File directory, java.lang.ClassLoader parent) {
super(generateURLArray(dirToURL(directory)), parent);
}
public DirectoryClassLoader(List<File> directory, java.lang.ClassLoader parent) {
super(directory.stream().map(DirectoryClassLoader::dirToURL).flatMap(List::stream).collect(Collectors.toList()).toArray(new URL[0]), parent.getParent());
super(directory.stream().map(DirectoryClassLoader::dirToURL).collect(Collectors.toList()).toArray(new URL[0]), parent);
}
private static URL[] generateURLArray(URL url) {
return new URL[]{url};
}
private static List<URL> dirToURL(File file) {
//if(!url.isDirectory())throw new RuntimeException(url.toString() + " is not a directory");
Path dir;
if (file.isDirectory()) {
try {
return List.of(file.toURI().toURL()); // if file is a directory, use it as is
} catch (MalformedURLException e) {
e.printStackTrace();
return List.of();
}
}
dir = file.toPath().getParent(); // if file is not a directory, get its parent directory
String pattern = file.toPath().getFileName().toString(); // use the file name as a glob pattern
List<URL> urls = new ArrayList<>();
private static URL dirToURL(File url){
if(!url.isDirectory())throw new RuntimeException(url.toString() + " is not a directory");
try {
urls = Files.walk(dir)
.filter(Files::isRegularFile) // only consider files (not directories)
.filter(path -> {
PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
return matcher.matches(path.getFileName()); // match the file name against the pattern
})
.map(path -> {
try {
return path.toUri().toURL();
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}) // convert the path to a URL
.toList(); // print the path of each matching file
} catch (IOException | RuntimeException e) {
e.printStackTrace();
return url.toURI().toURL();
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
return urls;
}
@Override

@ -1,10 +1,17 @@
package de.dhbwstuttgart.environment;
import io.github.classgraph.ClassGraph;
import io.github.classgraph.ScanResult;
import java.net.URL;
import java.util.*;
import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import org.reflections.vfs.SystemDir;
/**
* Hilft beim Durchsuchen von Packages
* Benutzt die Reflections-Library (https://github.com/ronmamo/reflections)
@ -12,30 +19,48 @@ import java.util.*;
*/
public class PackageCrawler {
final DirectoryClassLoader classLoader;
public PackageCrawler(DirectoryClassLoader classLoader) {
this.classLoader = classLoader;
final URL[] urls;
public PackageCrawler(List<URL> urlList) {
urls = urlList.toArray(new URL[0]);
}
public Set<Class<?>> getClassesInPackage(String packageName) {
var res = new HashSet<Class<?>>();
public Set<Class<?>> getClassesInPackage(String packageName){
/*
List<DirectoryClassLoader> classLoadersList = new LinkedList<DirectoryClassLoader>();
classLoadersList.add(Thread.currentThread().getContextClassLoader());
classLoadersList.add(ClasspathHelper.staticClassLoader());
classLoadersList.add(Thread.currentThread().getContextClassLoader().getParent());
classLoadersList.add(DirectoryClassLoader.getSystemClassLoader());
String bootClassPath = System.getProperty("sun.boot.class.path");
ArrayList<URL> urlList = new ArrayList<>();
for(String path : bootClassPath.split(";")) {
try {
urlList.add(new URL("file:"+path));
} catch (MalformedURLException e) {
new DebugException("Fehler im Classpath auf diesem System");
}
}
URL[] urls = urlList.toArray(new URL[0]);
classLoadersList.add(new URLClassLoader(urls, DirectoryClassLoader.getSystemClassLoader()));
*/
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
.setUrls(urls)
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix(packageName))));
try (ScanResult result = new ClassGraph()
.enableClassInfo()
.enableSystemJarsAndModules()
.addClassLoader(classLoader)
.acceptPackages(packageName)
.scan()) {
Set<Class<?>> classes = reflections.getSubTypesOf(Object.class);
for (var info : result.getAllClasses()) {
try {
var clazz = Class.forName(info.getName());
res.add(clazz);
} catch (ClassNotFoundException ignored) {}
}
};
return classes;
}
return res;
public Set<Class<?>> getAllAvailableClasses(){
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
.setUrls(urls));
Set<Class<?>> classes = reflections.getSubTypesOf(Object.class);
return classes;
}
public Map<String, Integer> getClassNames(String packageName){

@ -158,8 +158,7 @@ public class FCGenerator {
}
/**
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus auf der direkten Argumentebene.
* Hier sind keine Wildcards zulässig
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus.
*/
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
@ -169,52 +168,6 @@ public class FCGenerator {
this.gtvs = gtvs;
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
params.add(param.acceptTV(new TypeExchangerInner(gtvs)));
}
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
return ret;
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) {
throw new DebugException("Dieser Fall darf nicht auftreten");
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) {
throw new DebugException("Dieser Fall darf nicht auftreten");
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
throw new DebugException("Dieser Fall darf nicht auftreten");
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
if(! gtvs.containsKey(genericRefType.getParsedName()))
throw new DebugException("Dieser Fall darf nicht auftreten");
return gtvs.get(genericRefType.getParsedName());
}
}
/**
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus auf den Argumenten der Argumente.
* Hier sind Wildcards zulässig
*/
private static class TypeExchangerInner implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs;
TypeExchangerInner(HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs){
this.gtvs = gtvs;
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
@ -227,7 +180,7 @@ public class FCGenerator {
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) {
return superWildcardType;
throw new DebugException("Dieser Fall darf nicht auftreten");
}
@Override
@ -237,7 +190,7 @@ public class FCGenerator {
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
return extendsWildcardType;
throw new DebugException("Dieser Fall darf nicht auftreten");
}
@Override
@ -248,5 +201,4 @@ public class FCGenerator {
}
}
}

@ -14,8 +14,6 @@ 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;
@ -103,6 +101,7 @@ 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 {
@ -126,7 +125,7 @@ public class StatementGenerator {
this.superClass = superType;
}
public ParameterList convert(Java17Parser.FormalParameterListContext formalParameterListContext, boolean methodparameters) {
public ParameterList convert(Java17Parser.FormalParameterListContext formalParameterListContext) {
List<Pattern> ret = new ArrayList<>();
List<Java17Parser.FormalParameterContext> fps = new ArrayList<>();
if (Objects.isNull(formalParameterListContext))
@ -148,12 +147,10 @@ public class StatementGenerator {
if (fp.typeType() != null) {
type = TypeGenerator.convert(fp.typeType(), reg, generics);
} else {
type = methodparameters?
TypePlaceholder.fresh(fp.getStart(), 1, false)
: TypePlaceholder.fresh(fp.getStart());
type = TypePlaceholder.fresh(fp.getStart());
}
ret.add(new FormalParameter(paramName, type, fp.getStart()));
localVars.put(paramName, type);
localVars.put(paramName, type);
}
}
return new ParameterList(ret, ret.get(0).getOffset());
@ -442,7 +439,6 @@ public class StatementGenerator {
}
private Pattern convert(PatternContext pattern) {
return switch (pattern) {
case PPatternContext pPattern -> {
yield convert(pPattern.primaryPattern());
@ -457,36 +453,30 @@ public class StatementGenerator {
}
private FormalParameter convert(PrimaryPatternContext pPattern) {
switch (pPattern) {
case TPatternContext tPattern:
TypePatternContext typePattern = tPattern.typePattern();
var text = typePattern.identifier().getText();
var type = typePattern.typeType() == null ? TypePlaceholder.fresh(pPattern.getStart()) : TypeGenerator.convert(typePattern.typeType(), reg, generics);
var type = 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();
default:
throw new NotImplementedException();
}
}
private RecordPattern convert(RecordPatternContext recordPatternCtx) {
var cpl = recordPatternCtx.recordStructurePattern().recordComponentPatternList();
List<PatternContext> subPatternCtx = cpl == null ? List.of() : cpl.pattern();
List<PatternContext> subPatternCtx = recordPatternCtx.recordStructurePattern().recordComponentPatternList().pattern();
List<Pattern> subPattern = subPatternCtx.stream().map(this::convert).collect(Collectors.toList());
IdentifierContext identifierCtx = recordPatternCtx.identifier();
var text = (identifierCtx != null) ? identifierCtx.getText() : null;
//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);
var type = TypeGenerator.convert(recordPatternCtx.typeType(), reg, generics);
if (text != null) localVars.put(text, type);
var ret = new RecordPattern(subPattern, text, type, recordPatternCtx.getStart());
return ret;
return new RecordPattern(subPattern, text, type, recordPatternCtx.getStart());
}
private Statement convert(Java17Parser.WhileloopContext stmt) {
@ -593,7 +583,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()), name.getText(), type, varDecl.getStart())), initValue, name.getStart()));
return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), (fieldEntry.modifiers() & Modifier.STATIC) != 0, name.getText(), type, varDecl.getStart())), initValue, name.getStart()));
}
private Statement convert(Java17Parser.BreakstmtContext stmt) {
@ -607,12 +597,8 @@ public class StatementGenerator {
}
private Statement convert(Java17Parser.ContinuestmtContext stmt) {
Token offset = stmt.getStart();
if (!Objects.isNull(stmt.identifier())) {
return new Continue(localVars.get(stmt.identifier().getText()), offset);
} else {
return new Continue(TypePlaceholder.fresh(offset), offset);
}
// TODO
throw new NotImplementedException();
}
private Statement convert(Java17Parser.SemistmtContext stmt) {
@ -707,7 +693,7 @@ public class StatementGenerator {
if (!Objects.isNull(expr.methodCall())) {
return convert(expr.methodCall(), expr.expression(), offset);
} else if (!Objects.isNull(expr.identifier())) {
return new FieldVar(convert(expr.expression()), expr.identifier().getText(), TypePlaceholder.fresh(expr.identifier().start), offset);
return generateLocalOrFieldVarOrClassName(expr.getText(), offset);
} else {
// Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite
// generische Invokationen
@ -783,25 +769,62 @@ public class StatementGenerator {
/**
* Der Parser kann nicht zwischen einer lokalen Variable, einem Feldzugriff und einer Klassenangabe unterscheiden.
*
*
* @param expression
* @param offset
* @return
*/
private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) {
// Check for localVar:
if (localVars.get(expression) != null) {
return new LocalVar(expression, localVars.get(expression), offset);
} else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die
// gleiche TPH bekommen
return new FieldVar(new This(offset), expression, fields.get(expression).type(), offset);
} else if (reg.contains(expression)) {
return generateStaticClassName(expression, offset);
} else {
// lokale Variable wurde ohne "var"-Keyword deklariert und direkt mit Wert versehen
localVars.put(expression, TypePlaceholder.fresh(offset));
return new LocalVar(expression, localVars.get(expression), offset);
String[] parts = expression.split("\\.");
if (parts.length < 2) {
// Check for localVar:
if (localVars.get(expression) != null) {
return new LocalVar(expression, localVars.get(expression), offset);
} else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die
// gleiche TPH bekommen
var field = fields.get(expression);
return new FieldVar(new This(offset), Modifier.isStatic(field.modifiers()), expression, fields.get(expression).type(), offset);
} else if (reg.contains(expression)) {
return generateStaticClassName(expression, offset);
} else {
// lokale Variable wurde ohne "var"-Keyword deklariert und direkt mit Wert versehen
localVars.put(expression, TypePlaceholder.fresh(offset));
return new LocalVar(expression, localVars.get(expression), offset);
}
}
return generateFieldVarOrClassname(expression, offset);
}
private Expression generateFieldVarOrClassname(String expression, Token offset) {
String[] parts = expression.split("\\.");
String whole = "";
Expression receiver = null;
for (String part : parts) {
whole += part;
// Check for Classname:
if (reg.contains(whole)) {
receiver = generateStaticClassName(whole, offset);
}
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) {
@ -837,8 +860,10 @@ public class StatementGenerator {
private Statement convert(AssignexpressionContext expr) {
switch (expr.bop.getText()) {
case "=":
AssignLeftSide leftHandSide = convertAssignLHS(convert(expr.expression(0)));
return new Assign(leftHandSide, convert(expr.expression(1)), expr.getStart());
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;
case "+=":
case "-=":
case "*=":
@ -855,8 +880,8 @@ public class StatementGenerator {
}
}
private AssignLeftSide convertAssignLHS(Expression expr) {
Expression leftSide = expr;
private AssignLeftSide convert(String leftHandSide, Token start) {
Expression leftSide = generateLocalOrFieldVarOrClassName(leftHandSide, start);
if (leftSide instanceof FieldVar)
return new AssignToField((FieldVar) leftSide);
else if (leftSide instanceof LocalVar)
@ -1069,7 +1094,7 @@ public class StatementGenerator {
}
params = new ParameterList(parameterList, lambdaParams.getStart());
} else if (lambdaParams.formalParameterList() != null) {
params = convert(lambdaParams.formalParameterList(), false);
params = convert(lambdaParams.formalParameterList());
// }else if( lambdaParams.inferredFormalParameterList != null){
} else if (!Objects.isNull(lambdaParams.lambdaLVTIList())) {
List<Pattern> parameterList = new ArrayList<>();

@ -71,6 +71,10 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
import javassist.compiler.SyntaxError;
import javax.swing.text.html.Option;
public class SyntaxTreeGenerator {
private JavaClassRegistry reg;
@ -254,10 +258,7 @@ public class SyntaxTreeGenerator {
List<RefType> implementedInterfaces = new ArrayList<>();
List<Pattern> constructorParameters = new ArrayList<>();
List<Statement> constructorStatements = new ArrayList<>();
List<Java17Parser.RecordComponentContext> components = recordDeclaration.recordHeader().recordComponentList() != null ?
recordDeclaration.recordHeader().recordComponentList().recordComponent(): List.of();
for (RecordComponentContext component : components) {
for (RecordComponentContext component : recordDeclaration.recordHeader().recordComponentList().recordComponent()) {
int fieldmodifiers = allmodifiers.get("private") + allmodifiers.get("final");
String fieldname = component.identifier().getText();
Token fieldoffset = component.getStart();
@ -269,7 +270,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), fieldname, fieldtype, fieldoffset);
FieldVar fieldvar = new FieldVar(new This(offset), false, fieldname, fieldtype, fieldoffset);
constructorStatements.add(new Assign(new AssignToField(fieldvar), new LocalVar(fieldname, fieldtype, fieldoffset), offset));
Statement returnStatement = new Return(fieldvar, offset);
methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset));
@ -393,12 +394,12 @@ public class SyntaxTreeGenerator {
if (!Objects.isNull(ctx.EXTENDS())) {
extendedInterfaces.addAll(convert(ctx.typeList(0), generics));
}
List<RefType> permittedSubtypes = null;
List<RefType> permittedSubtypes = new ArrayList<>();
// Ist Bit für 'sealed'-Modifier gesetzt
if ((modifiers & 4096) != 0) {
if (!Objects.isNull(ctx.PERMITS())) {
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
permittedSubtypes = new ArrayList<>(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
} else {
// falls sealed modifier ohne 'permits'-List oder umgekehrt
throw new NotImplementedException("Invalid sealed class declaration");
@ -435,7 +436,7 @@ public class SyntaxTreeGenerator {
}
}
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>());
ParameterList paramlist = stmtgen.convert(bodydeclaration.formalParameters().formalParameterList(), true);
ParameterList paramlist = stmtgen.convert(bodydeclaration.formalParameters().formalParameterList());
MethodBodyContext body = bodydeclaration.methodBody();
Block block = null;
if (!(body instanceof EmptymethodContext)) {
@ -532,7 +533,7 @@ public class SyntaxTreeGenerator {
RefTypeOrTPHOrWildcardOrGeneric retType;
if (Objects.isNull(header.refType())) {
retType = TypePlaceholder.fresh(header.getStart(), -1, false);
retType = TypePlaceholder.fresh(header.getStart());
} else {
if (header.refType() instanceof RefType2Context reftype) {
retType = TypeGenerator.convert(reftype.typeType(), reg, generics);
@ -541,7 +542,7 @@ public class SyntaxTreeGenerator {
}
}
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList(), true);
ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList());
MethodBodyContext body = methoddeclaration.methodBody();
Block block = null;
if (body instanceof EmptymethodContext emptymethod) {
@ -581,7 +582,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(), true);
ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList());
Block block = prepareBlock(stmtgen.convert(constructordeclaration.constructorBody, true), superClass);
return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart());
}
@ -594,7 +595,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(), -1, false);
fieldType = TypePlaceholder.fresh(fieldDeclContext.variableDeclarators().getStart());
}
for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) {
String fieldName = varDecl.variableDeclaratorId().getText();

@ -10,8 +10,6 @@ public interface ASTVisitor extends StatementVisitor{
void visit(FormalParameter formalParameter);
void visit(LiteralPattern literalPattern);
void visit(GenericDeclarationList genericTypeVars);
void visit(Field field);

@ -37,11 +37,6 @@ 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();
@ -241,11 +236,6 @@ public abstract class AbstractASTWalker implements ASTVisitor {
aBreak.accept(this);
}
@Override
public void visit(Continue aContinue) {
aContinue.accept(this);
}
@Override
public void visit(StaticClassName staticClassName) {

@ -86,9 +86,6 @@ 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;
}
@ -191,8 +188,9 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ClassOrInterface other)) return false;
return Objects.equals(name, other.name);
if (o == null || getClass() != o.getClass()) return false;
ClassOrInterface that = (ClassOrInterface) o;
return Objects.equals(name, that.name);
}
@Override

@ -1,29 +0,0 @@
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,7 +3,6 @@ package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.statement.*;
public interface StatementVisitor {
void visit(ArgumentList argumentList);
@ -54,8 +53,6 @@ public interface StatementVisitor {
void visit(Break aBreak);
void visit(Continue aContinue);
void visit(Yield aYield);
void visit(StaticClassName staticClassName);

@ -176,9 +176,8 @@ public class ASTFactory {
for (Type jreInterface : jreClass.getGenericInterfaces()) {
implementedInterfaces.add((RefType) createType(jreInterface));
}
List<RefType> permittedSubtypes = null;
List<RefType> permittedSubtypes = new ArrayList<>();
if (jreClass.isSealed()) {
permittedSubtypes = new ArrayList<>();
for (Class subclass : jreClass.getPermittedSubclasses()) {
permittedSubtypes.add((RefType) createType(subclass));
}

@ -129,10 +129,9 @@ public class UnifyTypeFactory {
if (tph.getName().equals("AFR")) {
System.out.println("XXX"+innerType);
}
PlaceholderType ntph = new PlaceholderType(tph.getName(), tph.getVariance());
PlaceholderType ntph = new PlaceholderType(tph.getName());
ntph.setVariance(tph.getVariance());
ntph.setOrCons(tph.getOrCons());
ntph.setWildcardtable(tph.getWildcardtable());
int in = PLACEHOLDERS.indexOf(ntph);
if (in == -1) {
PLACEHOLDERS.add(ntph);

@ -1,18 +0,0 @@
package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import org.antlr.v4.runtime.Token;
public class Continue extends Statement {
public Continue(RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(type, offset);
}
@Override
public void accept(StatementVisitor visitor) {
visitor.visit(this);
}
}

@ -17,11 +17,13 @@ public class FieldVar extends Expression {
public final String fieldVarName;
public final Expression receiver;
public final boolean isStatic;
public FieldVar(Expression receiver, String fieldVarName, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
public FieldVar(Expression receiver, boolean isStatic, String fieldVarName, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(type, offset);
this.fieldVarName = fieldVarName;
this.receiver = receiver;
this.isStatic = isStatic;
}
@Override

@ -8,7 +8,6 @@ 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
@ -50,7 +49,10 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
@Override
public int hashCode() {
return this.name.hashCode();//Nur den Name hashen. Sorgt für langsame, aber funktionierende HashMaps
int hash = 0;
hash += super.hashCode();
hash += this.name.hashCode();//Nur den Name hashen. Sorgt für langsame, aber funktionierende HashMaps
return hash;
}
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset) {
@ -81,7 +83,6 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
public boolean equals(Object obj)
{
if(obj instanceof RefType){
if (!Objects.equals(this.name, ((RefType) obj).name)) return false;
boolean ret = true;
//if(!(super.equals(obj))) PL 2020-03-12 muss vll. einkommentiert werden

@ -21,17 +21,9 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
private final String name;
/**
* 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
* wird im Generate Generics Teil nach der Rueckumwandlung nach dem Unify genutzt
*/
private boolean wildcardable = true;
private int variance = 0;
/*
* Fuer Oder-Constraints:
@ -47,12 +39,10 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
* Factory-Methode <code>fresh()</code> erzeugt.
* <br>Author: J�rg B�uerle
*/
private TypePlaceholder(String name, Token offset, int variance, boolean wildcardable)
private TypePlaceholder(String name, Token offset)
{
super(offset);
this.name = name;
this.variance = variance;
this.wildcardable = wildcardable;
}
@ -63,15 +53,11 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
* @return
*/
public static TypePlaceholder fresh(Token position){
return new TypePlaceholder(NameGenerator.makeNewName(), position, 0, true);
}
public static TypePlaceholder fresh(Token position, int variance, boolean wildcardable){
return new TypePlaceholder(NameGenerator.makeNewName(), position, variance, wildcardable);
return new TypePlaceholder(NameGenerator.makeNewName(), position);
}
public static RefTypeOrTPHOrWildcardOrGeneric of(String name) {
return new TypePlaceholder(name, new NullToken(),0, true);
return new TypePlaceholder(name, new NullToken());
}
@ -134,9 +120,4 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
public byte getOrCons() {
return orCons;
}
public Boolean getWildcardtable() {
return wildcardable;
}
}

@ -57,11 +57,6 @@ 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();
@ -338,11 +333,6 @@ public class OutputGenerator implements ASTVisitor {
out.append("break");
}
@Override
public void visit(Continue aContinue) {
out.append("continue");
}
@Override
public void visit(StaticClassName staticClassName) {
@ -513,11 +503,12 @@ public class OutputGenerator implements ASTVisitor {
aRecordPattern.getType().accept(this);
out.append("(");
List<Pattern> subPatterns = aRecordPattern.getSubPattern();
for (var i = 0; i < subPatterns.size(); i++) {
int i;
for (i = 0; i < subPatterns.size() - 1; i++) {
subPatterns.get(i).accept(this);
if (i < subPatterns.size() - 1)
out.append(", ");
out.append(", ");
}
subPatterns.get(i).accept(this);
String name;
if ((name = aRecordPattern.getName()) != null)
out.append(name);

@ -4,7 +4,7 @@ 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.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.*;
@ -17,34 +17,26 @@ import de.dhbwstuttgart.target.tree.expression.*;
import de.dhbwstuttgart.target.tree.type.*;
import de.dhbwstuttgart.typeinference.result.*;
import javax.sql.rowset.RowSetWarning;
import java.lang.annotation.Target;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
* @author dholle
*/
public class ASTToTargetAST {
record SignaturePair(TypePlaceholder signature, RefTypeOrTPHOrWildcardOrGeneric parameter) {};
record SignaturePairTarget(TargetType signature, TargetType parameter) {}
public static RefType OBJECT = ASTFactory.createObjectType(); // TODO It would be better if I could call this directly but the hashcode seems to change
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();
}
@ -63,7 +55,7 @@ public class ASTToTargetAST {
}
public IByteArrayClassLoader classLoader;
protected IByteArrayClassLoader classLoader;
protected SourceFile sourceFile;
public ASTToTargetAST(List<ResultSet> resultSets) {
@ -85,12 +77,6 @@ public class ASTToTargetAST {
this.generics = all.get(0);
}
public void addSignaturePair(TypePlaceholder signature, RefTypeOrTPHOrWildcardOrGeneric parameter) {
var set = tphsInMethods.getOrDefault(currentMethod, new HashSet<>());
set.add(new SignaturePair(signature, parameter));
tphsInMethods.put(currentMethod, set);
}
Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList) {
Optional<Method> method = Optional.empty();
while (method.isEmpty()) {
@ -144,207 +130,6 @@ public class ASTToTargetAST {
return ret;
}
// This finds a common sealed interface type to group together methods that use different records
private List<ClassOrInterface> commonSuperInterfaceTypes(TargetType a, TargetType b) {
if (a instanceof TargetGenericType && b instanceof TargetGenericType) return List.of(ASTFactory.createObjectClass());
if (a instanceof TargetRefType ta && b instanceof TargetGenericType)
return List.of(compiler.getClass(new JavaClassName(ta.name())));
if (b instanceof TargetRefType tb && a instanceof TargetGenericType)
return List.of(compiler.getClass(new JavaClassName(tb.name())));
if (a instanceof TargetRefType ta && b instanceof TargetRefType tb) {
var res = new HashSet<ClassOrInterface>();
var cla = compiler.getClass(new JavaClassName(ta.name()));
var clb = compiler.getClass(new JavaClassName(tb.name()));
if (cla.equals(clb)) return List.of(cla);
while (!cla.equals(ASTFactory.createObjectClass())) {
var clb2 = clb;
while (!clb2.equals(ASTFactory.createObjectClass())) {
for (var intfa : cla.getSuperInterfaces()) {
for (var intfb : clb.getSuperInterfaces()) {
if (intfa.equals(intfb)) {
var clintf = compiler.getClass(intfa.getName());
if (clintf.isSealed()) {
res.add(clintf);
}
}
}
}
clb2 = compiler.getClass(clb2.getSuperClass().getName());
}
cla = compiler.getClass(cla.getSuperClass().getName());
}
return res.stream().toList();
}
return List.of();
}
// TODO This is ugly and probably doesn't work right
private boolean patternStrictlyEquals(TargetComplexPattern a, TargetComplexPattern b) {
if (!a.name().equals(b.name())) return false;
if (a.subPatterns().size() != b.subPatterns().size()) return false;
for (var i = 0; i < a.subPatterns().size(); i++) {
var p1 = a.subPatterns().get(i);
var p2 = b.subPatterns().get(i);
if (p1 instanceof TargetComplexPattern pc1 && p2 instanceof TargetComplexPattern pc2 &&
patternStrictlyEquals(pc1, pc2)) return false;
if (p1 instanceof TargetTypePattern pt1 && p2 instanceof TargetTypePattern pt2) {
if (pt1.type() instanceof TargetGenericType && pt2.type() instanceof TargetGenericType) continue;
}
if (!p1.type().equals(p2.type()) && commonSuperInterfaceTypes(p1.type(), p2.type()).isEmpty()) return false;
}
return true;
}
private boolean canCombine(TargetMethod m1, TargetMethod m2) {
if (!m1.name().equals(m2.name())) return false;
var s1 = m1.signature();
var s2 = m2.signature();
if (s1.parameters().size() != s2.parameters().size()) return false;
if (s1.parameters().isEmpty()) return false;
for (var i = 0; i < s1.parameters().size(); i++) {
var p1 = s1.parameters().get(i).pattern();
var p2 = s2.parameters().get(i).pattern();
if (p1.type() instanceof TargetGenericType || p2.type() instanceof TargetGenericType) continue;
if (p1 instanceof TargetComplexPattern pc1 && p2 instanceof TargetComplexPattern pc2 &&
patternStrictlyEquals(pc1, pc2)) return false;
if (!p1.equals(p2) && commonSuperInterfaceTypes(p1.type(), p2.type()).isEmpty()) return false;
}
return true;
}
private record Combination(TargetMethod a, TargetMethod b) {
@Override
public boolean equals(Object o) {
if (!(o instanceof Combination(TargetMethod a1, TargetMethod b1))) return false;
return this.a.equals(a1) && this.b.equals(b1) ||
this.a.equals(b1) && this.b.equals(a1);
}
@Override
public int hashCode() {
return Objects.hashCode(a) + Objects.hashCode(b);
}
}
public List<List<TargetMethod>> groupOverloads(ClassOrInterface input, List<Method> methods) {
var mapOfTargetMethods = new HashMap<Generics, TargetMethod[]>();
for (var generics : all) {
mapOfTargetMethods.put(generics, new TargetMethod[methods.size()]);
}
for (var i = 0; i < methods.size(); i++) {
var method = methods.get(i);
// Convert all methods
var methodsWithTphs = convert(input, method);
for (var m : methodsWithTphs) {
var resultMethods = mapOfTargetMethods.get(m.generics);
resultMethods[i] = m.method;
}
}
/*System.out.println("============== INPUT ==============");
for (var m : mapOfTargetMethods.values()) {
for (var v : m) System.out.println(v.name() + " " + v.getSignature());
System.out.println();
}*/
var allCombinations = new HashSet<Set<Combination>>();
// Combine methods based on their signature and position in the result set
for (var g1 : all) {
var resMeth1 = mapOfTargetMethods.get(g1);
for (var i = 0; i < methods.size(); i++) {
var m1 = resMeth1[i];
if (m1 == null) continue;
for (var g2 : all) {
if (g1 == g2) continue; // No need to combine the same method
var resMeth2 = mapOfTargetMethods.get(g2);
var m2 = resMeth2[i];
if (m2 == null) continue;
var combinations = new HashSet<Combination>();
if (canCombine(m1, m2)) {
//System.out.println(" Combining " + m1.getSignature() + " and " + m2.getSignature());
combinations.add(new Combination(m1, m2));
for (var j = 0; j < methods.size(); j++) {
if (j == i) continue;
var m3 = resMeth2[j];
if (m3 == null) continue;
var m4 = resMeth1[j];
if (m4 == null) continue;
combinations.add(new Combination(m4, m3));
//System.out.println("Also Combining " + m4.getSignature() + " and " + m3.getSignature());
}
} else {
//System.out.println(" Not Combining " + m1.getSignature() + " and " + m2.getSignature());
}
if (!combinations.isEmpty()) allCombinations.add(combinations);
}
}
}
if (allCombinations.isEmpty()) allCombinations.add(new HashSet<>());
// Combine back into output format
var r0 = new HashSet<Set<TargetMethod>>();
for (var combinations : allCombinations) {
var r1 = new HashSet<Set<TargetMethod>>();
// This is used to weed out duplicates
var uniqued = new HashSet<TargetMethod>();
// We go over all methods in the result
for (var g : all) for (var i = 0; i < methods.size(); i++) {
var r2 = new HashSet<TargetMethod>();
var m = mapOfTargetMethods.get(g)[i];
if (m == null) continue;
if (!uniqued.contains(m)) {
// Add the method to r2
r2.add(m);
uniqued.add(m);
} else continue;
// Find all combinations that contain the method and add them to the result
// if not filtered out by uniqued
for (var c : combinations) {
if (c.a.equals(m) || c.b.equals(m)) {
if (!uniqued.contains(c.a)) {
r2.add(c.a);
uniqued.add(c.a);
}
if (!uniqued.contains(c.b)) {
r2.add(c.b);
uniqued.add(c.b);
}
}
}
r1.add(r2);
}
outer: for (var s1 : r1) {
for (var s2 : new HashSet<>(r0)) {
if (s2.containsAll(s1)) {
continue outer;
} else if (s1.containsAll(s2)) {
r0.remove(s2);
r0.add(s1);
continue outer;
}
}
r0.add(s1);
}
}
var result = r0.stream().map(l -> l.stream().toList()).toList();
System.out.println("============== OUTPUT ==============");
for (var l : result) {
for (var m : l) System.out.println(m.name() + " " + m.getSignature());
System.out.println();
}
return result;
}
public TargetStructure convert(ClassOrInterface input) {
Set<TargetGeneric> javaGenerics = new HashSet<>();
Set<TargetGeneric> txGenerics = new HashSet<>();
@ -375,12 +160,11 @@ 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().map(m -> generatePatternOverloads(input, m)).flatMap(List::stream)
.collect(Collectors.toSet()).stream().toList(); // Unique generated methods
var methods = groupOverloads(input.getMethods()).stream().map(m -> convert(input, m)).flatMap(List::stream).toList();
TargetMethod staticConstructor = null;
if (input.getStaticInitializer().isPresent())
staticConstructor = this.convert(input, input.getStaticInitializer().get()).stream().findFirst().orElseThrow().method;
staticConstructor = this.convert(input, input.getStaticInitializer().get()).get(0);
if (input instanceof Record)
return new TargetRecord(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
@ -390,14 +174,9 @@ public class ASTToTargetAST {
}
public List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) {
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;
return input.getFormalparalist().stream().map(param ->
new MethodParameter((TargetPattern) convert(param))
).toList();
}
private boolean hasGeneric(Set<TargetGeneric> generics, GenericRefType type) {
@ -426,7 +205,6 @@ public class ASTToTargetAST {
generics = all.get(0);
List<TargetConstructor> result = new ArrayList<>();
Set<List<MethodParameter>> parameterSet = new HashSet<>();
this.currentMethod = input;
for (var s : all) {
generics = s;
@ -446,157 +224,111 @@ public class ASTToTargetAST {
return result;
}
private String encodeName(String name, TargetMethod.Signature params) {
/**
* This only considers type patterns, all other methods aren't grouped together
* @param a
* @param b
* @return
*/
private boolean signatureEquals(Method a, Method b) {
if (!a.name.equals(b.name)) return false;
var para = a.getParameterList().getFormalparalist();
var parb = b.getParameterList().getFormalparalist();
if (para.size() != parb.size()) return false;
for (var i = 0; i < para.size(); i++) {
var pa = para.get(i);
var pb = parb.get(i);
if (pa instanceof RecordPattern rpa) {
if (pb instanceof RecordPattern rpb) {
if (rpa.getType().equals(rpb.getType())) continue;
}
return false;
} else if (pa.getType().equals(pb.getType())) {
continue;
}
return false;
}
return true;
}
// TODO Nested patterns
private List<List<Method>> groupOverloads(List<Method> input) {
var done = new HashSet<Method>();
var res = new ArrayList<List<Method>>();
for (var method : input) {
if (done.contains(method)) continue;
var overloads = new ArrayList<Method>();
overloads.add(method);
done.add(method);
for (var method2 : input) {
if (!done.contains(method2) && signatureEquals(method, method2)) {
done.add(method2);
overloads.add(method2);
}
}
res.add(overloads);
}
return res;
}
private String encodeName(String name, ParameterList params) {
var res = new StringBuilder();
res.append(name);
res.append('$');
for (var param : params.parameters()) {
encodeName(param.pattern(), res);
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())));
}
}
}
return res.toString();
}
private void encodeName(TargetPattern pattern, StringBuilder res) {
if (pattern instanceof TargetComplexPattern cp) {
res.append(FunNGenerator.encodeType(cp.type()));
for (var pat : cp.subPatterns()) {
encodeName(pat, res);
}
} else {
res.append(FunNGenerator.encodeType(pattern.type()));
private List<TargetMethod> convert(ClassOrInterface clazz, List<Method> overloadedMethods) {
if (overloadedMethods.size() == 1) {
return convert(clazz, overloadedMethods.get(0));
}
}
private TargetType unwrap(TargetType type) {
if (type instanceof TargetRefType ref) {
if (!ref.params().isEmpty()) return new TargetRefType(ref.name());
}
return type;
}
private TargetExpression generatePatternOverloadsRec(int offset, TargetExpression switchExpr, List<TargetLocalVar> params, List<TargetPattern> patterns, List<TargetMethod> methods, TargetType classType) {
if (methods.isEmpty()) throw new DebugException("Couldn't find a candidate for switch overloading");
if (methods.size() == 1) {
var method = methods.getFirst();
var mParams = new ArrayList<TargetExpression>();
for (var i = 0; i < params.size(); i++) {
var tpe = method.signature().parameters().get(i).pattern().type();
mParams.add(new TargetLocalVar(tpe, params.get(i).name()));
}
TargetExpression caseBody = new TargetMethodCall(
method.signature().returnType(),
new TargetThis(classType),
mParams,
classType,
method.name(),
false, false, method.isPrivate()
);
if (method.signature().returnType() != null) {
caseBody = new TargetReturn(caseBody);
}
return caseBody;
}
var cases = new ArrayList<TargetSwitch.Case>();
var usedPatterns = new HashSet<TargetPattern>();
for (var method : methods) {
var patternsRec = new ArrayList<>(patterns);
TargetExpression expr = null;
var i = 0;
for (var param : method.signature().parameters()) {
if (i == offset) {
patternsRec.add(param.pattern());
}
if (i > offset) {
// Find next pattern
expr = params.get(i);
break;
}
i++;
}
var lastPattern = patternsRec.getLast();
if (usedPatterns.contains(lastPattern)) continue;
usedPatterns.add(lastPattern);
var candidates = methods.stream().filter(m -> {
var j = 0;
for (var param : m.signature().parameters()) {
if (j >= patternsRec.size()) return true;
if (!patternsRec.get(j).type().equals(param.pattern().type())) return false;
j++;
}
return true;
}).toList();
var caseBody = generatePatternOverloadsRec(offset + 1, expr, params, patternsRec, candidates, classType);
var body = new TargetBlock(List.of(caseBody));
var case_ = new TargetSwitch.Case(List.of(lastPattern), body);
cases.add(case_);
}
return new TargetSwitch(switchExpr, cases, null, true);
}
private List<TargetMethod> generatePatternOverloads(ClassOrInterface clazz, List<TargetMethod> overloadedMethods) {
if (overloadedMethods.size() <= 1) return overloadedMethods;
// Check if we have a pattern as a parameter
var firstMethod = overloadedMethods.getFirst();
var secondMethod = overloadedMethods.get(1);
if (firstMethod.signature().parameters().stream().noneMatch(mp -> mp.pattern() instanceof TargetComplexPattern)) return overloadedMethods;
// Rename existing methods
var res = new ArrayList<TargetMethod>();
var res = new ArrayList<Method>();
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 newMethod = new Method(
method.modifier,
method.name,
//encodeName(method.name, method.getParameterList()),
method.getReturnType(),
method.getParameterList(),
method.block,
method.getGenerics(),
method.getOffset()
);
res.add(newMethod);
}
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();
// TODO Record overloading
/*var template = overloadedMethods.get(0);
String name;
if (p1 instanceof TargetComplexPattern) name = "__var" + i;
else name = p1.name();
signatureParams.add(new MethodParameter(new TargetRefType(superType.getClassName().toString()), name));
var pParams = new ArrayList<Pattern>();
var i = 0;
for (var par : template.getParameterList()) {
pParams.add(switch (par) {
case RecordPattern rp -> new RecordPattern(rp.getSubPattern(), "par" + i, rp.getType(), new NullToken());
default -> par;
});
i++;
}
var params = new ParameterList(pParams, new NullToken());
var 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 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 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;
res.add(entryPoint); // TODO*/
return res.stream().map(m -> convert(clazz, m)).flatMap(List::stream).toList();
}
private Expression makeRecordSwitch(RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList params, List<Method> overloadedMethods) {
@ -634,35 +366,17 @@ public class ASTToTargetAST {
for (var i = 0; i < params.size(); i++) {
var a = TargetType.toPrimitive(params.get(i).pattern().type());
var b = convert(sParams.getFormalparalist().get(i).getType());
System.out.println(a + " " + b);
if (!Objects.equals(a, b)) return false;
}
return true;
}).findFirst();
}
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<>();
private List<TargetMethod> convert(ClassOrInterface currentClass, Method method) {
generics = all.get(0);
List<TargetMethod> result = new ArrayList<>();
Set<List<MethodParameter>> parameterSet = new HashSet<>();
for (var s : all) {
generics = s;
@ -673,37 +387,23 @@ public class ASTToTargetAST {
var superMethod = findSuperMethodToOverride(currentClass, method.getName(), params);
if (superMethod.isPresent()) {
// If we find a super method to override, use its parameters and return types
var newReturnType = convert(superMethod.get().getReturnType(), this.generics.javaGenerics);
if (newReturnType instanceof TargetPrimitiveType && TargetType.toPrimitive(returnType).equals(newReturnType)) {
returnType = newReturnType;
params = convert(superMethod.get().getParameterList(), method.getParameterList(), this.generics.javaGenerics);
}
returnType = convert(superMethod.get().getReturnType(), this.generics.javaGenerics);
params = convert(superMethod.get().getParameterList(), method.getParameterList(), this.generics.javaGenerics);
}
List<MethodParameter> txParams = convert(method.getParameterList(), this.generics.txGenerics);
List<MethodParameter> finalParams = params;
if (parameterSet.stream().noneMatch(p -> p.equals(finalParams))) {
List<MethodParameter> txParams = convert(method.getParameterList(), this.generics.txGenerics);
var javaMethodGenerics = collectMethodGenerics(currentClass, generics.javaGenerics(), javaGenerics, method);
var txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, method);
var javaMethodGenerics = collectMethodGenerics(currentClass, generics.javaGenerics(), javaGenerics, method);
var txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, method);
var javaSignature = new TargetMethod.Signature(javaMethodGenerics, params, returnType);
var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), this.generics.txGenerics));
signatures.add(new Signature(javaSignature, txSignature, generics));
var listOfGenerics = collectedGenerics.getOrDefault(javaSignature, new ArrayList<>());
listOfGenerics.add(generics);
collectedGenerics.put(javaSignature, listOfGenerics);
var javaSignature = new TargetMethod.Signature(javaMethodGenerics, params, returnType);
var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), this.generics.txGenerics));
result.add(new TargetMethod(method.modifier, method.name, convert(method.block), javaSignature, txSignature));
parameterSet.add(params);
}
}
for (var signature : signatures) {
generics = signature.generics;
currentMethodOverloads = collectedGenerics.get(signature.java);
var newMethod = new TargetMethod(method.modifier, method.name, convert(method.block), signature.java, signature.tx);
var concreteParams = tphsInMethods.getOrDefault(method, new HashSet<>()).stream().map(sig -> new SignaturePairTarget(convert(sig.signature), convert(sig.parameter))).toList();
result.add(new MethodWithTphs(newMethod, generics, concreteParams));
}
return result;
}
@ -711,9 +411,7 @@ public class ASTToTargetAST {
var list = new ArrayList<MethodParameter>();
for (var i = 0; i < paraList.getFormalparalist().size(); i++) {
var param = paraList.getParameterAt(i);
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)));
list.add(new MethodParameter((TargetPattern) convert(param)).withType(convert(superList.getParameterAt(i).getType(), generics)));
}
return list;
}
@ -775,59 +473,10 @@ public class ASTToTargetAST {
}
var filteredParams = new ArrayList<TargetType>();
for (var i = 0; i < newParams.size(); i++) {
if (i < gep.inParams.size() && gep.inParams.get(i) != null)
if (gep.parameters.get(i) != null)
filteredParams.add(newParams.get(i));
}
return TargetFunNType.fromParams(params, filteredParams, gep.getReturnType() != null ? 1 : 0);
}
private boolean isSubtype(TargetType test, TargetType other) {
var testClass = compiler.getClass(new JavaClassName(test.name()));
var otherClass = compiler.getClass(new JavaClassName(other.name()));
if (testClass == null) return false;
while (testClass != null) {
if (testClass.equals(otherClass)) return true;
if (testClass.getClassName().equals(new JavaClassName("java.lang.Object"))) break;
testClass = compiler.getClass(testClass.getSuperClass().getName());
}
return false;
}
private boolean isSupertype(TargetType test, TargetType other) {
return isSubtype(other, test);
}
private boolean isSubtype(FunNGenerator.GenericParameters test, FunNGenerator.GenericParameters other) {
if (test.getArguments().size() != other.getArguments().size()) return false;
if (!isSubtype(test.getReturnType(), other.getReturnType())) return false;
for (int i = 0; i < test.getArguments().size(); i++) {
var arg1 = test.getArguments().get(i);
var arg2 = other.getArguments().get(i);
if (!isSupertype(arg1, arg2)) return false;
}
return true;
}
public void generateFunNTypes() {
for (var entry : usedFunN.entrySet()) {
var gep = entry.getValue();
var superInterfaces = usedFunN.values().stream()
.filter(g -> !g.equals(gep))
.filter(genericParameters -> isSubtype(gep, genericParameters))
.map(FunNGenerator::getSpecializedClassName)
.toList();
var code = FunNGenerator.generateSpecializedBytecode(gep, superInterfaces);
try {
classLoader.findClass(entry.getKey());
} catch (ClassNotFoundException e) {
try {
classLoader.loadClass(code);
} catch (LinkageError ignored) {}
}
auxiliaries.put(entry.getKey(), code);
}
return TargetFunNType.fromParams(params, filteredParams);
}
protected TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics) {
@ -842,16 +491,17 @@ public class ASTToTargetAST {
}
var params = refType.getParaList().stream().map(type -> {
return convert(type, generics);
var res = convert(type, generics);
if (res == null) res = new TargetRefType("java.lang.Void");
return res;
}).toList();
if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea
var returnType = FunNGenerator.getReturnType(params);
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), returnType);
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
if (!usedFunNSuperTypes.contains(params.size())) {
usedFunNSuperTypes.add(params.size());
var code = FunNGenerator.generateSuperBytecode(params.size() - 1, returnType != null ? 1 : 0);
var superClassName = FunNGenerator.getSuperClassName(params.size() - 1, returnType != null ? 1 : 0);
var code = FunNGenerator.generateSuperBytecode(params.size() - 1);
var superClassName = FunNGenerator.getSuperClassName(params.size() - 1);
try {
classLoader.findClass(superClassName);
} catch (ClassNotFoundException e) {
@ -863,8 +513,17 @@ public class ASTToTargetAST {
}
FunNGenerator.GenericParameters gep = null;
if (!usedFunN.containsKey(className)) {
gep = new FunNGenerator.GenericParameters(params, returnType != null ? 1 : 0);
gep = new FunNGenerator.GenericParameters();
var code = FunNGenerator.generateSpecializedBytecode(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params), gep);
try {
classLoader.findClass(className);
} catch (ClassNotFoundException e) {
try {
classLoader.loadClass(code);
} catch (LinkageError ignored) {}
}
usedFunN.put(className, gep);
auxiliaries.put(className, code);
} else {
gep = usedFunN.get(className);
}

@ -1,7 +1,10 @@
package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.type.Void;
@ -131,8 +134,8 @@ public abstract class GenerateGenerics {
final Map<Method, Set<Pair>> familyOfMethods = new HashMap<>();
final Set<PairLT> simplifiedConstraints = new HashSet<>();
Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>();
final Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
final Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>();
GenerateGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
this.astToTargetAST = astToTargetAST;
@ -151,41 +154,6 @@ 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) {
@ -522,7 +490,9 @@ public abstract class GenerateGenerics {
if (!(method instanceof Constructor))
typeVariables.addAll(findTypeVariables(method.getReturnType()));
typeVariables.addAll(findTypeVariables(method.getParameterList()));
for (var arg : method.getParameterList().getFormalparalist()) {
typeVariables.addAll(findTypeVariables(arg.getType()));
}
if (method.block != null)
method.block.accept(new TracingStatementVisitor() {
@ -586,7 +556,9 @@ public abstract class GenerateGenerics {
var usedTphs = new HashSet<TPH>();
// For eliminating inner type variables we need to figure out which ones are actually used
usedTphs.addAll(findTypeVariables(method.getParameterList()));
for (var param : method.getParameterList().getFormalparalist()) {
usedTphs.addAll(findTypeVariables(param.getType()));
}
usedTphs.addAll(findTypeVariables(method.getReturnType()));
referenced.addAll(usedTphs);
referenced.addAll(typeVariablesOfClass);
@ -680,25 +652,17 @@ public abstract class GenerateGenerics {
}
void normalize(Set<Pair> result, Set<Pair> classGenerics, Set<TPH> usedTphs) {
for (var p1 : new HashSet<>(result)) {
if (p1 instanceof PairLT ptph && ptph.left.resolve().equals(ptph.right.resolve()))
result.remove(p1); // TODO This is a bit strange
}
outer:
for (var tph : usedTphs) {
for (var p1 : new HashSet<>(result)) {
if (p1 instanceof PairLT ptph && ptph.left.equals(ptph.right))
result.remove(p1); // TODO This is a bit strange
if (p1.left.equals(tph)) continue outer;
}
if (classGenerics == null || classGenerics.stream().noneMatch((pair) -> pair.left.equals(tph)))
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,21 +1,24 @@
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.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class StatementToTargetExpression implements ASTVisitor {
@ -140,11 +143,7 @@ public class StatementToTargetExpression implements ASTVisitor {
@Override
public void visit(FieldVar fieldVar) {
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);
result = new TargetFieldVar(converter.convert(fieldVar.getType()), converter.convert(fieldVar.receiver.getType()), fieldVar.isStatic, converter.convert(fieldVar.receiver), fieldVar.fieldVarName);
}
@Override
@ -209,11 +208,6 @@ public class StatementToTargetExpression implements ASTVisitor {
var isPrivate = false;
var signature = methodCall.signatureArguments().stream().map(converter::convert).toList();
// Add used TPHs to containing method
for (var i = 0; i < methodCall.signatureArguments().size(); i++) {
converter.addSignaturePair(methodCall.signatureArguments().get(i), methodCall.arglist.getArguments().get(i).getType());
}
var receiverClass = converter.compiler.getClass(receiverName);
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) {
if (receiverClass == null) throw new DebugException("Class " + receiverName + " does not exist!");
@ -234,7 +228,6 @@ public class StatementToTargetExpression implements ASTVisitor {
isInterface = receiverClass.isInterface();
}
System.out.println(argList);
result = new TargetMethodCall(converter.convert(methodCall.getType()), returnType, argList, converter.convert(methodCall.receiver), methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(), receiverType, methodCall.name, isStatic, isInterface, isPrivate);
}
@ -267,11 +260,6 @@ public class StatementToTargetExpression implements ASTVisitor {
result = new TargetBreak();
}
@Override
public void visit(Continue aContinue) {
result = new TargetContinue();
}
@Override
public void visit(StaticClassName staticClassName) {
result = new TargetClassName(converter.convert(staticClassName.getType()));
@ -294,7 +282,7 @@ public class StatementToTargetExpression implements ASTVisitor {
@Override
public void visit(DoStmt whileStmt) {
result = new TargetDo(converter.convert(whileStmt.expr), converter.convert(whileStmt.loopBlock));
throw new NotImplementedException();
}
// TODO These two might not be necessary
@ -387,94 +375,9 @@ 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 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();
var cases = switchStmt.getBlocks().stream().filter(s -> !s.isDefault()).map(converter::convert).toList();
TargetSwitch.Case default_ = null;
for (var block : switchStmt.getBlocks()) {
@ -568,11 +471,6 @@ 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());

@ -124,11 +124,6 @@ public abstract class TracingStatementVisitor implements StatementVisitor {
}
@Override
public void visit(Continue aContinue) {
}
@Override
public void visit(StaticClassName staticClassName) {

@ -11,8 +11,4 @@ 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));
}
}

@ -6,7 +6,6 @@ import de.dhbwstuttgart.target.tree.type.TargetType;
import org.objectweb.asm.Opcodes;
import java.util.List;
import java.util.Objects;
import java.util.Set;
public record TargetMethod(int access, String name, TargetBlock block, Signature signature, Signature txSignature) {
@ -18,19 +17,6 @@ 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) {
@ -78,20 +64,5 @@ public record TargetMethod(int access, String name, TargetBlock block, Signature
public boolean isStatic() {
return (access & Opcodes.ACC_STATIC) != 0;
}
public boolean isPrivate() {
return (access & Opcodes.ACC_PRIVATE) != 0;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof TargetMethod otherMethod)) return false;
return otherMethod.signature.equals(this.signature) && otherMethod.name.equals(this.name);
}
@Override
public int hashCode() {
return Objects.hash(name, signature);
}
}

@ -9,9 +9,4 @@ 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);
}
}

@ -1,4 +0,0 @@
package de.dhbwstuttgart.target.tree.expression;
public record TargetDo(TargetExpression cond, TargetExpression body) implements TargetExpression {
}

@ -3,7 +3,7 @@ package de.dhbwstuttgart.target.tree.expression;
import de.dhbwstuttgart.target.tree.type.*;
public sealed interface TargetExpression
permits TargetBinaryOp, TargetBlock, TargetBreak, TargetCast, TargetClassName, TargetContinue, TargetDo, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetPattern, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetTernary, TargetThis, TargetThrow, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield {
permits TargetBinaryOp, TargetBlock, TargetBreak, TargetCast, TargetClassName, TargetContinue, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetPattern, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetTernary, TargetThis, TargetThrow, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield {
default TargetType type() {
return null;

@ -1,20 +0,0 @@
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,9 +12,4 @@ 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, TargetExpressionPattern, TargetGuard, TargetTypePattern {
public sealed interface TargetPattern extends TargetExpression permits TargetComplexPattern, TargetGuard, TargetTypePattern {
default String name() {
return null;
}
@ -10,6 +10,4 @@ public sealed interface TargetPattern extends TargetExpression permits TargetCom
TargetPattern withType(TargetType type);
TargetType type();
TargetPattern withName(String name);
}

@ -7,9 +7,4 @@ 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);
}
}

@ -1,4 +1,6 @@
package de.dhbwstuttgart.target.tree.expression;
import de.dhbwstuttgart.target.tree.type.TargetType;
public record TargetWhile(TargetExpression cond, TargetExpression body) implements TargetExpression {
}

@ -4,29 +4,15 @@ import de.dhbwstuttgart.bytecode.FunNGenerator;
import java.util.List;
public record TargetFunNType(String name, List<TargetType> funNParams, List<TargetType> params, int returnArguments) implements TargetSpecializedType {
public record TargetFunNType(String name, List<TargetType> params) implements TargetSpecializedType {
public static TargetFunNType fromParams(List<TargetType> params, int returnArguments) {
return fromParams(params, params, returnArguments);
public static TargetFunNType fromParams(List<TargetType> params) {
return fromParams(params, params);
}
public static TargetFunNType fromParams(List<TargetType> params, List<TargetType> realParams, int returnArguments) {
public static TargetFunNType fromParams(List<TargetType> params, List<TargetType> realParams) {
var name = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
return new TargetFunNType(name, params, realParams, returnArguments);
}
public String toMethodDescriptor() {
var res = "(";
for (var i = 0; i < funNParams.size() - 1; i++) {
res += "Ljava/lang/Object;";
}
res += ")";
if (returnArguments > 0) {
res += "Ljava/lang/Object;";
} else {
res += "V";
}
return res;
return new TargetFunNType(name, realParams);
}
@Override

@ -53,17 +53,19 @@ public sealed interface TargetType
};
}
static TargetType toWrapper(TargetType f) {
if (f.equals(boolean_)) return Boolean;
if (f.equals(char_)) return Char;
if (f.equals(byte_)) return Byte;
if (f.equals(short_)) return Short;
if (f.equals(int_)) return Integer;
if (f.equals(long_)) return Long;
if (f.equals(float_)) return Float;
if (f.equals(double_)) return Double;
return f;
static TargetType toTargetType(Class<?> clazz) {
if (clazz.isPrimitive()) {
if (clazz.equals(boolean.class)) return boolean_;
if (clazz.equals(char.class)) return char_;
if (clazz.equals(byte.class)) return byte_;
if (clazz.equals(short.class)) return short_;
if (clazz.equals(int.class)) return int_;
if (clazz.equals(long.class)) return long_;
if (clazz.equals(float.class)) return float_;
if (clazz.equals(double.class)) return double_;
}
if (clazz.equals(void.class)) return null;
return new TargetRefType(clazz.getName());
}
String toSignature();

@ -13,7 +13,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class TypeInsertPlacer extends AbstractASTWalker {
public class TypeInsertPlacer extends AbstractASTWalker{
Set<TypeInsert> inserts = new HashSet<>();
private ResultSet withResults;
String pkgName;

@ -35,6 +35,7 @@ public class TypeInferenceBlockInformation extends TypeInferenceInformation {
public ClassOrInterface getSuperClass() {
for (var clazz : getAvailableClasses()) {
System.out.println(currentClass.getSuperClass().getName());
if (clazz.getClassName().equals(currentClass.getSuperClass().getName()))
return clazz;
}

@ -73,5 +73,5 @@ public class Constraint<A> extends HashSet<A> {
public String toStringBase() {
return super.toString();
}
}

@ -127,4 +127,5 @@ public class ConstraintSet<A> {
public Set<A> getUndConstraints() {
return undConstraints;
}
}

@ -136,8 +136,12 @@ public class Pair implements Serializable
public boolean OperatorSmallerDot() {
return eOperator == PairOperator.SMALLERDOT;
}
public boolean OperatorSmallerNEQDot() {
return eOperator == PairOperator.SMALLERNEQDOT;
}
static public Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
HashMap<String, TypePlaceholder> ret = new HashMap<>();
constraints.map((Pair p) -> {

@ -1,24 +1,21 @@
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.syntaxtree.type.*;
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.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
public class TYPE {
@ -31,16 +28,80 @@ public class TYPE {
}
public ConstraintSet getConstraints() {
ConstraintSet ret = new ConstraintSet();
ConstraintSet<Pair> ret = new ConstraintSet();
for (ClassOrInterface cl : sf.KlassenVektor) {
var allClasses = new HashSet<ClassOrInterface>();
allClasses.addAll(allAvailableClasses);
allClasses.addAll(sf.availableClasses);
ret.addAll(getConstraintsClass(cl, new TypeInferenceInformation(allClasses)));
}
writeASP(ret);
//System.exit(0);
return ret;
}
private String toASP(RefTypeOrTPHOrWildcardOrGeneric type){
if(type instanceof TypePlaceholder){
return "_"+((TypePlaceholder) type).getName();
}else if(type instanceof RefType){
if(((RefType) type).getParaList().size() > 0){
return ((RefType) type).getName() + "<" +
((RefType) type).getParaList().stream().map(this::toASP).collect(Collectors.joining(", ")) +
">";
}else{
return ((RefType) type).getName().toString();
}
}else if(type instanceof ExtendsWildcardType){
return toASP(((ExtendsWildcardType) type).getInnerType());
} else if(type instanceof SuperWildcardType) {
return toASP(((SuperWildcardType) type).getInnerType());
} else if(type instanceof GenericRefType){
return "G"+((GenericRefType) type).getParsedName();
}
throw new RuntimeException("Unsupported Type: "+ type);
}
private String genASP(Set<Pair> cs){
String ret = "";
for(Pair p : cs) {
if (p.OperatorEqual()) {
ret +=(toASP(p.TA1) + "=." + toASP(p.TA2) + "\n");
} else if (p.OperatorSmallerDot()) {
ret +=(toASP(p.TA1) + "<." + toASP(p.TA2) + "\n");
} else if (p.OperatorSmallerNEQDot()) {
ret += (toASP(p.TA1) + "<." + toASP(p.TA2) + "\n");
}else if(p.OperatorSmaller()){
ret += toASP(p.TA1) +"<"+toASP(p.TA2)+ "\n";
} else {
throw new RuntimeException("Operator unsupported: " + p.GetOperator());
}
}
return ret;
}
private void writeASP(ConstraintSet<Pair> cs){
try(var f = new FileWriter("/tmp/output")){
f.append(genASP(cs.getUndConstraints()));
List<List<Set<Pair>>> orCons = cs.getOderConstraints().stream().map(css -> {
return css.stream().map(cp -> {
return cp.stream().collect(Collectors.toSet());
}).collect(Collectors.toList());
}).toList();
for(var orCon : orCons){
f.append("{\n");
var it = orCon.iterator();
while(it.hasNext()) {
var orC = it.next();
f.append("{\n");
f.append(genASP(orC));
f.append("}\n");
if(it.hasNext())f.append("|");
}
f.append("}\n");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private ConstraintSet getConstraintsClass(ClassOrInterface cl, TypeInferenceInformation info) {
ConstraintSet ret = new ConstraintSet();
ConstraintSet methConstrains;
@ -86,53 +147,8 @@ 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);
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;
return methodScope.getConstraints();
}
private ConstraintSet getConstraintsConstructor(Constructor m, TypeInferenceInformation info, ClassOrInterface currentClass) {

@ -1,6 +1,7 @@
//PL 2018-12-19: Merge chekcen
package de.dhbwstuttgart.typeinference.typeAlgo;
import java.sql.Ref;
import java.util.*;
import java.util.stream.Collectors;
@ -47,13 +48,11 @@ 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.
*
*
* @return
*/
private static GenericsResolver getResolverInstance() {
@ -117,8 +116,6 @@ 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();
@ -130,6 +127,7 @@ 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));
@ -237,7 +235,7 @@ public class TYPEStmt implements StatementVisitor {
private final RefType doublee = new RefType(ASTFactory.createClass(Double.class).getClassName(), new NullToken());
private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken());
private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken());
private final RefType charr = new RefType(ASTFactory.createClass(Character.class).getClassName(), new NullToken());
@Override
@ -263,13 +261,13 @@ public class TYPEStmt implements StatementVisitor {
binary.lexpr.accept(this);
binary.rexpr.accept(this);
if (binary.operation.equals(BinaryExpr.Operator.DIV)
|| binary.operation.equals(BinaryExpr.Operator.MUL)
|| binary.operation.equals(BinaryExpr.Operator.MOD)
|| binary.operation.equals(BinaryExpr.Operator.ADD)
|| binary.operation.equals(BinaryExpr.Operator.SUB)
|| binary.operation.equals(BinaryExpr.Operator.OR)
|| binary.operation.equals(BinaryExpr.Operator.AND)
|| binary.operation.equals(BinaryExpr.Operator.XOR)) {
|| binary.operation.equals(BinaryExpr.Operator.MUL)
|| binary.operation.equals(BinaryExpr.Operator.MOD)
|| binary.operation.equals(BinaryExpr.Operator.ADD)
|| binary.operation.equals(BinaryExpr.Operator.SUB)
|| binary.operation.equals(BinaryExpr.Operator.OR)
|| binary.operation.equals(BinaryExpr.Operator.AND)
|| binary.operation.equals(BinaryExpr.Operator.XOR)) {
Set<Constraint<Pair>> numericAdditionOrStringConcatenation = new HashSet<>();
@ -332,7 +330,7 @@ public class TYPEStmt implements StatementVisitor {
}
/*
* PL auskommentiert Anfang 2018-07-17 /* In Java passiert bei den binären Operatoren eine sogenannte Type Promotion: https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 Das bedeutet, dass Java die Typen je nach belieben castet, so lange sie nur von Number erben
*
*
* numeric = new Constraint<>(); numeric.add(new Pair(binary.getType(), number, PairOperator.SMALLERDOT)); numericAdditionOrStringConcatenation.add(numeric); PL auskommentiert Ende 2018-07-17
*/
@ -356,7 +354,7 @@ public class TYPEStmt implements StatementVisitor {
* shortt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
* numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT)); numeric.add(new
* Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric);
*
*
* //***ACHTUNG: Moeglicherweise oder und und-Contraint falsch constraintsSet.addOderConstraint(numericRelationConcatenation); //***ACHTUNG: Moeglicherweise oder und und-Contraint falsch
*/
// Testeise eingefuegt PL 2018-05-24
@ -516,11 +514,6 @@ public class TYPEStmt implements StatementVisitor {
}
@Override
public void visit(Continue aContinue) {
}
@Override
public void visit(StaticClassName staticClassName) {
// Hier entstehen keine Constraints
@ -576,10 +569,7 @@ public class TYPEStmt implements StatementVisitor {
@Override
public void visit(DoStmt whileStmt) {
RefType booleanType = new RefType(ASTFactory.createClass(java.lang.Boolean.class).getClassName(), new NullToken());
whileStmt.expr.accept(this);
constraintsSet.addUndConstraint(new Pair(whileStmt.expr.getType(), booleanType, PairOperator.EQUALSDOT, loc(whileStmt.expr.getOffset())));
whileStmt.loopBlock.accept(this);
throw new NotImplementedException();
}
@Override
@ -630,14 +620,14 @@ public class TYPEStmt implements StatementVisitor {
public static RefTypeOrTPHOrWildcardOrGeneric getReceiverType(ClassOrInterface receiver, GenericsResolver resolver) {
if (receiver == null) return null;
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for (GenericTypeVar gtv : receiver.getGenerics()) {
for(GenericTypeVar gtv : receiver.getGenerics()){
//Die Generics werden alle zu TPHs umgewandelt.
params.add(resolver.resolve(new GenericRefType(gtv.getName(), new NullToken())));
}
RefTypeOrTPHOrWildcardOrGeneric receiverType;
if (receiver instanceof FunNClass) {
receiverType = new RefType(new JavaClassName(receiver.getClassName().toString() + "$$"), params, new NullToken()); // new FunN(params);
} else {
if(receiver instanceof FunNClass){
receiverType = new RefType(new JavaClassName(receiver.getClassName().toString()+"$$"), params, new NullToken()); // new FunN(params);
}else{
receiverType = new RefType(receiver.getClassName(), params, new NullToken());
}
@ -656,7 +646,7 @@ public class TYPEStmt implements StatementVisitor {
ClassOrInterface receiverCl = assumption.getReceiver();
/*
* List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); for(GenericTypeVar gtv : receiverCl.getGenerics()){ //Die Generics werden alle zu TPHs umgewandelt. params.add(resolver.resolve(gtv.getName())); }
*
*
* RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset());
*/
@ -778,7 +768,7 @@ public class TYPEStmt implements StatementVisitor {
// TODO: Hier müssen die Parameter mit den TPHs in den GEnerics des Receivers verknüpft werden
/*
* BEispiel: auto test = new List<String>(); test.add("hallo");
*
*
* Hier kriegt der Receiver ja den COnstraint TPH REceiver <. List<TPH A> Dann mus bei dem Parameter der COnstraint entstehen: TPH A <. String
*/
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
@ -823,10 +813,6 @@ 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()) {
@ -840,34 +826,7 @@ public class TYPEStmt implements StatementVisitor {
if (caseExpressionType == null) {
for (var child : switchStmt.getBlocks()) {
for (var label : child.getLabels()) {
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) {
if (label.getPattern() instanceof FormalParameter) {
constraintsSet.addUndConstraint(new Pair(label.getPattern().getType(), switchStmt.getSwitch().getType(), PairOperator.SMALLERDOT, loc(label.getOffset())));
}
}
@ -876,50 +835,14 @@ 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.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);
constraintsSet.addUndConstraint(new Pair(child.getType(), switchStmt.getType(), PairOperator.SMALLERDOT, loc(switchStmt.getOffset())));
}
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) {
@ -929,6 +852,7 @@ public class TYPEStmt implements StatementVisitor {
@Override
public void visit(SwitchLabel switchLabel) {
// TODO Auto-generated method stub
}
@Override

@ -53,8 +53,8 @@ public final class PlaceholderType extends UnifyType{
/**
* variance shows the variance of the pair
* 1: contravariant
* -1 covariant
* -1: contravariant
* 1 covariant
* 0 invariant
* PL 2018-03-21
*/
@ -77,14 +77,6 @@ public final class PlaceholderType extends UnifyType{
IsGenerated = false; // This type is user generated
}
public PlaceholderType(String name, int variance) {
super(name, new TypeParams());
EXISTING_PLACEHOLDERS.add(name); // Add to list of existing placeholder names
IsGenerated = false; // This type is user generated
this.variance = variance;
}
/**
* Creates a new placeholdertype
* @param isGenerated true if this placeholder is auto-generated, false if it is user-generated.

@ -1,7 +1,6 @@
import static org.junit.Assert.*;
import static targetast.TestCodegen.generateClassFiles;
import java.io.File;
import java.lang.reflect.Field;
@ -15,7 +14,6 @@ import org.junit.Test;
import com.google.common.collect.Lists;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
public class AllgemeinTest {
@ -65,10 +63,6 @@ public class AllgemeinTest {
//String className = "TripleTest";
//String className = "WildcardList";
String className = "List";
//String className = "Box";
//String className = "GenBox";
//String className = "InnerInf";
//String className = "Foo";
//PL 2019-10-24: genutzt fuer unterschiedliche Tests
path = System.getProperty("user.dir")+"/resources/AllgemeinTest/" + className + ".jav";
//path = System.getProperty("user.dir")+"/src/test/resources/AllgemeinTest/Overloading_Generics.jav";
@ -80,7 +74,7 @@ public class AllgemeinTest {
Lists.newArrayList(new File(System.getProperty("user.dir")+"/resources/bytecode/classFiles/")),
new File(System.getProperty("user.dir")+"/resources/bytecode/classFiles/"));
//*/
compiler.generateBytecode();
compiler.generateBytecode(new File(path));
pathToClassFile = System.getProperty("user.dir")+"/resources/bytecode/classFiles/";
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass(className);

@ -3,7 +3,9 @@ import de.dhbwstuttgart.environment.ByteArrayClassLoader;
import org.junit.Ignore;
import org.junit.Test;
import java.io.FileWriter;
import java.lang.reflect.*;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;
@ -11,7 +13,7 @@ import java.util.Vector;
import targetast.TestCodegen;
import static org.junit.Assert.*;
import static targetast.TestCodegen.generateClassFiles;
import static targetast.TestCodegen.generateClassFiles;
public class TestComplete {
@Test
@ -236,6 +238,9 @@ public class TestComplete {
@Test
//@Ignore("This is too complex")
public void matrixTest() throws Exception {
try(var f = new FileWriter("/tmp/output")){
f.append("hallo");
}
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Matrix.jav");
var matrix = classFiles.get("Matrix");
@ -601,18 +606,14 @@ public class TestComplete {
@Test
public void yTest() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Y.jav");
var fac1 = classFiles.get("Fac1");
var instance = fac1.getDeclaredConstructor().newInstance();
var fac = fac1.getDeclaredMethod("fac", Integer.class);
assertEquals(fac.invoke(instance, 10), 3628800);
var instance = classFiles.get("Y").getDeclaredConstructor().newInstance();
}
@Test
//@Ignore("This one isn't working")
@Ignore("This one isn't working")
public void boxTest() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Box.jav");
var instance = classFiles.get("Box").getDeclaredConstructor().newInstance();
var instance = classFiles.get("Box_Main").getDeclaredConstructor().newInstance();
}
@Test
@ -656,13 +657,6 @@ public class TestComplete {
System.out.println(clazz.getDeclaredMethod("toString").invoke(instance));
}
@Test
public void genericRecordTest() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "GenericRecord.jav");
var clazz = classFiles.get("GenericRecord");
var instance = clazz.getDeclaredConstructor(Object.class).newInstance((Object) null);
}
@Test
public void testSwitch() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Switch.jav");
@ -680,153 +674,9 @@ public class TestComplete {
assertEquals(swtch.invoke(instance, r2), 20);
assertEquals(swtch.invoke(instance, r3), 40);
assertEquals(swtch.invoke(instance, 50), 50);
try {
assertEquals(swtch.invoke(instance, "Some string"), 0);
fail("No assertion thrown!");
} catch (InvocationTargetException exception) {
assertTrue(exception.getCause() instanceof IllegalArgumentException);
assertEquals(exception.getCause().getMessage(), "Unhandled case value");
}
assertEquals(swtch.invoke(instance, "Some string"), 0);
}
@Test
public void testSwitchInfered() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchInfered.jav");
var clazz = classFiles.get("SwitchInfered");
var instance = clazz.getDeclaredConstructor().newInstance();
var swtch = clazz.getDeclaredMethod("main", Object.class);
var record = classFiles.get("Rec");
var ctor = record.getDeclaredConstructor(Object.class, Object.class);
var r1 = ctor.newInstance("asd", "asb");
assertEquals(swtch.invoke(instance, r1), "asd");
}
@Test
public void testSwitchAppend() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchAppend.jav");
var clazz = classFiles.get("SwitchAppend");
var listClass = classFiles.get("List");
var elemClass = classFiles.get("Elem");
var linkedElemClass = classFiles.get("LinkedElem");
var elemCtor = elemClass.getDeclaredConstructor(Object.class);
var listCtor = linkedElemClass.getDeclaredConstructor(Object.class, listClass);
var list1 = listCtor.newInstance("A", listCtor.newInstance("B", elemCtor.newInstance("C")));
var list2 = listCtor.newInstance("D", listCtor.newInstance("E", elemCtor.newInstance("F")));
var instance = clazz.getDeclaredConstructor().newInstance();
var appendMethod = clazz.getDeclaredMethod("append", linkedElemClass, listClass);
var res = appendMethod.invoke(instance, list2, list1);
var expected = listCtor.newInstance("D", listCtor.newInstance("E", listCtor.newInstance("F", listCtor.newInstance("A", listCtor.newInstance("B", elemCtor.newInstance("C"))))));
assertEquals(res, expected);
}
@Test
public void testSwitchRecordLiteral() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingLiteralStyle.jav");
var clazz = classFiles.get("SwitchOverload");
}
@Test
public void testSwitchCaseHeritageDetection() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchCaseHeritageDetection.jav");
var clazz = classFiles.get("SwitchCaseHeritageDetection");
var clazzAbst = classFiles.get("NumberOrText");
var clazzStringer = classFiles.get("Text");
var clazzNumber = classFiles.get("Number");
var instance = clazz.getDeclaredConstructor().newInstance();
var swtch = clazz.getDeclaredMethod("main", Object.class);
var record = classFiles.get("Cons");
var ctor = record.getDeclaredConstructor(Integer.class, clazzAbst.getConstructor().newInstance().getClass());
var r1 = ctor.newInstance(1, clazzStringer.getConstructor().newInstance());
var r2 = ctor.newInstance(1, clazzNumber.getConstructor().newInstance());
assertEquals(swtch.invoke(instance, r1), "Second Element is a Text");
assertEquals(swtch.invoke(instance, r2), "Second Element is a Number");
}
@Test
public void testSwitchListRecord() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchRecordList.jav");
var clazz = classFiles.get("SwitchCaseHeritageDetection");
var instance = clazz.getDeclaredConstructor().newInstance();
var swtch = clazz.getDeclaredMethod("main", Object.class);
var linkedElem = classFiles.get("LinkedElem");
var listInterface = classFiles.get("List");
var elem = classFiles.get("Elem");
var constructorLinkedElem = linkedElem.getDeclaredConstructor(Integer.class, listInterface);
var constructorElem = elem.getDeclaredConstructor(Integer.class);
var listWithMoreThanOneElement = constructorLinkedElem.newInstance(5, constructorLinkedElem.newInstance(1, constructorElem.newInstance(5)));
assertEquals(swtch.invoke(instance, listWithMoreThanOneElement), 11);
var listWithOneElement = constructorLinkedElem.newInstance(5, constructorElem.newInstance(5));
assertEquals(swtch.invoke(instance, listWithOneElement), 10);
}
@Test
public void testSwitchNestedValue() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchNestedValue.jav");
var clazz = classFiles.get("SwitchNestedValue");
var rec = classFiles.get("R");
var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("main", rec);
var ctor = rec.getDeclaredConstructor(Integer.class);
var r1 = ctor.newInstance(10);
var r2 = ctor.newInstance(20);
var r3 = ctor.newInstance(30);
assertEquals(m.invoke(instance, r1), 1);
assertEquals(m.invoke(instance, r2), 2);
assertEquals(m.invoke(instance, r3), 3);
}
@Test
public void testGenericRecordSwitchCase() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "GenericRecordSwitchCase.jav");
var clazz = classFiles.get("GenericRecordSwitchCase");
var instance = clazz.getDeclaredConstructor().newInstance();
var linkedElem = classFiles.get("LinkedElem");
var listInterface = classFiles.get("List");
var elem = classFiles.get("Elem");
var swtch = clazz.getDeclaredMethod("main", linkedElem);
var constructorLinkedElem = linkedElem.getConstructor(Object.class, listInterface);
var constructorElem = elem.getConstructor(Object.class);
var listWithMoreThanOneElement = constructorLinkedElem.newInstance(5, constructorLinkedElem.newInstance(1, constructorElem.newInstance(5)));
assertEquals(swtch.invoke(instance, listWithMoreThanOneElement), 5);
var listWithOneElement = constructorLinkedElem.newInstance(5, constructorElem.newInstance(5));
assertEquals(swtch.invoke(instance, listWithOneElement), 5);
}
@Ignore("Not implemented")
@Test
public void testSwitch2() throws Exception {
@ -856,6 +706,7 @@ public class TestComplete {
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Ignore("Not implemented")
@Test
public void testOverloadPattern() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OverloadPattern.jav");
@ -863,104 +714,12 @@ public class TestComplete {
var rec = classFiles.get("Point");
var instance = clazz.getDeclaredConstructor().newInstance();
var m1 = clazz.getDeclaredMethod("m", rec, rec);
var m2 = clazz.getDeclaredMethod("m", rec);
var m3 = clazz.getDeclaredMethod("m", Integer.class);
var m1 = clazz.getDeclaredMethod("m", rec);
var m2 = clazz.getDeclaredMethod("m", Integer.class);
var ptInt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(1, 2);
var ptFlt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(1f, 2f);
assertEquals(m1.invoke(instance, ptInt, ptFlt), 1);
assertEquals(m1.invoke(instance, ptInt, ptInt), 2);
assertEquals(m1.invoke(instance, ptFlt, ptInt), 3);
assertEquals(m1.invoke(instance, ptFlt, ptFlt), 4);
assertEquals(m2.invoke(instance, ptInt), 5);
assertEquals(m2.invoke(instance, ptFlt), 6);
assertEquals(m3.invoke(instance, 10), 10);
}
@Test
public void testOverloadNestedPattern() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OverloadNestedPattern.jav");
var clazz = classFiles.get("OverloadNestedPattern");
var rec = classFiles.get("R");
var instance = clazz.getDeclaredConstructor().newInstance();
var ctor = rec.getDeclaredConstructor(Object.class);
var r1 = ctor.newInstance(1);
var r2 = ctor.newInstance(r1);
var m = clazz.getDeclaredMethod("m", rec, rec);
assertEquals(m.invoke(instance, r2, r1), 1);
var r3 = ctor.newInstance(2f);
var r4 = ctor.newInstance(r3);
assertEquals(m.invoke(instance, r4, r3), 2);
assertEquals(m.invoke(instance, r1, r1), 3);
}
//@Ignore("Not implemented")
@Test
public void testPatternMatchingHaskellStyle() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingHaskellStyle.jav");
var clazz = classFiles.get("PatternMatchingHaskellStyle");
var R2 = classFiles.get("Elem");
var R = classFiles.get("LinkedElem");
var I = classFiles.get("List");
var rctor = R.getDeclaredConstructor(Object.class, I);
var r2ctor = R2.getDeclaredConstructor(Object.class);
var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("append$LLinkedElem$_$LTPH$_$LLinkedElem$_$LTPH$_$", R, Object.class);
var x = rctor.newInstance(rctor.newInstance(0, rctor.newInstance(0, r2ctor.newInstance(0))), r2ctor.newInstance(0));
var y = rctor.newInstance(r2ctor.newInstance(0), r2ctor.newInstance(0));
assertEquals(m.invoke(instance, x, y), null);
assertEquals(m.invoke(instance, y, y), null);
}
@Test
public void testPatternMatchingListAppend() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingListAppend.jav");
var clazz = classFiles.get("PatternMatchingListAppend");
var instance = clazz.getDeclaredConstructor().newInstance();
var Cons = classFiles.get("Cons");
var Empty = classFiles.get("Empty");
var List = classFiles.get("List");
var ConsCtor = Cons.getDeclaredConstructor(Object.class, List);
var EmptyCtor = Empty.getDeclaredConstructor();
var list1 = ConsCtor.newInstance(1, ConsCtor.newInstance(2, ConsCtor.newInstance(3, EmptyCtor.newInstance())));
var list2 = ConsCtor.newInstance(4, ConsCtor.newInstance(5, ConsCtor.newInstance(6, EmptyCtor.newInstance())));
var append = clazz.getDeclaredMethod("append", Cons, Cons);
System.out.println(append.invoke(instance, list1, list2));
}
@Test
public void testOverloadSwitch() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchOverload.jav");
var clazz = classFiles.get("SwitchOverload");
var R = classFiles.get("R");
var rctor = R.getDeclaredConstructor(Number.class);
var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("m", R, Integer.class);
var x = rctor.newInstance(10);
var d = rctor.newInstance(20.0);
assertEquals(m.invoke(instance, x, 0), 50);
assertEquals(m.invoke(instance, d, 0), 40.0);
var pt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(10, 20);
assertEquals(m1.invoke(instance, pt), 30);
assertEquals(m2.invoke(instance, 10), 10);
}
@Test
@ -969,7 +728,6 @@ public class TestComplete {
var clazz = classFiles.get("Interfaces");
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testStatic() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Static.jav");
@ -995,7 +753,7 @@ public class TestComplete {
var m = clazz.getDeclaredMethod("m");
assertEquals(m.invoke(instance), 6);
}
@Test
public void testLambdaRunnable() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "LambdaRunnable.jav");
@ -1106,6 +864,13 @@ public class TestComplete {
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testLamRunnable() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "LamRunnable.jav");
var clazz = classFiles.get("LamRunnable");
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testAccess() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Access.jav");
@ -1164,31 +929,6 @@ public class TestComplete {
assertEquals(clazz.getDeclaredMethod("main", Integer.class).invoke(instance, 5), "small");
}
@Test
public void testWhile() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "While.jav");
var clazz = classFiles.get("While");
var instance = clazz.getDeclaredConstructor().newInstance();
assertEquals(clazz.getDeclaredMethod("m", Integer.class).invoke(instance, 5), 5);
assertEquals(clazz.getDeclaredMethod("m2").invoke(instance), 10);
}
@Test
public void testImportWildcard() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "ImportWildcard.jav");
var clazz = classFiles.get("ImportWildcard");
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testAssign() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Assign.jav");
var clazz = classFiles.get("Assign");
var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("m");
assertEquals(m.invoke(instance), 20);
}
@Test
public void testBug122() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug122.jav");
@ -1349,7 +1089,6 @@ public class TestComplete {
var res = clazz.getDeclaredMethod("convert", List.class).invoke(instance, list);
assertEquals(res, List.of(6, 7, 8));
}
@Test
public void testBug325() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug325.jav");
@ -1373,40 +1112,4 @@ public class TestComplete {
var clazz = classFiles.get("Bug328");
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testBug332() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug332.jav");
var clazz = classFiles.get("Bug332");
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testBug333() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug333.jav");
var clazz = classFiles.get("Bug333");
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testBug337() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug337.jav");
var clazz = classFiles.get("Bug337");
var instance = clazz.getDeclaredConstructor().newInstance();
clazz.getDeclaredMethod("main").invoke(instance);
}
@Test
public void testBug338() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug338.jav");
var clazz = classFiles.get("Bug338");
var instance = clazz.getDeclaredConstructor().newInstance();
}
@Test
public void testBug343() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug343.jav");
var clazz = classFiles.get("Bug343");
var instance = clazz.getDeclaredConstructor().newInstance();
}
}

@ -57,7 +57,7 @@ public class ASTToTypedTargetAST {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Tph2.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(compiler, resultSet);
var converter = new ASTToTargetAST(resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();
var tphAndGenerics = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
@ -68,7 +68,7 @@ public class ASTToTypedTargetAST {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Cycle.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(compiler, resultSet);
var converter = new ASTToTargetAST(resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();
var cycle = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
@ -79,7 +79,7 @@ public class ASTToTypedTargetAST {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Infimum.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(compiler, resultSet);
var converter = new ASTToTargetAST(resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();
var infimum = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
@ -90,7 +90,7 @@ public class ASTToTypedTargetAST {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Gen.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(compiler, resultSet);
var converter = new ASTToTargetAST(resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();
var generics = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
@ -124,7 +124,7 @@ public class ASTToTypedTargetAST {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics2.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(compiler, resultSet);
var converter = new ASTToTargetAST(resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();
var generics2 = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
@ -140,7 +140,7 @@ public class ASTToTypedTargetAST {
var file = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/Generics3.jav").toFile();
var compiler = new JavaTXCompiler(file);
var resultSet = compiler.typeInference(file);
var converter = new ASTToTargetAST(compiler, resultSet);
var converter = new ASTToTargetAST(resultSet);
var classes = compiler.sourceFiles.get(file).getClasses();
var generics3 = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());

@ -60,8 +60,6 @@ public class TestCodegen {
}
}).collect(Collectors.toMap(Class::getName, Function.identity())));
converter.generateFunNTypes();
for (var entry : converter.auxiliaries.entrySet()) {
writeClassFile(entry.getKey(), entry.getValue());
}
@ -106,8 +104,6 @@ public class TestCodegen {
}
}).collect(Collectors.toMap(Class::getName, Function.identity()));
converter.generateFunNTypes();
for (var entry : converter.auxiliaries.entrySet()) {
writeClassFile(entry.getKey(), entry.getValue());
}
@ -220,19 +216,19 @@ public class TestCodegen {
public void testClassicSwitch() throws Exception {
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC , new JavaClassName("SwitchClassic"));
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "switchClassic", List.of(new MethodParameter(TargetType.Integer, "i")), TargetType.Integer, new TargetBlock(List.of(
new TargetVarDecl(TargetType.Integer, "res", null),
new TargetSwitch(new TargetLocalVar(TargetType.Integer, "i"), List.of(
new TargetSwitch.Case(List.of(new TargetLiteral.IntLiteral(10)), new TargetBlock(
List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "res"), new TargetLiteral.IntLiteral(0)), new TargetBreak())
)),
new TargetSwitch.Case(List.of(new TargetLiteral.IntLiteral(15), new TargetLiteral.IntLiteral(20)), new TargetBlock(List.of())),
new TargetSwitch.Case(List.of(new TargetLiteral.IntLiteral(30)), new TargetBlock(
List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "res"), new TargetLiteral.IntLiteral(1)), new TargetBreak())
))
), new TargetSwitch.Case(new TargetBlock(
List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "res"), new TargetLiteral.IntLiteral(2)), new TargetBreak())
), false)),
new TargetReturn(new TargetLocalVar(TargetType.Integer, "res"))
new TargetVarDecl(TargetType.Integer, "res", null),
new TargetSwitch(new TargetLocalVar(TargetType.Integer, "i"), List.of(
new TargetSwitch.Case(List.of(new TargetLiteral.IntLiteral(10)), new TargetBlock(
List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "res"), new TargetLiteral.IntLiteral(0)), new TargetBreak())
)),
new TargetSwitch.Case(List.of(new TargetLiteral.IntLiteral(15), new TargetLiteral.IntLiteral(20)), new TargetBlock(List.of())),
new TargetSwitch.Case(List.of(new TargetLiteral.IntLiteral(30)), new TargetBlock(
List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "res"), new TargetLiteral.IntLiteral(1)), new TargetBreak())
))
), new TargetSwitch.Case(new TargetBlock(
List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "res"), new TargetLiteral.IntLiteral(2)), new TargetBreak())
), false)),
new TargetReturn(new TargetLocalVar(TargetType.Integer, "res"))
)));
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
@ -248,22 +244,22 @@ public class TestCodegen {
public void testTypeSwitch() throws Exception {
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("SwitchEnhanced"));
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "switchType", List.of(new MethodParameter(TargetType.Object, "obj")), TargetType.Integer, new TargetBlock(List.of(
new TargetReturn(new TargetSwitch(new TargetLocalVar(TargetType.Object, "obj"), List.of(
new TargetSwitch.Case(List.of(new TargetTypePattern(TargetType.String, "aString")), new TargetBlock(
List.of(new TargetYield(new TargetLiteral.IntLiteral(0)))
), false),
new TargetSwitch.Case(List.of(
new TargetGuard(new TargetTypePattern(TargetType.Integer, "i"), new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10)))
), new TargetBlock(
List.of(new TargetLiteral.IntLiteral(3))
), true),
new TargetSwitch.Case(List.of(new TargetTypePattern(TargetType.Integer, "anInteger")), new TargetBlock(
List.of(new TargetLiteral.IntLiteral(1))
), true)
), new TargetSwitch.Case(new TargetBlock(
List.of(new TargetLiteral.IntLiteral(2))
), true), TargetType.Integer)
))));
new TargetReturn(new TargetSwitch(new TargetLocalVar(TargetType.Object, "obj"), List.of(
new TargetSwitch.Case(List.of(new TargetTypePattern(TargetType.String, "aString")), new TargetBlock(
List.of(new TargetYield(new TargetLiteral.IntLiteral(0)))
), false),
new TargetSwitch.Case(List.of(
new TargetGuard(new TargetTypePattern(TargetType.Integer, "i"), new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10)))
), new TargetBlock(
List.of(new TargetLiteral.IntLiteral(3))
), true),
new TargetSwitch.Case(List.of(new TargetTypePattern(TargetType.Integer, "anInteger")), new TargetBlock(
List.of(new TargetLiteral.IntLiteral(1))
), true)
), new TargetSwitch.Case(new TargetBlock(
List.of(new TargetLiteral.IntLiteral(2))
), true), TargetType.Integer)
))));
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
var m = clazz.getDeclaredMethod("switchType", Object.class);
assertEquals(m.invoke(null, "String"), 0);
@ -277,7 +273,7 @@ public class TestCodegen {
public void testLambda() throws Exception {
var classLoader = new ByteArrayClassLoader();
// var fun = classLoader.loadClass(Path.of(System.getProperty("user.dir"), "src/test/java/targetast/Fun1$$.class"));
var interfaceType = TargetFunNType.fromParams(List.of(TargetType.Integer), 1);
var interfaceType = TargetFunNType.fromParams(List.of(TargetType.Integer));
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("CGLambda"));
targetClass.addConstructor(Opcodes.ACC_PUBLIC, List.of(), new TargetBlock(List.of(new TargetMethodCall(null, new TargetSuper(TargetType.Object), List.of(), TargetType.Object, "<init>", false, false, false))));

@ -34,7 +34,7 @@ public class JavaTXCompilerTest {
@Test
public void importTest() throws IOException, ClassNotFoundException {
execute(new File(rootDirectory + "Import.jav"));
execute(new File(rootDirectory + "OrConsTest.jav"));
}
@Test

@ -0,0 +1,20 @@
import java.lang.Integer;
import java.lang.String;
class C1{
m(){return this;}
}
class C2{
m(){return this;}
}
public class OrConsTest {
ol(var1) {
return var1.m().m().m().m().m().m().m().m().m().m().m().m();
}
}