Compare commits

..

1 Commits

Author SHA1 Message Date
julian
b3ba2714da visualize constraints for mplr26 paper
Some checks failed
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 1m6s
2026-02-24 15:18:27 +01:00
4 changed files with 231 additions and 138 deletions

View File

@@ -422,6 +422,43 @@ public class JavaTXCompiler {
return typeInference(List.of(file));
}
public static String constraintSetToDot(ConstraintSet<Pair> c){
Iterator<String> colors = List.of(
"#FF0000", "#FF7F00", "#FFFF00", "#7FFF00", "#00FF00", "#00FF7F", "#00FFFF", "#007FFF",
"#0000FF", "#7F00FF", "#FF00FF", "#FF007F", "#BF0000", "#BF5F00", "#BFBF00", "#5FBF00",
"#00BF00", "#00BF5F", "#00BFBF", "#005FBF", "#0000BF", "#5F00BF", "#BF00BF", "#BF005F",
"#800000", "#804000", "#808000", "#408000", "#008000", "#008040", "#008080", "#004080",
"#000080", "#400080", "#800080", "#800040", "#FF4040", "#FF8040", "#FFFF40", "#80FF40",
"#40FF40", "#40FF80", "#40FFFF", "#4080FF", "#4040FF", "#8040FF", "#FF40FF", "#FF4080",
"#BF4040", "#BF8040", "#BFBF40", "#80BF40", "#40BF40", "#40BF80", "#40BFBF", "#4080BF",
"#4040BF", "#8040BF", "#BF40BF", "#BF4080", "#FF8080", "#FFBF80", "#FFFF80", "#BFFF80",
"#80FF80", "#80FFBF", "#80FFFF", "#80BFFF", "#8080FF", "#BF80FF", "#FF80FF", "#FF80BF").iterator();
StringBuilder sb = new StringBuilder();
sb.append("diagraph G{");
//and constraints to dot
sb.append(c.getUndConstraints().stream().map(Pair::toDot).collect(Collectors.joining("\n")));
//or constraints to dot
for (var orConstSet : c.getOderConstraints()){
for(var cons : orConstSet){
String color = colors.next();
sb.append(cons.stream().map(x -> x.toDot(color)).collect(Collectors.joining("\n")));
}
}
sb.append("}");
return sb.toString();
}
public static String q(String s) {
return "\"" + s.replace("\"", "\\\"") + "\"";
}
public List<ResultSet> typeInference(List<File> files) throws ClassNotFoundException, IOException {
Set<ClassOrInterface> allClasses = new HashSet<>();
@@ -438,6 +475,36 @@ public class JavaTXCompiler {
TYPE ty = new TYPE(definedClasses, allClasses);
var cons = ty.getConstraints();
var ANDconstraints = cons.getUndConstraints();
var ORConstraints = cons.getOderConstraints();
var orIterator = ORConstraints.iterator();
while(orIterator.hasNext()){
Set<Constraint<Pair>> y = orIterator.next();
if (y.isEmpty()) orIterator.remove();
else if (y.size() == 1){
ANDconstraints.addAll(y.iterator().next()); // add the OR constraint to the AND constraint since we only have one option
orIterator.remove();
}
}
String dot = constraintSetToDot(cons);
ANDconstraints.forEach(System.out::println);
for (var orc : ORConstraints){
System.out.println();
System.out.println("------");
System.out.println();
for(var hashs : orc){
System.out.print(hashs);
System.out.print("\n | \n");
}
}
Set<Set<UnifyPair>> results = new HashSet<>();
PlaceholderRegistry placeholderRegistry = new PlaceholderRegistry();

View File

@@ -85,11 +85,12 @@ public class Constraint<A extends IConstraintElement> extends HashSet<A> impleme
}
public String toString() {
return super.toString() + "\nisInherited = " + isInherited
+ " isOveridden = " + isImplemented
+ " msc[" + methodSignatureConstraint.size() + "] = " + methodSignatureConstraint
//" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" )
+ "\n";
return super.toString();
// + "\nisInherited = " + isInherited
// + " isOveridden = " + isImplemented
// + " msc[" + methodSignatureConstraint.size() + "] = " + methodSignatureConstraint
// //" + extendsContraint: " + (extendConstraint != null ? extendConstraint.toStringBase() : "null" )
// + "\n";
}
public String toStringBase() {

View File

@@ -4,6 +4,7 @@ import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
@@ -13,58 +14,60 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import static de.dhbwstuttgart.core.JavaTXCompiler.q;
public class Pair implements Serializable, IConstraintElement, ISerializableData {
public final RefTypeOrTPHOrWildcardOrGeneric TA1;
public final RefTypeOrTPHOrWildcardOrGeneric TA2;
public final RefTypeOrTPHOrWildcardOrGeneric TA1;
public final RefTypeOrTPHOrWildcardOrGeneric TA2;
private SourceLoc location;
private SourceLoc location;
private PairOperator eOperator = PairOperator.SMALLER;
private boolean noUnification = false;
private PairOperator eOperator = PairOperator.SMALLER;
private boolean noUnification = false;
private Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2) {
this.TA1 = TA1;
this.TA2 = TA2;
if (TA1 == null || TA2 == null)
throw new NullPointerException();
eOperator = PairOperator.SMALLER;
}
private Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2) {
this.TA1 = TA1;
this.TA2 = TA2;
if (TA1 == null || TA2 == null)
throw new NullPointerException();
eOperator = PairOperator.SMALLER;
}
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp) {
// Konstruktor
this(TA1, TA2);
this.eOperator = eOp;
}
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp) {
// Konstruktor
this(TA1, TA2);
this.eOperator = eOp;
}
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator e0p, SourceLoc location) {
this(TA1, TA2, e0p);
this.location = location;
}
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator e0p, SourceLoc location) {
this(TA1, TA2, e0p);
this.location = location;
}
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, boolean noUnification) {
// Konstruktor
this(TA1, TA2);
this.eOperator = eOp;
this.noUnification = noUnification;
}
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2, PairOperator eOp, boolean noUnification) {
// Konstruktor
this(TA1, TA2);
this.eOperator = eOp;
this.noUnification = noUnification;
}
public SourceLoc getLocation() {
return this.location;
}
public SourceLoc getLocation() {
return this.location;
}
public String toString() {
// otth: Gibt ein Paar als String aus --> zum Debuggen und Vergleichen
String strElement1 = "NULL";
String strElement2 = "NULL";
String Operator = "<.";
public String toString() {
// otth: Gibt ein Paar als String aus --> zum Debuggen und Vergleichen
String strElement1 = "NULL";
String strElement2 = "NULL";
String Operator = "<.";
if (TA1 != null)
strElement1 = TA1.toString();
if (TA1 != null)
strElement1 = TA1.toString();
if (TA2 != null)
strElement2 = TA2.toString();
if (TA2 != null)
strElement2 = TA2.toString();
/* PL ausskommentiert 2018-05-24
if(OperatorEqual())
@@ -75,103 +78,125 @@ public class Pair implements Serializable, IConstraintElement, ISerializableData
Operator = "<?";
*/
return "\n(P: " + strElement1 + " " + eOperator.toString() + " " + strElement2 + ")";
return "\n(P: " + strElement1 + " " + eOperator.toString() + " " + strElement2 + ")";
/*- Equals: " + bEqual*/
}
/*- Equals: " + bEqual*/
}
/**
* <br/>Author: J�rg B�uerle
*
* @param obj
* @return
*/
public boolean equals(Object obj) {
return (
(obj instanceof Pair pairObj) &&
pairObj.TA1.equals(this.TA1) &&
pairObj.TA2.equals(this.TA2)
);
}
/**
* <br/>Author: J�rg B�uerle
*
* @param obj
* @return
*/
public boolean equals(Object obj) {
return (
(obj instanceof Pair pairObj) &&
pairObj.TA1.equals(this.TA1) &&
pairObj.TA2.equals(this.TA2)
);
}
/**
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ Equal ist.
*/
public boolean OperatorEqual() {
return eOperator == PairOperator.EQUALSDOT;
}
/**
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ Equal ist.
*/
public boolean OperatorEqual() {
return eOperator == PairOperator.EQUALSDOT;
}
/**
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ Smaller ist.
*/
public boolean OperatorSmaller() {
return eOperator == PairOperator.SMALLER;
}
/**
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ Smaller ist.
*/
public boolean OperatorSmaller() {
return eOperator == PairOperator.SMALLER;
}
/**
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ SmallerExtends ist.
*/
public boolean OperatorSmallerExtends() {
return eOperator == PairOperator.SMALLERDOTWC;
}
/**
* Author: Arne Lüdtke<br/>
* Abfrage, ob Operator vom Typ SmallerExtends ist.
*/
public boolean OperatorSmallerExtends() {
return eOperator == PairOperator.SMALLERDOTWC;
}
/**
* Author: Arne Lüdtke<br/>
* Gibt den Operator zurück.
*/
public PairOperator GetOperator() {
return eOperator;
}
/**
* Author: Arne Lüdtke<br/>
* Gibt den Operator zurück.
*/
public PairOperator GetOperator() {
return eOperator;
}
public boolean OperatorSmallerDot() {
return eOperator == PairOperator.SMALLERDOT;
}
public boolean OperatorSmallerDot() {
return eOperator == PairOperator.SMALLERDOT;
}
static public Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
HashMap<String, TypePlaceholder> ret = new HashMap<>();
constraints.map((Pair p) -> {
if (p.TA1 instanceof TypePlaceholder) {
ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1);
}
if (p.TA2 instanceof TypePlaceholder) {
ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2);
}
return null;
});
return ret;
}
static public Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
HashMap<String, TypePlaceholder> ret = new HashMap<>();
constraints.map((Pair p) -> {
if (p.TA1 instanceof TypePlaceholder) {
ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1);
}
if (p.TA2 instanceof TypePlaceholder) {
ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2);
}
return null;
});
return ret;
}
@Override
public SerialMap toSerial(KeyStorage keyStorage) {
// because toString() will output TA1 and TA2 recursively, we can ignore potential infinite recursion here too
SerialMap serialized = new SerialMap();
serialized.put("ta1", this.TA1.toSerial(keyStorage));
serialized.put("ta2", this.TA2.toSerial(keyStorage));
serialized.put("op", this.eOperator.toString());
serialized.put("noUnification", this.noUnification ? 1 : 0);
serialized.put("location", this.location == null ? null : this.location.toSerial(keyStorage));
return serialized;
}
@Override
public SerialMap toSerial(KeyStorage keyStorage) {
// because toString() will output TA1 and TA2 recursively, we can ignore potential infinite recursion here too
SerialMap serialized = new SerialMap();
serialized.put("ta1", this.TA1.toSerial(keyStorage));
serialized.put("ta2", this.TA2.toSerial(keyStorage));
serialized.put("op", this.eOperator.toString());
serialized.put("noUnification", this.noUnification ? 1 : 0);
serialized.put("location", this.location == null ? null : this.location.toSerial(keyStorage));
return serialized;
}
public static Pair fromSerial(SerialMap data, UnifyContext context) {
String op = data.getValue("op").getOf(String.class);
SerialMap ta1 = data.getMap("ta1");
SerialMap ta2 = data.getMap("ta2");
boolean noUnification = data.getValue("noUnification").getOf(Integer.class) == 1;
SerialMap location = data.getMapOrNull("location");
public static Pair fromSerial(SerialMap data, UnifyContext context) {
String op = data.getValue("op").getOf(String.class);
SerialMap ta1 = data.getMap("ta1");
SerialMap ta2 = data.getMap("ta2");
boolean noUnification = data.getValue("noUnification").getOf(Integer.class) == 1;
SerialMap location = data.getMapOrNull("location");
var pair = new Pair(
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(ta1, context),
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(ta2, context),
PairOperator.fromString(op),
noUnification
);
if (location != null) pair.location = SourceLoc.fromSerial(location);
return pair;
}
var pair = new Pair(
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(ta1, context),
RefTypeOrTPHOrWildcardOrGeneric.fromSerial(ta2, context),
PairOperator.fromString(op),
noUnification
);
if (location != null) pair.location = SourceLoc.fromSerial(location);
return pair;
}
public String toDot(String color) {
return q(this.TA1.toString()) +
" -> " +
q(this.TA2.toString()) +
" [label=" +
q(this.GetOperator().toString()) +
",color=" + q(color) + "]" +
";\n";
}
public String toDot() {
return q(this.TA1.toString()) +
" -> " +
q(this.TA2.toString()) +
" [label=" +
q(this.GetOperator().toString()) +
"]" +
";\n";
}
}
// ino.end

View File

@@ -35,8 +35,8 @@ public class TYPE {
this.definedClasses = definedClasses;
}
public ConstraintSet getConstraints() {
ConstraintSet ret = new ConstraintSet();
public ConstraintSet<Pair> getConstraints() {
ConstraintSet<Pair> ret = new ConstraintSet<>();
for (ClassOrInterface cl : definedClasses) {
Set<ClassOrInterface> allClasses = TypeUnifyTaskHelper.getPresizedHashSet(allAvailableClasses.size());
allClasses.addAll(allAvailableClasses);
@@ -45,9 +45,9 @@ public class TYPE {
return ret;
}
private ConstraintSet getConstraintsClass(ClassOrInterface cl, TypeInferenceInformation info) {
ConstraintSet ret = new ConstraintSet();
ConstraintSet methConstrains;
private ConstraintSet<Pair> getConstraintsClass(ClassOrInterface cl, TypeInferenceInformation info) {
ConstraintSet<Pair> ret = new ConstraintSet<>();
ConstraintSet<Pair> methConstrains;
for(Method m : cl.getMethods()){
ret.addAll(methConstrains = getConstraintsMethod(m,info, cl));
m.constraints.addAll(methConstrains);
@@ -86,11 +86,11 @@ public class TYPE {
}
*/
private ConstraintSet getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) {
if(m.block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints
private ConstraintSet<Pair> getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) {
if(m.block == null)return new ConstraintSet<Pair>(); //Abstrakte Methoden generieren keine Constraints
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
TYPEStmt methodScope = new TYPEStmt(blockInfo);
ConstraintSet constraintSet = new ConstraintSet();
ConstraintSet<Pair> constraintSet = new ConstraintSet<>();
if (m.name.equals("main") && Modifier.isStatic(m.modifier) && m.getParameterList().getFormalparalist().size() == 1) {
// Add constraint for main method