2
0

Compare commits

..

26 Commits

Author SHA1 Message Date
22d1be5ea4 Fixed expected AST for Instanceof.jav 2023-07-17 19:55:16 +02:00
18fc82f036 Merge branch 'patternMatching' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into patternMatching 2023-07-17 19:53:16 +02:00
f5b843ec11 Extended instanceOfTest 2023-07-17 19:52:30 +02:00
bad5d26969 Extended instanceOfTest 2023-07-17 19:50:58 +02:00
951d741d90 Added test for Sealed classe and interface ASTs 2023-07-17 19:38:01 +02:00
fe6c9858a2 Finalized test cases for new jav-files 2023-07-17 17:58:39 +02:00
1df354d5f1 Modified InstanceOf to use Pattern 2023-07-17 17:49:28 +02:00
6119bc92ed Corrected ASTPrinter for RecordPattern 2023-07-15 22:05:34 +02:00
e8140b3160 Added method stubs in visitors for new AST nodes 2023-07-15 21:41:50 +02:00
75789e574e Modified ASTPrinter to support new AST nodes for tests 2023-07-15 21:41:27 +02:00
c0c46e197f Added sealed classes to AST 2023-07-14 08:52:51 +02:00
1643412f1b Added nestedPatterns 2023-07-12 21:54:17 +02:00
3ed6edc323 Added SwitchExpression to AST 2023-07-12 21:43:50 +02:00
fa7a331a66 Beginning of switchExpression for AST 2023-07-11 22:15:35 +02:00
939d402b1e Changed GatherNames to add types declared inside of other types to the JavaClassRegistry 2023-07-07 09:24:45 +02:00
492cbe48e9 Created RecordPattern & started development with test cases 2023-07-06 22:15:40 +02:00
359f3e68ab Added SwitchStmt including Type & GuardedPattern to AST 2023-07-04 15:27:29 +02:00
1a89920430 Created AST node TypePattern and adapted test cases in TestNewFeatures 2023-06-28 22:52:18 +02:00
54a836b734 Added missing version to pom.xml 2023-06-28 22:12:28 +02:00
8b3b07e32c Added test case Record(.jav) in TestNewFeatures 2023-06-28 22:10:08 +02:00
24900b8fcc Added test case for instanceof in syntaxtreegenerator 2023-06-27 20:25:31 +02:00
2368a087c0 Added BoolExpression and instanceof to AST 2023-06-27 20:25:05 +02:00
994a1571b7 Changed resources path in TestCodegen after merge 2023-06-27 19:14:28 +02:00
aed1d3848b Resolved last merge conflict 2023-06-27 18:48:18 +02:00
93cf39cfe9 Merge branch 'bigRefactoring' into patternMatching 2023-06-27 18:46:57 +02:00
41d8e223ce Fixed wrong resources path in TestCodegen 2023-06-26 20:24:59 +02:00
49 changed files with 2108 additions and 480 deletions

10
pom.xml

@ -54,12 +54,8 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<version>3.11.0</version>
<configuration>
<compilerArgs>--enable-preview</compilerArgs>
<<<<<<< HEAD
<source>20</source>
<target>20</target>
=======
<release>20</release>
>>>>>>> patternMatching
</configuration>
</plugin>
<plugin>
@ -89,6 +85,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
@ -127,11 +124,6 @@ http://maven.apache.org/maven-v4_0_0.xsd">
</repository>
</repositories>
<properties>
<<<<<<< HEAD
<maven.compiler.source>20</maven.compiler.source>
<maven.compiler.target>20</maven.compiler.target>
=======
>>>>>>> patternMatching
<mainClass>de.dhbwstuttgart.core.ConsoleInterface</mainClass>
</properties>
<distributionManagement>

@ -0,0 +1,44 @@
class Instanceof {
Instanceof(){
super(());
}
void checkInstanceof(){
TPH a;
a = 4;
return a instanceof java.lang.Integer;
}
void checkInstanceOfWithPattern(){
TPH b;
b = 4.0;
if(b instanceof d)
{
return d;
}
else
{
return Kein Double;
};
}
void checkInstanceOfWithGuardedPattern(){
TPH obj;
obj = test;
TPH flag;
if(obj instanceof s op s.length Signature: [TPH]() op 5)
{
flag = s.contains Signature: [TPH, TPH](jdk);
};
return;
}
java.lang.Boolean equals(java.lang.Object o){
return o instanceof other op x op other.x op y op other.y;
}
Instanceof(){
super(());
}
}

@ -0,0 +1,120 @@
class Point {
java.lang.Integer x;
java.lang.Integer y;
Point(java.lang.Integer x, java.lang.Integer y){
super(());
this.x = x;
this.y = y;
}
java.lang.Integer x(){
return this.x;
}
java.lang.Integer y(){
return this.y;
}
Point(java.lang.Integer x, java.lang.Integer y){
super(());
this.x = x;
this.y = y;
}
}class Shape {
}class ColoredPoint {
Point pt;
java.lang.String color;
ColoredPoint(Point pt, java.lang.String color){
super(());
this.pt = pt;
this.color = color;
}
Point pt(){
return this.pt;
}
java.lang.String color(){
return this.color;
}
ColoredPoint(Point pt, java.lang.String color){
super(());
this.pt = pt;
this.color = color;
}
}class Rectangle {
ColoredPoint upperLeft;
ColoredPoint lowerRight;
Rectangle(ColoredPoint upperLeft, ColoredPoint lowerRight){
super(());
this.upperLeft = upperLeft;
this.lowerRight = lowerRight;
}
ColoredPoint upperLeft(){
return this.upperLeft;
}
ColoredPoint lowerRight(){
return this.lowerRight;
}
Rectangle(ColoredPoint upperLeft, ColoredPoint lowerRight){
super(());
this.upperLeft = upperLeft;
this.lowerRight = lowerRight;
}
}class Color {
Color(){
super(());
}
Color(){
super(());
}
}class Blue {
Blue(){
super(());
}
Blue(){
super(());
}
}class Red {
Red(){
super(());
}
Red(){
super(());
}
}class PatternMatching {
PatternMatching(){
super(());
}
void printColorOfUpperLeftPoint(Shape shape){
switch(shape){
case Rectangle(ColoredPoint(Point pt, java.lang.String color), ColoredPoint lowerRight):
System.out.println Signature: [TPH, TPH](x: op pt.x Signature: [TPH]() op / color: op color op / lowerRight: op lowerRight);
default:
System.out.println Signature: [TPH, TPH](not a rectangle);
};
return;
}
PatternMatching(){
super(());
}
}

@ -0,0 +1,47 @@
class Point {
TPH x;
TPH y;
Point(TPH x, TPH y){
super(());
this.x = x;
this.y = y;
}
TPH x(){
return this.x;
}
TPH y(){
return this.y;
}
Point(TPH x, TPH y){
super(());
this.x = x;
this.y = y;
}
}class Line {
TPH pt1;
TPH pt2;
Line(TPH pt1, TPH pt2){
super(());
this.pt1 = pt1;
this.pt2 = pt2;
}
TPH pt1(){
return this.pt1;
}
TPH pt2(){
return this.pt2;
}
Line(TPH pt1, TPH pt2){
super(());
this.pt1 = pt1;
this.pt2 = pt2;
}
}

@ -0,0 +1,144 @@
class Shape {
Shape(){
super(());
}
Shape(){
super(());
}
}class Circle {
Circle(){
super(());
}
Circle(){
super(());
}
}class Rectangle {
Rectangle(){
super(());
}
Rectangle(){
super(());
}
}class TransparentRectangle {
TransparentRectangle(){
super(());
}
TransparentRectangle(){
super(());
}
}class FilledRectangle {
FilledRectangle(){
super(());
}
FilledRectangle(){
super(());
}
}class Square {
Square(){
super(());
}
Square(){
super(());
}
}class WeirdShape {
WeirdShape(){
super(());
}
WeirdShape(){
super(());
}
}class Expr {
}class ConstantExpr {
java.lang.Integer i;
ConstantExpr(java.lang.Integer i){
super(());
this.i = i;
}
java.lang.Integer i(){
return this.i;
}
ConstantExpr(java.lang.Integer i){
super(());
this.i = i;
}
}class PlusExpr {
Expr a;
Expr b;
PlusExpr(Expr a, Expr b){
super(());
this.a = a;
this.b = b;
}
Expr a(){
return this.a;
}
Expr b(){
return this.b;
}
PlusExpr(Expr a, Expr b){
super(());
this.a = a;
this.b = b;
}
}class TimesExpr {
Expr a;
Expr b;
TimesExpr(Expr a, Expr b){
super(());
this.a = a;
this.b = b;
}
Expr a(){
return this.a;
}
Expr b(){
return this.b;
}
TimesExpr(Expr a, Expr b){
super(());
this.a = a;
this.b = b;
}
}class NegExpr {
Expr e;
NegExpr(Expr e){
super(());
this.e = e;
}
Expr e(){
return this.e;
}
NegExpr(Expr e){
super(());
this.e = e;
}
}

@ -0,0 +1,96 @@
class SwitchStatement {
SwitchStatement(){
super(());
}
TPH switchStandard(){
str = SwitchMe;
switch(str){
case java.lang.String s:
return true;
default:
return false;
};
}
TPH switchInteger(){
i = 5;
switch(i){
case java.lang.Integer j:
case java.lang.String s:
i = 6;
break;
default:
i = 0;
break;
};
return i op 0;
}
TPH guardedPattern(){
TPH i;
i = 1;
switch(i){
case java.lang.Integer j:
return true;
default:
return false;
};
}
TPH recordPattern(java.lang.Object obj){
switch(obj){
case Coordinates(java.lang.Double lat, java.lang.Double lon):
return true;
default:
return false;
};
}
SwitchStatement(){
super(());
}
}class SwitchExpression {
java.lang.Integer x;
java.lang.Integer y;
SwitchExpression(java.lang.Integer x, java.lang.Integer y){
super(());
this.x = x;
this.y = y;
}
java.lang.Integer x(){
return this.x;
}
java.lang.Integer y(){
return this.y;
}
java.lang.Boolean switchStandard(TPH str){
return switch(str){
case java.lang.String s:
yield true;
default:
yield false;
};
}
SwitchExpression(java.lang.Integer x, java.lang.Integer y){
super(());
this.x = x;
this.y = y;
}
}

@ -0,0 +1,36 @@
import java.lang.Integer;
import java.lang.Double;
import java.lang.String;
import java.lang.Object;
public class Instanceof{
void checkInstanceof() {
var a = 4;
return (a instanceof java.lang.Integer);
}
void checkInstanceOfWithPattern(){
var b = 4.0;
if(b instanceof java.lang.Double d){
return d;
}else{
return "Kein Double";
}
}
void checkInstanceOfWithGuardedPattern(){
var obj = "test";
var flag;
if (obj instanceof String s && s.length() > 5) {
flag = s.contains("jdk");
}
}
record Point(int x, int y){ }
boolean equals(Object o) {
return (o instanceof Point other)
&& x == other.x
&& y == other.y;
}
}

@ -0,0 +1,19 @@
import java.lang.String;
record Point(int x, int y) {}
interface Shape {}
record ColoredPoint(Point pt, String color) {}
record Rectangle(ColoredPoint upperLeft, ColoredPoint lowerRight) implements Shape {}
sealed class Color permits Blue, Red {}
class Blue extends Color {}
class Red extends Color {}
class PatternMatching {
void printColorOfUpperLeftPoint(Shape shape)
{
switch (shape) {
case Rectangle(ColoredPoint(Point pt, String color), ColoredPoint lowerRight) -> System.out.println("x: " + pt.x() + " / color: " + color + " / lowerRight: " + lowerRight);
default -> System.out.println("not a rectangle");
};
}
}

@ -0,0 +1,5 @@
// Simple records
record Point(x, y){ }
//Combination of records
record Line(pt1, pt2){}

@ -0,0 +1,21 @@
public abstract sealed class Shape
permits Circle, Rectangle, Square, WeirdShape { }
public final class Circle extends Shape { }
public sealed class Rectangle extends Shape
permits TransparentRectangle, FilledRectangle { }
public final class TransparentRectangle extends Rectangle { }
public final class FilledRectangle extends Rectangle { }
public final class Square extends Shape { }
public non-sealed class WeirdShape extends Shape { }
public sealed interface Expr
permits ConstantExpr, PlusExpr, TimesExpr, NegExpr { }
public record ConstantExpr(int i) implements Expr { }
public record PlusExpr(Expr a, Expr b) implements Expr { }
public record TimesExpr(Expr a, Expr b) implements Expr { }
public record NegExpr(Expr e) implements Expr { }

@ -0,0 +1,52 @@
import java.lang.Integer;
import java.lang.Boolean;
import java.lang.String;
import java.lang.Object;
class SwitchStatement {
switchStandard(){
str = "SwitchMe";
switch(str){
case String s: return true;
default: return false;
}
}
switchInteger(){
i = 5;
switch(i){
case Integer j:
case String s: i = 6; break;
default: i = 0; break;
}
return (i==0);
}
guardedPattern(){
var i = 1;
switch(i){
case Integer j && j == 1: return true;
default: return false;
}
}
record Coordinates(double x, double y) {}
recordPattern(Object obj){
switch(obj){
case Coordinates(double lat, double lon): return true;
default: return false;
}
}
}
record SwitchExpression(int x, int y){
boolean switchStandard(str){
return switch(str){
case String s -> yield true;
default -> yield false;
};
}
}

@ -199,11 +199,7 @@ interfaceMemberDeclaration
: constDeclaration # interfaceconst
| interfaceMethodDeclaration # interfacemethod
| genericInterfaceMethodDeclaration # genericinterfacemethod
| interfaceDeclaration # subinterface
| annotationTypeDeclaration # interfaceannotationtype
| classDeclaration # interfaceclass
| enumDeclaration # interfaceenum
| recordDeclaration # interfacerecord // Java17
| classOrInterface # subclassorinterface
;
constDeclaration
@ -391,11 +387,7 @@ annotationTypeElementDeclaration
annotationTypeElementRest
: typeType annotationMethodOrConstantRest ';'
| classDeclaration ';'?
| interfaceDeclaration ';'?
| enumDeclaration ';'?
| annotationTypeDeclaration ';'?
| recordDeclaration ';'? // Java17
| classOrInterface ';'?
;
annotationMethodOrConstantRest
@ -538,7 +530,6 @@ statement
| YIELD expression ';' #yieldstmt // Java17
| SEMI #semistmt
| statementExpression=expression ';' #stmtexpression
| switchExpression ';'? #switchexpressionstmt // Java17
| identifierLabel=identifier ':' statement #labeledstmt
;
@ -575,8 +566,10 @@ switchBlockStatementGroup
;
switchLabel
: CASE (constantExpression=expression | enumConstantName=IDENTIFIER | pattern) ':'
| DEFAULT ':'
: CASE constantExpression=expression ':' #switchLabelConst
| CASE enumConstantName=IDENTIFIER ':' #switchLabelEnum
| CASE pattern ':' #switchLabelPattern
| DEFAULT ':' #switchLabelDefault
;
forControl
@ -652,14 +645,14 @@ expression
// Java17
pattern
: primaryPattern
| guardedPattern
: primaryPattern #pPattern
| guardedPattern #gPattern
;
primaryPattern
: typePattern
| recordPattern
| '(' pattern ')'
: typePattern #tPattern
| recordPattern #rPattern
| '(' pattern ')' #enclosedPattern
;
recordPattern
@ -667,7 +660,7 @@ recordPattern
;
typePattern
: variableModifier* typeType? identifier
: variableModifier* typeType identifier
;
recordStructurePattern
@ -714,13 +707,19 @@ switchExpression
// Java17
switchLabeledRule
: CASE (expressionList | NULL_LITERAL | pattern) (ARROW | COLON) switchRuleOutcome
| DEFAULT (ARROW | COLON) switchRuleOutcome
: switchLabelCase switchRuleOutcome
;
switchLabelCase
: CASE expressionList (ARROW | COLON) #labeledRuleExprList
| CASE NULL_LITERAL (ARROW | COLON) #labeledRuleNull
| CASE pattern (ARROW | COLON) #labeledRulePattern
| DEFAULT (ARROW | COLON) #labeledRuleDefault
;
// Java17
guardedPattern
: variableModifier* typeType? annotation* identifier ('&&' expression)*
: variableModifier* typeType annotation* identifier ('&&' expression)*
| guardedPattern '&&' expression
;

@ -1,5 +1,6 @@
package de.dhbwstuttgart.bytecode;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.target.tree.*;
import de.dhbwstuttgart.target.tree.expression.*;
import de.dhbwstuttgart.target.tree.type.*;
@ -432,6 +433,10 @@ public class Codegen {
mv.visitInsn(IXOR);
break;
}
case Instof instof: {
// TODO
throw new NotImplementedException();
}
case Shl shl: {
generate(state, shl.left());
convertTo(state, shl.left().type(), op.type());
@ -547,6 +552,9 @@ public class Codegen {
}
break;
}
default: {
throw new NotImplementedException();
}
}
}

@ -20,6 +20,7 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser.AssignexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.BitwiseandexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.BitwiseorexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.BitwisexorexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.BlockStatementContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.BlockstmtContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.BoolLiteralContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.BreakstmtContext;
@ -34,8 +35,14 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser.EqualityexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ExpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.FltLiteralContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ForloopContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.GPatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.GuardedPatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.IdentifierContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.InstanceofexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.IntLiteralContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.LabeledRuleDefaultContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.LabeledRuleExprListContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.LabeledRulePatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.LabeledstmtContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.LambdaLVTIParameterContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.LambdaexpressionContext;
@ -46,30 +53,45 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodcallexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.NewinstanceexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.NullLiteralContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.OrexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PPatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PostfixexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrefixexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryClassrefContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryExpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryIdentifierContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryLiteralContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryPatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimarySuperContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryThisContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.RPatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.RecordPatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.RelationalexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ReturnstmtContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SemistmtContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ShiftexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.StmtexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.StringLiteralContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchexpressionstmtContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchBlockStatementGroupContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchLabelConstContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchLabelContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchLabelDefaultContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchLabelPatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchLabeledRuleContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchRuleOutcomeContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchstmtContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SynchronizedstmtContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.TPatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ThrowstmtContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.TrycatchblockContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.TrycatchresourceContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.TypePatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.WhileloopContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.YieldstmtContext;
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.ParameterList;
@ -79,12 +101,16 @@ import de.dhbwstuttgart.syntaxtree.statement.AssignLeftSide;
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.BoolExpression;
import de.dhbwstuttgart.syntaxtree.statement.Break;
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.statement.ExpressionReceiver;
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
import de.dhbwstuttgart.syntaxtree.statement.GuardedPattern;
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
import de.dhbwstuttgart.syntaxtree.statement.InstanceOf;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import de.dhbwstuttgart.syntaxtree.statement.Literal;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
@ -92,14 +118,20 @@ import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
import de.dhbwstuttgart.syntaxtree.statement.NewClass;
import de.dhbwstuttgart.syntaxtree.statement.Receiver;
import de.dhbwstuttgart.syntaxtree.statement.RecordPattern;
import de.dhbwstuttgart.syntaxtree.statement.Return;
import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid;
import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.statement.StaticClassName;
import de.dhbwstuttgart.syntaxtree.statement.Super;
import de.dhbwstuttgart.syntaxtree.statement.Switch;
import de.dhbwstuttgart.syntaxtree.statement.SwitchBlock;
import de.dhbwstuttgart.syntaxtree.statement.SwitchLabel;
import de.dhbwstuttgart.syntaxtree.statement.This;
import de.dhbwstuttgart.syntaxtree.statement.Pattern;
import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr;
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
import de.dhbwstuttgart.syntaxtree.statement.Yield;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
@ -162,8 +194,6 @@ public class StatementGenerator {
return convert(dowhileloop);
case SwitchstmtContext switchstmt:
return convert(switchstmt);
case SwitchexpressionstmtContext switchexpression:
return convert(switchexpression);
case ReturnstmtContext returnstmt:
return convert(returnstmt);
case YieldstmtContext yieldstmt:
@ -243,6 +273,10 @@ public class StatementGenerator {
ret = convert(prefix);
ret.setStatement();
return ret;
case SwitchexpressionContext switchexpr:
ret = convert(switchexpr);
ret.setStatement();
return ret;
default:
throw new NotImplementedException();
}
@ -317,23 +351,146 @@ public class StatementGenerator {
}
private Statement convert(Java17Parser.SwitchstmtContext stmt) {
// TODO
throw new NotImplementedException();
Expression switched = convert(stmt.parExpression().expression());
List<SwitchBlock> switchBlocks = new ArrayList<>();
for (SwitchBlockStatementGroupContext blockstmt : stmt.switchBlockStatementGroup()) {
switchBlocks.add(convert(blockstmt));
}
return new Switch(switched, switchBlocks, switched.getType(), true, stmt.getStart());
}
private Statement convert(Java17Parser.SwitchexpressionstmtContext switchexpression) {
// TODO
throw new NotImplementedException();
// Um switchExpressions als Statement zu behandeln
private Statement convert(Java17Parser.SwitchexpressionContext switchexpression) {
Expression switchExpr = convert(switchexpression.switchExpression());
if (switchExpr instanceof Switch s) {
s.setStatement();
return s;
} else {
// sollte nie vorkommen, da convert(Java17Parser.SwitchExpressionContext switchExpression) eine Instanz von Switch zurückgibt
throw new RuntimeException();
}
}
private Expression convert(Java17Parser.SwitchExpressionContext switchExpression) {
Expression switched = convert(switchExpression.parExpression().expression());
List<SwitchBlock> switchBlocks = new ArrayList<>();
Token offset = switchExpression.getStart();
for (SwitchLabeledRuleContext labeledRule : switchExpression.switchLabeledRule()) {
switchBlocks.add(convert(labeledRule));
}
return new Switch(switched, switchBlocks, TypePlaceholder.fresh(offset), false, offset);
}
private SwitchBlock convert(Java17Parser.SwitchLabeledRuleContext labeledRule) {
Boolean isDefault = false;
List<SwitchLabel> labels = switch (labeledRule.switchLabelCase()) {
case LabeledRuleExprListContext exprList -> {
List<SwitchLabel> labelList = exprList.expressionList().expression().stream().map((exprctx) -> {
Expression expr = convert(exprctx);
return new SwitchLabel(expr, expr.getType(), exprList.getStart());
}).toList();
yield labelList;
}
case LabeledRulePatternContext pattern -> {
Expression p = convert(pattern.pattern());
yield Arrays.asList(new SwitchLabel(p, p.getType(), pattern.getStart()));
}
case LabeledRuleDefaultContext def -> {
isDefault = true;
yield Arrays.asList(new SwitchLabel(TypePlaceholder.fresh(def.getStart()), def.getStart()));
}
default -> throw new NotImplementedException();
};
Token offset = labeledRule.getStart();
SwitchRuleOutcomeContext outcome = labeledRule.switchRuleOutcome();
Block block;
if (Objects.isNull(outcome.block())) {
List<Statement> stmts = new ArrayList<>();
outcome.blockStatement().stream().forEach((stmt) -> {
stmts.addAll(convert(stmt));
});
block = new Block(stmts, outcome.blockStatement(0).getStart());
} else {
block = convert(outcome.block(), false);
}
return new SwitchBlock(labels, block, isDefault, offset);
}
private Statement convert(Java17Parser.YieldstmtContext yieldstmt) {
// TODO
throw new NotImplementedException();
return new Yield(convert(yieldstmt.expression()), yieldstmt.getStart());
}
private Statement convert(Java17Parser.SwitchBlockStatementGroupContext stmt) {
// TODO
throw new NotImplementedException();
private SwitchBlock convert(Java17Parser.SwitchBlockStatementGroupContext stmt) {
List<SwitchLabel> labels = new ArrayList<>();
stmt.switchLabel().forEach((label) -> {
labels.add(convert(label));
});
List<Statement> block = new ArrayList<>();
stmt.blockStatement().stream().forEach((blockStmt) -> {
block.addAll(convert(blockStmt));
});
return new SwitchBlock(labels, new Block(block, stmt.blockStatement(0).getStart()), stmt.getStart());
}
private SwitchLabel convert(SwitchLabelContext switchLabel) {
Expression caseExpression = switch (switchLabel) {
case SwitchLabelConstContext cons -> {
yield convert(cons.constantExpression);
}
case SwitchLabelPatternContext pattern -> {
yield convert(pattern.pattern());
}
case SwitchLabelDefaultContext def -> {
yield null;
}
default -> throw new NotImplementedException();
};
Token offset = switchLabel.getStart();
if (Objects.isNull(caseExpression)) {
return new SwitchLabel(TypePlaceholder.fresh(offset), offset);
} else {
return new SwitchLabel(caseExpression, caseExpression.getType(), offset);
}
}
private Pattern convert(PatternContext pattern) {
return switch (pattern) {
case PPatternContext pPattern -> {
yield convert(pPattern.primaryPattern());
}
case GPatternContext gPattern -> {
GuardedPatternContext guarded = gPattern.guardedPattern();
List<Expression> conditions = guarded.expression().stream().map((expr) -> {
return convert(expr);
}).toList();
yield new GuardedPattern(conditions, guarded.identifier().getText(), TypeGenerator.convert(guarded.typeType(), reg, generics), guarded.getStart());
}
default -> throw new NotImplementedException();
};
}
private Pattern convert(PrimaryPatternContext pPattern) {
switch (pPattern) {
case TPatternContext tPattern:
TypePatternContext typePattern = tPattern.typePattern();
return new Pattern(typePattern.identifier().getText(), TypeGenerator.convert(typePattern.typeType(), reg, generics), typePattern.getStart());
case RPatternContext rPattern:
RecordPatternContext recordPattern = rPattern.recordPattern();
return convert(recordPattern);
default:
throw new NotImplementedException();
}
}
private RecordPattern convert(RecordPatternContext recordPatternCtx) {
List<PatternContext> subPatternCtx = recordPatternCtx.recordStructurePattern().recordComponentPatternList().pattern();
List<Pattern> subPattern = subPatternCtx.stream().map((patternCtx) -> {
return convert(patternCtx);
}).collect(Collectors.toList());
IdentifierContext identifierCtx = recordPatternCtx.identifier();
return new RecordPattern(subPattern, (identifierCtx != null) ? identifierCtx.getText() : null, TypeGenerator.convert(recordPatternCtx.typeType(), reg, generics), recordPatternCtx.getStart());
}
private Statement convert(Java17Parser.WhileloopContext stmt) {
@ -414,8 +571,13 @@ public class StatementGenerator {
}
private Statement convert(Java17Parser.BreakstmtContext stmt) {
// TODO
throw new NotImplementedException();
Token offset = stmt.getStart();
if (!Objects.isNull(stmt.identifier())) {
return new Break(localVars.get(stmt.identifier().getText()), offset);
} else {
return new Break(TypePlaceholder.fresh(offset), offset);
}
}
private Statement convert(Java17Parser.ContinuestmtContext stmt) {
@ -482,9 +644,10 @@ public class StatementGenerator {
return convert(mathexpr);
case RelationalexpressionContext comparison:
return convert(comparison);
/*
* TODO: syntaxtree for instanceof vorbereiten case InstanceofexpressionContext instanceof: case SwitchexpressionContext switchexpression:
*/
case InstanceofexpressionContext instanceOf:
return convert(instanceOf);
case SwitchexpressionContext switchexpression:
return convert(switchexpression.switchExpression());
case EqualityexpressionContext equal:
return convert(equal);
case AssignexpressionContext assignment:
@ -588,16 +751,14 @@ public class StatementGenerator {
// 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), 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), offset);
} else {
// kann eigentlich nicht vorkommen
// Dann Muss es ein Feld sein!
return new FieldVar(new This(offset), expression, TypePlaceholder.fresh(offset), 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);
@ -636,11 +797,19 @@ public class StatementGenerator {
}
private Expression convert(Java17Parser.OrexpressionContext expression) {
throw new NotImplementedException();
if (expression.expression().size() != 2) {
throw new NotImplementedException();
} else {
return new BoolExpression(BoolExpression.Operator.OR, new RefType(new JavaClassName("java.lang.Boolean"), expression.getStart()), convert(expression.expression(0)), convert(expression.expression(1)), expression.getStart());
}
}
private Expression convert(Java17Parser.AndexpressionContext expression) {
throw new NotImplementedException();
if (expression.expression().size() != 2) {
throw new NotImplementedException();
} else {
return new BoolExpression(BoolExpression.Operator.AND, new RefType(new JavaClassName("java.lang.Boolean"), expression.getStart()), convert(expression.expression(0)), convert(expression.expression(1)), expression.getStart());
}
}
private Statement convert(AssignexpressionContext expr) {
@ -700,6 +869,30 @@ public class StatementGenerator {
return new BinaryExpr(convertBinaryOperator(operator), TypePlaceholder.fresh(expression.getStart()), convert(expression.expression(0)), convert(expression.expression(1)), expression.getStart());
}
private Expression convert(Java17Parser.InstanceofexpressionContext expression) {
Expression left = convert(expression.expression());
Token offset = expression.getStart();
if (Objects.isNull(expression.pattern())) {
return new InstanceOf(left, TypeGenerator.convert(expression.typeType(), reg, generics), offset);
} else {
switch (expression.pattern()) {
case PPatternContext primaryPattern:
switch (primaryPattern.primaryPattern()) {
case TPatternContext typePattern:
TypePatternContext typePatternCtx = typePattern.typePattern();
String localVarName = typePatternCtx.identifier().getText();
RefTypeOrTPHOrWildcardOrGeneric localVarType = TypeGenerator.convert(typePatternCtx.typeType(), reg, generics);
localVars.put(localVarName, localVarType);
return new InstanceOf(left, new Pattern(localVarName, localVarType, typePatternCtx.getStart()), offset);
default:
throw new NotImplementedException();
}
default:
throw new NotImplementedException();
}
}
}
private BinaryExpr.Operator convertBinaryOperator(String operator) {
// return BinaryExpr.Operator.ADD;
if (operator.equals("+")) {

@ -85,6 +85,7 @@ 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;
public class SyntaxTreeGenerator {
private JavaClassRegistry reg;
@ -220,21 +221,16 @@ public class SyntaxTreeGenerator {
}
// Ist Bit für 'sealed'-Modifier gesetzt
if ((modifiers & 4096) != 0) {
switch (ctx.typeList().size()) {
case 1: {
permittedSubtypes.addAll(convert(ctx.typeList(0), generics));
break;
}
case 2: {
permittedSubtypes.addAll(convert(ctx.typeList(1), generics));
break;
}
default: {
break;
}
if (!Objects.isNull(ctx.PERMITS())) {
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
} else {
// falls sealed modifier ohne 'permits'-List oder umgekehrt
throw new NotImplementedException("Invalid sealed class declaration");
}
}
return new ClassOrInterface(modifiers, name, fielddecl, Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), name, superClass, genericClassParameters, offset)), methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
return new ClassOrInterface(modifiers, name, fielddecl, Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), name, superClass, genericClassParameters, offset)), methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, permittedSubtypes, offset);
}
private de.dhbwstuttgart.syntaxtree.Record convertRecord(RecordDeclarationContext recordDeclaration, int modifiers) {
@ -388,7 +384,18 @@ public class SyntaxTreeGenerator {
if (!Objects.isNull(ctx.EXTENDS())) {
extendedInterfaces.addAll(convert(ctx.typeList(0), generics));
}
return new ClassOrInterface(modifiers, name, fields, Optional.empty(), methods, new ArrayList<>(), genericParams, superClass, true, extendedInterfaces, ctx.getStart());
List<RefType> permittedSubtypes = new ArrayList<>();
// Ist Bit für 'sealed'-Modifier gesetzt
if ((modifiers & 4096) != 0) {
if (!Objects.isNull(ctx.PERMITS())) {
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
} else {
// falls sealed modifier ohne 'permits'-List oder umgekehrt
throw new NotImplementedException("Invalid sealed class declaration");
}
}
return new ClassOrInterface(modifiers, name, fields, Optional.empty(), methods, new ArrayList<>(), genericParams, superClass, true, extendedInterfaces, permittedSubtypes, ctx.getStart());
}
private GenericDeclarationList createEmptyGenericDeclarationList(Token classNameIdentifier) {

@ -65,6 +65,8 @@ public class TypeGenerator {
return new RefType(ASTFactory.createClass(Boolean.class).getClassName(), typeContext.getStart());
case "int":
return new RefType(ASTFactory.createClass(Integer.class).getClassName(), typeContext.getStart());
case "double":
return new RefType(ASTFactory.createClass(Double.class).getClassName(), typeContext.getStart());
default:
throw new NotImplementedException();
}

@ -1,88 +1,136 @@
package de.dhbwstuttgart.parser.scope;
import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.antlr.v4.runtime.ParserRuleContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassorinterfacedeclContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.NoclassorinterfaceContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext;
import de.dhbwstuttgart.environment.PackageCrawler;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.antlr.Java17Parser;
import de.dhbwstuttgart.parser.antlr.Java17Parser.AnnotationTypeElementDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassBodyContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassBodyDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassOrInterfaceContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassorinterfacedeclContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.EnumConstantContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.EnumConstantsContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfaceBodyDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfacememberContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberclassorinterfaceContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberdeclContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.NoclassorinterfaceContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SubclassorinterfaceContext;
public class GatherNames {
public static Map<String, Integer> getNames(SrcfileContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
Map<String, Integer> ret = new HashMap<>();
String pkgName = getPackageName(ctx);
String nameString = "";
for (Java17Parser.ClassOrInterfaceContext member : ctx.classOrInterface()) {
if (member instanceof NoclassorinterfaceContext) {
for (Java17Parser.ClassOrInterfaceContext clsoifctx : ctx.classOrInterface()) {
if (clsoifctx instanceof NoclassorinterfaceContext) {
continue;
}
ClassorinterfacedeclContext clsoif = (ClassorinterfacedeclContext) member;
String fullname = clsoif.getChild(clsoif.getChildCount() - 1).getClass().getName();
String classname = fullname.substring(fullname.indexOf("$") + 1);
int numGenerics = 0;
/*
* Es werden alle Namen gesammelt, die syntaktisch von Java-TX (sprich der Grammatik) erkannt werden. Auch wenn z.B. Annotationen oder Enumerationen noch nicht im Compiler implementiert sind. Die "NotImplementedException" wird dann im "SyntaxTreeGenerator" geworfen. Das Statement soll als Vorbereitung dienen, für den Fall, dass weitere Sprachkonstrukte in den Compiler aufgenommen werden.
*/
switch (classname) {
case "ClassDeclarationContext":
if (!pkgName.isEmpty()) {
nameString = pkgName + "." + clsoif.classDeclaration().identifier().getText();
} else {
nameString = clsoif.classDeclaration().identifier().getText();
}
numGenerics = clsoif.classDeclaration().genericDeclarationList() != null ? clsoif.classDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
ret.put(nameString, numGenerics);
break;
case "EnumDeclarationContext":
if (!pkgName.isEmpty()) {
nameString = pkgName + "." + clsoif.enumDeclaration().identifier().getText();
} else {
nameString = clsoif.enumDeclaration().identifier().getText();
}
numGenerics = 0;
ret.put(nameString, numGenerics);
break;
case "InterfaceDeclarationContext":
if (pkgName != "") {
nameString = pkgName + "." + clsoif.interfaceDeclaration().identifier().getText();
} else {
nameString = clsoif.interfaceDeclaration().identifier().getText();
}
numGenerics = clsoif.interfaceDeclaration().genericDeclarationList() != null ? clsoif.interfaceDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
ret.put(nameString, numGenerics);
break;
case "AnnotationTypeDeclarationContext":
if (pkgName != "") {
nameString = pkgName + "." + clsoif.annotationTypeDeclaration().identifier().getText();
} else {
nameString = clsoif.annotationTypeDeclaration().identifier().getText();
}
numGenerics = 0;
ret.put(nameString, numGenerics);
break;
case "RecordDeclarationContext":
if (pkgName != "") {
nameString = pkgName + "." + clsoif.recordDeclaration().identifier().getText();
} else {
nameString = clsoif.recordDeclaration().identifier().getText();
}
numGenerics = clsoif.recordDeclaration().genericDeclarationList() != null ? clsoif.recordDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
ret.put(nameString, numGenerics);
break;
default:
throw new NotImplementedException();
}
ret.putAll(getNames(clsoifctx, getPackageName(ctx), packages, classLoader));
}
ret.putAll(getImports(ctx, packages, classLoader));
return ret;
}
public static Map<String, Integer> getNames(ClassOrInterfaceContext clsoifctx, String pkgName, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
Map<String, Integer> ret = new HashMap<>();
ClassorinterfacedeclContext clsoif = (ClassorinterfacedeclContext) clsoifctx;
String nameString = "";
String fullname = clsoif.getChild(clsoif.getChildCount() - 1).getClass().getName();
String classname = fullname.substring(fullname.indexOf("$") + 1);
int numGenerics = 0;
/*
* Es werden alle Namen gesammelt, die syntaktisch von Java-TX (sprich der Grammatik) erkannt werden. Auch wenn z.B. Annotationen oder Enumerationen noch nicht im Compiler implementiert sind. Die "NotImplementedException" wird dann im "SyntaxTreeGenerator" geworfen. Das Statement soll als Vorbereitung dienen, für den Fall, dass weitere Sprachkonstrukte in den Compiler aufgenommen werden.
*/
switch (classname) {
case "ClassDeclarationContext":
if (!pkgName.isEmpty()) {
nameString = pkgName + "." + clsoif.classDeclaration().identifier().getText();
} else {
nameString = clsoif.classDeclaration().identifier().getText();
}
numGenerics = clsoif.classDeclaration().genericDeclarationList() != null ? clsoif.classDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
ret.put(nameString, numGenerics);
ret.putAll(getNames(clsoif.classDeclaration().classBody().classBodyDeclaration(), pkgName, packages, classLoader));
break;
case "EnumDeclarationContext":
if (!pkgName.isEmpty()) {
nameString = pkgName + "." + clsoif.enumDeclaration().identifier().getText();
} else {
nameString = clsoif.enumDeclaration().identifier().getText();
}
numGenerics = 0;
ret.put(nameString, numGenerics);
EnumConstantsContext enumConstants = clsoif.enumDeclaration().enumConstants();
if (!Objects.isNull(enumConstants)) {
for (EnumConstantContext enumConstant : enumConstants.enumConstant()) {
ClassBodyContext enumConstClassBody = enumConstant.classBody();
if (!Objects.isNull(enumConstClassBody)) {
ret.putAll(getNames(enumConstClassBody.classBodyDeclaration(), pkgName, packages, classLoader));
}
}
}
break;
case "InterfaceDeclarationContext":
if (pkgName != "") {
nameString = pkgName + "." + clsoif.interfaceDeclaration().identifier().getText();
} else {
nameString = clsoif.interfaceDeclaration().identifier().getText();
}
numGenerics = clsoif.interfaceDeclaration().genericDeclarationList() != null ? clsoif.interfaceDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
ret.put(nameString, numGenerics);
for (InterfaceBodyDeclarationContext ifbody : clsoif.interfaceDeclaration().interfaceBody().interfaceBodyDeclaration()) {
if (ifbody instanceof InterfacememberContext member && member.interfaceMemberDeclaration() instanceof SubclassorinterfaceContext sub) {
ret.putAll(getNames(sub.classOrInterface(), pkgName, packages, classLoader));
}
}
break;
case "AnnotationTypeDeclarationContext":
if (pkgName != "") {
nameString = pkgName + "." + clsoif.annotationTypeDeclaration().identifier().getText();
} else {
nameString = clsoif.annotationTypeDeclaration().identifier().getText();
}
numGenerics = 0;
ret.put(nameString, numGenerics);
for (AnnotationTypeElementDeclarationContext anTypeElem : clsoif.annotationTypeDeclaration().annotationTypeBody().annotationTypeElementDeclaration()) {
ClassOrInterfaceContext anClsoifctx = anTypeElem.annotationTypeElementRest().classOrInterface();
if (!Objects.isNull(anClsoifctx)) {
ret.putAll(getNames(anClsoifctx, pkgName, packages, classLoader));
}
}
break;
case "RecordDeclarationContext":
if (pkgName != "") {
nameString = pkgName + "." + clsoif.recordDeclaration().identifier().getText();
} else {
nameString = clsoif.recordDeclaration().identifier().getText();
}
numGenerics = clsoif.recordDeclaration().genericDeclarationList() != null ? clsoif.recordDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
ret.put(nameString, numGenerics);
ret.putAll(getNames(clsoif.recordDeclaration().recordBody().classBodyDeclaration(), pkgName, packages, classLoader));
break;
default:
throw new NotImplementedException();
}
return ret;
}
public static Map<String, Integer> getNames(List<ClassBodyDeclarationContext> clsBodyDecl, String pkgName, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
Map<String, Integer> ret = new HashMap<>();
for (ClassBodyDeclarationContext clsbody : clsBodyDecl) {
if (clsbody instanceof MemberdeclContext member && member.memberDeclaration() instanceof MemberclassorinterfaceContext memberclsoifctx) {
ret.putAll(getNames(memberclsoifctx.classOrInterface(), pkgName, packages, classLoader));
}
}
return ret;
}
public static Map<String, Integer> getImports(Java17Parser.SrcfileContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
Map<String, Integer> ret = new HashMap<>();
// ret.putAll(packages.getClassNames("java.lang"));

@ -2,10 +2,10 @@ package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.statement.Literal;
import de.dhbwstuttgart.syntaxtree.type.*;
import java.util.Iterator;
import java.util.Objects;
public abstract class AbstractASTWalker implements ASTVisitor {
@Override
@ -134,6 +134,11 @@ public abstract class AbstractASTWalker implements ASTVisitor {
}
@Override
public void visit(BoolExpression logical) {
}
@Override
public void visit(Block block) {
for (Statement stmt : block.getStatements()) {
@ -164,7 +169,8 @@ public abstract class AbstractASTWalker implements ASTVisitor {
@Override
public void visit(IfStmt ifStmt) {
ifStmt.then_block.accept(this);
ifStmt.else_block.accept(this);
if (!Objects.isNull(ifStmt.else_block))
ifStmt.else_block.accept(this);
}
@Override
@ -269,4 +275,47 @@ public abstract class AbstractASTWalker implements ASTVisitor {
public void visit(SuperCall superCall) {
this.visit((MethodCall) superCall);
}
@Override
public void visit(Switch switchStmt) {
switchStmt.getSwitch().accept(this);
switchStmt.getBlocks().stream().forEach((switchBlock) -> {
switchBlock.accept(this);
});
}
@Override
public void visit(SwitchBlock switchBlock) {
switchBlock.getLabels().stream().forEach((label) -> {
label.accept(this);
});
switchBlock.getStatements().stream().forEach((stmt) -> {
stmt.accept(this);
});
}
@Override
public void visit(SwitchLabel switchLabel) {
}
@Override
public void visit(Yield aYield) {
aYield.accept(this);
}
@Override
public void visit(Pattern aPattern) {
}
@Override
public void visit(RecordPattern aRecordPattern) {
}
@Override
public void visit(GuardedPattern aGuardedPattern) {
}
}

@ -24,96 +24,95 @@ import java.util.Optional;
/**
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
*/
public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
private Boolean methodAdded = false; //wird benoetigt bei in JavaTXCompiler.getConstraints()
public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
private Boolean methodAdded = false; // wird benoetigt bei in JavaTXCompiler.getConstraints()
protected int modifiers;
protected JavaClassName name;
private List<Field> fields = new ArrayList<>();
private Optional<Constructor> fieldInitializations; //PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen
private Optional<Constructor> fieldInitializations; // PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen
private List<Method> methods = new ArrayList<>();
private GenericDeclarationList genericClassParameters;
private RefType superClass;
protected boolean isInterface;
private List<RefType> implementedInterfaces;
private List<RefType> permittedSubtypes;
private List<Constructor> constructors;
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters,
RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset){
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset) {
super(offset);
if(isInterface && !Modifier.isInterface(modifiers))modifiers += Modifier.INTERFACE;
this.modifiers = modifiers;
this.name = name;
this.fields = fielddecl;
this.fieldInitializations= fieldInitializations;
if (isInterface && !Modifier.isInterface(modifiers))
modifiers += Modifier.INTERFACE;
this.modifiers = modifiers;
this.name = name;
this.fields = fielddecl;
this.fieldInitializations = fieldInitializations;
this.genericClassParameters = genericClassParameters;
this.superClass = superClass;
this.superClass = superClass;
this.isInterface = isInterface;
this.implementedInterfaces = implementedInterfaces;
this.implementedInterfaces = implementedInterfaces;
this.permittedSubtypes = permittedSubtypes;
this.methods = methods;
this.constructors = constructors;
}
/* erzeugt fuer Fields, Konstruktoren und Methoden neue ArrayList-Objekte
* alle anderen Datenobjekte werden nur kopiert.
/*
* erzeugt fuer Fields, Konstruktoren und Methoden neue ArrayList-Objekte alle anderen Datenobjekte werden nur kopiert.
*/
public ClassOrInterface(ClassOrInterface cl){
super(cl.getOffset());
this.modifiers = cl.modifiers;
this.name = cl.name;
this.fields = new ArrayList<>(cl.fields);
this.fieldInitializations= cl.fieldInitializations;
this.genericClassParameters = cl.genericClassParameters;
this.superClass = cl.superClass;
this.isInterface = cl.isInterface;
this.implementedInterfaces = cl.implementedInterfaces;
this.methods = new ArrayList<>(cl.methods);
this.constructors = new ArrayList<>(cl.constructors);
public ClassOrInterface(ClassOrInterface cl) {
super(cl.getOffset());
this.modifiers = cl.modifiers;
this.name = cl.name;
this.fields = new ArrayList<>(cl.fields);
this.fieldInitializations = cl.fieldInitializations;
this.genericClassParameters = cl.genericClassParameters;
this.superClass = cl.superClass;
this.isInterface = cl.isInterface;
this.implementedInterfaces = cl.implementedInterfaces;
this.methods = new ArrayList<>(cl.methods);
this.constructors = new ArrayList<>(cl.constructors);
}
//Gets if it is added
// Gets if it is added
public Boolean areMethodsAdded() {
return methodAdded;
return methodAdded;
}
//Sets that it is added
// Sets that it is added
public void setMethodsAdded() {
methodAdded = true;
methodAdded = true;
}
// Gets class name
public JavaClassName getClassName(){
public JavaClassName getClassName() {
return this.name;
}
// Get modifiers
public int getModifiers(){
public int getModifiers() {
return this.modifiers;
}
public List<Field> getFieldDecl(){
public List<Field> getFieldDecl() {
return this.fields;
}
public Optional<Constructor> getfieldInitializations(){
return this.fieldInitializations;
}
public List<Method> getMethods(){
public Optional<Constructor> getfieldInitializations() {
return this.fieldInitializations;
}
public List<Method> getMethods() {
return this.methods;
}
/*
public RefType getType() {
return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset());
}
*/
//TODO: Das hier ist ein Problem. Je nach Kontext wird hier ein anderer Typ benötigt
public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass ,Token offset){
//Hier wird immer ein generischer Typ generiert, also mit Type placeholdern
* public RefType getType() { return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset()); }
*/
// TODO: Das hier ist ein Problem. Je nach Kontext wird hier ein anderer Typ benötigt
public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass, Token offset) {
// Hier wird immer ein generischer Typ generiert, also mit Type placeholdern
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar genericTypeVar : genericsOfClass){
//params.add(genericTypeVar.getTypePlaceholder());
for (GenericTypeVar genericTypeVar : genericsOfClass) {
// params.add(genericTypeVar.getTypePlaceholder());
params.add(TypePlaceholder.fresh(offset));
}
return new RefType(name, params, offset);
@ -123,18 +122,18 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
*
* @return die aktuelle Klasse als RefType
*/
public RefType generateTypeOfThisClass(){
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar genericTypeVar : this.getGenerics()){
//params.add(genericTypeVar.getTypePlaceholder());
params.add(new GenericRefType(genericTypeVar.getName(), new NullToken()));
}
return new RefType(name, params, new NullToken());
}
public RefType generateTypeOfThisClass() {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for (GenericTypeVar genericTypeVar : this.getGenerics()) {
// params.add(genericTypeVar.getTypePlaceholder());
params.add(new GenericRefType(genericTypeVar.getName(), new NullToken()));
}
return new RefType(name, params, new NullToken());
}
/**
* Die Superklasse im Kontext dieser ClassOrInterface
* Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind
*/
* Die Superklasse im Kontext dieser ClassOrInterface Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind
*/
public RefType getSuperClass() {
return superClass;
}
@ -160,8 +159,8 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
public Collection<RefType> getSuperInterfaces() {
return implementedInterfaces;
}
public String toString() {
return this.name.toString() + this.genericClassParameters.toString();
return this.name.toString() + this.genericClassParameters.toString();
}
}

@ -1,5 +1,6 @@
package de.dhbwstuttgart.syntaxtree;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@ -11,6 +12,6 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
public class Record extends ClassOrInterface {
public Record(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset) {
super(modifiers, name, fielddecl, fieldInitializations, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
super(modifiers, name, fielddecl, fieldInitializations, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, new ArrayList<>(), offset);
}
}

@ -13,6 +13,8 @@ public interface StatementVisitor {
void visit(BinaryExpr binary);
void visit(BoolExpression logical);
void visit(Block block);
void visit(CastExpr castExpr);
@ -41,8 +43,22 @@ public interface StatementVisitor {
void visit(ReturnVoid aReturn);
void visit(Switch switchStmt);
void visit(SwitchBlock switchBlock);
void visit(SwitchLabel switchLabel);
void visit(Break aBreak);
void visit(Yield aYield);
void visit(Pattern aPattern);
void visit(RecordPattern aRecordPattern);
void visit(GuardedPattern aGuardedPattern);
void visit(StaticClassName staticClassName);
void visit(Super aSuper);

@ -29,13 +29,11 @@ import org.objectweb.asm.signature.SignatureReader;
import org.objectweb.asm.signature.SignatureVisitor;
/**
* Anmerkung:
* Die ASTFactory Methoden, welche ASTBäume aus java.lang.Class Objekten generieren, können davon ausgehen,
* dass alle Imports und Typnamen korrekt sind und müssen diese nicht überprüfen.
* Anmerkung: Die ASTFactory Methoden, welche ASTBäume aus java.lang.Class Objekten generieren, können davon ausgehen, dass alle Imports und Typnamen korrekt sind und müssen diese nicht überprüfen.
*/
public class ASTFactory {
public static ClassOrInterface createClass(java.lang.Class jreClass){
public static ClassOrInterface createClass(java.lang.Class jreClass) {
// TODO Inner classes
@ -82,7 +80,7 @@ public class ASTFactory {
}
};
classReader.accept(classVisitor, new Attribute[]{new JavaTXSignatureAttribute()}, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
classReader.accept(classVisitor, new Attribute[] { new JavaTXSignatureAttribute() }, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
classSignature = classVisitor.classSignature;
}
} catch (IOException e) {
@ -92,7 +90,7 @@ public class ASTFactory {
JavaClassName name = new JavaClassName(jreClass.getName());
List<Method> methoden = new ArrayList<>();
List<de.dhbwstuttgart.syntaxtree.Constructor> konstruktoren = new ArrayList<>();
for(java.lang.reflect.Constructor constructor : jreClass.getConstructors()){
for (java.lang.reflect.Constructor constructor : jreClass.getConstructors()) {
var signature = methodSignatures.get(new Pair<>(constructor.getName(), org.objectweb.asm.Type.getConstructorDescriptor(constructor)));
createConstructor(constructor, signature, jreClass).map(c -> konstruktoren.add(c));
}
@ -100,65 +98,72 @@ public class ASTFactory {
Set<java.lang.reflect.Method> allDeclaredMethods = new HashSet<>(Arrays.asList(jreClass.getDeclaredMethods()));
Set<java.lang.reflect.Method> allInheritedMethods = new HashSet<>(allMethods);
allInheritedMethods.removeAll(allDeclaredMethods);
for(java.lang.reflect.Method method : allDeclaredMethods){
for (java.lang.reflect.Method method : allDeclaredMethods) {
var signature = methodSignatures.get(new Pair<>(method.getName(), org.objectweb.asm.Type.getMethodDescriptor(method)));
methoden.add(createMethod(method, signature, jreClass, false));
}
for(java.lang.reflect.Method method : allInheritedMethods){
for (java.lang.reflect.Method method : allInheritedMethods) {
var signature = methodSignatures.get(new Pair<>(method.getName(), org.objectweb.asm.Type.getMethodDescriptor(method)));
methoden.add(createMethod(method, signature, jreClass, true));
}
List<Field> felder = new ArrayList<>();
for(java.lang.reflect.Field field : jreClass.getDeclaredFields()){
for (java.lang.reflect.Field field : jreClass.getDeclaredFields()) {
felder.add(createField(field, name));
}
int modifier = jreClass.getModifiers();
boolean isInterface = jreClass.isInterface();
//see: https://stackoverflow.com/questions/9934774/getting-generic-parameter-from-supertype-class
// see: https://stackoverflow.com/questions/9934774/getting-generic-parameter-from-supertype-class
ParameterizedType parameterSuperClass = null;
Type tempSuperClass = jreClass.getGenericSuperclass();
if(tempSuperClass != null && tempSuperClass instanceof ParameterizedType)
if (tempSuperClass != null && tempSuperClass instanceof ParameterizedType)
parameterSuperClass = (ParameterizedType) tempSuperClass;
java.lang.Class superjreClass = jreClass.getSuperclass();
RefType superClass;
if(parameterSuperClass != null){
if (parameterSuperClass != null) {
superClass = (RefType) createType(parameterSuperClass);
}else if(superjreClass != null){
} else if (superjreClass != null) {
superClass = (RefType) createType(superjreClass);
}else{//Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!)
} else {// Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!)
superClass = (RefType) createType(java.lang.Object.class);
}
List<RefType> implementedInterfaces = new ArrayList<>();
for(Type jreInterface : jreClass.getGenericInterfaces()){
for (Type jreInterface : jreClass.getGenericInterfaces()) {
implementedInterfaces.add((RefType) createType(jreInterface));
}
List<RefType> permittedSubtypes = new ArrayList<>();
if (jreClass.isSealed()) {
for (Class subclass : jreClass.getPermittedSubclasses()) {
permittedSubtypes.add((RefType) createType(subclass));
}
}
GenericDeclarationList genericDeclarationList = createGenerics(jreClass.getTypeParameters(), jreClass, null, classSignature);
GenericDeclarationList genericDeclarationList = createGenerics(jreClass.getTypeParameters(), jreClass, null, classSignature);
Token offset = new NullToken(); //Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
Token offset = new NullToken(); // Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
return new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */,methoden, konstruktoren, genericDeclarationList, superClass,isInterface, implementedInterfaces, offset);
return new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */, methoden, konstruktoren, genericDeclarationList, superClass, isInterface, implementedInterfaces, permittedSubtypes, offset);
}
private static Field createField(java.lang.reflect.Field field, JavaClassName jreClass) {
return new Field(field.getName(), createType(field.getGenericType()), field.getModifiers(), new NullToken());
}
//private static RefType createType(Class classType) {
// return createClass(classType).getType();
//}
// private static RefType createType(Class classType) {
// return createClass(classType).getType();
// }
private static Optional<de.dhbwstuttgart.syntaxtree.Constructor> createConstructor(Constructor constructor, String signature, Class inClass) {
private static Optional<de.dhbwstuttgart.syntaxtree.Constructor> createConstructor(Constructor constructor, String signature, Class inClass) {
String name = constructor.getName();
RefTypeOrTPHOrWildcardOrGeneric returnType = createType(inClass);
Parameter[] jreParams = constructor.getParameters();
Type[] jreGenericParams = constructor.getGenericParameterTypes();
List<FormalParameter> params = new ArrayList<>();
int i = 0;
for(Type jreParam : jreGenericParams){
if (jreParam == null) continue;
for (Type jreParam : jreGenericParams) {
if (jreParam == null)
continue;
RefTypeOrTPHOrWildcardOrGeneric paramType = createType(jreParam);
params.add(new FormalParameter(jreParams[i].getName(),paramType, new NullToken()));
params.add(new FormalParameter(jreParams[i].getName(), paramType, new NullToken()));
i++;
}
ParameterList parameterList = new ParameterList(params, new NullToken());
@ -167,20 +172,20 @@ public class ASTFactory {
Token offset = new NullToken();
int modifier = constructor.getModifiers();
if(inClass.equals(java.lang.Object.class)){
if (inClass.equals(java.lang.Object.class)) {
return Optional.empty();
}
return Optional.of(new de.dhbwstuttgart.syntaxtree.Constructor(modifier, name,returnType, parameterList, block, gtvDeclarations, offset /*, new ArrayList<>() geloescht PL 2018-11-24 */));
return Optional.of(new de.dhbwstuttgart.syntaxtree.Constructor(modifier, name, returnType, parameterList, block, gtvDeclarations, offset /* , new ArrayList<>() geloescht PL 2018-11-24 */));
}
public static Method createMethod(java.lang.reflect.Method jreMethod, String signature, java.lang.Class inClass, Boolean isInherited){
public static Method createMethod(java.lang.reflect.Method jreMethod, String signature, java.lang.Class inClass, Boolean isInherited) {
String name = jreMethod.getName();
RefTypeOrTPHOrWildcardOrGeneric returnType;
Type jreRetType;
if(jreMethod.getGenericReturnType()!=null){
if (jreMethod.getGenericReturnType() != null) {
jreRetType = jreMethod.getGenericReturnType();
}else{
} else {
jreRetType = jreMethod.getReturnType();
}
returnType = createType(jreRetType);
@ -188,24 +193,25 @@ public class ASTFactory {
Type[] jreGenericParams = jreMethod.getGenericParameterTypes();
List<FormalParameter> params = new ArrayList<>();
int i = 0;
for(Type jreParam : jreGenericParams){
if (jreParam == null) continue;
for (Type jreParam : jreGenericParams) {
if (jreParam == null)
continue;
RefTypeOrTPHOrWildcardOrGeneric paramType = createType(jreParam);
params.add(new FormalParameter(jreParams[i].getName(),paramType, new NullToken()));
params.add(new FormalParameter(jreParams[i].getName(), paramType, new NullToken()));
i++;
}
ParameterList parameterList = new ParameterList(params, new NullToken());
Block block = new Block(new ArrayList<Statement>(), new NullToken());
GenericDeclarationList gtvDeclarations = createGenerics(jreMethod.getTypeParameters(), inClass, jreMethod.getName(), signature);
GenericDeclarationList gtvDeclarations = createGenerics(jreMethod.getTypeParameters(), inClass, jreMethod.getName(), signature);
Token offset = new NullToken();
return new Method(jreMethod.getModifiers(), name,returnType, parameterList, block, gtvDeclarations, offset, isInherited);
return new Method(jreMethod.getModifiers(), name, returnType, parameterList, block, gtvDeclarations, offset, isInherited);
}
public static GenericDeclarationList createGenerics(TypeVariable[] typeParameters, Class context, String methodName, String signature) {
if (signature == null) {
List<de.dhbwstuttgart.syntaxtree.GenericTypeVar> gtvs = new ArrayList<>();
for(TypeVariable jreTV : typeParameters){
for (TypeVariable jreTV : typeParameters) {
de.dhbwstuttgart.syntaxtree.GenericTypeVar gtv = createGeneric(jreTV, jreTV.getName(), context, methodName);
gtvs.add(gtv);
}
@ -217,7 +223,8 @@ public class ASTFactory {
}
public static GenericDeclarationList createGenerics(String signature) {
if (signature == null) return new GenericDeclarationList(new ArrayList<>(), new NullToken());
if (signature == null)
return new GenericDeclarationList(new ArrayList<>(), new NullToken());
var gtvs = new ArrayList<GenericTypeVar>();
var signatureVisitor = new SignatureVisitor(Opcodes.ASM7) {
@ -226,7 +233,8 @@ public class ASTFactory {
final Stack<RefType> classTypes = new Stack<>();
// All hail the mighty visitor pattern
final SignatureVisitor doNothing = new SignatureVisitor(Opcodes.ASM7) {};
final SignatureVisitor doNothing = new SignatureVisitor(Opcodes.ASM7) {
};
char wildcard = '=';
@ -334,61 +342,61 @@ public class ASTFactory {
return new GenericDeclarationList(gtvs, new NullToken());
}
private static RefTypeOrTPHOrWildcardOrGeneric createType(java.lang.reflect.Type type){
if(type == null || type.getTypeName().equals("void")){
private static RefTypeOrTPHOrWildcardOrGeneric createType(java.lang.reflect.Type type) {
if (type == null || type.getTypeName().equals("void")) {
return new Void(new NullToken());
}else if(type.getTypeName().equals("int")){
} else if (type.getTypeName().equals("int")) {
return new RefType(new JavaClassName("java.lang.Integer"), new ArrayList<>(), new NullToken());
}else if(type.getTypeName().equals("byte")){
} else if (type.getTypeName().equals("byte")) {
return new RefType(new JavaClassName("java.lang.Byte"), new ArrayList<>(), new NullToken());
}else if(type.getTypeName().equals("boolean")){
} else if (type.getTypeName().equals("boolean")) {
return new RefType(new JavaClassName("java.lang.Boolean"), new ArrayList<>(), new NullToken());
}else if(type.getTypeName().equals("char")){
} else if (type.getTypeName().equals("char")) {
return new RefType(new JavaClassName("java.lang.Char"), new ArrayList<>(), new NullToken());
}else if(type.getTypeName().equals("short")){
} else if (type.getTypeName().equals("short")) {
return new RefType(new JavaClassName("java.lang.Short"), new ArrayList<>(), new NullToken());
}else if(type.getTypeName().equals("double")){
} else if (type.getTypeName().equals("double")) {
return new RefType(new JavaClassName("java.lang.Double"), new ArrayList<>(), new NullToken());
}else if(type.getTypeName().equals("long")){
} else if (type.getTypeName().equals("long")) {
return new RefType(new JavaClassName("java.lang.Long"), new ArrayList<>(), new NullToken());
}else{
if(type instanceof TypeVariable){
//GTVDeclarationContext via "(TypeVariable) type).getGenericDeclaration()"
} else {
if (type instanceof TypeVariable) {
// GTVDeclarationContext via "(TypeVariable) type).getGenericDeclaration()"
return new GenericRefType(type.getTypeName(), new NullToken());
}
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
if(type instanceof ParameterizedType){
for(Type t : ((ParameterizedType)type).getActualTypeArguments()){
if (type instanceof ParameterizedType) {
for (Type t : ((ParameterizedType) type).getActualTypeArguments()) {
params.add(createType(t));
}
}
String name = type.getTypeName();
if(name.contains("<")){ //Komischer fix. Type von Generischen Typen kann die Generics im Namen enthalten Type<A>
//Diese entfernen:
if (name.contains("<")) { // Komischer fix. Type von Generischen Typen kann die Generics im Namen enthalten Type<A>
// Diese entfernen:
name = name.split("<")[0];
}
if(type instanceof java.lang.reflect.WildcardType){
if (type instanceof java.lang.reflect.WildcardType) {
java.lang.reflect.WildcardType wildcardType = (java.lang.reflect.WildcardType) type;
if(wildcardType.getLowerBounds().length > 0){
if (wildcardType.getLowerBounds().length > 0) {
return new SuperWildcardType(createType(wildcardType.getLowerBounds()[0]), new NullToken());
}else if(wildcardType.getUpperBounds().length > 0){
} else if (wildcardType.getUpperBounds().length > 0) {
return new ExtendsWildcardType(createType(wildcardType.getUpperBounds()[0]), new NullToken());
}else{//Es handelt sich um den '?'-Typ:
} else {// Es handelt sich um den '?'-Typ:
return new ExtendsWildcardType(createObjectType(), new NullToken());
}
}else{
} else {
RefType ret = new RefType(new JavaClassName(name), params, new NullToken());
return ret;
}
}
}
public static de.dhbwstuttgart.syntaxtree.GenericTypeVar createGeneric(TypeVariable jreTypeVar, String jreTVName, Class context, String parentMethod){
public static de.dhbwstuttgart.syntaxtree.GenericTypeVar createGeneric(TypeVariable jreTypeVar, String jreTVName, Class context, String parentMethod) {
JavaClassName parentClass = new JavaClassName(context.getName());
List<RefTypeOrTPHOrWildcardOrGeneric> genericBounds = new ArrayList<>();
java.lang.reflect.Type[] bounds = jreTypeVar.getBounds();
if(bounds.length > 0){
for(java.lang.reflect.Type bound : bounds){
if (bounds.length > 0) {
for (java.lang.reflect.Type bound : bounds) {
genericBounds.add(createType(bound));
}
}
@ -403,49 +411,27 @@ public class ASTFactory {
return new RefType(createClass(Object.class).getClassName(), new NullToken());
}
/*
public Constructor createEmptyConstructor(Class parent){
Block block = new Block();
block.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0));
block.statements.add(new SuperCall(block));
return ASTFactory.createConstructor(parent, new ParameterList(), block);
}
public static Constructor createConstructor(Class superClass, ParameterList paralist, Block block){
block.parserPostProcessing(superClass);
Method method = ASTFactory.createMethod("<init>", paralist, block, superClass);
method.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0));
return new Constructor(method, superClass);
}
public static Class createClass(String className, RefType type, Modifiers modifiers, Menge supertypeGenPara, SourceFile parent) {
// TODO bytecode createClass
//String name, RefType superClass, Modifiers modifiers, Menge<String> supertypeGenPara
Class generatedClass = new Class(className, type, modifiers, supertypeGenPara);
generatedClass.addField(ASTFactory.createEmptyConstructor(generatedClass));
generatedClass.parserPostProcessing(parent);
return generatedClass;
}
public static Class createObject(){
return createClass(java.lang.Object.class);
}
public static Class createInterface(String className, RefType superClass, Modifiers modifiers,
Menge supertypeGenPara, SourceFile parent){
Class generatedClass = new Class(new JavaClassName(className), new ArrayList<Method>(), new ArrayList<Field>(), modifiers,
true, superClass, new ArrayList<RefType>(), new GenericDeclarationList(), -1);
generatedClass.parserPostProcessing(parent);
return generatedClass;
}
public static RefType createObjectType(){
return createObjectClass().getType();
}
*/
/*
* public Constructor createEmptyConstructor(Class parent){ Block block = new Block(); block.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0)); block.statements.add(new SuperCall(block));
*
* return ASTFactory.createConstructor(parent, new ParameterList(), block); }
*
* public static Constructor createConstructor(Class superClass, ParameterList paralist, Block block){ block.parserPostProcessing(superClass);
*
* Method method = ASTFactory.createMethod("<init>", paralist, block, superClass); method.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0));
*
* return new Constructor(method, superClass); }
*
* public static Class createClass(String className, RefType type, Modifiers modifiers, Menge supertypeGenPara, SourceFile parent) { // TODO bytecode createClass //String name, RefType superClass, Modifiers modifiers, Menge<String> supertypeGenPara Class generatedClass = new Class(className, type, modifiers, supertypeGenPara); generatedClass.addField(ASTFactory.createEmptyConstructor(generatedClass));
*
* generatedClass.parserPostProcessing(parent);
*
* return generatedClass; }
*
* public static Class createObject(){ return createClass(java.lang.Object.class); }
*
* public static Class createInterface(String className, RefType superClass, Modifiers modifiers, Menge supertypeGenPara, SourceFile parent){ Class generatedClass = new Class(new JavaClassName(className), new ArrayList<Method>(), new ArrayList<Field>(), modifiers, true, superClass, new ArrayList<RefType>(), new GenericDeclarationList(), -1); generatedClass.parserPostProcessing(parent); return generatedClass; }
*
* public static RefType createObjectType(){ return createObjectClass().getType(); }
*/
}

@ -15,15 +15,16 @@ public class BinaryExpr extends Expression {
SUB, // -
MUL, // *
MOD, // Modulo Operator %
AND, // &&
OR, // ||
AND, // &
OR, // |
DIV, // /
LESSTHAN, // <
BIGGERTHAN, // >
LESSEQUAL, // <=
BIGGEREQUAL, // >=
EQUAL, // ==
NOTEQUAL // !=
NOTEQUAL, // !=
INSTOF // instanceof
}
public final Operator operation;

@ -1,26 +1,22 @@
package de.dhbwstuttgart.syntaxtree.statement;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import org.antlr.v4.runtime.Token;
public class Block extends Statement
{
public class Block extends Statement {
public Block(List<Statement> statements, Token offset) {
super(TypePlaceholder.fresh(offset), offset);
this.statements = statements;
}
super(TypePlaceholder.fresh(offset), offset);
this.statements = statements;
}
public List<Statement> statements = new ArrayList<>();
public List<Statement> getStatements()
{
public List<Statement> getStatements() {
return statements;
}
@ -29,5 +25,3 @@ public class Block extends Statement
visitor.visit(this);
}
}

@ -0,0 +1,31 @@
package de.dhbwstuttgart.syntaxtree.statement;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class BoolExpression extends Expression {
public enum Operator {
AND, // &&
OR, // ||
}
public final Operator operation;
public final Expression lexpr;
public final Expression rexpr;
public BoolExpression(Operator operation, RefTypeOrTPHOrWildcardOrGeneric type, Expression lexpr, Expression rexpr, Token offset) {
super(type, offset);
this.operation = operation;
this.lexpr = lexpr;
this.rexpr = rexpr;
}
@Override
public void accept(StatementVisitor visitor) {
visitor.visit(this);
}
}

@ -13,7 +13,7 @@ public class Break extends Statement {
@Override
public void accept(StatementVisitor visitor) {
this.accept((StatementVisitor) visitor);
visitor.visit(this);
}
}

@ -9,9 +9,8 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import org.antlr.v4.runtime.Token;
public abstract class Expression extends TypableStatement
{
public Expression(RefTypeOrTPHOrWildcardOrGeneric type, Token offset){
public abstract class Expression extends TypableStatement {
public Expression(RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(type, offset);
}
}

@ -0,0 +1,22 @@
package de.dhbwstuttgart.syntaxtree.statement;
import java.util.List;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class GuardedPattern extends Pattern {
private List<Expression> conditions;
public GuardedPattern(List<Expression> conditions, String name, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(name, type, offset);
this.conditions = conditions;
}
public List<Expression> getConditions() {
return conditions;
}
}

@ -7,17 +7,13 @@ import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import org.antlr.v4.runtime.Token;
public class IfStmt extends Statement
{
public class IfStmt extends Statement {
public final Expression expr;
public final Statement then_block;
public final Statement else_block;
public IfStmt(RefTypeOrTPHOrWildcardOrGeneric type,
Expression expr, Statement thenBlock, Statement elseBlock, Token offset)
{
super(type,offset);
public IfStmt(RefTypeOrTPHOrWildcardOrGeneric type, Expression expr, Statement thenBlock, Statement elseBlock, Token offset) {
super(type, offset);
this.expr = expr;
this.then_block = thenBlock;
this.else_block = elseBlock;

@ -1,17 +1,34 @@
package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class InstanceOf extends BinaryExpr {
public Expression expr;
private RefTypeOrTPHOrWildcardOrGeneric reftype;
private Pattern pattern;
public InstanceOf(int offset, int variableLength) {
super(null, null, null, null, null);
throw new NotImplementedException();
// #JB# 20.04.2005
public InstanceOf(Expression expr, RefTypeOrTPHOrWildcardOrGeneric reftype, Token offset) {
super(BinaryExpr.Operator.INSTOF, TypePlaceholder.fresh(offset), expr, new LocalVar("", reftype, reftype.getOffset()), offset);
this.pattern = new Pattern(null, reftype, offset);
}
public InstanceOf(Expression expr, Pattern pattern, Token offset) {
super(BinaryExpr.Operator.INSTOF, TypePlaceholder.fresh(offset), expr, new LocalVar(pattern.getName(), pattern.getType(), pattern.getOffset()), offset);
this.pattern = pattern;
}
public RefTypeOrTPHOrWildcardOrGeneric getReftype() {
return pattern.getType();
}
public String getName() {
return pattern.getName();
}
public Pattern gPattern() {
return pattern;
}
@Override

@ -0,0 +1,26 @@
package de.dhbwstuttgart.syntaxtree.statement;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class Pattern extends Expression {
private String name;
public Pattern(String name, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(type, offset);
this.name = name;
}
public String getName() {
return name;
}
@Override
public void accept(StatementVisitor visitor) {
visitor.visit(this);
}
}

@ -0,0 +1,37 @@
package de.dhbwstuttgart.syntaxtree.statement;
import java.util.ArrayList;
import java.util.List;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class RecordPattern extends Pattern {
private List<Pattern> subPattern = new ArrayList<>();
public RecordPattern(String name, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(name, type, offset);
}
public RecordPattern(List<Pattern> subPattern, String name, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(name, type, offset);
this.subPattern = subPattern;
}
public List<Pattern> getSubPattern() {
return this.subPattern;
}
public void addSubPattern(Pattern newPattern) {
this.subPattern.add(newPattern);
}
@Override
public void accept(StatementVisitor visitor) {
visitor.visit(this);
}
}

@ -0,0 +1,37 @@
package de.dhbwstuttgart.syntaxtree.statement;
import java.util.ArrayList;
import java.util.List;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class Switch extends Statement {
private Expression switchedExpression;
private List<SwitchBlock> blocks = new ArrayList<>();
public Switch(Expression switched, List<SwitchBlock> blocks, RefTypeOrTPHOrWildcardOrGeneric type, Boolean isStatement, Token offset) {
super(type, offset);
if (isStatement)
setStatement();
this.switchedExpression = switched;
this.blocks = blocks;
}
public Expression getSwitch() {
return switchedExpression;
}
public List<SwitchBlock> getBlocks() {
return blocks;
}
@Override
public void accept(StatementVisitor visitor) {
visitor.visit(this);
}
}

@ -0,0 +1,40 @@
package de.dhbwstuttgart.syntaxtree.statement;
import java.util.ArrayList;
import java.util.List;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
public class SwitchBlock extends Block {
private List<SwitchLabel> labels = new ArrayList<>();
private Boolean defaultBlock = false;
public SwitchBlock(List<SwitchLabel> labels, Block statements, Token offset) {
super(statements.getStatements(), offset);
this.labels = labels;
}
public SwitchBlock(List<SwitchLabel> labels, Block statements, Boolean isDefault, Token offset) {
super(statements.getStatements(), offset);
this.labels = labels;
this.defaultBlock = isDefault;
}
public Boolean isDefault() {
return defaultBlock;
}
public List<SwitchLabel> getLabels() {
return labels;
}
@Override
public void accept(StatementVisitor visitor) {
visitor.visit(this);
}
}

@ -0,0 +1,36 @@
package de.dhbwstuttgart.syntaxtree.statement;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class SwitchLabel extends Expression {
private Expression caseExpression;
private Boolean defaultCase = false;
public SwitchLabel(Expression caseExpression, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(type, offset);
this.caseExpression = caseExpression;
}
public SwitchLabel(RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(type, offset);
this.defaultCase = true;
}
public Expression getExpression() {
return caseExpression;
}
public Boolean isDefault() {
return this.defaultCase;
}
@Override
public void accept(StatementVisitor visitor) {
visitor.visit(this);
}
}

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

@ -4,7 +4,7 @@ import de.dhbwstuttgart.syntaxtree.*;
public class ASTPrinter {
public static String print(SourceFile toPrint){
public static String print(SourceFile toPrint) {
StringBuilder output = new StringBuilder();
new OutputGenerator(output).visit(toPrint);
return output.toString();

@ -7,7 +7,7 @@ import de.dhbwstuttgart.syntaxtree.type.*;
import java.lang.reflect.Modifier;
import java.util.Iterator;
import java.util.Optional;
import java.util.List;
public class OutputGenerator implements ASTVisitor {
private static final String TAB = " ";
@ -202,6 +202,13 @@ public class OutputGenerator implements ASTVisitor {
binary.rexpr.accept(this);
}
@Override
public void visit(BoolExpression logical) {
logical.lexpr.accept(this);
out.append(" op ");
logical.rexpr.accept(this);
}
@Override
public void visit(Block block) {
tab();
@ -257,12 +264,18 @@ public class OutputGenerator implements ASTVisitor {
@Override
public void visit(InstanceOf instanceOf) {
instanceOf.lexpr.accept(this);
out.append(" instanceof ");
instanceOf.rexpr.accept(this);
}
@Override
public void visit(LocalVar localVar) {
out.append(localVar.name);
if (localVar.name.isEmpty()) {
localVar.getType().accept(this);
} else {
out.append(localVar.name);
}
}
@Override
@ -388,4 +401,84 @@ public class OutputGenerator implements ASTVisitor {
public void visit(de.dhbwstuttgart.syntaxtree.statement.Literal literal) {
out.append(literal.value);
}
@Override
public void visit(Switch switchStmt) {
out.append("switch(");
switchStmt.getSwitch().accept(this);
out.append("){\n");
tab();
for (SwitchBlock switchBlock : switchStmt.getBlocks()) {
switchBlock.accept(this);
}
untab();
out.append(tabs);
out.append("}");
}
@Override
public void visit(SwitchBlock switchBlock) {
switchBlock.getLabels().stream().forEach((label) -> {
out.append(tabs);
label.accept(this);
});
tab();
switchBlock.getStatements().stream().forEach((stmt) -> {
out.append(tabs);
stmt.accept(this);
out.append(";\n");
});
out.append("\n");
untab();
}
@Override
public void visit(SwitchLabel switchLabel) {
if (switchLabel.isDefault()) {
out.append("default");
} else {
out.append("case ");
switchLabel.getExpression().accept(this);
}
out.append(":\n");
}
@Override
public void visit(Yield aYield) {
out.append("yield ");
aYield.retexpr.accept(this);
}
@Override
public void visit(Pattern aPattern) {
aPattern.getType().accept(this);
out.append(" " + aPattern.getName());
}
@Override
public void visit(RecordPattern aRecordPattern) {
aRecordPattern.getType().accept(this);
out.append("(");
List<Pattern> subPatterns = aRecordPattern.getSubPattern();
int i;
for (i = 0; i < subPatterns.size() - 1; i++) {
subPatterns.get(i).accept(this);
out.append(", ");
}
subPatterns.get(i).accept(this);
String name;
if ((name = aRecordPattern.getName()) != null)
out.append(name);
out.append(")");
}
@Override
public void visit(GuardedPattern aGuardedPattern) {
aGuardedPattern.getType().accept(this);
out.append(aGuardedPattern.getName());
for (Expression cond : aGuardedPattern.getConditions()) {
out.append("&&");
cond.accept(this);
}
}
}

@ -35,8 +35,10 @@ public abstract class GenerateGenerics {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
TPH tph = (TPH) o;
return Objects.equals(resolve(), tph.resolve());
}
@ -72,8 +74,10 @@ public abstract class GenerateGenerics {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
PairLT pairLT = (PairLT) o;
return Objects.equals(right, pairLT.right) && Objects.equals(left, pairLT.left);
}
@ -103,8 +107,10 @@ public abstract class GenerateGenerics {
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
PairEQ pairLT = (PairEQ) o;
return Objects.equals(right, pairLT.right) && Objects.equals(left, pairLT.left);
}
@ -238,12 +244,7 @@ public abstract class GenerateGenerics {
return all;
}
private void methodFindConstraints(
ClassOrInterface owner, Method method,
Set<TPH> typeVariables,
Set<TPH> typeVariablesOfClass,
Set<Pair> result
) {
private void methodFindConstraints(ClassOrInterface owner, Method method, Set<TPH> typeVariables, Set<TPH> typeVariablesOfClass, Set<Pair> result) {
var userDefinedGenericsOfClass = astToTargetAST.userDefinedGenerics.get(owner);
// Type variables with bounds that are also type variables of the method
@ -263,24 +264,15 @@ public abstract class GenerateGenerics {
@Override
public void visit(MethodCall methodCall) {
//Anfang es werden Paare von TPHs gespeichert, die bei den Generated Generics ueber die Methodengrenzen hinweg
//betrachtet werden muessen
//Definition 7.2 (Family of generated generics). T1 <. R1 <.^ R2 <. T2
Set<TPH> T1s =
methodCall.getArgumentList()
.getArguments()
.stream()
.map(TypableStatement::getType)
.collect(Collectors.toCollection(HashSet::new))
.stream().filter(TypePlaceholder.class::isInstance)
.map(TypePlaceholder.class::cast)
.map(TPH::new)
.collect(Collectors.toCollection(HashSet::new));
// Anfang es werden Paare von TPHs gespeichert, die bei den Generated Generics ueber die Methodengrenzen hinweg
// betrachtet werden muessen
// Definition 7.2 (Family of generated generics). T1 <. R1 <.^ R2 <. T2
Set<TPH> T1s = methodCall.getArgumentList().getArguments().stream().map(TypableStatement::getType).collect(Collectors.toCollection(HashSet::new)).stream().filter(TypePlaceholder.class::isInstance).map(TypePlaceholder.class::cast).map(TPH::new).collect(Collectors.toCollection(HashSet::new));
Set<TPH> T2s = new HashSet<>();
findTphs(superType, T2s);
System.out.println("T1s: " + T1s + " T2s: " + T2s);
//Ende
// Ende
superType = methodCall.receiverType;
methodCall.receiver.accept(this);
@ -292,7 +284,8 @@ public abstract class GenerateGenerics {
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) {
if (expressionReceiver.expr instanceof This) {
var optMethod = astToTargetAST.findMethod(owner, methodCall.name, methodCall.getArgumentList());
if (optMethod.isEmpty()) return;
if (optMethod.isEmpty())
return;
var method2 = optMethod.get();
System.out.println("In: " + method.getName() + " Method: " + method2.getName());
var generics = family(owner, method2);
@ -309,9 +302,9 @@ public abstract class GenerateGenerics {
HashSet<PairLT> newPairs = new HashSet<>();
// Loop from hell
outer:
for (var R1 : typeVariables) {
if (typeVariablesOfClass.contains(R1)) continue;
outer: for (var R1 : typeVariables) {
if (typeVariablesOfClass.contains(R1))
continue;
for (var generic : all)
if (generic instanceof PairLT ptph) {
for (var pair : simplifiedConstraints) {
@ -323,8 +316,10 @@ public abstract class GenerateGenerics {
if (!(pair2.right.equals(R2) && pair2.left.equals(ptph.right)))
continue;
if (R1.equals(R2)) continue;
if (!T1s.contains(R1) || !T2s.contains(R2)) continue;
if (R1.equals(R2))
continue;
if (!T1s.contains(R1) || !T2s.contains(R2))
continue;
var newPair = new PairLT(R1, R2);
System.out.println("New pair: " + newPair);
@ -402,16 +397,53 @@ public abstract class GenerateGenerics {
arglist.getArguments().get(i).accept(this);
}
}
@Override
public void visit(Switch switchStmt) {
// TODO Auto-generated method stub
}
@Override
public void visit(SwitchBlock switchBlock) {
// TODO Auto-generated method stub
}
@Override
public void visit(SwitchLabel switchLabel) {
// TODO Auto-generated method stub
}
@Override
public void visit(Yield aYield) {
// TODO Auto-generated method stub
}
@Override
public void visit(Pattern aPattern) {
// TODO Auto-generated method stub
}
@Override
public void visit(RecordPattern aRecordPattern) {
// TODO Auto-generated method stub
}
@Override
public void visit(GuardedPattern aGuardedPattern) {
// TODO Auto-generated method stub
}
});
var closure = transitiveClosure(simplifiedConstraints);
// Type variables with bounds that are also type variables of the class
for (var typeVariable : new HashSet<>(typeVariables)) {
if (typeVariablesOfClass.contains(typeVariable)) continue;
if (typeVariablesOfClass.contains(typeVariable))
continue;
var pairs = new HashSet<PairLT>();
for (var pair : closure) {
if (!(pair instanceof PairLT ptph)) continue;
if (!(pair instanceof PairLT ptph))
continue;
if (ptph.left.equals(typeVariable) && typeVariablesOfClass.contains(ptph.right)) {
pairs.add(new PairLT(ptph.left, ptph.right));
}
@ -435,7 +467,8 @@ public abstract class GenerateGenerics {
break;
}
}
if (!found) break;
if (!found)
break;
}
if (steps < minSteps) {
minSteps = steps;
@ -448,8 +481,7 @@ public abstract class GenerateGenerics {
}
// All unbounded type variables (bounds not in method)
outer:
for (var typeVariable : typeVariables) {
outer: for (var typeVariable : typeVariables) {
if (classHasGeneric(userDefinedGenericsOfClass, typeVariablesOfClass, typeVariable))
continue;
for (var pair : result) {
@ -460,8 +492,7 @@ public abstract class GenerateGenerics {
}
// All unbounded bounds
outer:
for (var pair : simplifiedConstraints) {
outer: for (var pair : simplifiedConstraints) {
for (var pair2 : simplifiedConstraints) {
if (pair.right.equals(pair2.left))
continue outer;
@ -476,10 +507,7 @@ public abstract class GenerateGenerics {
return typeVariablesOfClass.contains(typeVariable) || userDefinedGenericsOfClass.stream().anyMatch(g -> g.getName().equals(typeVariable.resolve().getName()));
}
private void methodFindTypeVariables(
Method method,
Set<TPH> typeVariables
) {
private void methodFindTypeVariables(Method method, Set<TPH> typeVariables) {
if (!(method instanceof Constructor))
typeVariables.addAll(findTypeVariables(method.getReturnType()));
@ -498,6 +526,41 @@ public abstract class GenerateGenerics {
super.visit(methodCall);
typeVariables.addAll(findTypeVariables(methodCall.getType()));
}
@Override
public void visit(Switch switchStmt) {
// TODO Auto-generated method stub
}
@Override
public void visit(SwitchBlock switchBlock) {
// TODO Auto-generated method stub
}
@Override
public void visit(SwitchLabel switchLabel) {
// TODO Auto-generated method stub
}
@Override
public void visit(Yield aYield) {
// TODO Auto-generated method stub
}
@Override
public void visit(Pattern aPattern) {
// TODO Auto-generated method stub
}
@Override
public void visit(RecordPattern aRecordPattern) {
// TODO Auto-generated method stub
}
@Override
public void visit(GuardedPattern aGuardedPattern) {
// TODO Auto-generated method stub
}
});
}
@ -567,7 +630,8 @@ public abstract class GenerateGenerics {
private void eliminateChain(Set<Pair> result, List<TPH> chain) {
for (var pair : new HashSet<>(result)) {
if (pair instanceof PairLT ptph && chain.get(chain.size() - 1).equals(ptph.left)) {
if (chain.contains(ptph.right)) return;
if (chain.contains(ptph.right))
return;
var copy = new ArrayList<>(chain);
copy.add(ptph.right);
if (copy.size() > 2)
@ -644,12 +708,12 @@ public abstract class GenerateGenerics {
}
void normalize(Set<Pair> result, Set<Pair> classGenerics, Set<TPH> usedTphs) {
outer:
for (var tph : usedTphs) {
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 (p1.left.equals(tph))
continue outer;
}
if (classGenerics == null || classGenerics.stream().noneMatch((pair) -> pair.left.equals(tph)))
@ -664,22 +728,24 @@ public abstract class GenerateGenerics {
chain.add(ptph.left);
chain.add(ptph.right);
outer:
while (true) {
outer: while (true) {
var added = false;
for (var pair2 : input) {
if (pair2 instanceof PairLT ptph2 && ptph2.left.equals(chain.get(chain.size() - 1))) {
if (chain.contains(ptph2.right)) break outer;
if (chain.contains(ptph2.right))
break outer;
chain.add(ptph2.right);
added = true;
}
}
if (!added) break;
if (!added)
break;
}
System.out.println(chain + " " + chain.stream().map(e -> e.resolve().getVariance()).toList());
var variance = chain.get(0).resolve().getVariance();
if (variance != 1) continue;
if (variance != 1)
continue;
var index = 0;
for (var tph : chain) {
if (variance == 1 && tph.resolve().getVariance() == -1) {
@ -690,14 +756,15 @@ public abstract class GenerateGenerics {
}
index++;
}
if (variance == 1) continue;
if (variance == 1)
continue;
var start = chain.get(0);
var prev = start;
for (var i = 1; i < index; i++) {
var cur = chain.get(i);
if (!referenced.contains(cur)) continue;
if (!referenced.contains(cur))
continue;
addToEquality(cur.resolve(), start.resolve(), referenced);
TPH finalPrev = prev;
input.removeIf(p -> p.equals(new PairLT(finalPrev, cur)));
@ -750,7 +817,7 @@ public abstract class GenerateGenerics {
for (var method : classOrInterface.getMethods()) {
family(classOrInterface, method);
}
} while(!oldFamily.equals(familyOfMethods));
} while (!oldFamily.equals(familyOfMethods));
for (var method : classOrInterface.getMethods()) {
generics(classOrInterface, method);
@ -766,7 +833,8 @@ public abstract class GenerateGenerics {
var foundNext = false;
for (var pair : input) {
if (pair instanceof PairLT ptph && ptph.left.equals(end)) {
if (chain.contains(ptph.right)) return;
if (chain.contains(ptph.right))
return;
chain = new HashSet<>(chain);
chain.add(ptph.right);
findChain(referenced, input, output, start, ptph.right, chain);
@ -851,7 +919,7 @@ public abstract class GenerateGenerics {
}
newTph.setVariance(variance);
//referenced.add(newTph);
// referenced.add(newTph);
addToPairs(input, new PairLT(left, new TPH(newTph)));
input.removeAll(infima);
for (var infimum : infima) {
@ -893,7 +961,8 @@ public abstract class GenerateGenerics {
return getTargetType(equality.get(tph));
}
var type = concreteTypes.get(new TPH(tph));
if (type == null) return new TargetGenericType(tph.getName());
if (type == null)
return new TargetGenericType(tph.getName());
return astToTargetAST.convert(type, this);
}
return astToTargetAST.convert(in, this);

@ -74,6 +74,41 @@ public class StatementToTargetExpression implements StatementVisitor {
@Override
public void visit(LambdaExpression lambda) {
} // Don't look at lambda expressions
@Override
public void visit(Switch switchStmt) {
// TODO Auto-generated method stub
}
@Override
public void visit(SwitchBlock switchBlock) {
// TODO Auto-generated method stub
}
@Override
public void visit(SwitchLabel switchLabel) {
// TODO Auto-generated method stub
}
@Override
public void visit(Yield aYield) {
// TODO Auto-generated method stub
}
@Override
public void visit(Pattern aPattern) {
// TODO Auto-generated method stub
}
@Override
public void visit(RecordPattern aRecordPattern) {
// TODO Auto-generated method stub
}
@Override
public void visit(GuardedPattern aGuardedPattern) {
// TODO Auto-generated method stub
}
});
result = new TargetLambdaExpression(converter.convert(lambdaExpression.getType()), captures, parameters, converter.convert(lambdaExpression.getReturnType()), converter.convert(lambdaExpression.methodBody));
@ -107,9 +142,15 @@ public class StatementToTargetExpression implements StatementVisitor {
case BIGGEREQUAL -> new TargetBinaryOp.GreaterOrEqual(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case EQUAL -> new TargetBinaryOp.Equal(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case NOTEQUAL -> new TargetBinaryOp.NotEqual(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case INSTOF -> new TargetBinaryOp.Instof(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
};
}
@Override
public void visit(BoolExpression bool) {
System.out.println("BoolExpression");
}
@Override
public void visit(Block block) {
result = converter.convert(block);
@ -334,4 +375,39 @@ public class StatementToTargetExpression implements StatementVisitor {
result = new TargetLiteral.BooleanLiteral((boolean) literal.value);
}
}
@Override
public void visit(Switch switchStmt) {
// TODO Auto-generated method stub
}
@Override
public void visit(SwitchBlock switchBlock) {
// TODO Auto-generated method stub
}
@Override
public void visit(SwitchLabel switchLabel) {
// TODO Auto-generated method stub
}
@Override
public void visit(Yield aYield) {
// TODO Auto-generated method stub
}
@Override
public void visit(Pattern aPattern) {
// TODO Auto-generated method stub
}
@Override
public void visit(RecordPattern aRecordPattern) {
// TODO Auto-generated method stub
}
@Override
public void visit(GuardedPattern aGuardedPattern) {
// TODO Auto-generated method stub
}
}

@ -34,6 +34,12 @@ public abstract class TracingStatementVisitor implements StatementVisitor {
binary.rexpr.accept(this);
}
@Override
public void visit(BoolExpression bool) {
bool.lexpr.accept(this);
bool.rexpr.accept(this);
}
@Override
public void visit(Block block) {
for (var expr : block.statements)

@ -5,44 +5,81 @@ import de.dhbwstuttgart.target.tree.type.TargetType;
public sealed interface TargetBinaryOp extends TargetExpression {
TargetExpression left();
TargetExpression right();
// Arithmetic
record Add(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {}
record Sub(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {}
record Div(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {}
record Mul(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {}
record Rem(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {}
record Add(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {
}
record Sub(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {
}
record Div(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {
}
record Mul(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {
}
record Rem(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {
}
// Bitwise
record BAnd(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {}
record BOr(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {}
record XOr(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {}
record Shl(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {}
record Shr(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {}
record UShr(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {}
record BAnd(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {
}
record BOr(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {
}
record XOr(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {
}
record Shl(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {
}
record Shr(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {
}
record UShr(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {
}
// Conditional
record And(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {}
record Or(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {}
record And(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {
}
record Or(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {
}
record Instof(TargetType type, TargetExpression left, TargetExpression right) implements TargetBinaryOp {
}
sealed interface TargetRelationalOp extends TargetBinaryOp {
@Override
default TargetType type() {
return TargetType.Boolean;
}
TargetType exprType();
}
// Comparison
// exprType is the type that both arguments get converted to before comparison
record Equal(TargetType exprType, TargetExpression left, TargetExpression right) implements TargetRelationalOp {}
record Greater(TargetType exprType, TargetExpression left, TargetExpression right) implements TargetRelationalOp {}
record GreaterOrEqual(TargetType exprType, TargetExpression left, TargetExpression right) implements TargetRelationalOp {}
record Less(TargetType exprType, TargetExpression left, TargetExpression right) implements TargetRelationalOp {}
record LessOrEqual(TargetType exprType, TargetExpression left, TargetExpression right) implements TargetRelationalOp {}
record NotEqual(TargetType exprType, TargetExpression left, TargetExpression right) implements TargetRelationalOp {}
record Equal(TargetType exprType, TargetExpression left, TargetExpression right) implements TargetRelationalOp {
}
record Greater(TargetType exprType, TargetExpression left, TargetExpression right) implements TargetRelationalOp {
}
record GreaterOrEqual(TargetType exprType, TargetExpression left, TargetExpression right) implements TargetRelationalOp {
}
record Less(TargetType exprType, TargetExpression left, TargetExpression right) implements TargetRelationalOp {
}
record LessOrEqual(TargetType exprType, TargetExpression left, TargetExpression right) implements TargetRelationalOp {
}
record NotEqual(TargetType exprType, TargetExpression left, TargetExpression right) implements TargetRelationalOp {
}
}

@ -21,18 +21,15 @@ import java.util.Optional;
public class FunNClass extends ClassOrInterface {
public FunNClass(List<GenericRefType> funNParams) {
super(0, new JavaClassName("Fun"+(funNParams.size()-1)), new ArrayList<>(), Optional.empty() /* eingefuegt PL 2018-11-24 */,
createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams),
ASTFactory.createObjectType(), true, new ArrayList<>(), new NullToken());
super(0, new JavaClassName("Fun" + (funNParams.size() - 1)), new ArrayList<>(), Optional.empty() /* eingefuegt PL 2018-11-24 */, createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams), ASTFactory.createObjectType(), true, new ArrayList<>(), new ArrayList<>(), new NullToken());
}
}
private static GenericDeclarationList createGenerics(List<GenericRefType> funNParams) {
//PL 2018-06-22: so geaendert, dass generierte Generics den Namen der funParams entsprechen.
// PL 2018-06-22: so geaendert, dass generierte Generics den Namen der funParams entsprechen.
List<GenericTypeVar> generics = new ArrayList<>();
for(GenericRefType param : funNParams){
generics.add(new GenericTypeVar(param.getParsedName(),//NameGenerator.makeNewName(),
for (GenericRefType param : funNParams) {
generics.add(new GenericTypeVar(param.getParsedName(), // NameGenerator.makeNewName(),
new ArrayList<>(), new NullToken(), new NullToken()));
}
return new GenericDeclarationList(generics, new NullToken());

@ -1,31 +1,78 @@
//PL 2018-12-19: Merge chekcen
package de.dhbwstuttgart.typeinference.typeAlgo;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.exceptions.TypeinferenceException;
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.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
import de.dhbwstuttgart.syntaxtree.statement.Assign;
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.BoolExpression;
import de.dhbwstuttgart.syntaxtree.statement.Break;
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt;
import de.dhbwstuttgart.syntaxtree.statement.ExpressionReceiver;
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
import de.dhbwstuttgart.syntaxtree.statement.ForStmt;
import de.dhbwstuttgart.syntaxtree.statement.GuardedPattern;
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
import de.dhbwstuttgart.syntaxtree.statement.InstanceOf;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import de.dhbwstuttgart.syntaxtree.statement.Literal;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
import de.dhbwstuttgart.syntaxtree.statement.NewArray;
import de.dhbwstuttgart.syntaxtree.statement.NewClass;
import de.dhbwstuttgart.syntaxtree.statement.Pattern;
import de.dhbwstuttgart.syntaxtree.statement.RecordPattern;
import de.dhbwstuttgart.syntaxtree.statement.Return;
import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid;
import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.statement.StaticClassName;
import de.dhbwstuttgart.syntaxtree.statement.Super;
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
import de.dhbwstuttgart.syntaxtree.statement.Switch;
import de.dhbwstuttgart.syntaxtree.statement.SwitchBlock;
import de.dhbwstuttgart.syntaxtree.statement.SwitchLabel;
import de.dhbwstuttgart.syntaxtree.statement.This;
import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr;
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
import de.dhbwstuttgart.syntaxtree.statement.Yield;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.FunNClass;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.*;
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.util.BiRelation;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class TYPEStmt implements StatementVisitor {
@ -343,6 +390,12 @@ public class TYPEStmt implements StatementVisitor {
}
}
@Override
public void visit(BoolExpression bool) {
// TODO
return;
}
@Override
public void visit(Literal literal) {
// Nothing to do here. Literale erzeugen keine Constraints
@ -680,4 +733,39 @@ public class TYPEStmt implements StatementVisitor {
return methodConstraint;
}
@Override
public void visit(Switch switchStmt) {
// TODO Auto-generated method stub
}
@Override
public void visit(SwitchBlock switchBlock) {
// TODO Auto-generated method stub
}
@Override
public void visit(SwitchLabel switchLabel) {
// TODO Auto-generated method stub
}
@Override
public void visit(Yield aYield) {
// TODO Auto-generated method stub
}
@Override
public void visit(Pattern aPattern) {
// TODO Auto-generated method stub
}
@Override
public void visit(RecordPattern aRecordPattern) {
// TODO Auto-generated method stub
}
@Override
public void visit(GuardedPattern aGuardedPattern) {
// TODO Auto-generated method stub
}
}

@ -14,46 +14,40 @@ import java.util.HashSet;
import java.util.Optional;
public class FamilyOfGenerics {
@Test
public void generateBC() throws Exception {
/*SourceFile sf = generateAST();
PositionFinder.getPositionOfTPH(sf, null);
TPHExtractor tphExtractor = new TPHExtractor();
List<ResultSet> results = new ArrayList<ResultSet>();
GeneratedGenericsFinder generatedGenericsFinder = new GeneratedGenericsFinder(sf, results);*/
/*
* SourceFile sf = generateAST(); PositionFinder.getPositionOfTPH(sf, null); TPHExtractor tphExtractor = new TPHExtractor(); List<ResultSet> results = new ArrayList<ResultSet>(); GeneratedGenericsFinder generatedGenericsFinder = new GeneratedGenericsFinder(sf, results);
*/
}
public static SourceFile generateAST(){
public static SourceFile generateAST() {
ArrayList<ClassOrInterface> classes = new ArrayList<>();
ArrayList<Field> fields = new ArrayList<>();
ArrayList<Method> methods = new ArrayList<>();
fields.add(generateField("fld1"));
String[] paramNames = {"a"};
String[] paramNames = { "a" };
methods.add(generateMethod("testMethode", paramNames));
classes.add(new ClassOrInterface(Modifier.PUBLIC, new JavaClassName("Test"), fields, Optional.empty(), methods,
new ArrayList<>(), generateEmptyGenericDeclList(),
new RefType(new JavaClassName("java.lang.Object"), new NullToken()),
false, new ArrayList<>(), new NullToken()));
classes.add(new ClassOrInterface(Modifier.PUBLIC, new JavaClassName("Test"), fields, Optional.empty(), methods, new ArrayList<>(), generateEmptyGenericDeclList(), new RefType(new JavaClassName("java.lang.Object"), new NullToken()), false, new ArrayList<>(), new ArrayList<>(), new NullToken()));
return new SourceFile("Test.jav", classes, new HashSet<>());
}
public static Method generateMethod(String methodName, String[] paramNames){
public static Method generateMethod(String methodName, String[] paramNames) {
ArrayList<FormalParameter> parameters = new ArrayList<>();
for(String str: paramNames) {
for (String str : paramNames) {
FormalParameter fp = new FormalParameter(str, TypePlaceholder.fresh(new NullToken()), new NullToken());
parameters.add(fp);
}
ParameterList parameterList = new ParameterList(parameters, new NullToken());
return new Method(Modifier.PUBLIC, methodName, TypePlaceholder.fresh(new NullToken()), parameterList,
new Block(new ArrayList<>(), new NullToken()), generateEmptyGenericDeclList(), new NullToken());
return new Method(Modifier.PUBLIC, methodName, TypePlaceholder.fresh(new NullToken()), parameterList, new Block(new ArrayList<>(), new NullToken()), generateEmptyGenericDeclList(), new NullToken());
}
public static GenericDeclarationList generateEmptyGenericDeclList(){
public static GenericDeclarationList generateEmptyGenericDeclList() {
return new GenericDeclarationList(new ArrayList<>(), new NullToken());
}

@ -7,6 +7,9 @@ import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import org.junit.BeforeClass;
@ -14,6 +17,7 @@ import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
/**

@ -1,5 +1,131 @@
package syntaxtreegenerator;
public class TestNewFeatures {
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.util.HashMap;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
public class TestNewFeatures {
private static HashMap<String, File[]> javFiles = new HashMap<>();
@BeforeClass
public static void setUp() {
final String testFileDirectory = "resources/syntaxtreegenerator/javFiles/";
final String expectedASTDirectory = "resources/syntaxtreegenerator/";
File dir = new File(testFileDirectory);
for (File f : dir.listFiles(new JavFilter())) {
String basefilename = f.getName().replace(".jav", "");
// javFiles.put(basefilename, new File[] { f, new File(expectedASTDirectory + basefilename + ".ast") });
javFiles.put(basefilename, new File[] { f, new File(expectedASTDirectory + basefilename + ".ast") });
}
}
@Test
public void instanceOfTest() {
try {
FileInputStream fileIn = new FileInputStream(javFiles.get("Instanceof")[1]);
String expectedAST = new String(fileIn.readAllBytes());
fileIn.close();
expectedAST = expectedAST.replaceAll("TPH [A-Z]+", "TPH");
File srcfile = javFiles.get("Instanceof")[0];
JavaTXCompiler compiler = new JavaTXCompiler(srcfile);
String resultingAST = new String(ASTPrinter.print(compiler.sourceFiles.get(srcfile)));
resultingAST = resultingAST.replaceAll("TPH [A-Z]+", "TPH");
System.out.println("Expected:\n" + new String(expectedAST));
System.out.println("Result:\n" + new String(resultingAST));
assertEquals("Comparing expected and resulting AST for Instanceof.jav", expectedAST, resultingAST);
} catch (Exception exc) {
exc.printStackTrace();
fail("An error occured while generating the AST for Instanceof.jav");
}
}
@Test
public void recordTest() {
try {
FileInputStream fileIn = new FileInputStream(javFiles.get("Record")[1]);
String expectedAST = new String(fileIn.readAllBytes());
fileIn.close();
expectedAST = expectedAST.replaceAll("TPH [A-Z]+", "TPH");
File srcfile = javFiles.get("Record")[0];
JavaTXCompiler compiler = new JavaTXCompiler(srcfile);
String resultingAST = new String(ASTPrinter.print(compiler.sourceFiles.get(srcfile)));
resultingAST = resultingAST.replaceAll("TPH [A-Z]+", "TPH");
System.out.println("Expected:\n" + new String(expectedAST));
System.out.println("Result:\n" + new String(resultingAST));
assertEquals("Comparing expected and resulting AST for Record.jav", expectedAST, resultingAST);
} catch (Exception exc) {
exc.printStackTrace();
fail("An error occured while generating the AST for Record.jav");
}
}
@Test
public void sealedTest() {
try {
FileInputStream fileIn = new FileInputStream(javFiles.get("Sealed")[1]);
String expectedAST = new String(fileIn.readAllBytes());
fileIn.close();
expectedAST = expectedAST.replaceAll("TPH [A-Z]+", "TPH");
File srcfile = javFiles.get("Sealed")[0];
JavaTXCompiler compiler = new JavaTXCompiler(srcfile);
String resultingAST = new String(ASTPrinter.print(compiler.sourceFiles.get(srcfile)));
resultingAST = resultingAST.replaceAll("TPH [A-Z]+", "TPH");
System.out.println("Expected:\n" + new String(expectedAST));
System.out.println("Result:\n" + new String(resultingAST));
assertEquals("Comparing expected and resulting AST for Sealed.jav", expectedAST, resultingAST);
} catch (Exception exc) {
exc.printStackTrace();
fail("An error occured while generating the AST for Sealed.jav");
}
}
@Test
public void switchTest() {
try {
FileInputStream fileIn = new FileInputStream(javFiles.get("Switch")[1]);
String expectedAST = new String(fileIn.readAllBytes());
fileIn.close();
expectedAST = expectedAST.replaceAll("TPH [A-Z]+", "TPH");
File srcfile = javFiles.get("Switch")[0];
JavaTXCompiler compiler = new JavaTXCompiler(srcfile);
String resultingAST = new String(ASTPrinter.print(compiler.sourceFiles.get(srcfile)));
resultingAST = resultingAST.replaceAll("TPH [A-Z]+", "TPH");
System.out.println("Expected:\n" + new String(expectedAST));
System.out.println("Result:\n" + new String(resultingAST));
assertEquals("Comparing expected and resulting AST for Switch.jav", expectedAST, resultingAST);
} catch (Exception exc) {
exc.printStackTrace();
fail("An error occured while generating the AST for Switch.jav");
}
}
@Test
public void patternMatching() {
try {
FileInputStream fileIn = new FileInputStream(javFiles.get("PatternMatching")[1]);
String expectedAST = new String(fileIn.readAllBytes());
fileIn.close();
expectedAST = expectedAST.replaceAll("TPH [A-Z]+", "TPH");
File srcfile = javFiles.get("PatternMatching")[0];
JavaTXCompiler compiler = new JavaTXCompiler(srcfile);
String resultingAST = new String(ASTPrinter.print(compiler.sourceFiles.get(srcfile)));
resultingAST = resultingAST.replaceAll("TPH [A-Z]+", "TPH");
System.out.println("Expected:\n" + new String(expectedAST));
System.out.println("Result:\n" + new String(resultingAST));
assertEquals("Comparing expected and resulting AST for PatternMatching.jav", expectedAST, resultingAST);
} catch (Exception exc) {
exc.printStackTrace();
fail("An error occured while generating the AST for PatternMatching.jav");
}
}
}

@ -25,7 +25,7 @@ public class ASTToTypedTargetAST {
@Test
public void emptyClass() {
ClassOrInterface emptyClass = new ClassOrInterface(0, new JavaClassName("EmptyClass"), new ArrayList<>(), java.util.Optional.empty(), new ArrayList<>(), new ArrayList<>(), new GenericDeclarationList(new ArrayList<>(), new NullToken()), new RefType(new JavaClassName("Object"), new NullToken()), false, new ArrayList<>(), new NullToken());
ClassOrInterface emptyClass = new ClassOrInterface(0, new JavaClassName("EmptyClass"), new ArrayList<>(), java.util.Optional.empty(), new ArrayList<>(), new ArrayList<>(), new GenericDeclarationList(new ArrayList<>(), new NullToken()), new RefType(new JavaClassName("Object"), new NullToken()), false, new ArrayList<>(), new ArrayList<>(), new NullToken());
ResultSet emptyResultSet = new ResultSet(new HashSet<>());
TargetClass emptyTargetClass = new ASTToTargetAST(List.of(emptyResultSet)).convert(emptyClass);
assert emptyTargetClass.getName().equals("EmptyClass");

@ -37,7 +37,7 @@ public class TestCodegen {
}
public static Map<String, ? extends Class<?>> generateClassFiles(IByteArrayClassLoader classLoader, String... files) throws IOException, ClassNotFoundException {
var path = Path.of(System.getProperty("user.dir"), "/resources/bytecode/javFiles/");
var path = Path.of(System.getProperty("user.dir"), "resources/bytecode/javFiles/");
var filenames = Arrays.stream(files).map(filename -> Path.of(path.toString(), filename).toFile()).toList();
var compiler = new JavaTXCompiler(filenames, List.of(path.toFile(), outputPath.toFile()));
var resultSet = compiler.typeInference();