Fix non chainable parts in dotted expression
Some checks failed
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 49s

This commit is contained in:
Daniel Holle 2024-10-04 16:41:05 +02:00
parent 44754e73ac
commit 7811ecce63
7 changed files with 53 additions and 68 deletions

View File

@ -54,8 +54,8 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<version>3.11.0</version> <version>3.11.0</version>
<configuration> <configuration>
<compilerArgs>--enable-preview</compilerArgs> <compilerArgs>--enable-preview</compilerArgs>
<source>21</source> <source>22</source>
<target>21</target> <target>22</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>

View File

@ -0,0 +1,15 @@
import java.lang.Integer;
public class Assign {
public x = 10;
public y = this;
public call() {
return this;
}
public m() {
this.call().call().y.x = 20;
return x;
}
}

View File

@ -14,6 +14,7 @@ import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.target.tree.expression.TargetUnaryOp;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
@ -101,7 +102,6 @@ import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import org.stringtemplate.v4.ST;
public class StatementGenerator { public class StatementGenerator {
@ -586,7 +586,7 @@ public class StatementGenerator {
initValue = convert(varDecl.variableInitializer().expression()); initValue = convert(varDecl.variableInitializer().expression());
} }
var fieldEntry = fields.get(name.getText()); var fieldEntry = fields.get(name.getText());
return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), (fieldEntry.modifiers() & Modifier.STATIC) != 0, name.getText(), type, varDecl.getStart())), initValue, name.getStart())); return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), name.getText(), type, varDecl.getStart())), initValue, name.getStart()));
} }
private Statement convert(Java17Parser.BreakstmtContext stmt) { private Statement convert(Java17Parser.BreakstmtContext stmt) {
@ -700,8 +700,7 @@ public class StatementGenerator {
if (!Objects.isNull(expr.methodCall())) { if (!Objects.isNull(expr.methodCall())) {
return convert(expr.methodCall(), expr.expression(), offset); return convert(expr.methodCall(), expr.expression(), offset);
} else if (!Objects.isNull(expr.identifier())) { } else if (!Objects.isNull(expr.identifier())) {
// FIXME This is not the right way of handling any of this return new FieldVar(convert(expr.expression()), expr.identifier().getText(), TypePlaceholder.fresh(expr.identifier().start), offset);
return generateLocalOrFieldVarOrClassName(expr.getText(), offset);
} else { } else {
// Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite // Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite
// generische Invokationen // generische Invokationen
@ -777,64 +776,25 @@ public class StatementGenerator {
/** /**
* Der Parser kann nicht zwischen einer lokalen Variable, einem Feldzugriff und einer Klassenangabe unterscheiden. * Der Parser kann nicht zwischen einer lokalen Variable, einem Feldzugriff und einer Klassenangabe unterscheiden.
* *
* @param expression * @param expression
* @param offset * @param offset
* @return * @return
*/ */
private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) { private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) {
// FIXME Why does this take a String argument??? // Check for localVar:
String[] parts = expression.split("\\."); if (localVars.get(expression) != null) {
if (parts.length < 2) { return new LocalVar(expression, localVars.get(expression), offset);
// Check for localVar: } else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die
if (localVars.get(expression) != null) { // gleiche TPH bekommen
return new LocalVar(expression, localVars.get(expression), offset); return new FieldVar(new This(offset), expression, fields.get(expression).type(), offset);
} else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die } else if (reg.contains(expression)) {
// gleiche TPH bekommen return generateStaticClassName(expression, offset);
var field = fields.get(expression);
return new FieldVar(new This(offset), Modifier.isStatic(field.modifiers()), expression, fields.get(expression).type(), offset);
} else if (reg.contains(expression)) {
return generateStaticClassName(expression, offset);
} else {
// lokale Variable wurde ohne "var"-Keyword deklariert und direkt mit Wert versehen
localVars.put(expression, TypePlaceholder.fresh(offset));
return new LocalVar(expression, localVars.get(expression), offset);
}
}
return generateFieldVarOrClassname(expression, offset);
}
private Expression generateFieldVarOrClassname(String expression, Token offset) {
String[] parts = expression.split("\\.");
String whole = "";
Expression receiver = null;
for (String part : parts) {
whole += part;
// Check for Classname:
if (reg.contains(whole)) {
receiver = generateStaticClassName(whole, offset);
break;
}
whole += ".";
}
var fieldName = parts[parts.length - 1];
var isStatic = false;
if (parts.length < 2 || parts[0].contentEquals("this")) {
receiver = new This(offset);
isStatic = Modifier.isStatic(fields.get(fieldName).modifiers());
} else if (parts[0].contentEquals("super")) {
receiver = new Super(TypePlaceholder.fresh(offset), offset);
isStatic = Modifier.isStatic(compiler.getClass(new JavaClassName(superClass.getName().toString())).getField(fieldName).orElseThrow().modifier);
} else if (receiver == null) { // Handelt es sich um keinen Statischen Klassennamen:
String part = expression.substring(0, expression.length() - (1 + parts[parts.length - 1].length()));
receiver = generateLocalOrFieldVarOrClassName(part, offset);
} else { } else {
StaticClassName cname = (StaticClassName) receiver; // lokale Variable wurde ohne "var"-Keyword deklariert und direkt mit Wert versehen
var javaClassName = reg.getName(cname.getType().toString()); localVars.put(expression, TypePlaceholder.fresh(offset));
isStatic = Modifier.isStatic(compiler.getClass(javaClassName).getField(fieldName).orElseThrow().modifier); return new LocalVar(expression, localVars.get(expression), offset);
} }
return new FieldVar(receiver, isStatic, fieldName, TypePlaceholder.fresh(offset), offset);
} }
private Expression convert(Java17Parser.ArrayaccessexpressionContext arrayaccess) { private Expression convert(Java17Parser.ArrayaccessexpressionContext arrayaccess) {
@ -870,10 +830,8 @@ public class StatementGenerator {
private Statement convert(AssignexpressionContext expr) { private Statement convert(AssignexpressionContext expr) {
switch (expr.bop.getText()) { switch (expr.bop.getText()) {
case "=": case "=":
ExpressionContext leftside = expr.expression(0); AssignLeftSide leftHandSide = convertAssignLHS(convert(expr.expression(0)));
AssignLeftSide leftHandSide = convert(leftside.getText(), leftside.getStart()); return new Assign(leftHandSide, convert(expr.expression(1)), expr.getStart());
Statement ret = new Assign(leftHandSide, convert(expr.expression(1)), expr.getStart());
return ret;
case "+=": case "+=":
case "-=": case "-=":
case "*=": case "*=":
@ -890,8 +848,8 @@ public class StatementGenerator {
} }
} }
private AssignLeftSide convert(String leftHandSide, Token start) { private AssignLeftSide convertAssignLHS(Expression expr) {
Expression leftSide = generateLocalOrFieldVarOrClassName(leftHandSide, start); Expression leftSide = expr;
if (leftSide instanceof FieldVar) if (leftSide instanceof FieldVar)
return new AssignToField((FieldVar) leftSide); return new AssignToField((FieldVar) leftSide);
else if (leftSide instanceof LocalVar) else if (leftSide instanceof LocalVar)

View File

@ -269,7 +269,7 @@ public class SyntaxTreeGenerator {
} }
fielddecl.add(new Field(fieldname, fieldtype, fieldmodifiers, fieldoffset)); fielddecl.add(new Field(fieldname, fieldtype, fieldmodifiers, fieldoffset));
constructorParameters.add(new FormalParameter(fieldname, fieldtype, fieldoffset)); constructorParameters.add(new FormalParameter(fieldname, fieldtype, fieldoffset));
FieldVar fieldvar = new FieldVar(new This(offset), false, fieldname, fieldtype, fieldoffset); FieldVar fieldvar = new FieldVar(new This(offset), fieldname, fieldtype, fieldoffset);
constructorStatements.add(new Assign(new AssignToField(fieldvar), new LocalVar(fieldname, fieldtype, fieldoffset), offset)); constructorStatements.add(new Assign(new AssignToField(fieldvar), new LocalVar(fieldname, fieldtype, fieldoffset), offset));
Statement returnStatement = new Return(fieldvar, offset); Statement returnStatement = new Return(fieldvar, offset);
methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset)); methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset));

View File

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

View File

@ -1,5 +1,6 @@
package de.dhbwstuttgart.target.generate; package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
@ -139,7 +140,11 @@ public class StatementToTargetExpression implements ASTVisitor {
@Override @Override
public void visit(FieldVar fieldVar) { public void visit(FieldVar fieldVar) {
result = new TargetFieldVar(converter.convert(fieldVar.getType()), converter.convert(fieldVar.receiver.getType()), fieldVar.isStatic, converter.convert(fieldVar.receiver), fieldVar.fieldVarName); var isStatic = false;
var type = converter.convert(fieldVar.receiver.getType());
var clazz = converter.compiler.getClass(new JavaClassName(type.name()));
var field = clazz.getField(fieldVar.fieldVarName).orElseThrow();
result = new TargetFieldVar(converter.convert(fieldVar.getType()), type, Modifier.isStatic(field.modifier), converter.convert(fieldVar.receiver), fieldVar.fieldVarName);
} }
@Override @Override

View File

@ -1084,6 +1084,15 @@ public class TestComplete {
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
} }
@Test
public void testAssign() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Assign.jav");
var clazz = classFiles.get("Assign");
var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("m");
assertEquals(m.invoke(instance), 20);
}
@Test @Test
public void testBug122() throws Exception { public void testBug122() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug122.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug122.jav");