diff --git a/src/de/dhbwstuttgart/strucTypes/ClassOrInterfaceFactory.java b/src/de/dhbwstuttgart/strucTypes/ClassOrInterfaceFactory.java new file mode 100644 index 00000000..56fb4eb2 --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/ClassOrInterfaceFactory.java @@ -0,0 +1,25 @@ +package de.dhbwstuttgart.strucTypes; + +import java.util.Optional; + +import de.dhbwstuttgart.parser.scope.JavaClassName; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; +import de.dhbwstuttgart.syntaxtree.type.RefType; + +public class ClassOrInterfaceFactory { + + public static Optional createClass(JavaClassName name) { + try { + return Optional.of(ASTFactory.createClass(ClassLoader.getSystemClassLoader().loadClass(name.toString()))); + } catch (ClassNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return Optional.empty(); + } + + public static Optional createClass(RefType refType) { + return ClassOrInterfaceFactory.createClass(refType.getName()); + } +} diff --git a/src/de/dhbwstuttgart/strucTypes/Construct.java b/src/de/dhbwstuttgart/strucTypes/Construct.java new file mode 100644 index 00000000..0e02be7e --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/Construct.java @@ -0,0 +1,148 @@ +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.SyntaxTreeGenerator.GenericContext; +import de.dhbwstuttgart.parser.scope.JavaClassName; +import de.dhbwstuttgart.strucTypes.constraint.ConstraintsSet; +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.FormalParameter; +import de.dhbwstuttgart.syntaxtree.GenericDeclarationList; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; +import de.dhbwstuttgart.syntaxtree.Method; +import de.dhbwstuttgart.syntaxtree.ParameterList; +import de.dhbwstuttgart.syntaxtree.statement.Block; +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 subTypeConstraints = new ArrayList<>(); + private ConstraintsSet constraintsSet = new ConstraintsSet(); + private List newInterf = new ArrayList<>(); + private InferredTypes inferredTypes = new InferredTypes(); + private List 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 getConstructedInterfaces() { + this.newInterf.forEach(i -> i.accept(this)); + return constructedInterfaces; + } + + public List getSubTypeConstraints() { + return subTypeConstraints; + } + + 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("constructedinterface." + typePlaceholder.getName()); + this.constructedInterfaces.add(this.constructInterface(typePlaceholder, name)); + } + + // TODO check nur TPH in newInterf + @Override + public void visit(RefType refType) { + // JavaClassName name = refType.getName(); + // this.constructedInterfaces.add(this.constructInterface(refType, + // name)); + } + + private ClassOrInterface constructInterface(TypePlaceholder i, JavaClassName name) { + List fielddecl = new ArrayList<>(); + List methods = new ArrayList<>(); + List generics = new ArrayList<>(); + List parameterInhTyterm = new ArrayList<>(); + final Token offset = new NullToken(); + + // For über alle FieldConstraints mit ClassType i + this.constraintsSet.getFieldConstraints().stream().filter(fc -> fc.getClassType().equals(i)).forEach(fc -> { + TypePlaceholder type = TypePlaceholder.fresh(offset); + parameterInhTyterm.add(fc.getFieldType()); + // TODO generics.add(new GenericTypeVar(s, bounds, offset, + // endOffset)); mit type + generics.add(new GenericTypeVar( type.getName(), + new ArrayList<>(), offset, offset)); + Field field = new Field(fc.getFieldName(), type, Modifier.PUBLIC, offset); + fielddecl.add(field); + }); + + // For über alle MethodConstraints mit ClassType i + this.constraintsSet.getMethodConstraints().stream().filter(mc -> mc.getClassType().equals(i)).forEach(mc -> { + TypePlaceholder returnType = TypePlaceholder.fresh(offset); + parameterInhTyterm.add(mc.getReturnType()); + // TODO generics.add(new GenericTypeVar(s, bounds, offset, + // endOffset)); mit retrunType + generics.add(new GenericTypeVar(returnType.getName(), new ArrayList<>(), offset, offset)); + Block block = new Block(new ArrayList<>(), offset); + GenericDeclarationList gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), offset); + List params = new ArrayList<>(); + mc.getArguments().stream().map(a -> a.getSupertype()).forEach(supertype -> { + TypePlaceholder tph = TypePlaceholder.fresh(offset); + params.add(new FormalParameter(tph.getName(), tph, offset)); + parameterInhTyterm.add(supertype); + // TODO generics.add(new GenericTypeVar(s, bounds, offset, + // endOffset)); mit tph + generics.add(new GenericTypeVar(tph.getName(), new ArrayList<>(), offset, offset)); + }); + ParameterList parameterList = new ParameterList(params, offset); + Method method = new Method(Modifier.PUBLIC, mc.getMethodName(), returnType, parameterList, block, gtvDeclarations, offset); + methods.add(method); + }); + + RefType inh_tyterm = new RefType(name, parameterInhTyterm, offset); + TypePlaceholder x = TypePlaceholder.fresh(offset); + this.subTypeConstraints.add(new SubTypeConstraint(x, inh_tyterm)); + this.inferredTypes.put(i, x); + this.subTypeConstraints.forEach(sc -> sc.inferTypes(this.inferredTypes)); + + + final int modifiers = Modifier.PUBLIC; + final RefType superClass = this.createSuperClass(); + final boolean isInterface = true; + final List constructors = new ArrayList<>(); + final List implementedInterfaces = new ArrayList<>(); + GenericDeclarationList genericClassParameters = new GenericDeclarationList(generics, i.getOffset()); + ClassOrInterface constructedInterface = new ClassOrInterface(modifiers, name, fielddecl, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset); +// new ClassOrInterface(modifiers, name, fielddecl, methods, constructors, genericClassParameters, +// superClass, isInterface, implementedInterfaces, offset); + return constructedInterface; + } + + 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()); + } + +} diff --git a/src/de/dhbwstuttgart/strucTypes/DefaultASTVisitor.java b/src/de/dhbwstuttgart/strucTypes/DefaultASTVisitor.java new file mode 100644 index 00000000..8336f2b5 --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/DefaultASTVisitor.java @@ -0,0 +1,309 @@ +package de.dhbwstuttgart.strucTypes; + +import de.dhbwstuttgart.exceptions.NotImplementedException; +import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; +import de.dhbwstuttgart.syntaxtree.ASTVisitor; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.Constructor; +import de.dhbwstuttgart.syntaxtree.Field; +import de.dhbwstuttgart.syntaxtree.FormalParameter; +import de.dhbwstuttgart.syntaxtree.GenericDeclarationList; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; +import de.dhbwstuttgart.syntaxtree.Method; +import de.dhbwstuttgart.syntaxtree.ParameterList; +import de.dhbwstuttgart.syntaxtree.SourceFile; +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.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.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.Return; +import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid; +import de.dhbwstuttgart.syntaxtree.statement.StaticClassName; +import de.dhbwstuttgart.syntaxtree.statement.Super; +import de.dhbwstuttgart.syntaxtree.statement.SuperCall; +import de.dhbwstuttgart.syntaxtree.statement.This; +import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr; +import de.dhbwstuttgart.syntaxtree.statement.WhileStmt; +import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; +import de.dhbwstuttgart.syntaxtree.type.GenericRefType; +import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; + +public abstract class DefaultASTVisitor implements ASTVisitor { + + @Override + public void visit(ArgumentList argumentList) { + throw new NotImplementedException(); + } + + @Override + public void visit(LambdaExpression lambdaExpression) { + throw new NotImplementedException(); + } + + @Override + public void visit(Assign assign) { + throw new NotImplementedException(); + + } + + @Override + public void visit(BinaryExpr binary) { + throw new NotImplementedException(); + + } + + @Override + public void visit(Block block) { + throw new NotImplementedException(); + + } + + @Override + public void visit(CastExpr castExpr) { + throw new NotImplementedException(); + + } + + @Override + public void visit(EmptyStmt emptyStmt) { + throw new NotImplementedException(); + + } + + @Override + public void visit(FieldVar fieldVar) { + throw new NotImplementedException(); + + } + + @Override + public void visit(ForStmt forStmt) { + throw new NotImplementedException(); + + } + + @Override + public void visit(IfStmt ifStmt) { + throw new NotImplementedException(); + + } + + @Override + public void visit(InstanceOf instanceOf) { + throw new NotImplementedException(); + + } + + @Override + public void visit(LocalVar localVar) { + throw new NotImplementedException(); + + } + + @Override + public void visit(LocalVarDecl localVarDecl) { + throw new NotImplementedException(); + + } + + @Override + public void visit(MethodCall methodCall) { + throw new NotImplementedException(); + + } + + @Override + public void visit(NewClass methodCall) { + throw new NotImplementedException(); + + } + + @Override + public void visit(NewArray newArray) { + throw new NotImplementedException(); + + } + + @Override + public void visit(Return aReturn) { + throw new NotImplementedException(); + + } + + @Override + public void visit(ReturnVoid aReturn) { + throw new NotImplementedException(); + + } + + @Override + public void visit(StaticClassName staticClassName) { + throw new NotImplementedException(); + + } + + @Override + public void visit(Super aSuper) { + throw new NotImplementedException(); + + } + + @Override + public void visit(This aThis) { + throw new NotImplementedException(); + + } + + + @Override + public void visit(WhileStmt whileStmt) { + throw new NotImplementedException(); + + } + + @Override + public void visit(DoStmt whileStmt) { + throw new NotImplementedException(); + + } + + + @Override + public void visit(UnaryExpr unaryExpr) { + throw new NotImplementedException(); + + } + + @Override + public void visit(Literal literal) { + throw new NotImplementedException(); + + } + + @Override + public void visit(AssignToField assignLeftSide) { + throw new NotImplementedException(); + + } + + @Override + public void visit(AssignToLocal assignLeftSide) { + throw new NotImplementedException(); + + } + + @Override + public void visit(SuperCall superCall) { + throw new NotImplementedException(); + + } + + @Override + public void visit(ExpressionReceiver expressionReceiver) { + throw new NotImplementedException(); + + } + + @Override + public void visit(SourceFile sourceFile) { + throw new NotImplementedException(); + + } + + @Override + public void visit(GenericTypeVar genericTypeVar) { + throw new NotImplementedException(); + + } + + @Override + public void visit(FormalParameter formalParameter) { + throw new NotImplementedException(); + + } + + @Override + public void visit(GenericDeclarationList genericTypeVars) { + throw new NotImplementedException(); + + } + + @Override + public void visit(Field field) { + throw new NotImplementedException(); + + } + + @Override + public void visit(Method field) { + throw new NotImplementedException(); + + } + + @Override + public void visit(Constructor field) { + throw new NotImplementedException(); + + } + + @Override + public void visit(ParameterList formalParameters) { + throw new NotImplementedException(); + + } + + @Override + public void visit(ClassOrInterface classOrInterface) { + throw new NotImplementedException(); + + } + + @Override + public void visit(RefType refType) { + throw new NotImplementedException(); + + } + + @Override + public void visit(SuperWildcardType superWildcardType) { + throw new NotImplementedException(); + + } + + @Override + public void visit(TypePlaceholder typePlaceholder) { + throw new NotImplementedException(); + + } + + @Override + public void visit(ExtendsWildcardType extendsWildcardType) { + throw new NotImplementedException(); + + } + + @Override + public void visit(GenericRefType genericRefType) { + throw new NotImplementedException(); + + } + +} diff --git a/src/de/dhbwstuttgart/strucTypes/InferredTypes.java b/src/de/dhbwstuttgart/strucTypes/InferredTypes.java new file mode 100644 index 00000000..7fb49e12 --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/InferredTypes.java @@ -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 { + + private Map inferredTypes = new HashMap<>(); + + public void resolveTransitiveTypes() { + Set 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 m) { + inferredTypes.putAll(m); + } + + @Override + public void clear() { + inferredTypes.clear(); + } + + @Override + public Set keySet() { + return inferredTypes.keySet(); + } + + @Override + public Collection values() { + return inferredTypes.values(); + } + + @Override + public Set> entrySet() { + return inferredTypes.entrySet(); + } + +} diff --git a/src/de/dhbwstuttgart/strucTypes/StrucTYPE.java b/src/de/dhbwstuttgart/strucTypes/StrucTYPE.java new file mode 100644 index 00000000..dbca1113 --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/StrucTYPE.java @@ -0,0 +1,62 @@ +package de.dhbwstuttgart.strucTypes; + +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.RefType; +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 InferredTypes inferredTypes = new InferredTypes(); + + public StrucTYPE(SourceFile sourceFile) { + this.sourceFile = sourceFile; + } + + public ConstraintsSet getConstraints() { + for (ClassOrInterface cls : sourceFile.getClasses()) { + TYPEExpr typeExpr = new TYPEExpr(); + cls.accept(typeExpr); + cls.getMethods().forEach(m -> m.accept(this)); + this.evaluateTypeExpr(typeExpr); + } + return this.constraintsSet; + } + + public InferredTypes getInferredTypes() { + return this.inferredTypes; + } + + @Override + public void visit(Method method) { + // Es gibt nur ein Return Statement + Expression retexpr = ((Return) method.block.statements.get(0)).retexpr; + + RefTypeOrTPHOrWildcardOrGeneric methodReturnType = method.getReturnType(); + RefTypeOrTPHOrWildcardOrGeneric retExprType = retexpr.getType(); + + // ordnet dem Methodentyp den Returntyp zu [sigma(Mt)] + if (methodReturnType instanceof TypePlaceholder) { + this.inferredTypes.put((TypePlaceholder) methodReturnType, retExprType); + } + if (methodReturnType instanceof RefType && retExprType instanceof TypePlaceholder) { + this.inferredTypes.put((TypePlaceholder) retExprType, methodReturnType); + } + } + + private void evaluateTypeExpr(TYPEExpr typeExpr) { + this.inferredTypes.putAll(typeExpr.getInferredTypes()); + this.inferredTypes.resolveTransitiveTypes(); + this.constraintsSet.addConstraintsSet(typeExpr.getConstraints()); + // TODO infer types in constraints + this.constraintsSet.inferTypes(inferredTypes); + } + +} diff --git a/src/de/dhbwstuttgart/strucTypes/TYPEExpr.java b/src/de/dhbwstuttgart/strucTypes/TYPEExpr.java new file mode 100644 index 00000000..0da45426 --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/TYPEExpr.java @@ -0,0 +1,202 @@ +package de.dhbwstuttgart.strucTypes; + +import java.util.ArrayList; +import java.util.List; + +import de.dhbwstuttgart.strucTypes.constraint.ConstraintsSet; +import de.dhbwstuttgart.strucTypes.constraint.FieldConstraint; +import de.dhbwstuttgart.strucTypes.constraint.MethodConstraint; +import de.dhbwstuttgart.strucTypes.constraint.SubTypeConstraint; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.Field; +import de.dhbwstuttgart.syntaxtree.Method; +import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; +import de.dhbwstuttgart.syntaxtree.statement.Block; +import de.dhbwstuttgart.syntaxtree.statement.CastExpr; +import de.dhbwstuttgart.syntaxtree.statement.Expression; +import de.dhbwstuttgart.syntaxtree.statement.ExpressionReceiver; +import de.dhbwstuttgart.syntaxtree.statement.FieldVar; +import de.dhbwstuttgart.syntaxtree.statement.LocalVar; +import de.dhbwstuttgart.syntaxtree.statement.MethodCall; +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.TypePlaceholder; + +public class TYPEExpr extends DefaultASTVisitor { + + private ClassOrInterface aThis; + private ConstraintsSet constraints = new ConstraintsSet(); + private InferredTypes inferredTypes = new InferredTypes(); + + public TYPEExpr() { + } + + public ConstraintsSet getConstraints() { + return this.constraints; + } + + public InferredTypes getInferredTypes() { + return inferredTypes; + } + + @Override + public void visit(ClassOrInterface classOrInterface) { + this.aThis = classOrInterface; + classOrInterface.getMethods().forEach(m -> m.accept(this)); + } + + @Override + public void visit(LocalVar localVar) { + // keine neuen Constraints. Typisierung bereits im SyntaxTree vorhanden. + } + + @Override + public void visit(FieldVar fieldVar) { + fieldVar.receiver.accept(this); + + // Löst Typen zwischen Feld und Feldvariable auf + boolean receiverIsThis = this.inferFieldVarTypes(fieldVar); + + // Ermittelt den Typ ty von fieldVar.receiver und fields(f) + TypeExtract fieldTypeVisitor = new TypeExtract(); + if (receiverIsThis) { + this.aThis.accept(fieldTypeVisitor); + } else { + fieldVar.receiver.getType().accept(fieldTypeVisitor); + } + + if (!fieldTypeVisitor.isTypeVariable() && fieldTypeVisitor.getField(fieldVar.fieldVarName).isPresent()) { + fieldTypeVisitor.getField(fieldVar.fieldVarName).ifPresent( + f -> this.inferredTypes.put((TypePlaceholder) fieldVar.getType(), (RefType) f.getType())); + } // keine neuen Constraints + else { + FieldConstraint fieldConstraint = new FieldConstraint(fieldVar.receiver.getType(), fieldVar.fieldVarName, + fieldVar.getType()); + this.constraints.addConstraint(fieldConstraint); + } + } + + 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 + public void visit(MethodCall methodCall) { + methodCall.receiver.accept(this); + methodCall.arglist.accept(this); + + // ermittelt den Typ ty0 von methodCall.receiver und mtype(m, ty0) + TypeExtract methodTypeVisitor = new TypeExtract(); + if (methodCall.receiver instanceof ExpressionReceiver + && ((ExpressionReceiver) methodCall.receiver).expr instanceof This) { + this.aThis.accept(methodTypeVisitor); + } else { + methodCall.receiver.getType().accept(methodTypeVisitor); + } + + List arguments = methodCall.getArgumentList().getArguments(); + if (!methodTypeVisitor.isTypeVariable() + && methodTypeVisitor.getMethod(methodCall.name, arguments.size()).isPresent()) { + methodTypeVisitor.getMethod(methodCall.name, arguments.size()).ifPresent(m -> { + for (int i = 0; i < arguments.size(); i++) { + this.constraints.addConstraint(new SubTypeConstraint(arguments.get(i).getType(), + m.getParameterList().getParameterAt(i).getType())); + } + this.inferredTypes.put((TypePlaceholder) methodCall.getType(), (RefType) m.getReturnType()); + }); + } else { + MethodConstraint methodConstraint = new MethodConstraint(methodCall.receiver.getType(), methodCall.name, + new ArrayList(), methodCall.getType()); + arguments.forEach(e -> methodConstraint.addArguments(e.getType())); + this.constraints.addConstraint(methodConstraint); + } + } + + @Override + public void visit(ArgumentList argumentList) { + argumentList.getArguments().forEach(a -> a.accept(this)); + } + + @Override + public void visit(CastExpr castExpr) { + castExpr.expr.accept(this); + // TODO RefType equals implementieren + if (((RefType) castExpr.getType()).getName().equals(this.aThis.getClassName())) { + // keine neuen Constraints + } else { + // TODO implement generics + } + } + + @Override + public void visit(NewClass newClass) { + newClass.getArgumentList().accept(this); + RefType type = (RefType) newClass.getType(); + TypeExtract typeExtract = new TypeExtract(); + // TODO RefType equals implementieren + if (type.getName().equals(this.aThis.getClassName())) { + this.aThis.accept(typeExtract); + } else { + type.accept(typeExtract); + // TODO implement generics + } + this.createNewClassSubTypeConstraints(newClass, typeExtract); + } + + private void createNewClassSubTypeConstraints(NewClass newClass, TypeExtract typeExtract) { + List arguments = newClass.getArgumentList().getArguments(); + List fields = typeExtract.getFields(); + int argumentsSize = arguments.size(); + int fieldsSize = fields.size(); + if (argumentsSize != fieldsSize) { + throw new IllegalArgumentException(String.format( + "The number of fields (%d) in %s doesn't match the number of arguments (%d) passed to its constructor.", + fieldsSize, newClass.name, argumentsSize)); + } + for (int i = 0; i < argumentsSize; i++) { + SubTypeConstraint subTypeConstraint = new SubTypeConstraint(arguments.get(i).getType(), + fields.get(i).getType()); + this.constraints.addConstraint(subTypeConstraint); + } + } + + @Override + public void visit(This aThis) { + //TODO TPH von This mit Klasse in inferredTypes verknüpfen +// if (this.aThis != null) { +// this.inferredTypes.put((TypePlaceholder) aThis.getType(), (RefType) this.aThis.getType()); +// } + + } + + @Override + public void visit(ExpressionReceiver expressionReceiver) { + expressionReceiver.expr.accept(this); + } + + @Override + public void visit(Method method) { + method.block.accept(this); + } + + @Override + public void visit(Block block) { + // Es gibt nur ein Statement: Return + block.getStatements().forEach(s -> s.accept(this)); + } + + @Override + public void visit(Return aReturn) { + aReturn.retexpr.accept(this); + } + +} diff --git a/src/de/dhbwstuttgart/strucTypes/TypeExtract.java b/src/de/dhbwstuttgart/strucTypes/TypeExtract.java new file mode 100644 index 00000000..22f5f34e --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/TypeExtract.java @@ -0,0 +1,104 @@ +package de.dhbwstuttgart.strucTypes; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import de.dhbwstuttgart.parser.scope.JavaClassName; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.Constructor; +import de.dhbwstuttgart.syntaxtree.Field; +import de.dhbwstuttgart.syntaxtree.Method; +import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; + +/** + * Extrahiert die typisierten Felder und Methoden von ClassOrInterface bzw. von + * RefType rekursiv über alle Superklassen und implementierten Interfaces. + * + * @author mvr + * + */ +public class TypeExtract extends DefaultASTVisitor { + + private List fields = new ArrayList<>(); + private List methods = new ArrayList<>(); + private List constructors = new ArrayList<>(); + private boolean typeVariable = false; + private boolean initialClass = true; + + public List getFields() { + return this.fields; + } + + public List getMethods() { + return this.methods; + } + + public List getConstructors() { + return constructors; + } + + public Optional getField(String fieldName) { + return this.fields.stream().filter(f -> f.getName().equals(fieldName)) + // keine statische Polymorphie zugelassen + .findFirst(); + } + + public Optional getMethod(String methodName, int parameterCount) { + return this.methods.stream() + .filter(m -> m.getName().equals(methodName) + && m.getParameterList().getFormalparalist().size() == parameterCount) + // keine statische Polymorphie zugelassen + .findFirst(); + } + + public boolean isTypeVariable() { + return this.typeVariable; + } + + @Override + public void visit(ClassOrInterface classOrInterface) { + classOrInterface.getFieldDecl().forEach(f -> f.accept(this)); + classOrInterface.getMethods().forEach(m -> m.accept(this)); + classOrInterface.getConstructors().forEach(c -> { + if (c != null && this.initialClass) + c.accept(this); + }); + this.initialClass = false; + // superClass(Object) -> Object => unendliche Rekursionstiefe! + if (!classOrInterface.getClassName().equals(new JavaClassName("java.lang.Object"))) { + classOrInterface.getSuperClass().accept(this); + classOrInterface.getSuperInterfaces().forEach(i -> i.accept(this)); + } + } + + @Override + public void visit(RefType refType) { + this.typeVariable = false; + ClassOrInterfaceFactory.createClass(refType).ifPresent(c -> c.accept(this)); + } + + @Override + public void visit(Field field) { +// if (field.getType() instanceof RefType) + this.fields.add(field); + } + + @Override + public void visit(Method method) { + if (method.getReturnType() instanceof RefType) + this.methods.add(method); + } + + @Override + public void visit(TypePlaceholder typePlaceholder) { + this.typeVariable = true; + } + + @Override + public void visit(Constructor constructor) { + this.constructors.add(constructor); + } + +} diff --git a/src/de/dhbwstuttgart/strucTypes/constraint/ConstraintsSet.java b/src/de/dhbwstuttgart/strucTypes/constraint/ConstraintsSet.java new file mode 100644 index 00000000..c9347627 --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/constraint/ConstraintsSet.java @@ -0,0 +1,56 @@ +package de.dhbwstuttgart.strucTypes.constraint; + +import java.util.ArrayList; +import java.util.List; + +import de.dhbwstuttgart.strucTypes.InferredTypes; + +public class ConstraintsSet { + + private List subTypeConstraints; + private List fieldConstraints; + private List methodConstraints; + + public ConstraintsSet() { + this.subTypeConstraints = new ArrayList<>(); + this.fieldConstraints = new ArrayList<>(); + this.methodConstraints = new ArrayList<>(); + } + + public List getSubTypeConstraints() { + return subTypeConstraints; + } + + public List getFieldConstraints() { + return fieldConstraints; + } + + public List getMethodConstraints() { + return methodConstraints; + } + + public void addConstraint(SubTypeConstraint constraint) { + this.subTypeConstraints.add(constraint); + } + + public void addConstraint(FieldConstraint constraint) { + this.fieldConstraints.add(constraint); + } + + public void addConstraint(MethodConstraint constraint) { + this.methodConstraints.add(constraint); + } + + public void addConstraintsSet(ConstraintsSet constraintsSet) { + constraintsSet.getSubTypeConstraints().forEach(this::addConstraint); + constraintsSet.getFieldConstraints().forEach(this::addConstraint); + constraintsSet.getMethodConstraints().forEach(this::addConstraint); + } + + public void inferTypes(InferredTypes inferredTypes) { + this.subTypeConstraints.forEach(c -> c.inferTypes(inferredTypes)); + this.fieldConstraints.forEach(c -> c.inferTypes(inferredTypes)); + this.methodConstraints.forEach(c -> c.inferTypes(inferredTypes)); + } + +} diff --git a/src/de/dhbwstuttgart/strucTypes/constraint/FieldConstraint.java b/src/de/dhbwstuttgart/strucTypes/constraint/FieldConstraint.java new file mode 100644 index 00000000..abe2b119 --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/constraint/FieldConstraint.java @@ -0,0 +1,46 @@ +package de.dhbwstuttgart.strucTypes.constraint; + +import de.dhbwstuttgart.strucTypes.InferredTypes; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; + +/** + * fc(c, f, c') : Klasse/Typ c hat ein Feld f mit Typ c' + * + * @author mvr + * + */ +public class FieldConstraint { + + private RefTypeOrTPHOrWildcardOrGeneric classType; + private String fieldName; + private RefTypeOrTPHOrWildcardOrGeneric fieldType; + + public FieldConstraint(RefTypeOrTPHOrWildcardOrGeneric classType, String fieldName, + RefTypeOrTPHOrWildcardOrGeneric fieldType) { + this.classType = classType; + this.fieldName = fieldName; + this.fieldType = fieldType; + } + + public RefTypeOrTPHOrWildcardOrGeneric getClassType() { + return classType; + } + + public RefTypeOrTPHOrWildcardOrGeneric getFieldType() { + return fieldType; + } + + public String getFieldName() { + return fieldName; + } + + public void inferTypes(InferredTypes inferredTypes) { + if (inferredTypes.containsKey(classType)) { + this.classType = inferredTypes.get(classType); + } + if (inferredTypes.containsKey(fieldType)) { + this.fieldType = inferredTypes.get(fieldType); + } + } + +} diff --git a/src/de/dhbwstuttgart/strucTypes/constraint/MethodConstraint.java b/src/de/dhbwstuttgart/strucTypes/constraint/MethodConstraint.java new file mode 100644 index 00000000..285698ef --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/constraint/MethodConstraint.java @@ -0,0 +1,74 @@ +package de.dhbwstuttgart.strucTypes.constraint; + +import java.util.List; + +import org.antlr.v4.runtime.Token; + +import de.dhbwstuttgart.strucTypes.InferredTypes; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; + +/** + * mc(c, m, C, (c', C')) : Klasse/Typ c hat Methode m mit Argumenten von Typ C + * mit Rückgabewert c' und Subtyp-Constraints C <. C' wobei C = {c1,... , cn) + * + * @author mvr + * + */ +public class MethodConstraint { + + private RefTypeOrTPHOrWildcardOrGeneric classType; + private RefTypeOrTPHOrWildcardOrGeneric returnType; + private String methodName; + private List arguments; + + public MethodConstraint(RefTypeOrTPHOrWildcardOrGeneric classType, String methodName, + List arguments, RefTypeOrTPHOrWildcardOrGeneric returnType) { + this.classType = classType; + this.returnType = returnType; + this.methodName = methodName; + this.arguments = arguments; + } + + public RefTypeOrTPHOrWildcardOrGeneric getClassType() { + return classType; + } + + public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { + return returnType; + } + + public String getMethodName() { + return methodName; + } + + public List getArguments() { + return arguments; + } + + public void addArguments(SubTypeConstraint... subTypeConstraints) { + for (SubTypeConstraint subTypeConstraint : subTypeConstraints) { + this.arguments.add(subTypeConstraint); + } + } + + public void addArguments(RefTypeOrTPHOrWildcardOrGeneric... parameters) { + for (RefTypeOrTPHOrWildcardOrGeneric parameter : parameters) { + Token offset = parameter.getOffset(); + TypePlaceholder tph = TypePlaceholder.fresh(offset); + SubTypeConstraint subTypeConstraint = new SubTypeConstraint(parameter, tph); + this.arguments.add(subTypeConstraint); + } + } + + public void inferTypes(InferredTypes inferredTypes) { + if (inferredTypes.containsKey(classType)) { + this.classType = inferredTypes.get(classType); + } + if (inferredTypes.containsKey(returnType)) { + this.returnType = inferredTypes.get(returnType); + } + arguments.forEach(c -> c.inferTypes(inferredTypes)); + } + +} diff --git a/src/de/dhbwstuttgart/strucTypes/constraint/SubTypeConstraint.java b/src/de/dhbwstuttgart/strucTypes/constraint/SubTypeConstraint.java new file mode 100644 index 00000000..1e4248e4 --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/constraint/SubTypeConstraint.java @@ -0,0 +1,65 @@ +package de.dhbwstuttgart.strucTypes.constraint; + +import de.dhbwstuttgart.strucTypes.InferredTypes; +import de.dhbwstuttgart.strucTypes.exception.ImpossibleSubTypeException; +import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; + +/** + * c <. c' : c ist subtyp von c' + * + * @author mvr + * + */ +public class SubTypeConstraint { + + private RefTypeOrTPHOrWildcardOrGeneric subtype; + private RefTypeOrTPHOrWildcardOrGeneric supertype; + + public SubTypeConstraint(RefTypeOrTPHOrWildcardOrGeneric subtype, RefTypeOrTPHOrWildcardOrGeneric supertype) { + this.subtype = subtype; + this.supertype = supertype; + } + + public RefTypeOrTPHOrWildcardOrGeneric getSubtype() { + return subtype; + } + + public RefTypeOrTPHOrWildcardOrGeneric getSupertype() { + return supertype; + } + + public void inferTypes(InferredTypes inferredTypes) { + if (inferredTypes.containsKey(subtype)) { + this.subtype = inferredTypes.get(subtype); + } + if (inferredTypes.containsKey(supertype)) { + this.supertype = inferredTypes.get(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; + } + +} diff --git a/src/de/dhbwstuttgart/strucTypes/exception/ImpossibleSubTypeException.java b/src/de/dhbwstuttgart/strucTypes/exception/ImpossibleSubTypeException.java new file mode 100644 index 00000000..89bd123d --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/exception/ImpossibleSubTypeException.java @@ -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); + } + +} diff --git a/src/de/dhbwstuttgart/strucTypes/printutils/PrintConstraints.java b/src/de/dhbwstuttgart/strucTypes/printutils/PrintConstraints.java new file mode 100644 index 00000000..ae9399b7 --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/printutils/PrintConstraints.java @@ -0,0 +1,87 @@ +package de.dhbwstuttgart.strucTypes.printutils; + +import java.util.List; + +import de.dhbwstuttgart.strucTypes.DefaultASTVisitor; +import de.dhbwstuttgart.strucTypes.constraint.ConstraintsSet; +import de.dhbwstuttgart.strucTypes.constraint.FieldConstraint; +import de.dhbwstuttgart.strucTypes.constraint.MethodConstraint; +import de.dhbwstuttgart.strucTypes.constraint.SubTypeConstraint; +import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; + +public class PrintConstraints extends DefaultASTVisitor { + + public void print(ConstraintsSet constraintsSet) { + printSubTypeConstraints(constraintsSet.getSubTypeConstraints()); + printFieldConstraints(constraintsSet.getFieldConstraints()); + printMethodConstraints(constraintsSet.getMethodConstraints()); + } + + public void printSubTypeConstraints(List constraints) { + System.out.println("\n SubTypeConstraints:"); + constraints.forEach(c -> { + c.getSubtype().accept(this); + System.out.print(" <* "); + c.getSupertype().accept(this); + System.out.println(); + }); + } + + public void printFieldConstraints(List constraints) { + System.out.println("\n FieldConstraints:"); + constraints.forEach(c -> { + System.out.print("F("); + c.getClassType().accept(this); + System.out.print(", "); + System.out.print(c.getFieldName()); + System.out.print(", "); + c.getFieldType().accept(this); + System.out.println(")"); + }); + } + + public void printMethodConstraints(List constraints) { + System.out.println("\n MethodConstraints:"); + constraints.forEach(c -> { + System.out.print("M("); + c.getClassType().accept(this); + System.out.print(", "); + System.out.print(c.getMethodName() + ", ["); + c.getArguments().forEach(a -> { + a.getSubtype().accept(this); + System.out.print(", "); + }); + System.out.print("],("); + c.getReturnType().accept(this); + System.out.print(", ["); + c.getArguments().forEach(a -> { + a.getSupertype().accept(this); + System.out.print(", "); + }); + System.out.print("]))"); + System.out.println(); + }); + + } + + @Override + public void visit(RefType refType) { + List paraList = refType.getParaList(); + System.out.print(refType.getName()); + if (!paraList.isEmpty()) { + System.out.print(" <"); + paraList.forEach(p -> { + p.accept(this); + System.out.print(", "); + }); + System.out.print(">"); + } + } + + @Override + public void visit(TypePlaceholder typePlaceholder) { + System.out.print(typePlaceholder); + } +} diff --git a/src/de/dhbwstuttgart/strucTypes/printutils/PrintInferredTypes.java b/src/de/dhbwstuttgart/strucTypes/printutils/PrintInferredTypes.java new file mode 100644 index 00000000..ae6ccdc3 --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/printutils/PrintInferredTypes.java @@ -0,0 +1,11 @@ +package de.dhbwstuttgart.strucTypes.printutils; + +import de.dhbwstuttgart.strucTypes.InferredTypes; + +public class PrintInferredTypes { + + public static void print(InferredTypes inferredTypes){ + System.out.println("\n Inferred Types:"); + inferredTypes.keySet().forEach(key -> System.out.println("[" + key + " -> " + inferredTypes.get(key) + "]")); + } +} diff --git a/src/de/dhbwstuttgart/strucTypes/printutils/SyntaxTreePrinter.java b/src/de/dhbwstuttgart/strucTypes/printutils/SyntaxTreePrinter.java new file mode 100644 index 00000000..a85c9826 --- /dev/null +++ b/src/de/dhbwstuttgart/strucTypes/printutils/SyntaxTreePrinter.java @@ -0,0 +1,390 @@ +package de.dhbwstuttgart.strucTypes.printutils; + +import java.util.Collection; +import java.util.List; + +import de.dhbwstuttgart.exceptions.NotImplementedException; +import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; +import de.dhbwstuttgart.parser.scope.JavaClassName; +import de.dhbwstuttgart.syntaxtree.ASTVisitor; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.Constructor; +import de.dhbwstuttgart.syntaxtree.Field; +import de.dhbwstuttgart.syntaxtree.FormalParameter; +import de.dhbwstuttgart.syntaxtree.GenericDeclarationList; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; +import de.dhbwstuttgart.syntaxtree.Method; +import de.dhbwstuttgart.syntaxtree.ParameterList; +import de.dhbwstuttgart.syntaxtree.SourceFile; +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.CastExpr; +import de.dhbwstuttgart.syntaxtree.statement.DoStmt; +import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt; +import de.dhbwstuttgart.syntaxtree.statement.Expression; +import de.dhbwstuttgart.syntaxtree.statement.ExpressionReceiver; +import de.dhbwstuttgart.syntaxtree.statement.FieldVar; +import de.dhbwstuttgart.syntaxtree.statement.ForStmt; +import de.dhbwstuttgart.syntaxtree.statement.IfStmt; +import de.dhbwstuttgart.syntaxtree.statement.InstanceOf; +import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; +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.Receiver; +import de.dhbwstuttgart.syntaxtree.statement.Return; +import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid; +import de.dhbwstuttgart.syntaxtree.statement.StaticClassName; +import de.dhbwstuttgart.syntaxtree.statement.Super; +import de.dhbwstuttgart.syntaxtree.statement.SuperCall; +import de.dhbwstuttgart.syntaxtree.statement.This; +import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr; +import de.dhbwstuttgart.syntaxtree.statement.WhileStmt; +import de.dhbwstuttgart.syntaxtree.statement.Literal; +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.SuperWildcardType; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; + +public class SyntaxTreePrinter implements ASTVisitor { + + @Override + public void visit(SourceFile sourceFile) { + sourceFile.KlassenVektor.forEach(cl -> cl.accept(this)); + } + + @Override + public void visit(ClassOrInterface classOrInterface) { + JavaClassName className = classOrInterface.getClassName(); + List fields = classOrInterface.getFieldDecl(); + List methods = classOrInterface.getMethods(); + RefType superClass = classOrInterface.getSuperClass(); + Collection implementedInterfaces = classOrInterface.getSuperInterfaces(); + GenericDeclarationList generics = classOrInterface.getGenerics(); + + System.out.print("class: " + className); + if (generics.iterator().hasNext()) { + System.out.print(" <"); + generics.forEach(g -> { + g.accept(this); + System.out.print(", "); + }); + System.out.print(">"); + } + System.out.println(); + + fields.forEach(f -> f.accept(this)); + methods.forEach(m -> m.accept(this)); + + System.out.print("\n superClass: "); + superClass.accept(this); + System.out.println(); + + if (!implementedInterfaces.isEmpty()) { + System.out.println("\n implemented Interfaces: "); + implementedInterfaces.forEach(i -> i.accept(this)); + } + + } + + @Override + public void visit(Field field) { + String name = field.getName(); + RefTypeOrTPHOrWildcardOrGeneric type = field.getType(); + System.out.print("field: " + name + " : "); + type.accept(this); + System.out.println(); + + } + + @Override + public void visit(Method method) { + String name = method.getName(); + RefTypeOrTPHOrWildcardOrGeneric returnType = method.getReturnType(); + ParameterList parameterList = method.getParameterList(); + System.out.print("\n method: " + name + " : "); + returnType.accept(this); + System.out.println(); + parameterList.accept(this); + method.block.accept(this); + + } + + @Override + public void visit(Block block) { + block.statements.forEach(s -> s.accept(this)); + } + + @Override + public void visit(ArgumentList argumentList) { + List arguments = argumentList.getArguments(); + if (!arguments.isEmpty()) { + System.out.println("arguments: "); + arguments.forEach(a -> a.accept(this)); + } + } + + @Override + public void visit(ParameterList formalParameters) { + List formalparalist = formalParameters.getFormalparalist(); + formalparalist.forEach(p -> p.accept(this)); + + } + + @Override + public void visit(FormalParameter formalParameter) { + String name = formalParameter.getName(); + RefTypeOrTPHOrWildcardOrGeneric type = formalParameter.getType(); + System.out.print("parameter: " + name + " : "); + type.accept(this); + System.out.println(); + } + + @Override + public void visit(MethodCall methodCall) { + String name = methodCall.name; + RefTypeOrTPHOrWildcardOrGeneric type = methodCall.getType(); + ArgumentList argumentList = methodCall.getArgumentList(); + Receiver receiver = methodCall.receiver; + System.out.print("methodCall: " + name + " : "); + type.accept(this); + System.out.println(); + argumentList.accept(this); + System.out.print("receiver: "); + receiver.accept(this); + + } + + @Override + public void visit(Return aReturn) { + RefTypeOrTPHOrWildcardOrGeneric type = aReturn.getType(); + System.out.println("returnType: " + type); + aReturn.retexpr.accept(this); + } + + @Override + public void visit(LocalVar localVar) { + String name = localVar.name; + RefTypeOrTPHOrWildcardOrGeneric type = localVar.getType(); + System.out.print("localVar: " + name + " : "); + type.accept(this); + System.out.println(); + } + + @Override + public void visit(LocalVarDecl localVarDecl) { + throw new NotImplementedException(); + } + + @Override + public void visit(FieldVar fieldVar) { + String name = fieldVar.fieldVarName; + RefTypeOrTPHOrWildcardOrGeneric type = fieldVar.getType(); + Expression receiver = fieldVar.receiver; + System.out.print("fieldVar: " + name + " : "); + type.accept(this); + System.out.println(); + System.out.println("receiver: "); + receiver.accept(this); + } + + @Override + public void visit(CastExpr castExpr) { + Expression expr = castExpr.expr; + RefTypeOrTPHOrWildcardOrGeneric type = castExpr.getType(); + System.out.print("castExpr: "); + expr.accept(this); + System.out.print("typeCastExpr: "); + type.accept(this); + System.out.println(); + + } + + @Override + public void visit(NewClass newClass) { + String name = newClass.name; + RefTypeOrTPHOrWildcardOrGeneric type = newClass.getType(); + ArgumentList argumentList = newClass.getArgumentList(); + System.out.print("new: " + name + " : "); + type.accept(this); + System.out.println(); + argumentList.accept(this); + + } + + @Override + public void visit(This aThis) { + ArgumentList arglist = aThis.arglist; + RefTypeOrTPHOrWildcardOrGeneric type = aThis.getType(); + System.out.print("this : "); + type.accept(this); + if (arglist != null) + arglist.accept(this); + System.out.println(); + } + + @Override + public void visit(RefType refType) { + List paraList = refType.getParaList(); + System.out.print(refType.getName()); + if (!paraList.isEmpty()) { + System.out.print(" <"); + paraList.forEach(p -> { + p.accept(this); + System.out.print(", "); + }); + System.out.print(">"); + } + } + + @Override + public void visit(TypePlaceholder typePlaceholder) { + String name = typePlaceholder.getName(); + System.out.print("TPH " + name); + + } + + @Override + public void visit(NewArray newArray) { + throw new NotImplementedException(); + } + + @Override + public void visit(ReturnVoid aReturn) { + throw new NotImplementedException(); + } + + @Override + public void visit(StaticClassName staticClassName) { + throw new NotImplementedException(); + } + + @Override + public void visit(Super aSuper) { + throw new NotImplementedException(); + } + + + @Override + public void visit(LambdaExpression lambdaExpression) { + throw new NotImplementedException(); + + } + + @Override + public void visit(WhileStmt whileStmt) { + throw new NotImplementedException(); + } + + @Override + public void visit(DoStmt whileStmt) { + throw new NotImplementedException(); + } + + @Override + public void visit(Assign assign) { + throw new NotImplementedException(); + + } + + @Override + public void visit(ForStmt forStmt) { + throw new NotImplementedException(); + } + + @Override + public void visit(BinaryExpr binary) { + throw new NotImplementedException(); + } + + @Override + public void visit(IfStmt ifStmt) { + throw new NotImplementedException(); + } + + @Override + public void visit(EmptyStmt emptyStmt) { + System.out.println("empty statement"); + } + + + @Override + public void visit(Literal literal) { + RefTypeOrTPHOrWildcardOrGeneric type = literal.getType(); + System.out.print("literal: "); + type.accept(this); + } + + @Override + public void visit(InstanceOf instanceOf) { + throw new NotImplementedException(); + } + + @Override + public void visit(AssignToField assignLeftSide) { + throw new NotImplementedException(); + } + + @Override + public void visit(AssignToLocal assignLeftSide) { + throw new NotImplementedException(); + } + + @Override + public void visit(SuperCall superCall) { + throw new NotImplementedException(); + } + + @Override + public void visit(ExpressionReceiver expressionReceiver) { + Expression expr = expressionReceiver.expr; + RefTypeOrTPHOrWildcardOrGeneric type = expressionReceiver.getType(); + System.out.print("expressionReceiverType: " + type); + System.out.print(" expressionReceiver: "); + expr.accept(this); + + } + + @Override + public void visit(GenericTypeVar genericTypeVar) { + System.out.print(genericTypeVar); + } + + @Override + public void visit(GenericDeclarationList genericTypeVars) { + throw new NotImplementedException(); + } + + @Override + public void visit(Constructor field) { + throw new NotImplementedException(); + } + + @Override + public void visit(SuperWildcardType superWildcardType) { + throw new NotImplementedException(); + } + + @Override + public void visit(ExtendsWildcardType extendsWildcardType) { + throw new NotImplementedException(); + } + + @Override + public void visit(GenericRefType genericRefType) { + throw new NotImplementedException(); + } + + @Override + public void visit(UnaryExpr unaryExpr) { + throw new NotImplementedException(); + } + +} diff --git a/test/strucType/TestConstruct.java b/test/strucType/TestConstruct.java new file mode 100644 index 00000000..f5222c71 --- /dev/null +++ b/test/strucType/TestConstruct.java @@ -0,0 +1,66 @@ +package strucType; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import de.dhbwstuttgart.core.JavaTXCompiler; +import de.dhbwstuttgart.strucTypes.Construct; +import de.dhbwstuttgart.strucTypes.InferredTypes; +import de.dhbwstuttgart.strucTypes.StrucTYPE; +import de.dhbwstuttgart.strucTypes.constraint.ConstraintsSet; +import de.dhbwstuttgart.strucTypes.constraint.SubTypeConstraint; +import de.dhbwstuttgart.strucTypes.exception.ImpossibleSubTypeException; +import de.dhbwstuttgart.strucTypes.printutils.PrintConstraints; +import de.dhbwstuttgart.strucTypes.printutils.PrintInferredTypes; +import de.dhbwstuttgart.strucTypes.printutils.SyntaxTreePrinter; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.SourceFile; + +public class TestConstruct { + public static final String rootDirectory = System.getProperty("user.dir") + "/test/strucType/javFiles/"; + public final PrintConstraints printConstraints = new PrintConstraints(); + + @org.junit.Test + public void test() throws ClassNotFoundException, IOException, ImpossibleSubTypeException { + ArrayList files = new ArrayList<>(); + 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 + "testMethod.jav")); + files.add(new File(rootDirectory + "testPaperExample.jav")); + JavaTXCompiler compiler = new JavaTXCompiler(files); + for (File f : compiler.sourceFiles.keySet()) { + String name = f.getName(); + System.out.println("Filename: " + name); + SourceFile sourceFile = compiler.sourceFiles.get(f); + //Print SourceFile Infos + sourceFile.accept(new SyntaxTreePrinter()); + + StrucTYPE strucTYPE = new StrucTYPE(sourceFile); + + ConstraintsSet constraints = strucTYPE.getConstraints(); + printConstraints.print(constraints); + + InferredTypes inferredTypes = strucTYPE.getInferredTypes(); + PrintInferredTypes.print(inferredTypes); + + Construct construct = new Construct(constraints, inferredTypes); + + List constructedInterfaces = construct.getConstructedInterfaces(); + System.out.println("\nConstructed Interfaces:"); + constructedInterfaces.forEach(i-> i.accept(new SyntaxTreePrinter())); + + List subTypeConstraints = construct.getSubTypeConstraints(); + printConstraints.printSubTypeConstraints(subTypeConstraints); + + inferredTypes = construct.getInferredTypes(); + PrintInferredTypes.print(inferredTypes); + + System.out.println("____________________________________________________________________________"); + } + } +} diff --git a/test/strucType/TestInterface.java b/test/strucType/TestInterface.java new file mode 100644 index 00000000..dcbef4e9 --- /dev/null +++ b/test/strucType/TestInterface.java @@ -0,0 +1,66 @@ +package strucType; + + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +import de.dhbwstuttgart.core.JavaTXCompiler; +import de.dhbwstuttgart.strucTypes.TypeExtract; + +public class TestInterface { + public static final String rootDirectory = System.getProperty("user.dir")+"/test/strucType/javFiles/"; + + + @org.junit.Test + public void test() throws ClassNotFoundException, IOException { + ArrayList files = new ArrayList<>(); + files.add(new File(rootDirectory + "testInterface.jav")); + JavaTXCompiler compiler = new JavaTXCompiler(files); + compiler.sourceFiles.keySet().forEach(f->{ + String name = f.getName(); + System.out.println("Filename: " + name); + compiler.sourceFiles.get(f).getClasses().forEach(c-> c.accept(new TypeExtract())); + System.out.println(); + }); +// this.printSyntaxTree(compiler); + System.out.println("test end"); + } + +// private void printSyntaxTree(JavaTXCompiler compiler){ +// Collection sourceFiles= compiler.sourceFiles.values(); +// for (SourceFile sourceFile : sourceFiles) { +// List klassenVektor = sourceFile.KlassenVektor; +// for (ClassOrInterface classOrInterface : klassenVektor) { +// JavaClassName className = classOrInterface.getClassName(); +// System.out.println("class: "+ className); +// List fields = classOrInterface.getFieldDecl(); +// List methods = classOrInterface.getMethods(); +// for (Field field : fields) { +// String fName = field.getName(); +// RefTypeOrTPHOrWildcardOrGeneric fType = field.getType(); +// System.out.println("field: "+ fName + " : " + fType); +// } +// for (Method method : methods) { +// String mName = method.getName(); +// RefTypeOrTPHOrWildcardOrGeneric mReturnType = method.getReturnType(); +// System.out.println("method: " + mName + " : " + mReturnType); +// ParameterList mParameterList = method.getParameterList(); +// for (FormalParameter formalParameter : mParameterList) { +// String paraName = formalParameter.getName(); +// RefTypeOrTPHOrWildcardOrGeneric paraType = formalParameter.getType(); +// System.out.println("parameter: " + paraName + " : " + paraType); +// } +// RefTypeOrTPHOrWildcardOrGeneric blockType = method.block.getType(); +// System.out.println("blockType: " + blockType); +// List blockStatements = method.block.getStatements(); +// for (Statement statement : blockStatements) { +// RefTypeOrTPHOrWildcardOrGeneric statementType = statement.getType(); +// System.out.println("statementType: " + statementType); +// } +// } +// } +// } +// } + +} diff --git a/test/strucType/TestStrucType.java b/test/strucType/TestStrucType.java new file mode 100644 index 00000000..8d7424c7 --- /dev/null +++ b/test/strucType/TestStrucType.java @@ -0,0 +1,49 @@ +package strucType; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +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; + +public class TestStrucType { + public static final String rootDirectory = System.getProperty("user.dir") + "/test/strucType/javFiles/"; + private final PrintConstraints printConstraints = new PrintConstraints(); + + @org.junit.Test + public void test() throws ClassNotFoundException, IOException { + ArrayList files = new ArrayList<>(); +// 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 + "testMethod.jav")); +// files.add(new File(rootDirectory + "testPaperExample.jav")); + JavaTXCompiler compiler = new JavaTXCompiler(files); + for (File f : compiler.sourceFiles.keySet()) { + String name = f.getName(); + System.out.println("Filename: " + name); + SourceFile sourceFile = compiler.sourceFiles.get(f); + //Print SourceFile Infos + sourceFile.accept(new SyntaxTreePrinter()); + + StrucTYPE strucTYPE = new StrucTYPE(sourceFile); + + ConstraintsSet constraints = strucTYPE.getConstraints(); + printConstraints.print(constraints); + + InferredTypes inferredTypes = strucTYPE.getInferredTypes(); + PrintInferredTypes.print(inferredTypes); + + System.out.println("____________________________________________________________________________"); + } + } +} diff --git a/test/strucType/TestSyntaxTreePrinter.java b/test/strucType/TestSyntaxTreePrinter.java new file mode 100644 index 00000000..c1b5d04f --- /dev/null +++ b/test/strucType/TestSyntaxTreePrinter.java @@ -0,0 +1,71 @@ +package strucType; + + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +import de.dhbwstuttgart.core.JavaTXCompiler; +import de.dhbwstuttgart.strucTypes.printutils.SyntaxTreePrinter; + +public class TestSyntaxTreePrinter { + public static final String rootDirectory = System.getProperty("user.dir")+"/test/strucType/javFiles/"; + + + @org.junit.Test + public void test() throws ClassNotFoundException, IOException { + ArrayList files = new ArrayList<>(); +// 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")); + JavaTXCompiler compiler = new JavaTXCompiler(files); + compiler.sourceFiles.keySet().forEach(f->{ + String name = f.getName(); + System.out.println("Filename: " + name); + compiler.sourceFiles.get(f).accept(new SyntaxTreePrinter()); + System.out.println(); + }); +// this.printSyntaxTree(compiler); + System.out.println("test end"); + } + +// private void printSyntaxTree(JavaTXCompiler compiler){ +// Collection sourceFiles= compiler.sourceFiles.values(); +// for (SourceFile sourceFile : sourceFiles) { +// List klassenVektor = sourceFile.KlassenVektor; +// for (ClassOrInterface classOrInterface : klassenVektor) { +// JavaClassName className = classOrInterface.getClassName(); +// System.out.println("class: "+ className); +// List fields = classOrInterface.getFieldDecl(); +// List methods = classOrInterface.getMethods(); +// for (Field field : fields) { +// String fName = field.getName(); +// RefTypeOrTPHOrWildcardOrGeneric fType = field.getType(); +// System.out.println("field: "+ fName + " : " + fType); +// } +// for (Method method : methods) { +// String mName = method.getName(); +// RefTypeOrTPHOrWildcardOrGeneric mReturnType = method.getReturnType(); +// System.out.println("method: " + mName + " : " + mReturnType); +// ParameterList mParameterList = method.getParameterList(); +// for (FormalParameter formalParameter : mParameterList) { +// String paraName = formalParameter.getName(); +// RefTypeOrTPHOrWildcardOrGeneric paraType = formalParameter.getType(); +// System.out.println("parameter: " + paraName + " : " + paraType); +// } +// RefTypeOrTPHOrWildcardOrGeneric blockType = method.block.getType(); +// System.out.println("blockType: " + blockType); +// List blockStatements = method.block.getStatements(); +// for (Statement statement : blockStatements) { +// RefTypeOrTPHOrWildcardOrGeneric statementType = statement.getType(); +// System.out.println("statementType: " + statementType); +// } +// } +// } +// } +// } + +} diff --git a/test/strucType/javFiles/testCast.jav b/test/strucType/javFiles/testCast.jav new file mode 100644 index 00000000..30ed4bc1 --- /dev/null +++ b/test/strucType/javFiles/testCast.jav @@ -0,0 +1,10 @@ +package strucType.input; +import strucType.typedtestclasses.A; +import strucType.typedtestclasses.A2; +import strucType.typedtestclasses.B; + +class C +{ + mA(A x){return (A2)x; } + mB(c) { return (B)c; } +} \ No newline at end of file diff --git a/test/strucType/javFiles/testFieldMethod.jav b/test/strucType/javFiles/testFieldMethod.jav new file mode 100644 index 00000000..98a56240 --- /dev/null +++ b/test/strucType/javFiles/testFieldMethod.jav @@ -0,0 +1,10 @@ +package strucType.input; +import java.lang.Integer; + +class M +{ + f; + mM(x, y) { return f.mF(x, y); } + mInt(Integer x) { return x.doubleValue(); } + +} \ No newline at end of file diff --git a/test/strucType/javFiles/testFieldVar.jav b/test/strucType/javFiles/testFieldVar.jav new file mode 100644 index 00000000..8cf92566 --- /dev/null +++ b/test/strucType/javFiles/testFieldVar.jav @@ -0,0 +1,14 @@ +package strucType.input; +import strucType.typedtestclasses.A; + +class F +{ + f; + A a; + + mF() { return f; } + + mA() { return a; } + + mX(x) { return x.f; } +} \ No newline at end of file diff --git a/test/strucType/javFiles/testInterface.jav b/test/strucType/javFiles/testInterface.jav new file mode 100644 index 00000000..c0b1968d --- /dev/null +++ b/test/strucType/javFiles/testInterface.jav @@ -0,0 +1,7 @@ +package strucType.input; + +import java.util.List; + +class A implements List +{ +} \ No newline at end of file diff --git a/test/strucType/javFiles/testLocalVar.jav b/test/strucType/javFiles/testLocalVar.jav new file mode 100644 index 00000000..615306f8 --- /dev/null +++ b/test/strucType/javFiles/testLocalVar.jav @@ -0,0 +1,6 @@ +package strucType.input; + +class C +{ + m(x) { return x; } +} diff --git a/test/strucType/javFiles/testMethod.jav b/test/strucType/javFiles/testMethod.jav new file mode 100644 index 00000000..8acb24bd --- /dev/null +++ b/test/strucType/javFiles/testMethod.jav @@ -0,0 +1,14 @@ +package strucType.input; +import strucType.typedtestclasses.A; +import strucType.typedtestclasses.A2; + +class M +{ + mM(x) { return mA(x); } + + A mA(x) { return x.getA(); } + + A2 m(A a) { return a; } + + +} \ No newline at end of file diff --git a/test/strucType/javFiles/testNew.jav b/test/strucType/javFiles/testNew.jav new file mode 100644 index 00000000..7ee62428 --- /dev/null +++ b/test/strucType/javFiles/testNew.jav @@ -0,0 +1,10 @@ +package strucType.input; +import strucType.typedtestclasses.A; +import strucType.typedtestclasses.B; +class Neu +{ + a; + + mA(){ return new A(a); } + mB(x){ return new B(x,a); } +} \ No newline at end of file diff --git a/test/strucType/javFiles/testPaperExample.jav b/test/strucType/javFiles/testPaperExample.jav new file mode 100644 index 00000000..347a1656 --- /dev/null +++ b/test/strucType/javFiles/testPaperExample.jav @@ -0,0 +1,6 @@ +package strucType.input; + +class A +{ + mt(x, y, z) { return x.sub(y).add(z); } +} \ No newline at end of file diff --git a/test/strucType/typedtestclasses/A.java b/test/strucType/typedtestclasses/A.java new file mode 100644 index 00000000..9a7da22c --- /dev/null +++ b/test/strucType/typedtestclasses/A.java @@ -0,0 +1,19 @@ +package strucType.typedtestclasses; + +public class A { + + public A a; + + public A(A a) { + this.a = a; + } + + public A getA() { + return this.a; + } + + public B getB(B b) { + return b; + } + +} diff --git a/test/strucType/typedtestclasses/A2.java b/test/strucType/typedtestclasses/A2.java new file mode 100644 index 00000000..b5862912 --- /dev/null +++ b/test/strucType/typedtestclasses/A2.java @@ -0,0 +1,9 @@ +package strucType.typedtestclasses; + +public class A2 extends A { + + public A2(A a) { + super(a); + } + +} diff --git a/test/strucType/typedtestclasses/B.java b/test/strucType/typedtestclasses/B.java new file mode 100644 index 00000000..6fd3db35 --- /dev/null +++ b/test/strucType/typedtestclasses/B.java @@ -0,0 +1,20 @@ +package strucType.typedtestclasses; + +public class B { + + public E e; + public A a; + public B(E e, A a) { + this.e = e; + this.a = a; + } + + public E getGeneric(){ + return this.e; + } + + public A getInput(){ + return this.a; + } + +} diff --git a/test/strucType/typedtestclasses/C.java b/test/strucType/typedtestclasses/C.java new file mode 100644 index 00000000..cc751d43 --- /dev/null +++ b/test/strucType/typedtestclasses/C.java @@ -0,0 +1,27 @@ +package strucType.typedtestclasses; + +public class C { + + + public E e; + public F f; + + + + public C(E e, F f) { + this.e = e; + this.f = f; + } + + public E getGeneric1(){ + return this.e; + } + + public F getGeneric2(){ + return this.f; + } + + public C> convert(A a, B b){ + return new C<>(a,b); + } +}