Construct added, InferredTypes ausgelagert, TypeExpr fieldVar bei receiver = This keine Constraints mehr, InferredTypes transitive Typen aufgeloest

This commit is contained in:
Aldaron7 2018-03-16 19:39:11 +01:00
parent 7e88ddc3d5
commit 492f11a91e
8 changed files with 261 additions and 32 deletions

View File

@ -0,0 +1,97 @@
package de.dhbwstuttgart.strucTypes;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.strucTypes.constraint.ConstraintsSet;
import de.dhbwstuttgart.strucTypes.constraint.FieldConstraint;
import de.dhbwstuttgart.strucTypes.constraint.SubTypeConstraint;
import de.dhbwstuttgart.strucTypes.exception.ImpossibleSubTypeException;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.Field;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class Construct extends DefaultASTVisitor {
private List<SubTypeConstraint> subTypeConstraints = new ArrayList<>();
private ConstraintsSet constraintsSet = new ConstraintsSet();
private List<RefTypeOrTPHOrWildcardOrGeneric> newInterf = new ArrayList<>();
private InferredTypes inferredTypes = new InferredTypes();
private List<ClassOrInterface> constructedInterfaces = new ArrayList<>();
public Construct(ConstraintsSet constraintsSet, InferredTypes inferredTypes) throws ImpossibleSubTypeException {
this.constraintsSet = constraintsSet;
this.inferredTypes = inferredTypes;
this.gatherSubTypeConstraints(constraintsSet);
for (SubTypeConstraint constraint : this.subTypeConstraints) {
constraint.checkConstraintPossible();
}
}
public InferredTypes getInferredTypes() {
return inferredTypes;
}
public List<ClassOrInterface> getConstructedInterfaces() {
return constructedInterfaces;
}
private void gatherSubTypeConstraints(ConstraintsSet constraintsSet) {
this.subTypeConstraints.addAll(constraintsSet.getSubTypeConstraints());
constraintsSet.getFieldConstraints().forEach(fc -> this.newInterf.add(fc.getClassType()));
constraintsSet.getMethodConstraints().forEach(mc -> {
this.subTypeConstraints.addAll(mc.getArguments());
this.newInterf.add(mc.getClassType());
});
}
@Override
public void visit(TypePlaceholder typePlaceholder) {
JavaClassName name = new JavaClassName("de.dhbw.constructedinterface." + typePlaceholder.getName());
this.constructInterface(typePlaceholder, name);
}
@Override
public void visit(RefType refType) {
JavaClassName name = refType.getName();
this.constructInterface(refType, name);
}
private ClassOrInterface constructInterface(RefTypeOrTPHOrWildcardOrGeneric i, JavaClassName name) {
final int modifiers = Modifier.interfaceModifiers();
List<Field> fielddecl = new ArrayList<>();
List<Method> methods = new ArrayList<>();
List<Constructor> constructors = new ArrayList<>();
List<GenericTypeVar> generics = new ArrayList<>();
GenericDeclarationList genericClassParameters = new GenericDeclarationList(generics, i.getOffset());
final RefType superClass = this.createSuperClass();
final boolean isInterface = true;
List<RefTypeOrTPHOrWildcardOrGeneric> implementedInterfaces = new ArrayList<>();
final Token offset = i.getOffset();
this.constraintsSet.getFieldConstraints().stream().filter(fc -> fc.getClassType().equals(i)).forEach(fc -> {
TypePlaceholder type = TypePlaceholder.fresh(i.getOffset());
new Field(fc.getFieldName(), type, Modifier.fieldModifiers(), i.getOffset());
});
return new ClassOrInterface(modifiers, name, fielddecl, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
}
private RefType createSuperClass(){
JavaClassName name = new JavaClassName(Object.class.getName());
GenericDeclarationList genericsOfClass = new GenericDeclarationList(new ArrayList<>(), new NullToken());
return ClassOrInterface.generateTypeOfClass(name, genericsOfClass, new NullToken());
}
}

View File

@ -0,0 +1,85 @@
package de.dhbwstuttgart.strucTypes;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class InferredTypes implements Map<TypePlaceholder, RefTypeOrTPHOrWildcardOrGeneric> {
private Map<TypePlaceholder, RefTypeOrTPHOrWildcardOrGeneric> inferredTypes = new HashMap<>();
public void resolveTransitiveTypes() {
Set<TypePlaceholder> keySet = this.inferredTypes.keySet();
for (TypePlaceholder key : keySet) {
RefTypeOrTPHOrWildcardOrGeneric value = this.inferredTypes.get(key);
if (value instanceof TypePlaceholder && keySet.contains(value)) {
this.inferredTypes.put(key, this.inferredTypes.get(value));
}
}
}
@Override
public int size() {
return inferredTypes.size();
}
@Override
public boolean isEmpty() {
return inferredTypes.isEmpty();
}
@Override
public boolean containsKey(Object key) {
return inferredTypes.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
return inferredTypes.containsValue(value);
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric get(Object key) {
return inferredTypes.get(key);
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric put(TypePlaceholder key, RefTypeOrTPHOrWildcardOrGeneric value) {
return inferredTypes.put(key, value);
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric remove(Object key) {
return inferredTypes.remove(key);
}
@Override
public void putAll(Map<? extends TypePlaceholder, ? extends RefTypeOrTPHOrWildcardOrGeneric> m) {
inferredTypes.putAll(m);
}
@Override
public void clear() {
inferredTypes.clear();
}
@Override
public Set<TypePlaceholder> keySet() {
return inferredTypes.keySet();
}
@Override
public Collection<RefTypeOrTPHOrWildcardOrGeneric> values() {
return inferredTypes.values();
}
@Override
public Set<java.util.Map.Entry<TypePlaceholder, RefTypeOrTPHOrWildcardOrGeneric>> entrySet() {
return inferredTypes.entrySet();
}
}

View File

@ -1,22 +1,18 @@
package de.dhbwstuttgart.strucTypes;
import java.util.HashMap;
import java.util.Map;
import de.dhbwstuttgart.strucTypes.constraint.ConstraintsSet;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.statement.Return;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class StrucTYPE extends DefaultASTVisitor {
private SourceFile sourceFile;
private ConstraintsSet constraintsSet = new ConstraintsSet();
private Map<TypePlaceholder, RefTypeOrTPHOrWildcardOrGeneric> inferredTypes = new HashMap<>();
private InferredTypes inferredTypes = new InferredTypes();
public StrucTYPE(SourceFile sourceFile) {
this.sourceFile = sourceFile;
@ -32,8 +28,9 @@ public class StrucTYPE extends DefaultASTVisitor {
return this.constraintsSet;
}
public Map<TypePlaceholder, RefTypeOrTPHOrWildcardOrGeneric> getInferredTypes() {
return inferredTypes;
public InferredTypes getInferredTypes() {
this.inferredTypes.resolveTransitiveTypes();
return this.inferredTypes;
}
@Override

View File

@ -1,9 +1,7 @@
package de.dhbwstuttgart.strucTypes;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.dhbwstuttgart.strucTypes.constraint.ConstraintsSet;
import de.dhbwstuttgart.strucTypes.constraint.FieldConstraint;
@ -24,14 +22,13 @@ import de.dhbwstuttgart.syntaxtree.statement.NewClass;
import de.dhbwstuttgart.syntaxtree.statement.Return;
import de.dhbwstuttgart.syntaxtree.statement.This;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class TYPEExpr extends DefaultASTVisitor {
private ClassOrInterface aThis;
private ConstraintsSet constraints = new ConstraintsSet();
private Map<TypePlaceholder, RefTypeOrTPHOrWildcardOrGeneric> inferredTypes = new HashMap<>();
private InferredTypes inferredTypes = new InferredTypes();
public TYPEExpr() {
}
@ -40,7 +37,7 @@ public class TYPEExpr extends DefaultASTVisitor {
return this.constraints;
}
public Map<TypePlaceholder, RefTypeOrTPHOrWildcardOrGeneric> getInferredTypes() {
public InferredTypes getInferredTypes() {
return inferredTypes;
}
@ -60,7 +57,7 @@ public class TYPEExpr extends DefaultASTVisitor {
fieldVar.receiver.accept(this);
// Löst Typen zwischen Feld und Feldvariable auf
this.inferFieldVarTypes(fieldVar);
boolean receiverIsThis = this.inferFieldVarTypes(fieldVar);
// Ermittelt den Typ ty von fieldVar.receiver und fields(f)
TypeExtract fieldTypeVisitor = new TypeExtract();
@ -71,19 +68,23 @@ public class TYPEExpr extends DefaultASTVisitor {
f -> this.inferredTypes.put((TypePlaceholder) fieldVar.receiver.getType(), (RefType) f.getType()));
} // keine neuen Constraints
else {
FieldConstraint fieldConstraint = new FieldConstraint(fieldVar.receiver.getType(), fieldVar.fieldVarName,
fieldVar.getType());
if (!receiverIsThis) {
FieldConstraint fieldConstraint = new FieldConstraint(fieldVar.receiver.getType(),
fieldVar.fieldVarName, fieldVar.getType());
this.constraints.addConstraint(fieldConstraint);
}
}
}
private void inferFieldVarTypes(FieldVar fieldVar) {
private boolean inferFieldVarTypes(FieldVar fieldVar) {
if (fieldVar.receiver instanceof This) {
this.aThis.getFieldDecl().stream().filter(f -> f.getName().equals(fieldVar.fieldVarName))
// keine statische Polymorphie zugelassen
.findFirst()
.ifPresent(f -> this.inferredTypes.put((TypePlaceholder) fieldVar.getType(), f.getType()));
return true;
}
return false;
}
@Override

View File

@ -1,5 +1,7 @@
package de.dhbwstuttgart.strucTypes.constraint;
import de.dhbwstuttgart.strucTypes.exception.ImpossibleSubTypeException;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
/**
@ -26,4 +28,28 @@ public class SubTypeConstraint {
return supertype;
}
public boolean checkConstraintPossible() throws ImpossibleSubTypeException {
if (this.subtype instanceof RefType && this.supertype instanceof RefType) {
Class<?> subClass = this.createClass(((RefType) this.subtype).getName().toString());
Class<?> superClass = this.createClass(((RefType) this.supertype).getName().toString());
if (subClass != null && superClass != null) {
if (superClass.isAssignableFrom(subClass))
return true;
else
throw new ImpossibleSubTypeException(
String.format("%s ist kein subtyp von %s", subClass.getName(), superClass.getName()));
}
}
return true;
}
private Class<?> createClass(String name) {
try {
return ClassLoader.getSystemClassLoader().loadClass(name);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,28 @@
package de.dhbwstuttgart.strucTypes.exception;
public class ImpossibleSubTypeException extends Exception {
private static final long serialVersionUID = 1L;
public ImpossibleSubTypeException() {
super();
}
public ImpossibleSubTypeException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public ImpossibleSubTypeException(String message, Throwable cause) {
super(message, cause);
}
public ImpossibleSubTypeException(String message) {
super(message);
}
public ImpossibleSubTypeException(Throwable cause) {
super(cause);
}
}

View File

@ -1,14 +1,11 @@
package de.dhbwstuttgart.strucTypes.printutils;
import java.util.Map;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.strucTypes.InferredTypes;
public class PrintInferredTypes {
public static void print(Map<TypePlaceholder, RefTypeOrTPHOrWildcardOrGeneric> inferredTypes){
public static void print(InferredTypes inferredTypes){
System.out.println("\n Inferred Types:");
inferredTypes.keySet().forEach(key -> System.out.println(key + " <=> " + inferredTypes.get(key)));
inferredTypes.keySet().forEach(key -> System.out.println("[" + key + " -> " + inferredTypes.get(key) + "]"));
}
}

View File

@ -3,17 +3,15 @@ package strucType;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.strucTypes.InferredTypes;
import de.dhbwstuttgart.strucTypes.StrucTYPE;
import de.dhbwstuttgart.strucTypes.constraint.ConstraintsSet;
import de.dhbwstuttgart.strucTypes.printutils.PrintConstraints;
import de.dhbwstuttgart.strucTypes.printutils.PrintInferredTypes;
import de.dhbwstuttgart.strucTypes.printutils.SyntaxTreePrinter;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class TestStrucType {
public static final String rootDirectory = System.getProperty("user.dir") + "/test/strucType/javFiles/";
@ -21,12 +19,12 @@ public class TestStrucType {
@org.junit.Test
public void test() throws ClassNotFoundException, IOException {
ArrayList<File> files = new ArrayList<>();
// files.add(new File(rootDirectory + "testLocalVar.jav"));
// files.add(new File(rootDirectory + "testCast.jav"));
files.add(new File(rootDirectory + "testLocalVar.jav"));
files.add(new File(rootDirectory + "testCast.jav"));
files.add(new File(rootDirectory + "testNew.jav"));
// files.add(new File(rootDirectory + "testFieldVar.jav"));
// files.add(new File(rootDirectory + "testFieldMethod.jav"));
// files.add(new File(rootDirectory + "testPaperExample.jav"));
files.add(new File(rootDirectory + "testFieldVar.jav"));
files.add(new File(rootDirectory + "testFieldMethod.jav"));
files.add(new File(rootDirectory + "testPaperExample.jav"));
JavaTXCompiler compiler = new JavaTXCompiler(files);
for (File f : compiler.sourceFiles.keySet()) {
String name = f.getName();
@ -40,7 +38,7 @@ public class TestStrucType {
ConstraintsSet constraints = strucTYPE.getConstraints();
PrintConstraints.print(constraints);
Map<TypePlaceholder, RefTypeOrTPHOrWildcardOrGeneric> inferredTypes = strucTYPE.getInferredTypes();
InferredTypes inferredTypes = strucTYPE.getInferredTypes();
PrintInferredTypes.print(inferredTypes);
System.out.println("____________________________________________________________________________");