Compare commits

...

26 Commits

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

@@ -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>

View File

@@ -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(());
}
}

View File

@@ -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(());
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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");
};
}
}

View File

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

View File

@@ -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 { }

View File

@@ -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;
};
}
}

View File

@@ -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
;

View File

@@ -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();
}
}
}

View File

@@ -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
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
} 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);
}
// 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) {
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) {
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("+")) {

View File

@@ -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) {

View File

@@ -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();
}

View File

@@ -1,28 +1,46 @@
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;
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;
@@ -38,6 +56,7 @@ public class GatherNames {
}
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()) {
@@ -47,6 +66,15 @@ public class GatherNames {
}
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 != "") {
@@ -56,6 +84,11 @@ public class GatherNames {
}
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 != "") {
@@ -65,6 +98,12 @@ public class GatherNames {
}
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 != "") {
@@ -74,12 +113,21 @@ public class GatherNames {
}
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));
}
}
ret.putAll(getImports(ctx, packages, classLoader));
return ret;
}

View File

@@ -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,6 +169,7 @@ public abstract class AbstractASTWalker implements ASTVisitor {
@Override
public void visit(IfStmt ifStmt) {
ifStmt.then_block.accept(this);
if (!Objects.isNull(ifStmt.else_block))
ifStmt.else_block.accept(this);
}
@@ -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) {
}
}

View File

@@ -24,45 +24,46 @@ 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;
if (isInterface && !Modifier.isInterface(modifiers))
modifiers += Modifier.INTERFACE;
this.modifiers = modifiers;
this.name = name;
this.fields = fielddecl;
this.fieldInitializations= fieldInitializations;
this.fieldInitializations = fieldInitializations;
this.genericClassParameters = genericClassParameters;
this.superClass = superClass;
this.isInterface = isInterface;
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){
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.fieldInitializations = cl.fieldInitializations;
this.genericClassParameters = cl.genericClassParameters;
this.superClass = cl.superClass;
this.isInterface = cl.isInterface;
@@ -71,49 +72,47 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
this.constructors = new ArrayList<>(cl.constructors);
}
//Gets if it is added
// Gets if it is added
public Boolean areMethodsAdded() {
return methodAdded;
}
//Sets that it is added
// Sets that it is added
public void setMethodsAdded() {
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(){
public Optional<Constructor> getfieldInitializations() {
return this.fieldInitializations;
}
public List<Method> getMethods(){
public List<Method> getMethods() {
return this.methods;
}
/*
public RefType getType() {
return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset());
}
* 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
// 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,17 +122,17 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
*
* @return die aktuelle Klasse als RefType
*/
public RefType generateTypeOfThisClass(){
public RefType generateTypeOfThisClass() {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar genericTypeVar : this.getGenerics()){
//params.add(genericTypeVar.getTypePlaceholder());
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;

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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,53 +98,59 @@ 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);
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) {
// private static RefType createType(Class classType) {
// return createClass(classType).getType();
//}
// }
private static Optional<de.dhbwstuttgart.syntaxtree.Constructor> createConstructor(Constructor constructor, String signature, Class inClass) {
String name = constructor.getName();
@@ -155,10 +159,11 @@ public class ASTFactory {
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,10 +193,11 @@ 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());
@@ -199,13 +205,13 @@ public class ASTFactory {
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));
}
}
@@ -404,48 +412,26 @@ public class ASTFactory {
}
/*
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(); }
*/
}

View File

@@ -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;

View File

@@ -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;
}
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);
}
}

View File

@@ -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);
}
}

View File

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

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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();

View File

@@ -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,13 +264,19 @@ 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) {
if (localVar.name.isEmpty()) {
localVar.getType().accept(this);
} else {
out.append(localVar.name);
}
}
@Override
public void visit(LocalVarDecl localVarDecl) {
@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -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
}
}

View File

@@ -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)

View File

@@ -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 {
}
}

View File

@@ -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());

View File

@@ -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
}
}

View File

@@ -17,43 +17,37 @@ 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());
}

View File

@@ -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;
/**

View File

@@ -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");
}
}
}

View File

@@ -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");

View File

@@ -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();