Merge branch 'plugin' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into strucTypesNew

src/de/dhbwstuttgart/core/JavaTXCompiler.java
	src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java
	src/de/dhbwstuttgart/syntaxtree/GenericDeclarationList.java
 It looks like you may be committing a merge.
 If this is not correct, please remove the file
	.git/MERGE_HEAD
 and try again.
This commit is contained in:
Martin Plümicke 2018-06-08 14:37:04 +02:00
commit aac113e12e
168 changed files with 5334 additions and 807 deletions

3
.gitignore vendored
View File

@ -20,3 +20,6 @@ bin
.project .project
.settings/ .settings/
/target/ /target/
#
manually/

19
README.md Normal file
View File

@ -0,0 +1,19 @@
# plugin site erstellen
* die JAvaTXCOmpiler DAtei in ein plugin umwandeln und deployen.
* siehe: http://www.vogella.com/tutorials/EclipseJarToPlugin/article.html#convert-jar-files-to-osgi-bundles-with-the-p2-maven-plugin
* AUsführung:
* mvn deploy #erstellt die JAR-Datei und steckt sie in ein lokales Repo (maven-repository)
* mvn p2:site
* mvn package # hier wird die ZIP-Filf zum Einbinden in Eclipse erstellt
# Einbinden in Eclipse
* In Eclipse kann die Zip-FIle wie ein Plugin installiert werden
* Hier tritt FEhler auf. Reflections-Library kann nicht installiert werden. Möglicherweise wird sie auch nicht gebraucht
* Nach dem installieren de.dhbwstuttagrt.JavaTXcompiler zu den DEpendencies des plugins hinzufügen
* Anschließend unter "Overview" auf "Updata Classpath" klicken
# Windows
* JAVA_HOME setzen:
* export JAVA_HOME=/c/Program\ Files/Java/jdk1.8.0_102/

BIN
Website/JavaTXExamples.zip Normal file

Binary file not shown.

88
Website/index.html Normal file
View File

@ -0,0 +1,88 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html> <head>
<title>Java-TX Plugin</title></head>
<center>
<h1>Java-TX Plugin</h1>
</center>
<h2>Content</h2>
<ul>
<li><h4><a href="#introduction">Introduction</a></h4></li>
<li><h4><a href="newJavaTXProject/newJavaTXProject.html" >New Java-TX project</a></h4></li>
<li><h4><a href=" JavaTXExamples.zip" >Example project</a></h4></li>
<li><a href="usePlugin/usePlugin.html" >Using the plugin</a></li>
<li><h4><a href="install/install.html" >Installation</a></h4>
</li>
</ul>
<br/>
<h2 id="introduction">Introduction</h2>
Java-TX (Java Type eXtended) is an extension of Java in which a global type inference algorithm and real function types are added. Since the end of the nineties features from functional program- ming languages have been transferred to Java. Parametric polymorphism extended by wildcards, called generics, were transfered to Java 5.0. Higher-order functions and lambda expression were introduced in Java 8. Java 8 uses functional interfaces as target types of lambda expressions in contrast to real function types as in functional programming languages.
The powerful feature type inference from functional programming languages is incorporated into Java, as into other object-oriented
languages, i.e. only in a restricted way called local type inference. Local type inference allows certain type annotations to be omitted. For instance, it is often not necessary to specify the type of a variable. Type parameters of classes in the new-statement can be left out. Return types of methods can often also be omitted. Local type inference is at its most pronounced in Scala. In Java 10 an extention of local type inference is introduced, where types of local variables can be replaced by the keyword var and inferred automatically during the compilation. In contrast to global type inference, local type inference allows types of recursive methods and lambda expressions not to be omitted.<br>
The Java-TX project contributes to the design of object-oriented languages by developing global type inference algorithms for Java-like languages.
<h3>First Example</h3>
The class <tt>Id</tt> has the method <tt>id</tt>. The type annotations are omitted.
<br/>
<pre> <code class="language-java">
class Id {
id(x) {
return x;
}
}
</code> </pre>
The type inference algorithm inferrs the types, such that <tt>Id</tt> can be applied:
<pre>
new Id().id(1);
new Id().id("hallo");
</pre>
<h3>More complex example</h3>
<pre>
import java.lang.Integer;
import java.lang.Double;
import java.lang.String;
class OL {
m(x) { return x + x; }
}
class OLMain {
main(x) {
var ol;
ol = new OL();
return ol.m(x);
}
}
</pre>
The type inference mechanism considers only imported types. Therefore <tt>Integer</tt> <tt>Double</tt>, and <tt>String</tt> are imported.
<br/>
As the operator <tt>+</tt> is overloaded by all numeric types and String the methods <tt>m</tt> in the class <tt>OL</tt> and <tt>main</tt> in the class <tt>OLMain</tt>, respectively, gets all these types. The generated classfile demonstrates this:
<pre>
> javap OL.class
Compiled from "OL.jav"
class OL {
public OL();
public java.lang.Integer m(java.lang.Integer);
public java.lang.Double m(java.lang.Double);
}
> javap OLMain.class
Compiled from "OLMain.jav"
class OLMain {
public OLMain();
public java.lang.Integer main(java.lang.Integer);
public java.lang.Double main(java.lang.Double);
}
</pre>
<hr>
<address></address>
<!-- hhmts start -->Last modified: Fri Jun 1 16:43:55 CEST 2018 <!-- hhmts end -->
</body> </html>

BIN
Website/install/Restart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

@ -0,0 +1,40 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html> <head>
<title>Install Java-TX Plugin</title>
</head>
<body>
<h1>Install Java-TX Plugin</h1>
<ol>
<li>Select "Install New Software ..."<br>
<img width= 400 src="newsoftware.png" >
</li>
<li>Add ...<br>
<img width=550 src="availableSoftware1.png" >
</li>
<li>Insert address<br>
<img width=550 src="availableSoftware2.png" >
</li>
<li>Select installation<br>
<img width=550 src="selectInstallation.png" >
</li>
<li>Installation details<br>
<img width=550 src="installationDetails.png" >
</li>
<li>Accept license agreement<br>
<img width=550 src="licenseAgreement.png" >
</li>
<li>Install anyway<br>
<img width=450 src="installAnyway.png">
</li>
<li>Restart<br>
<img width=450 src="Restart.png">
</li>
</ol>
<hr>
<address></address>
<!-- hhmts start -->Last modified: Fri Jun 1 11:57:15 CEST 2018 <!-- hhmts end -->
</body> </html>

View File

@ -0,0 +1,40 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html> <head>
<title>Install Java-TX Plugin</title>
</head>
<body>
<h2>Install Java-TX Plugin</h2>
<ol>
<li>Select "Install New Software ..."<br>
<img width= 400 src="newsoftware.png" >
</li>
<li>Add ...<br>
<img width=550 src="availableSoftware1.png" >
</li>
<li>Insert address<br>
<img width=550 src="availableSoftware2.png" >
</li>
<li>Select installation<br>
<img width=550 src="selectInstallation.png" >
</li>
<li>Installation details<br>
<img width=550 src="installationDetails.png" >
</li>
<li>Accept license agreement<br>
<img width=550 src="licenseAgreement.png" >
</li>
<li>Install anyway<br>
<img width=450 src="installAnyway.png">
</li>
<li>Restart<br>
<img width=450 src="Restart.png">
</li>
</ol>
<hr>
<address></address>
<!-- hhmts start -->Last modified: Fri Jun 1 12:05:43 CEST 2018 <!-- hhmts end -->
</body> </html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@ -0,0 +1,34 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html> <head>
<title></title>
</head>
<h2>New Java-TX project in eclipse</h2>
<ol>
<li>New -> Java Project<br/>
<img width= 400 src="newJavaTXProject.png" >
</li>
<br/>
<li>Generate a jav-File folder<br/>
<img width= 550 src="newJavFolder1.png" ><br/><br/>
<img width= 550 src="newJavFolder2.png" >
</li>
<br/>
<li>Add jav-File folder as library<br/>
At the moment no package system is implemented, Therefore the compiled class files are in the jav-File folder. This has to be added as library:<br/>
<img width= 550 src="buildPath1.png" ><br/><br/>
<img width= 550 src="buildPath2.png" ><br/><br/>
<img width= 400 src="buildPath3.png" ><br/><br/>
<img width= 550 src="buildPath4.png" ><br/>
</li>
</ol>
<body>
<h1></h1>
<hr>
<address></address>
<!-- hhmts start -->Last modified: Fri Jun 1 16:50:02 CEST 2018 <!-- hhmts end -->
</body> </html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

View File

@ -0,0 +1,24 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html> <head>
<title>Using the plugin</title>
</head>
<h2>Using the plugin</h2>
<ol>
<li>Overview<br/>
<img width=800 src="usePlugin1.png" >
</li>
<br/>
<li>Select types<br/>
If the method is overloaded the user can select types in the outline the right mouse button:<br/><br/>
<img src="usePlugin2.png" ><br/>
</li>
</ol>
<body>
<h1></h1>
<hr>
<address></address>
<!-- hhmts start -->Last modified: Fri Jun 1 16:51:28 CEST 2018 <!-- hhmts end -->
</body> </html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

84
pom.xml
View File

@ -7,6 +7,7 @@
<groupId>de.dhbwstuttgart</groupId> <groupId>de.dhbwstuttgart</groupId>
<artifactId>JavaTXcompiler</artifactId> <artifactId>JavaTXcompiler</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>0.1</version> <version>0.1</version>
<name>JavaTXcompiler</name> <name>JavaTXcompiler</name>
<url>http://maven.apache.org</url> <url>http://maven.apache.org</url>
@ -53,7 +54,7 @@
<build> <build>
<directory>target</directory> <directory>target</directory>
<outputDirectory>target/classes</outputDirectory> <outputDirectory>target/classes</outputDirectory>
<finalName>${artifactId}-${version}</finalName> <finalName>${project.artifactId}-${project.version}</finalName>
<testOutputDirectory>target/test-classes</testOutputDirectory> <testOutputDirectory>target/test-classes</testOutputDirectory>
<sourceDirectory>src/</sourceDirectory> <sourceDirectory>src/</sourceDirectory>
<testSourceDirectory>test/</testSourceDirectory> <testSourceDirectory>test/</testSourceDirectory>
@ -71,10 +72,7 @@
<configuration> <configuration>
<sourceDirectory>src/de/dhbwstuttgart/parser/antlr/</sourceDirectory> <sourceDirectory>src/de/dhbwstuttgart/parser/antlr/</sourceDirectory>
<outputDirectory>src/de/dhbwstuttgart/parser/antlr/</outputDirectory> <outputDirectory>src/de/dhbwstuttgart/parser/antlr/</outputDirectory>
<arguments> <arguments> <argument>-package</argument> <argument>de.dhbwstuttgart.parser.antlr</argument> </arguments>
<argument>-package</argument>
<argument>de.dhbwstuttgart.parser.antlr</argument>
</arguments>
</configuration> </configuration>
</execution> </execution>
<execution> <execution>
@ -93,19 +91,91 @@
</execution> </execution>
</executions> </executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<plugin>
<groupId>org.reficio</groupId>
<artifactId>p2-maven-plugin</artifactId>
<version>1.1.2-SNAPSHOT</version>
<executions>
<execution>
<id>default-cli</id>
<configuration>
<artifacts>
<!-- specify your depencies here -->
<!-- groupId:artifactId:version -->
<artifact>
<id>de.dhbwstuttgart:JavaTXcompiler:0.1</id>
</artifact>
<artifact><id>org.reflections:reflections:0.9.11</id></artifact>
<artifact><id>com.google.guava:guava:22.0</id></artifact>
<artifact><id>javax.annotation:javax.annotation-api:1.3.1</id></artifact>
<artifact><id>org.glassfish:javax.annotation:3.1.1</id></artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-repository-plugin</artifactId>
<version>${tycho.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>archive-repository</goal>
</goals>
</execution>
</executions>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<configuration> <configuration>
<source>8</source> <source>9</source>
<target>8</target> <target>9</target>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<pluginRepositories>
<pluginRepository>
<id>reficio</id>
<url>http://repo.reficio.org/maven/</url>
</pluginRepository>
</pluginRepositories>
<repositories>
<repository>
<id>maven-repository</id>
<url>file:///${project.basedir}/target</url>
</repository>
</repositories>
<properties> <properties>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
<tycho.version>0.23.0</tycho.version>
</properties> </properties>
<distributionManagement>
<repository>
<id>maven-repository</id>
<name>MyCo Internal Repository</name>
<url>file:///${project.basedir}/maven-repository/</url>
</repository>
</distributionManagement>
</project> </project>

View File

@ -0,0 +1,30 @@
package de.dhbwstuttgart.bytecode;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
public abstract class AStatement implements IStatement {
protected Expression expr;
public AStatement(Expression expr) {
this.expr = expr;
}
@Override
public boolean isExprBinary() {
return (expr instanceof BinaryExpr);
}
@Override
public void genBCForRelOp(MethodVisitor mv,Label branchLabel, Label endLabel, BytecodeGenMethod bytecodeGenMethod) {
mv.visitInsn(Opcodes.ICONST_1);
mv.visitJumpInsn(Opcodes.GOTO, endLabel);
mv.visitLabel(branchLabel);
mv.visitInsn(Opcodes.ICONST_0);
mv.visitLabel(endLabel);
}
}

View File

@ -0,0 +1,11 @@
package de.dhbwstuttgart.bytecode;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
public class ArgumentExpr extends AStatement {
public ArgumentExpr(Expression expr) {
super(expr);
}
}

View File

@ -0,0 +1,11 @@
package de.dhbwstuttgart.bytecode;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
public class AssignStmt extends AStatement {
public AssignStmt(Expression rightSide) {
super(rightSide);
}
}

View File

@ -1,7 +1,9 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
@ -9,11 +11,14 @@ import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString; import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor; import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.bytecode.signature.Signature; import de.dhbwstuttgart.bytecode.signature.Signature;
import de.dhbwstuttgart.bytecode.signature.TypeToString; import de.dhbwstuttgart.bytecode.signature.TypeToString;
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.Literal; import de.dhbwstuttgart.syntaxtree.statement.Literal;
@ -23,6 +28,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.ResultPair;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
public class BytecodeGen implements ASTVisitor { public class BytecodeGen implements ASTVisitor {
@ -33,6 +39,7 @@ public class BytecodeGen implements ASTVisitor {
String className; String className;
private boolean isInterface; private boolean isInterface;
private List<ResultSet> listOfResultSets;
private ResultSet resultSet; private ResultSet resultSet;
private int indexOfFirstParam = 0; private int indexOfFirstParam = 0;
@ -47,16 +54,18 @@ public class BytecodeGen implements ASTVisitor {
byte[] bytecode; byte[] bytecode;
HashMap<String,byte[]> classFiles; HashMap<String,byte[]> classFiles;
public BytecodeGen(HashMap<String,byte[]> classFiles, ResultSet resultSet) { ArrayList<String> methodNameAndParamsT = new ArrayList<>();
public BytecodeGen(HashMap<String,byte[]> classFiles, List<ResultSet> listOfResultSets) {
this.classFiles = classFiles; this.classFiles = classFiles;
this.resultSet = resultSet; this.listOfResultSets = listOfResultSets;
} }
@Override @Override
public void visit(SourceFile sourceFile) { public void visit(SourceFile sourceFile) {
for(ClassOrInterface cl : sourceFile.getClasses()) { for(ClassOrInterface cl : sourceFile.getClasses()) {
System.out.println("in Class: " + cl.getClassName().toString()); System.out.println("in Class: " + cl.getClassName().toString());
BytecodeGen classGen = new BytecodeGen(classFiles, resultSet); BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets);
cl.accept(classGen); cl.accept(classGen);
classGen.writeClass(cl.getClassName().toString()); classGen.writeClass(cl.getClassName().toString());
} }
@ -101,18 +110,27 @@ public class BytecodeGen implements ASTVisitor {
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString() cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString()
, sig, classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null); , sig, classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
// for each field in the class
for(Field f : classOrInterface.getFieldDecl()) { for(Field f : classOrInterface.getFieldDecl()) {
f.accept(this); f.accept(this);
} }
// resultSet = listOfResultSets.get(0);
boolean isConsWithNoParamsVisited = false;
for(ResultSet rs : listOfResultSets) {
resultSet = rs;
for(Constructor c : classOrInterface.getConstructors()) { for(Constructor c : classOrInterface.getConstructors()) {
if(!isConsWithNoParamsVisited)
c.accept(this); c.accept(this);
if(!c.getParameterList().iterator().hasNext())
isConsWithNoParamsVisited = true;
} }
for(Method m : classOrInterface.getMethods()) { for(Method m : classOrInterface.getMethods()) {
m.accept(this); m.accept(this);
} }
}
} }
@Override @Override
@ -151,18 +169,35 @@ public class BytecodeGen implements ASTVisitor {
public void visit(Method method) { public void visit(Method method) {
// TODO: check if the method is static => if static then the first param will be stored in pos 0 // TODO: check if the method is static => if static then the first param will be stored in pos 0
// else it will be stored in pos 1 and this will be stored in pos 0 // else it will be stored in pos 1 and this will be stored in pos 0
String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
String methParamTypes = retType+method.name+"%%";
method.getParameterList().accept(this); method.getParameterList().accept(this);
Iterator<FormalParameter> itr = method.getParameterList().iterator();
while(itr.hasNext()) {
FormalParameter fp = itr.next();
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";";
}
if(methodNameAndParamsT.contains(methParamTypes)) {
return;
}
methodNameAndParamsT.add(methParamTypes);
System.out.println("Method: "+method.name +" , paramsType: "+methParamTypes);
String methDesc = null; String methDesc = null;
// Method getModifiers() ? // Method getModifiers() ?
int acc = isInterface?Opcodes.ACC_ABSTRACT:method.modifier; int acc = isInterface?Opcodes.ACC_ABSTRACT:method.modifier;
System.out.println(acc);
boolean hasGenInParameterList = genericsAndBounds.containsKey(resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())); /*Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist*/
boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.subSequence(0, 4).equals("TPH ");
/*Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature, wenn nicht,
* prüfe, ob einer der Parameter Typ-Variable als Typ hat*/
if(!hasGenInParameterList) { if(!hasGenInParameterList) {
for(String paramName : methodParamsAndTypes.keySet()) { for(String paramName : methodParamsAndTypes.keySet()) {
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor()); String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor());
if(genericsAndBounds.containsKey(typeOfParam)) { if(genericsAndBounds.containsKey(typeOfParam)||typeOfParam.substring(0, 4).equals("TPH ")) {
hasGenInParameterList = true; hasGenInParameterList = true;
break; break;
} }
@ -170,27 +205,31 @@ public class BytecodeGen implements ASTVisitor {
} }
//TODO: Test if the return-type or any of the parameter is a parameterized type. (VP) //TODO: Test if the return-type or any of the parameter is a parameterized type. (VP)
//than create the descriptor with the new syntax. //then create the descriptor with the new syntax.
String sig = null; String sig = null;
/* method.getGenerics: <....> RT method(..)
* */
boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList; boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList;
/* if method has generics or return type is TPH, create signature */ /* if method has generics or return type is TPH, create signature */
// zwite operand muss weggelassen werden
if(hasGen||method.getReturnType().acceptTV(new TypeToString()).equals("TPH")) { if(hasGen||method.getReturnType().acceptTV(new TypeToString()).equals("TPH")) {
// resultset hier zum testen // resultset hier zum testen
Signature signature = new Signature(method, genericsAndBoundsMethod, methodParamsAndTypes,resultSet); Signature signature = new Signature(method, genericsAndBoundsMethod, methodParamsAndTypes,resultSet);
sig = signature.toString(); sig = signature.toString();
} }
System.out.println(sig); // System.out.println(sig);
NormalMethod meth = new NormalMethod(method,genericsAndBounds,genericsAndBoundsMethod,hasGen); NormalMethod meth = new NormalMethod(method,genericsAndBounds,genericsAndBoundsMethod,hasGen);
methDesc = meth.accept(new DescriptorToString(resultSet)); methDesc = meth.accept(new DescriptorToString(resultSet));
System.out.println(methDesc);
// System.out.println(methDesc);
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+acc, method.getName(), methDesc, sig, null); MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+acc, method.getName(), methDesc, sig, null);
mv.visitCode(); mv.visitCode();
BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,cw, BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,cw,
genericsAndBounds,genericsAndBounds,isInterface,classFiles); genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles);
mv.visitMaxs(0, 0); mv.visitMaxs(0, 0);
mv.visitEnd(); mv.visitEnd();
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
package de.dhbwstuttgart.bytecode;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
public interface IStatement {
public boolean isExprBinary();
public void genBCForRelOp(MethodVisitor mv, Label branchLabel, Label endLabel, BytecodeGenMethod bytecodeGenMethod);
}

View File

@ -0,0 +1,25 @@
package de.dhbwstuttgart.bytecode;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.statement.Statement;
public class LoopStmt extends AStatement {
private Statement loopBlock;
public LoopStmt(Expression expr, Statement loopBlock) {
super(expr);
this.loopBlock = loopBlock;
}
@Override
public void genBCForRelOp(MethodVisitor mv,Label branchLabel, Label endLabel, BytecodeGenMethod bytecodeGenMethod) {
this.loopBlock.accept(bytecodeGenMethod);
mv.visitJumpInsn(Opcodes.GOTO, endLabel);
mv.visitLabel(branchLabel);
}
}

View File

@ -0,0 +1,14 @@
package de.dhbwstuttgart.bytecode;
import org.objectweb.asm.MethodVisitor;
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
public class ReturnStmt extends AStatement {
public ReturnStmt(Expression retexpr) {
super(retexpr);
}
}

View File

@ -2,12 +2,12 @@ package de.dhbwstuttgart.bytecode.descriptor;
import java.util.Iterator; import java.util.Iterator;
import de.dhbwstuttgart.bytecode.Lambda;
import de.dhbwstuttgart.bytecode.MethodFromMethodCall;
import de.dhbwstuttgart.bytecode.NormalConstructor;
import de.dhbwstuttgart.bytecode.NormalMethod;
import de.dhbwstuttgart.bytecode.SamMethod;
import de.dhbwstuttgart.bytecode.signature.TypeToSignature; import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
import de.dhbwstuttgart.bytecode.utilities.Lambda;
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
import de.dhbwstuttgart.bytecode.utilities.SamMethod;
import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.statement.Expression; import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
@ -46,12 +46,19 @@ public class DescriptorToString implements DescriptorVisitor{
}else if(method.getGenericsAndBounds().containsKey(fpDesc)){ }else if(method.getGenericsAndBounds().containsKey(fpDesc)){
desc += "L"+method.getGenericsAndBounds().get(fpDesc)+ ";"; desc += "L"+method.getGenericsAndBounds().get(fpDesc)+ ";";
}else { }else {
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; // desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
String resType = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
if(resType.subSequence(0, 4).equals("TPH ")) {
desc += "L"+method.getGenericsAndBoundsMethod().get(resType.substring(4)+"$")+ ";";
} else {
desc += "L"+resType+ ";";
} }
} }
// else if(((RefType) fp.getType()).getParaList().size() > 0){ }
// desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "%").replace("<", "%%").replace(">", "%%")+ ";"; //TODO: generate a class java%% ... %%
// } else if(resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()).contains("<")){
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "$$").replace("<", "$$$").replace(">", "$$$")+ ";";
}
else { else {
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
} }
@ -67,7 +74,12 @@ public class DescriptorToString implements DescriptorVisitor{
}else if(method.getGenericsAndBounds().containsKey(ret)){ }else if(method.getGenericsAndBounds().containsKey(ret)){
desc += ")L"+method.getGenericsAndBounds().get(ret)+ ";"; desc += ")L"+method.getGenericsAndBounds().get(ret)+ ";";
}else { }else {
desc += ")" + "L"+resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; String resType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
if(resType.subSequence(0, 4).equals("TPH ")) {
desc += ")" + "L"+method.getGenericsAndBoundsMethod().get(resType.substring(4)+"$")+ ";";
} else {
desc += ")" + "L"+resType+ ";";
}
} }
}else { }else {
desc += ")" + "L"+resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; desc += ")" + "L"+resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";

View File

@ -1,10 +1,10 @@
package de.dhbwstuttgart.bytecode.descriptor; package de.dhbwstuttgart.bytecode.descriptor;
import de.dhbwstuttgart.bytecode.Lambda; import de.dhbwstuttgart.bytecode.utilities.Lambda;
import de.dhbwstuttgart.bytecode.MethodFromMethodCall; import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
import de.dhbwstuttgart.bytecode.NormalConstructor; import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
import de.dhbwstuttgart.bytecode.NormalMethod; import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
import de.dhbwstuttgart.bytecode.SamMethod; import de.dhbwstuttgart.bytecode.utilities.SamMethod;
public interface DescriptorVisitor { public interface DescriptorVisitor {
public String visit(NormalMethod method); public String visit(NormalMethod method);

View File

@ -13,6 +13,8 @@ public class TypeToDescriptor implements TypeVisitor<String>{
@Override @Override
public String visit(RefType refType) { public String visit(RefType refType) {
return refType.getName().toString().replace(".", "/"); return refType.getName().toString().replace(".", "/");
// String t = refType.getName().toString().replace(".", "/");
// return t.equals("Fun1")?(t+"$$"):t;
} }
@Override @Override
@ -27,7 +29,8 @@ public class TypeToDescriptor implements TypeVisitor<String>{
@Override @Override
public String visit(ExtendsWildcardType extendsWildcardType) { public String visit(ExtendsWildcardType extendsWildcardType) {
throw new NotImplementedException(); return extendsWildcardType.getInnerType().toString().replace(".", "/");
//throw new NotImplementedException();
} }
@Override @Override

View File

@ -59,10 +59,7 @@ public class Signature {
private void createSignatureForFunN(LambdaExpression lambdaExpression, int numberOfParams) { private void createSignatureForFunN(LambdaExpression lambdaExpression, int numberOfParams) {
sw.visitFormalTypeParameter("R"); // sw.visitClassBound().visitEnd();
// getBounds vom Return-Type
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd();
for(int i = 0;i<numberOfParams;i++) { for(int i = 0;i<numberOfParams;i++) {
int j = i+1; int j = i+1;
sw.visitFormalTypeParameter("T"+ j); sw.visitFormalTypeParameter("T"+ j);
@ -70,6 +67,11 @@ public class Signature {
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class)); sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd(); sw.visitClassBound().visitEnd();
} }
sw.visitFormalTypeParameter("R");
// getBounds vom Return-Type
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd();
// TODO: prüfe ob Return-Type = void, // TODO: prüfe ob Return-Type = void,
sw.visitSuperclass().visitClassType(Type.getInternalName(Object.class));; sw.visitSuperclass().visitClassType(Type.getInternalName(Object.class));;
sw.visitEnd(); sw.visitEnd();
@ -90,7 +92,31 @@ public class Signature {
GenericTypeVar g = itr.next(); GenericTypeVar g = itr.next();
getBoundsOfTypeVar(g,genericsAndBoundsMethod); getBoundsOfTypeVar(g,genericsAndBoundsMethod);
} }
// visits each method-parameter to create the signature // Wenn die RückgabeType eine TPH ist, wird als generic behandelt
// z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
if(ret.substring(0,4).equals("TPH ")) {
String g = ret.substring(4)+"$";
sw.visitFormalTypeParameter(g);
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
genericsAndBoundsMethod.put(g, Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd();
}
for(String paramName : methodParamsAndTypes.keySet()) {
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
String pT = t.acceptTV(new TypeToSignature());
// S.o
if(pT.substring(0,4).equals("TPH ") && !genericsAndBoundsMethod.containsKey(pT)) {
String gP = pT.substring(4)+"$";
sw.visitFormalTypeParameter(gP);
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
genericsAndBoundsMethod.put(gP, Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd();
}
}
// visit each method-parameter to create the signature
for(String paramName : methodParamsAndTypes.keySet()) { for(String paramName : methodParamsAndTypes.keySet()) {
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName); RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
// parameter type deswegen ist true // parameter type deswegen ist true
@ -99,6 +125,15 @@ public class Signature {
if(isConstructor) { if(isConstructor) {
sw.visitReturnType().visitBaseType('V'); sw.visitReturnType().visitBaseType('V');
}else { }else {
// String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
// if(ret.substring(0,4).equals("TPH ")) {
// String g = ret.substring(4);
// if(!genericsAndBoundsMethod.containsKey(g)) {
// genericsAndBoundsMethod.put(g, Type.getInternalName(Object.class));
// } else {
// genericsAndBoundsMethod.put(g+"_", Type.getInternalName(Object.class));
// }
// }
RefTypeOrTPHOrWildcardOrGeneric returnType = method.getReturnType(); RefTypeOrTPHOrWildcardOrGeneric returnType = method.getReturnType();
// return type deswegen ist false // return type deswegen ist false
doVisitParamsOrReturn(returnType, false); doVisitParamsOrReturn(returnType, false);
@ -130,10 +165,16 @@ public class Signature {
break; break;
case "TPH": case "TPH":
RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType; RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType;
if(!r.acceptTV(new TypeToSignature()).substring(0, 4).equals("TPH ")) // der Fall wenn die Type eine Interface ist, muss betrachtet werden
sv.visitInterface().visitClassType(r.acceptTV(new TypeToSignature())); // Deswegen muss in ResutSet noch enthalten werden, ob die Type eine
// sv.visitClassType(r.acceptTV(new TypeToSignature())); // Interface oder eine Klasse ist.
if(!r.acceptTV(new TypeToSignature()).substring(0, 4).equals("TPH ")) {
// sv.visitInterface().visitClassType(r.acceptTV(new TypeToSignature()));
sv.visitClassType(r.acceptTV(new TypeToSignature()));
} else {
System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature())); System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature()));
sv.visitTypeVariable(r.acceptTV(new TypeToSignature()).substring(4)+"$");
}
break; break;
default: default:
if(!isParameterType) if(!isParameterType)

View File

@ -27,6 +27,8 @@ public class TypeToSignature implements TypeVisitor<String> {
} }
params += ";>"; params += ";>";
} }
// String t = refType.getName().toString().replace(".", "/");
// return t.equals("Fun1")?t+"$$"+params+";":t+params+";";
return refType.getName().toString().replace(".", "/") + params+";"; return refType.getName().toString().replace(".", "/") + params+";";
} }

View File

@ -1,4 +1,4 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode.utilities;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;

View File

@ -1,4 +1,4 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode.utilities;
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor; import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.ParameterList;

View File

@ -1,4 +1,4 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode.utilities;
import java.util.HashMap; import java.util.HashMap;

View File

@ -1,4 +1,4 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode.utilities;
import java.util.HashMap; import java.util.HashMap;

View File

@ -1,4 +1,4 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode.utilities;
import java.util.HashMap; import java.util.HashMap;

View File

@ -1,4 +1,4 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode.utilities;
import java.util.List; import java.util.List;

View File

@ -11,8 +11,14 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import de.dhbwstuttgart.bytecode.BytecodeGen;
import de.dhbwstuttgart.environment.CompilationEnvironment; import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.parser.JavaTXParser; import de.dhbwstuttgart.parser.JavaTXParser;
<<<<<<< HEAD
=======
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
>>>>>>> e0d5699ae7f35d8b7af47aeb4adfb33a5167cd00
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
import de.dhbwstuttgart.parser.antlr.Java8Parser.CompilationUnitContext; import de.dhbwstuttgart.parser.antlr.Java8Parser.CompilationUnitContext;
import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.GenericsRegistry;
@ -27,20 +33,29 @@ import de.dhbwstuttgart.strucTypes.exception.InconsistentConstraintsException;
import de.dhbwstuttgart.strucTypes.model.InferredTypes; import de.dhbwstuttgart.strucTypes.model.InferredTypes;
import de.dhbwstuttgart.strucTypes.model.SolvedClass; import de.dhbwstuttgart.strucTypes.model.SolvedClass;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
import de.dhbwstuttgart.typeinference.unify.RuleSet;
import de.dhbwstuttgart.typeinference.unify.TypeUnify; import de.dhbwstuttgart.typeinference.unify.TypeUnify;
<<<<<<< HEAD
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
=======
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
>>>>>>> e0d5699ae7f35d8b7af47aeb4adfb33a5167cd00
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
<<<<<<< HEAD
public class JavaTXCompiler { public class JavaTXCompiler {
final CompilationEnvironment environment; final CompilationEnvironment environment;
@ -172,5 +187,240 @@ public class JavaTXCompiler {
SourceFile ret = generator.convert(tree, environment.packageCrawler); SourceFile ret = generator.convert(tree, environment.packageCrawler);
return ret; return ret;
} }
=======
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class JavaTXCompiler {
final CompilationEnvironment environment;
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"/test/logFiles/log" geschrieben werden soll?
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
this(Arrays.asList(sourceFile));
}
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
this(sourceFile);
this.log = log;
}
public JavaTXCompiler(List<File> sources) throws IOException, ClassNotFoundException {
environment = new CompilationEnvironment(sources);
for (File s : sources) {
sourceFiles.put(s, parse(s));
}
}
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException {
List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
for (SourceFile sf : sourceFiles.values()) {
allClasses.addAll(sf.getClasses());
}
List<ClassOrInterface> importedClasses = new ArrayList<>();
//Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
for (File forSourceFile : sourceFiles.keySet())
for (JavaClassName name : sourceFiles.get(forSourceFile).getImports()) {
//TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
ClassOrInterface importedClass = ASTFactory.createClass(
ClassLoader.getSystemClassLoader().loadClass(name.toString()));
importedClasses.add(importedClass);
}
allClasses.addAll(importedClasses);
return new TYPE(sourceFiles.values(), allClasses).getConstraints();
}
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
for (SourceFile sf : sourceFiles.values()) {
allClasses.addAll(sf.getClasses());
}
List<ClassOrInterface> importedClasses = new ArrayList<>();
for (JavaClassName name : forSourceFile.getImports()) {
//TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
ClassOrInterface importedClass = ASTFactory.createClass(
ClassLoader.getSystemClassLoader().loadClass(name.toString()));
importedClasses.add(importedClass);
allClasses.addAll(importedClasses);
}
return allClasses;
}
public List<ResultSet> typeInference() throws ClassNotFoundException {
List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
//Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
for(SourceFile sf : this.sourceFiles.values()) {
allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses());
}
final ConstraintSet<Pair> cons = getConstraints();
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses);
System.out.println(finiteClosure);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
TypeUnify unify = new TypeUnify();
Set<Set<UnifyPair>> results = new HashSet<>();
try {
FileWriter logFile = new FileWriter(new File(System.getProperty("user.dir")+"/test/logFiles/"+"log"));
logFile.write("FC:\\" + finiteClosure.toString()+"\n");
for(SourceFile sf : this.sourceFiles.values()) {
logFile.write(ASTTypePrinter.print(sf));
}
logFile.flush();
Set<List<Constraint<UnifyPair>>> cardProd = unifyCons.cartesianProduct();
for (List<Constraint<UnifyPair>> xCons : cardProd ){
Set<UnifyPair> xConsSet = new HashSet<>();
for (Constraint<UnifyPair> constraint : xCons) {
xConsSet.addAll(constraint);
}
//.collect(Collectors.toCollection(ArrayList::new))))
System.out.println(xConsSet);
Set<String> paraTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist()
.stream().filter(z -> z.getType() instanceof TypePlaceholder)
.map(z -> ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(HashSet::new)))
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;}, (a,b) -> { a.addAll(b); return a;} ) )
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;} );
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
.map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get();
xConsSet = xConsSet.stream().map(x -> {
//Hier muss ueberlegt werden, ob
//1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs
// mit disableWildcardtable() werden.
//2. alle Typvariablen mit Argument- oder Retuntyp-Variablen
//in Beziehung auch auf disableWildcardtable() gesetzt werden muessen
//PL 2018-04-23
if ((x.getLhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType)x.getLhsType()).setVariance((byte)1);
((PlaceholderType)x.getLhsType()).disableWildcardtable();
}
if (returnTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType)x.getLhsType()).setVariance((byte)-1);
((PlaceholderType)x.getLhsType()).disableWildcardtable();
}
}
if ((x.getRhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType)x.getRhsType()).setVariance((byte)1);
((PlaceholderType)x.getRhsType()).disableWildcardtable();
}
if (returnTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType)x.getRhsType()).setVariance((byte)-1);
((PlaceholderType)x.getRhsType()).disableWildcardtable();
}
}
return x;//HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE JEWEILS ANDERE SEITE
}).map( y -> {
if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) {
if (((PlaceholderType)y.getLhsType()).getVariance() != 0 && ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType()).getVariance());
}
if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) {
((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType()).getVariance());
}
}
return y; } )
.collect(Collectors.toCollection(HashSet::new));
varianceInheritance(xConsSet);
Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure, logFile, log);
//Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
System.out.println("RESULT: " + result);
logFile.write("RES: " + result.toString()+"\n");
logFile.flush();
results.addAll(result);
}
}
catch (IOException e) { }
return results.stream().map((unifyPairs ->
new ResultSet(UnifyTypeFactory.convert(unifyPairs, generateTPHMap(cons))))).collect(Collectors.toList());
}
/**
* Vererbt alle Variancen
* @param eq The set of constraints
*/
private void varianceInheritance(Set<UnifyPair> eq) {
Set<PlaceholderType> usedTPH = new HashSet<>();
Set<PlaceholderType> phSet = eq.stream().map(x -> {
Set<PlaceholderType> pair = new HashSet<>();
if (x.getLhsType() instanceof PlaceholderType) pair.add((PlaceholderType)x.getLhsType());
if (x.getRhsType() instanceof PlaceholderType) pair.add((PlaceholderType)x.getRhsType());
return pair;
}).reduce(new HashSet<>(), (a,b) -> { a.addAll(b); return a;} , (c,d) -> { c.addAll(d); return c;});
ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet);
phSetVariance.removeIf(x -> (x.getVariance() == 0));
while(!phSetVariance.isEmpty()) {
PlaceholderType a = phSetVariance.remove(0);
usedTPH.add(a);
//HashMap<PlaceholderType,Integer> ht = new HashMap<>();
//ht.put(a, a.getVariance());
Set<UnifyPair> eq1 = new HashSet<>(eq);
eq1.removeIf(x -> !(x.getLhsType() instanceof PlaceholderType && ((PlaceholderType)x.getLhsType()).equals(a)));
eq1.stream().forEach(x -> { x.getRhsType().accept(new distributeVariance(), a.getVariance());});
eq1 = new HashSet<>(eq);
eq1.removeIf(x -> !(x.getRhsType() instanceof PlaceholderType && ((PlaceholderType)x.getRhsType()).equals(a)));
eq1.stream().forEach(x -> { x.getLhsType().accept(new distributeVariance(), a.getVariance());});
phSetVariance = new ArrayList<>(phSet);
phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x)));
}
}
private 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;
}
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
CompilationUnitContext tree = JavaTXParser.parse(sourceFile);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile), new GenericsRegistry(null));
SourceFile ret = generator.convert(tree, environment.packageCrawler);
return ret;
}
public void generateBytecode() throws ClassNotFoundException, IOException {
for(File f : sourceFiles.keySet()) {
HashMap<String,byte[]> classFiles = new HashMap<>();
SourceFile sf = sourceFiles.get(f);
List<ResultSet> typeinferenceResult = this.typeInference();
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult);
// BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult.get(0));
bytecodeGen.visit(sf);
this.writeClassFile(bytecodeGen.getClassFiles());
}
}
private void writeClassFile(HashMap<String, byte[]> classFiles) throws IOException {
FileOutputStream output;
for(String name : classFiles.keySet()) {
byte[] bytecode = classFiles.get(name);
System.out.println("generating "+name+ ".class file ...");
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class"));
output.write(bytecode);
output.close();
System.out.println(name+".class file generated");
}
}
} }

View File

@ -832,7 +832,7 @@ public class StatementGenerator {
}else if(literal.StringLiteral()!=null){ }else if(literal.StringLiteral()!=null){
RefType type = new RefType(reg.getName("java.lang.String"),literal.getStart()); RefType type = new RefType(reg.getName("java.lang.String"),literal.getStart());
return new Literal(type, return new Literal(type,
literal.StringLiteral().getText(), literal.StringLiteral().getText().substring(1, literal.StringLiteral().getText().length()-1),
literal.getStart()); literal.getStart());
}else if(literal.NullLiteral() != null){ }else if(literal.NullLiteral() != null){
return new Literal(TypePlaceholder.fresh(literal.getStart()), null, return new Literal(TypePlaceholder.fresh(literal.getStart()), null,

View File

@ -22,18 +22,20 @@ import java.util.List;
public class TypeGenerator { public class TypeGenerator {
public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.UnannClassOrInterfaceTypeContext unannClassOrInterfaceTypeContext, JavaClassRegistry reg, GenericsRegistry generics) { public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.UnannClassOrInterfaceTypeContext unannClassOrInterfaceTypeContext, JavaClassRegistry reg, GenericsRegistry generics) {
String name;
if(unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType() != null){
name = unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().unannClassType_lfno_unannClassOrInterfaceType().Identifier().getText();
}
Java8Parser.TypeArgumentsContext arguments; Java8Parser.TypeArgumentsContext arguments;
if(unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType() != null){ if(unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType() != null){
name = unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().Identifier().getText();
arguments = unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().typeArguments(); arguments = unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().typeArguments();
}else{// if(unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType() != null){ }else{// if(unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType() != null){
name = unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().unannClassType_lfno_unannClassOrInterfaceType().getText();
arguments = unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().unannClassType_lfno_unannClassOrInterfaceType().typeArguments(); arguments = unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().unannClassType_lfno_unannClassOrInterfaceType().typeArguments();
} }
/**
* Problem sind hier die verschachtelten Typen mit verschachtelten Typargumenten
* Beispiel: Typ<String>.InnererTyp<Integer>
*/
String name = unannClassOrInterfaceTypeContext.getText();
if(name.contains("<")){
name = name.split("<")[0]; //Der Typ ist alles vor den ersten Argumenten
}
return convertTypeName(name, arguments, unannClassOrInterfaceTypeContext.getStart(), reg, generics); return convertTypeName(name, arguments, unannClassOrInterfaceTypeContext.getStart(), reg, generics);
} }

View File

@ -114,4 +114,8 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
public List<RefType> getSuperInterfaces() { public List<RefType> getSuperInterfaces() {
return implementedInterfaces; return implementedInterfaces;
} }
public String toString() {
return this.name.toString() + this.genericClassParameters.toString();
}
} }

View File

@ -38,8 +38,13 @@ public class GenericDeclarationList extends SyntaxTreeNode implements Iterable<G
visitor.visit(this); visitor.visit(this);
} }
@Override @Override
public GenericDeclarationList accept(ASTReturnVisitor visitor) { public GenericDeclarationList accept(ASTReturnVisitor visitor) {
return visitor.visit(this); return visitor.visit(this);
} }
public String toString() {
return this.gtvs.toString();
}
} }

View File

@ -27,6 +27,8 @@ import de.dhbwstuttgart.typeinference.unify.model.*;
public class UnifyTypeFactory { public class UnifyTypeFactory {
private static ArrayList<PlaceholderType> PLACEHOLDERS = new ArrayList<>();
public static FiniteClosure generateFC(List<ClassOrInterface> fromClasses) throws ClassNotFoundException { public static FiniteClosure generateFC(List<ClassOrInterface> fromClasses) throws ClassNotFoundException {
/* /*
Die transitive Hülle muss funktionieren. Die transitive Hülle muss funktionieren.
@ -49,6 +51,10 @@ public class UnifyTypeFactory {
return new UnifyPair(tl, tr, PairOperator.SMALLERDOT); return new UnifyPair(tl, tr, PairOperator.SMALLERDOT);
} }
public static UnifyPair generateSmallNotEqualDotPair(UnifyType tl, UnifyType tr){
return new UnifyPair(tl, tr, PairOperator.SMALLERNEQDOT);
}
public static UnifyPair generateEqualDotPair(UnifyType tl, UnifyType tr){ public static UnifyPair generateEqualDotPair(UnifyType tl, UnifyType tr){
return new UnifyPair(tl, tr, PairOperator.EQUALSDOT); return new UnifyPair(tl, tr, PairOperator.EQUALSDOT);
} }
@ -113,7 +119,15 @@ public class UnifyTypeFactory {
} }
public static UnifyType convert(TypePlaceholder tph){ public static UnifyType convert(TypePlaceholder tph){
return new PlaceholderType(tph.getName()); PlaceholderType ntph = new PlaceholderType(tph.getName());
int in = PLACEHOLDERS.indexOf(ntph);
if (in == -1) {
PLACEHOLDERS.add(ntph);
return ntph;
}
else {
return PLACEHOLDERS.get(in);
}
} }
public static UnifyType convert(GenericRefType t){ public static UnifyType convert(GenericRefType t){
@ -142,6 +156,10 @@ public class UnifyTypeFactory {
UnifyPair ret = generateSmallerDotPair(UnifyTypeFactory.convert(p.TA1) UnifyPair ret = generateSmallerDotPair(UnifyTypeFactory.convert(p.TA1)
, UnifyTypeFactory.convert(p.TA2)); , UnifyTypeFactory.convert(p.TA2));
return ret; return ret;
}else if(p.GetOperator().equals(PairOperator.SMALLERNEQDOT)) {
UnifyPair ret = generateSmallNotEqualDotPair(UnifyTypeFactory.convert(p.TA1)
, UnifyTypeFactory.convert(p.TA2));
return ret;
}else if(p.GetOperator().equals(PairOperator.EQUALSDOT)) { }else if(p.GetOperator().equals(PairOperator.EQUALSDOT)) {
UnifyPair ret = generateEqualDotPair(UnifyTypeFactory.convert(p.TA1) UnifyPair ret = generateEqualDotPair(UnifyTypeFactory.convert(p.TA1)
, UnifyTypeFactory.convert(p.TA2)); , UnifyTypeFactory.convert(p.TA2));

View File

@ -12,6 +12,7 @@ public class Pair implements Serializable
private PairOperator eOperator = PairOperator.SMALLER; private PairOperator eOperator = PairOperator.SMALLER;
public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2 ) public Pair(RefTypeOrTPHOrWildcardOrGeneric TA1, RefTypeOrTPHOrWildcardOrGeneric TA2 )
{ {
this.TA1 = TA1; this.TA1 = TA1;
@ -41,14 +42,16 @@ public class Pair implements Serializable
if( TA2 != null ) if( TA2 != null )
strElement2 = TA2.toString(); strElement2 = TA2.toString();
/* PL ausskommentiert 2018-05-24
if(OperatorEqual()) if(OperatorEqual())
Operator = "="; Operator = "=";
if(OperatorSmaller()) if(OperatorSmaller())
Operator = "<."; Operator = "<.";
if(OperatorSmallerExtends()) if(OperatorSmallerExtends())
Operator = "<?"; Operator = "<?";
*/
return "\n(" + strElement1 + " " + Operator + " " + strElement2 + ")"; return "\n(" + strElement1 + " " + eOperator.toString() + " " + strElement2 + ")";
/*- Equals: " + bEqual*/ /*- Equals: " + bEqual*/
} }

View File

@ -57,8 +57,8 @@ public class TYPEStmt implements StatementVisitor{
public void visit(LambdaExpression lambdaExpression) { public void visit(LambdaExpression lambdaExpression) {
TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken()); TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken());
List<RefTypeOrTPHOrWildcardOrGeneric> lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList()); List<RefTypeOrTPHOrWildcardOrGeneric> lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList());
//lambdaParams.add(tphRetType); lambdaParams.add(tphRetType);
lambdaParams.add(0,tphRetType); //lambdaParams.add(0,tphRetType);
constraintsSet.addUndConstraint( constraintsSet.addUndConstraint(
new Pair(lambdaExpression.getType(), new Pair(lambdaExpression.getType(),
new FunN(lambdaParams),PairOperator.EQUALSDOT)); new FunN(lambdaParams),PairOperator.EQUALSDOT));
@ -185,6 +185,12 @@ public class TYPEStmt implements StatementVisitor{
} }
private final RefType number = new RefType(ASTFactory.createClass(Number.class).getClassName(), new NullToken()); private final RefType number = new RefType(ASTFactory.createClass(Number.class).getClassName(), new NullToken());
private final RefType longg = new RefType(ASTFactory.createClass(Long.class).getClassName(), new NullToken());
private final RefType integer = new RefType(ASTFactory.createClass(Integer.class).getClassName(), new NullToken());
private final RefType shortt = new RefType(ASTFactory.createClass(Short.class).getClassName(), new NullToken());
private final RefType bytee = new RefType(ASTFactory.createClass(Byte.class).getClassName(), new NullToken());
private final RefType floatt = new RefType(ASTFactory.createClass(Float.class).getClassName(), new NullToken());
private final RefType doublee = new RefType(ASTFactory.createClass(Double.class).getClassName(), new NullToken());
private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken()); private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken());
private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken()); private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken());
@Override @Override
@ -205,18 +211,47 @@ public class TYPEStmt implements StatementVisitor{
@Override @Override
public void visit(BinaryExpr binary) { public void visit(BinaryExpr binary) {
binary.lexpr.accept(this);
binary.rexpr.accept(this);
if(binary.operation.equals(BinaryExpr.Operator.DIV) || if(binary.operation.equals(BinaryExpr.Operator.DIV) ||
binary.operation.equals(BinaryExpr.Operator.MUL)|| binary.operation.equals(BinaryExpr.Operator.MUL)||
binary.operation.equals(BinaryExpr.Operator.MOD)|| binary.operation.equals(BinaryExpr.Operator.MOD)||
binary.operation.equals(BinaryExpr.Operator.ADD)){ binary.operation.equals(BinaryExpr.Operator.ADD)){
Set<Constraint> numericAdditionOrStringConcatenation = new HashSet<>(); Set<Constraint<Pair>> numericAdditionOrStringConcatenation = new HashSet<>();
Constraint<Pair> numeric = new Constraint<>();
//Zuerst der Fall für Numerische AusdrücPairOpnumericeratorke, das sind Mul, Mod und Div immer: //Zuerst der Fall für Numerische AusdrücPairOpnumericeratorke, das sind Mul, Mod und Div immer:
//see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17 //see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17
//Expression muss zu Numeric Convertierbar sein. also von Numeric erben //Expression muss zu Numeric Convertierbar sein. also von Numeric erben
numeric.add(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERDOT)); Constraint<Pair> numeric = new Constraint<>();
numeric.add(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), integer, PairOperator.SMALLERDOT));
numericAdditionOrStringConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), shortt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), integer, PairOperator.SMALLERDOT));
numericAdditionOrStringConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), integer, PairOperator.SMALLERDOT));
numericAdditionOrStringConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), longg, PairOperator.SMALLERDOT));
numericAdditionOrStringConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), floatt, PairOperator.SMALLERDOT));
numericAdditionOrStringConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), doublee, PairOperator.SMALLERDOT));
numericAdditionOrStringConcatenation.add(numeric);
/* /*
In Java passiert bei den binären Operatoren eine sogenannte Type Promotion: In Java passiert bei den binären Operatoren eine sogenannte Type Promotion:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2
@ -237,10 +272,54 @@ public class TYPEStmt implements StatementVisitor{
binary.operation.equals(BinaryExpr.Operator.BIGGEREQUAL) || binary.operation.equals(BinaryExpr.Operator.BIGGEREQUAL) ||
binary.operation.equals(BinaryExpr.Operator.BIGGERTHAN) || binary.operation.equals(BinaryExpr.Operator.BIGGERTHAN) ||
binary.operation.equals(BinaryExpr.Operator.LESSTHAN)){ binary.operation.equals(BinaryExpr.Operator.LESSTHAN)){
constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERDOT)); /* //eingefuegt PL 2018-05-24
constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERDOT)); Set<Constraint<Pair>> numericRelationConcatenation = new HashSet<>();
Constraint<Pair> numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
numericRelationConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), shortt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
numericRelationConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
numericRelationConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
numericRelationConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
numericRelationConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
numericRelationConcatenation.add(numeric);
//***ACHTUNG: Moeglicherweise oder und und-Contraint falsch
constraintsSet.addOderConstraint(numericRelationConcatenation);
//***ACHTUNG: Moeglicherweise oder und und-Contraint falsch
*/
//Testeise eingefuegt PL 2018-05-24
constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERNEQDOT));
constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERNEQDOT));
//Rückgabetyp ist Boolean //Rückgabetyp ist Boolean
constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.SMALLERDOT));
//auskommentiert PL 2018-05-24
//constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERDOT));
//constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERDOT));
//Rückgabetyp ist Boolean
//constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT));
}else{ }else{
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@ -94,7 +94,8 @@ public class MartelliMontanariUnify implements IUnify {
// SUBST - Rule // SUBST - Rule
if(lhsType instanceof PlaceholderType) { if(lhsType instanceof PlaceholderType) {
mgu.add((PlaceholderType) lhsType, rhsType); mgu.add((PlaceholderType) lhsType, rhsType);
termsList = termsList.stream().map(mgu::apply).collect(Collectors.toCollection(ArrayList::new)); //PL 2018-04-01 nach checken, ob es richtig ist, dass keine Substitutionen uebergeben werden muessen.
termsList = termsList.stream().map(x -> mgu.apply(x)).collect(Collectors.toCollection(ArrayList::new));
idx = idx+1 == termsList.size() ? 0 : idx+1; idx = idx+1 == termsList.size() ? 0 : idx+1;
continue; continue;
} }

View File

@ -24,6 +24,10 @@ import de.dhbwstuttgart.typeinference.unify.model.Unifier;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import de.dhbwstuttgart.typeinference.unify.model.WildcardType; import de.dhbwstuttgart.typeinference.unify.model.WildcardType;
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
import java.io.FileWriter;
import java.io.IOException;
/** /**
* Implementation of the type inference rules. * Implementation of the type inference rules.
@ -32,6 +36,16 @@ import de.dhbwstuttgart.typeinference.unify.model.WildcardType;
*/ */
public class RuleSet implements IRuleSet{ public class RuleSet implements IRuleSet{
FileWriter logFile;
RuleSet() {
super();
}
RuleSet(FileWriter logFile) {
this.logFile = logFile;
}
@Override @Override
public Optional<UnifyPair> reduceUp(UnifyPair pair) { public Optional<UnifyPair> reduceUp(UnifyPair pair) {
// Check if reduce up is applicable // Check if reduce up is applicable
@ -47,7 +61,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty(); return Optional.empty();
// Rule is applicable, unpack the SuperType // Rule is applicable, unpack the SuperType
return Optional.of(new UnifyPair(lhsType, ((SuperType) rhsType).getSuperedType(), PairOperator.SMALLERDOT)); return Optional.of(new UnifyPair(lhsType, ((SuperType) rhsType).getSuperedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
} }
@Override @Override
@ -65,7 +79,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty(); return Optional.empty();
// Rule is applicable, unpack the ExtendsType // Rule is applicable, unpack the ExtendsType
return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(), rhsType, PairOperator.SMALLERDOT)); return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(), rhsType, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
} }
@Override @Override
@ -83,7 +97,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty(); return Optional.empty();
// Rule is applicable, unpack both sides // Rule is applicable, unpack both sides
return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(),((SuperType) rhsType).getSuperedType(), PairOperator.SMALLERDOT)); return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(),((SuperType) rhsType).getSuperedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
} }
@Override @Override
@ -117,7 +131,7 @@ public class RuleSet implements IRuleSet{
if(x instanceof ExtendsType) if(x instanceof ExtendsType)
xFromFc = new ExtendsType(xFromFc); xFromFc = new ExtendsType(xFromFc);
UnifyType extYFromFc = fc.grArg(xFromFc).stream().filter(t -> t.getName().equals(extY.getName())).filter(t -> t.getTypeParams().arePlaceholders()).findAny().orElse(null); UnifyType extYFromFc = fc.grArg(xFromFc, new HashSet<>()).stream().filter(t -> t.getName().equals(extY.getName())).filter(t -> t.getTypeParams().arePlaceholders()).findAny().orElse(null);
if(extYFromFc == null || extYFromFc.getTypeParams() != xFromFc.getTypeParams()) if(extYFromFc == null || extYFromFc.getTypeParams() != xFromFc.getTypeParams())
return Optional.empty(); return Optional.empty();
@ -133,7 +147,7 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<>(); Set<UnifyPair> result = new HashSet<>();
for(int rhsIdx = 0; rhsIdx < extYParams.size(); rhsIdx++) for(int rhsIdx = 0; rhsIdx < extYParams.size(); rhsIdx++)
result.add(new UnifyPair(xParams.get(pi[rhsIdx]), extYParams.get(rhsIdx), PairOperator.SMALLERDOTWC)); result.add(new UnifyPair(xParams.get(pi[rhsIdx]), extYParams.get(rhsIdx), PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result); return Optional.of(result);
} }
@ -169,7 +183,7 @@ public class RuleSet implements IRuleSet{
if(x instanceof SuperType) if(x instanceof SuperType)
xFromFc = new SuperType(xFromFc); xFromFc = new SuperType(xFromFc);
UnifyType supYFromFc = fc.grArg(xFromFc).stream().filter(t -> t.getName().equals(supY.getName())).filter(t -> t.getTypeParams().arePlaceholders()).findAny().orElse(null); UnifyType supYFromFc = fc.grArg(xFromFc, new HashSet<>()).stream().filter(t -> t.getName().equals(supY.getName())).filter(t -> t.getTypeParams().arePlaceholders()).findAny().orElse(null);
if(supYFromFc == null || supYFromFc.getTypeParams() != xFromFc.getTypeParams()) if(supYFromFc == null || supYFromFc.getTypeParams() != xFromFc.getTypeParams())
return Optional.empty(); return Optional.empty();
@ -184,7 +198,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty(); return Optional.empty();
for(int rhsIdx = 0; rhsIdx < supYParams.size(); rhsIdx++) for(int rhsIdx = 0; rhsIdx < supYParams.size(); rhsIdx++)
result.add(new UnifyPair(supYParams.get(rhsIdx), xParams.get(pi[rhsIdx]), PairOperator.SMALLERDOTWC)); result.add(new UnifyPair(supYParams.get(rhsIdx), xParams.get(pi[rhsIdx]), PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result); return Optional.of(result);
} }
@ -215,7 +229,7 @@ public class RuleSet implements IRuleSet{
TypeParams rhsTypeParams = rhsType.getTypeParams(); TypeParams rhsTypeParams = rhsType.getTypeParams();
for(int i = 0; i < lhsTypeParams.size(); i++) for(int i = 0; i < lhsTypeParams.size(); i++)
result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT)); result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result); return Optional.of(result);
} }
@ -236,19 +250,53 @@ public class RuleSet implements IRuleSet{
ReferenceType lhsSType = (ReferenceType) c; ReferenceType lhsSType = (ReferenceType) c;
ReferenceType rhsSType = (ReferenceType) d; ReferenceType rhsSType = (ReferenceType) d;
//try {
// logFile.write("PAIR Rules: " + pair + "\n");
// logFile.flush();
//}
//catch (IOException e) { }
if(lhsSType.getTypeParams().empty() || lhsSType.getTypeParams().size() != rhsSType.getTypeParams().size()) if(lhsSType.getTypeParams().empty() || lhsSType.getTypeParams().size() != rhsSType.getTypeParams().size())
return Optional.empty(); return Optional.empty();
UnifyType cFromFc = fc.getLeftHandedType(c.getName()).orElse(null); UnifyType cFromFc = fc.getLeftHandedType(c.getName()).orElse(null);
//2018-02-23: liefert Vector<Vector<Integer>>: Das kann nicht sein.
//NOCHMAL UEBERPRUEFEN
//PL 18-02-09 Eingfuegt Anfang
//C und D koennen auch gleich sein.
if (c.getName().equals(d.getName())) {
Set<UnifyPair> result = new HashSet<>();
TypeParams rhsTypeParams = d.getTypeParams();
TypeParams lhsTypeParams = c.getTypeParams();
for(int rhsIdx = 0; rhsIdx < c.getTypeParams().size(); rhsIdx++)
result.add(new UnifyPair(lhsTypeParams.get(rhsIdx), rhsTypeParams.get(rhsIdx), PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result);
}
//PL 18-02-09 Eingfuegt ENDE
//try {
// logFile.write("cFromFc: " + cFromFc);
// logFile.flush();
//}
//catch (IOException e) { }
if(cFromFc == null || !cFromFc.getTypeParams().arePlaceholders()) if(cFromFc == null || !cFromFc.getTypeParams().arePlaceholders())
return Optional.empty(); return Optional.empty();
UnifyType dFromFc = fc.getAncestors(cFromFc).stream().filter(x -> x.getName().equals(d.getName())).findAny().orElse(null); UnifyType dFromFc = fc.getAncestors(cFromFc).stream().filter(x -> x.getName().equals(d.getName())).findAny().orElse(null);
//try {
// logFile.write("cFromFc: " + cFromFc);
// logFile.flush();
//}
//catch (IOException e) { }
if(dFromFc == null || !dFromFc.getTypeParams().arePlaceholders() || dFromFc.getTypeParams().size() != cFromFc.getTypeParams().size()) if(dFromFc == null || !dFromFc.getTypeParams().arePlaceholders() || dFromFc.getTypeParams().size() != cFromFc.getTypeParams().size())
return Optional.empty(); return Optional.empty();
//System.out.println("cFromFc: " + cFromFc);
//System.out.println("dFromFc: " + dFromFc);
int[] pi = pi(cFromFc.getTypeParams(), dFromFc.getTypeParams()); int[] pi = pi(cFromFc.getTypeParams(), dFromFc.getTypeParams());
if(pi.length == 0) if(pi.length == 0)
@ -259,7 +307,7 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<>(); Set<UnifyPair> result = new HashSet<>();
for(int rhsIdx = 0; rhsIdx < rhsTypeParams.size(); rhsIdx++) for(int rhsIdx = 0; rhsIdx < rhsTypeParams.size(); rhsIdx++)
result.add(new UnifyPair(lhsTypeParams.get(pi[rhsIdx]), rhsTypeParams.get(rhsIdx), PairOperator.SMALLERDOTWC)); result.add(new UnifyPair(lhsTypeParams.get(pi[rhsIdx]), rhsTypeParams.get(rhsIdx), PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result); return Optional.of(result);
} }
@ -314,16 +362,31 @@ public class RuleSet implements IRuleSet{
TypeParams rhsTypeParams = rhsSType.getTypeParams(); TypeParams rhsTypeParams = rhsSType.getTypeParams();
TypeParams lhsTypeParams = lhsSType.getTypeParams(); TypeParams lhsTypeParams = lhsSType.getTypeParams();
for(int i = 0; i < rhsTypeParams.size(); i++) for(int i = 0; i < rhsTypeParams.size(); i++)
result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT)); result.add(new UnifyPair(lhsTypeParams.get(i), rhsTypeParams.get(i), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
return Optional.of(result); return Optional.of(result);
} }
@Override @Override
public boolean erase1(UnifyPair pair, IFiniteClosure fc) { public boolean erase1(UnifyPair pair, IFiniteClosure fc) {
if(pair.getPairOp() != PairOperator.SMALLERDOT) if((pair.getPairOp() != PairOperator.SMALLERDOT) && (pair.getPairOp() != PairOperator.SMALLERNEQDOT))
return false; return false;
if (pair.getPairOp() == PairOperator.SMALLERNEQDOT) {
UnifyType lhs = pair.getLhsType();
UnifyType rhs = pair.getRhsType();
if (lhs instanceof WildcardType) {
lhs = ((WildcardType)lhs).getWildcardedType();
}
if (rhs instanceof WildcardType) {
rhs = ((WildcardType)rhs).getWildcardedType();
}
if (lhs.equals(rhs)){
return false;
}
}
UnifyType lhsType = pair.getLhsType(); UnifyType lhsType = pair.getLhsType();
if(!(lhsType instanceof ReferenceType) && !(lhsType instanceof PlaceholderType)) if(!(lhsType instanceof ReferenceType) && !(lhsType instanceof PlaceholderType))
return false; return false;
@ -332,7 +395,7 @@ public class RuleSet implements IRuleSet{
if(!(rhsType instanceof ReferenceType) && !(rhsType instanceof PlaceholderType)) if(!(rhsType instanceof ReferenceType) && !(rhsType instanceof PlaceholderType))
return false; return false;
return fc.greater(lhsType).contains(rhsType); return fc.greater(lhsType, new HashSet<>()).contains(rhsType);
} }
@Override @Override
@ -343,7 +406,7 @@ public class RuleSet implements IRuleSet{
UnifyType lhsType = pair.getLhsType(); UnifyType lhsType = pair.getLhsType();
UnifyType rhsType = pair.getRhsType(); UnifyType rhsType = pair.getRhsType();
return fc.grArg(lhsType).contains(rhsType); return fc.grArg(lhsType, new HashSet<>()).contains(rhsType);
} }
@Override @Override
@ -365,7 +428,7 @@ public class RuleSet implements IRuleSet{
if(!(pair.getRhsType() instanceof PlaceholderType)) if(!(pair.getRhsType() instanceof PlaceholderType))
return Optional.empty(); return Optional.empty();
return Optional.of(new UnifyPair(pair.getRhsType(), pair.getLhsType(), PairOperator.EQUALSDOT)); return Optional.of(new UnifyPair(pair.getRhsType(), pair.getLhsType(), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
} }
@Override @Override
@ -407,11 +470,19 @@ public class RuleSet implements IRuleSet{
TypeParams typeDParams = typeD.getTypeParams(); TypeParams typeDParams = typeD.getTypeParams();
TypeParams typeDgenParams = typeDgen.getTypeParams(); TypeParams typeDgenParams = typeDgen.getTypeParams();
//System.out.println("Pair: " +pair);
//System.out.println("typeD: " +typeD);
//System.out.println("typeDParams: " +typeDParams);
//System.out.println("typeDgen: " +typeD);
//System.out.println("typeDgenParams: " +typeDgenParams);
Unifier unif = Unifier.identity(); Unifier unif = Unifier.identity();
for(int i = 0; i < typeDParams.size(); i++) for(int i = 0; i < typeDParams.size(); i++) {
//System.out.println("ADAPT" +typeDgenParams);
if (typeDgenParams.get(i) instanceof PlaceholderType)
unif.add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i)); unif.add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i));
else System.out.println("ERROR");
return Optional.of(new UnifyPair(unif.apply(newLhs), typeDs, PairOperator.SMALLERDOT)); }
return Optional.of(new UnifyPair(unif.apply(newLhs), typeDs, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
} }
@Override @Override
@ -441,7 +512,7 @@ public class RuleSet implements IRuleSet{
if(typeDgen == null) if(typeDgen == null)
return Optional.empty(); return Optional.empty();
Set<UnifyType> grArg = fc.grArg(typeDgen); Set<UnifyType> grArg = fc.grArg(typeDgen, new HashSet<>());
Optional<UnifyType> opt = grArg.stream().filter(x -> x.getName().equals(typeExtDs.getName())).findAny(); Optional<UnifyType> opt = grArg.stream().filter(x -> x.getName().equals(typeExtDs.getName())).findAny();
@ -457,7 +528,7 @@ public class RuleSet implements IRuleSet{
for(int i = 1; i < typeDParams.size(); i++) for(int i = 1; i < typeDParams.size(); i++)
unif.add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i)); unif.add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i));
return Optional.of(new UnifyPair(unif.apply(newLhs), typeExtDs, PairOperator.SMALLERDOTWC)); return Optional.of(new UnifyPair(unif.apply(newLhs), typeExtDs, PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
} }
@Override @Override
@ -487,7 +558,7 @@ public class RuleSet implements IRuleSet{
// Use of smArg instead of grArg because // Use of smArg instead of grArg because
// a in grArg(b) => b in smArg(a) // a in grArg(b) => b in smArg(a)
Set<UnifyType> smArg = fc.smArg(typeSupDgen); Set<UnifyType> smArg = fc.smArg(typeSupDgen, new HashSet<>());
opt = smArg.stream().filter(x -> x.getName().equals(typeDs.getName())).findAny(); opt = smArg.stream().filter(x -> x.getName().equals(typeDs.getName())).findAny();
if(!opt.isPresent()) if(!opt.isPresent())
@ -509,7 +580,7 @@ public class RuleSet implements IRuleSet{
for(int i = 1; i < typeDParams.size(); i++) for(int i = 1; i < typeDParams.size(); i++)
unif.add((PlaceholderType) typeSupDsgenParams.get(i), typeDParams.get(i)); unif.add((PlaceholderType) typeSupDsgenParams.get(i), typeDParams.get(i));
return Optional.of(new UnifyPair(unif.apply(newLhs), newRhs, PairOperator.SMALLERDOTWC)); return Optional.of(new UnifyPair(unif.apply(newLhs), newRhs, PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
} }
/** /**
@ -581,8 +652,8 @@ public class RuleSet implements IRuleSet{
&& typeMap.get(lhsType) > 1 // The type occurs in more pairs in the set than just the recent pair. && typeMap.get(lhsType) > 1 // The type occurs in more pairs in the set than just the recent pair.
&& !rhsType.getTypeParams().occurs(lhsType)) { && !rhsType.getTypeParams().occurs(lhsType)) {
Unifier uni = new Unifier(lhsType, rhsType); Unifier uni = new Unifier(lhsType, rhsType);
result = result.stream().map(uni::apply).collect(Collectors.toCollection(ArrayList::new)); result = result.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(ArrayList::new));
result1 = result1.stream().map(uni::apply).collect(Collectors.toCollection(LinkedList::new)); result1 = result1.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(LinkedList::new));
applied = true; applied = true;
} }
@ -602,7 +673,7 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof ExtendsType) || !(rhsType instanceof ExtendsType)) if(!(lhsType instanceof ExtendsType) || !(rhsType instanceof ExtendsType))
return Optional.empty(); return Optional.empty();
return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(), ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT)); return Optional.of(new UnifyPair(((ExtendsType) lhsType).getExtendedType(), ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
} }
@Override @Override
@ -615,7 +686,7 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof ExtendsType)) if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof ExtendsType))
return Optional.empty(); return Optional.empty();
return Optional.of(new UnifyPair(lhsType, ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT)); return Optional.of(new UnifyPair(lhsType, ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
} }
@Override @Override
@ -628,7 +699,7 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof SuperType) || !(rhsType instanceof SuperType)) if(!(lhsType instanceof SuperType) || !(rhsType instanceof SuperType))
return Optional.empty(); return Optional.empty();
return Optional.of(new UnifyPair(((SuperType) rhsType).getSuperedType(), ((SuperType) lhsType).getSuperedType(), PairOperator.SMALLERDOT)); return Optional.of(new UnifyPair(((SuperType) rhsType).getSuperedType(), ((SuperType) lhsType).getSuperedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
} }
@Override @Override
@ -641,9 +712,11 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof SuperType)) if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof SuperType))
return Optional.empty(); return Optional.empty();
return Optional.of(new UnifyPair(((SuperType) rhsType).getSuperedType(), lhsType, PairOperator.SMALLERDOTWC)); return Optional.of(new UnifyPair(((SuperType) rhsType).getSuperedType(), lhsType, PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
} }
/* PL 2018-03-06 auskommentiert sind mutmaßlich falsch
* vgl. JAVA_BSP/Wildcard6.java
@Override @Override
public Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair) { public Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair) {
if(pair.getPairOp() != PairOperator.SMALLERDOTWC) if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
@ -670,6 +743,7 @@ public class RuleSet implements IRuleSet{
return Optional.of(new UnifyPair(((SuperType) lhsType).getSuperedType(), ((ExtendsType) rhsType).getExtendedType(), PairOperator.EQUALSDOT)); return Optional.of(new UnifyPair(((SuperType) lhsType).getSuperedType(), ((ExtendsType) rhsType).getExtendedType(), PairOperator.EQUALSDOT));
} }
@Override @Override
public Optional<UnifyPair> reduceWildcardLeft(UnifyPair pair) { public Optional<UnifyPair> reduceWildcardLeft(UnifyPair pair) {
if(pair.getPairOp() != PairOperator.SMALLERDOTWC) if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
@ -686,7 +760,7 @@ public class RuleSet implements IRuleSet{
return Optional.empty(); return Optional.empty();
} }
*/
@Override @Override
public Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair) { public Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair) {
if((pair.getPairOp() != PairOperator.SMALLERDOT) if((pair.getPairOp() != PairOperator.SMALLERDOT)
@ -709,13 +783,19 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<UnifyPair>(); Set<UnifyPair> result = new HashSet<UnifyPair>();
result.add(new UnifyPair(funNLhsType.getTypeParams().get(0), funNRhsType.getTypeParams().get(0), PairOperator.SMALLERDOT)); result.add(new UnifyPair(funNLhsType.getTypeParams().get(funNLhsType.getTypeParams().size()-1), funNRhsType.getTypeParams().get(funNRhsType.getTypeParams().size()-1), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
for(int i = 1; i < funNLhsType.getTypeParams().size(); i++) for(int i = 0; i < funNLhsType.getTypeParams().size()-1; i++) {
result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT)); result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
}
result.stream().forEach(x -> { UnifyType l = x.getLhsType();
if (l instanceof PlaceholderType) { ((PlaceholderType)l).disableWildcardtable(); }
UnifyType r = x.getRhsType();
if (r instanceof PlaceholderType) { ((PlaceholderType)r).disableWildcardtable(); }
} );
return Optional.of(result); return Optional.of(result);
} }
@Override @Override
public Optional<Set<UnifyPair>> greaterFunN(UnifyPair pair) { public Optional<Set<UnifyPair>> greaterFunN(UnifyPair pair) {
if(pair.getPairOp() != PairOperator.SMALLERDOT) if(pair.getPairOp() != PairOperator.SMALLERDOT)
@ -731,15 +811,29 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<UnifyPair>(); Set<UnifyPair> result = new HashSet<UnifyPair>();
Integer variance = ((PlaceholderType)rhsType).getVariance();
Integer inversVariance = distributeVariance.inverseVariance(variance);
UnifyType[] freshPlaceholders = new UnifyType[funNLhsType.getTypeParams().size()]; UnifyType[] freshPlaceholders = new UnifyType[funNLhsType.getTypeParams().size()];
for(int i = 0; i < freshPlaceholders.length; i++) for(int i = 0; i < freshPlaceholders.length-1; i++) {
freshPlaceholders[i] = PlaceholderType.freshPlaceholder(); freshPlaceholders[i] = PlaceholderType.freshPlaceholder();
((PlaceholderType)freshPlaceholders[i]).setVariance(inversVariance);
}
freshPlaceholders[freshPlaceholders.length-1] = PlaceholderType.freshPlaceholder();
((PlaceholderType)freshPlaceholders[freshPlaceholders.length-1]).setVariance(variance);
result.add(new UnifyPair(funNLhsType.getTypeParams().get(funNLhsType.getTypeParams().size()-1), freshPlaceholders[funNLhsType.getTypeParams().size()-1], PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
result.add(new UnifyPair(funNLhsType.getTypeParams().get(0), freshPlaceholders[0], PairOperator.SMALLERDOT)); for(int i = 0; i < funNLhsType.getTypeParams().size()-1; i++) {
for(int i = 1; i < funNLhsType.getTypeParams().size(); i++) result.add(new UnifyPair(freshPlaceholders[i], funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
result.add(new UnifyPair(freshPlaceholders[i], funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT)); }
result.add(new UnifyPair(rhsType, funNLhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT));
result.add(new UnifyPair(rhsType, funNLhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
result.stream().forEach(x -> { UnifyType l = x.getLhsType();
if (l instanceof PlaceholderType) { ((PlaceholderType)l).disableWildcardtable(); }
UnifyType r = x.getRhsType();
if (r instanceof PlaceholderType) { ((PlaceholderType)r).disableWildcardtable(); }
} );
return Optional.of(result); return Optional.of(result);
} }
@ -758,15 +852,30 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<UnifyPair>(); Set<UnifyPair> result = new HashSet<UnifyPair>();
Integer variance = ((PlaceholderType)lhsType).getVariance();
Integer inversVariance = distributeVariance.inverseVariance(variance);
UnifyType[] freshPlaceholders = new UnifyType[funNRhsType.getTypeParams().size()]; UnifyType[] freshPlaceholders = new UnifyType[funNRhsType.getTypeParams().size()];
for(int i = 0; i < freshPlaceholders.length; i++) for(int i = 0; i < freshPlaceholders.length-1; i++) {
freshPlaceholders[i] = PlaceholderType.freshPlaceholder(); freshPlaceholders[i] = PlaceholderType.freshPlaceholder();
((PlaceholderType)freshPlaceholders[i]).setVariance(inversVariance);
}
freshPlaceholders[freshPlaceholders.length-1] = PlaceholderType.freshPlaceholder();
((PlaceholderType)freshPlaceholders[freshPlaceholders.length-1]).setVariance(variance);
result.add(new UnifyPair(freshPlaceholders[0], funNRhsType.getTypeParams().get(0), PairOperator.SMALLERDOT)); result.add(new UnifyPair(freshPlaceholders[funNRhsType.getTypeParams().size()-1], funNRhsType.getTypeParams().get(funNRhsType.getTypeParams().size()-1), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
for(int i = 1; i < funNRhsType.getTypeParams().size(); i++)
result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), freshPlaceholders[i], PairOperator.SMALLERDOT));
result.add(new UnifyPair(lhsType, funNRhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT));
for(int i = 0; i < funNRhsType.getTypeParams().size()-1; i++) {
result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), freshPlaceholders[i], PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
}
result.add(new UnifyPair(lhsType, funNRhsType.setTypeParams(new TypeParams(freshPlaceholders)), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
result.stream().forEach(x -> { UnifyType l = x.getLhsType();
if (l instanceof PlaceholderType) { ((PlaceholderType)l).disableWildcardtable(); }
UnifyType r = x.getRhsType();
if (r instanceof PlaceholderType) { ((PlaceholderType)r).disableWildcardtable(); }
} );
return Optional.of(result); return Optional.of(result);
} }
@ -780,7 +889,7 @@ public class RuleSet implements IRuleSet{
if(!(lhsType instanceof PlaceholderType) || !(rhsType instanceof ReferenceType)) if(!(lhsType instanceof PlaceholderType) || !(rhsType instanceof ReferenceType))
return Optional.empty(); return Optional.empty();
return Optional.of(new UnifyPair(lhsType, rhsType, PairOperator.EQUALSDOT)); return Optional.of(new UnifyPair(lhsType, rhsType, PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
} }
@Override @Override
@ -799,11 +908,11 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<>(); Set<UnifyPair> result = new HashSet<>();
if(isGen) if(isGen)
result.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT)); result.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
else { else {
UnifyType freshTph = PlaceholderType.freshPlaceholder(); UnifyType freshTph = PlaceholderType.freshPlaceholder();
result.add(new UnifyPair(rhsType, new ExtendsType(freshTph), PairOperator.EQUALSDOT)); result.add(new UnifyPair(rhsType, new ExtendsType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
result.add(new UnifyPair(extendedType, freshTph, PairOperator.SMALLERDOT)); result.add(new UnifyPair(extendedType, freshTph, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
} }
return Optional.of(result); return Optional.of(result);
@ -825,11 +934,11 @@ public class RuleSet implements IRuleSet{
Set<UnifyPair> result = new HashSet<>(); Set<UnifyPair> result = new HashSet<>();
if(isGen) if(isGen)
result.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT)); result.add(new UnifyPair(rhsType, lhsType, PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
else { else {
UnifyType freshTph = PlaceholderType.freshPlaceholder(); UnifyType freshTph = PlaceholderType.freshPlaceholder();
result.add(new UnifyPair(rhsType, new SuperType(freshTph), PairOperator.EQUALSDOT)); result.add(new UnifyPair(rhsType, new SuperType(freshTph), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
result.add(new UnifyPair(freshTph, superedType, PairOperator.SMALLERDOT)); result.add(new UnifyPair(freshTph, superedType, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
} }
return Optional.of(result); return Optional.of(result);

View File

@ -1,5 +1,6 @@
package de.dhbwstuttgart.typeinference.unify; package de.dhbwstuttgart.typeinference.unify;
import java.io.FileWriter;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
@ -7,16 +8,16 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
public class TypeUnify { public class TypeUnify {
public Set<Set<UnifyPair>> unify(Set<UnifyPair> eq, IFiniteClosure fc) { public Set<Set<UnifyPair>> unify(Set<UnifyPair> eq, IFiniteClosure fc, FileWriter logFile, Boolean log) {
TypeUnifyTask unifyTask = new TypeUnifyTask(eq, fc, true); TypeUnifyTask unifyTask = new TypeUnifyTask(eq, fc, true, logFile, log);
ForkJoinPool pool = new ForkJoinPool(); ForkJoinPool pool = new ForkJoinPool();
pool.invoke(unifyTask); pool.invoke(unifyTask);
Set<Set<UnifyPair>> res = unifyTask.join(); Set<Set<UnifyPair>> res = unifyTask.join();
return res; return res;
} }
public Set<Set<UnifyPair>> unifySequential(Set<UnifyPair> eq, IFiniteClosure fc) { public Set<Set<UnifyPair>> unifySequential(Set<UnifyPair> eq, IFiniteClosure fc, FileWriter logFile, Boolean log) {
TypeUnifyTask unifyTask = new TypeUnifyTask(eq, fc, false); TypeUnifyTask unifyTask = new TypeUnifyTask(eq, fc, false, logFile, log);
Set<Set<UnifyPair>> res = unifyTask.compute(); Set<Set<UnifyPair>> res = unifyTask.compute();
return res; return res;
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,54 @@
package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
public class distributeVariance extends visitUnifyTypeVisitor<Integer> {
public static int inverseVariance(int variance) {
Integer ret = 0;
if (variance == 1) {
ret = -1;
}
if (variance == -1) {
ret = 1;
}
return ret;
}
@Override
public PlaceholderType visit(PlaceholderType phty, Integer ht) {
if (ht != 0) {
if (phty.getVariance() == 0) {
phty.setVariance(ht);
}
//PL 2018-05-17 urspruengliche Variance nicht veraendern
//else if (phty.getVariance() != ht) {
// phty.setVariance(0);
//}
}
return phty;
}
public FunNType visit(FunNType funnty, Integer ht) {
List<UnifyType> param = new ArrayList<>(funnty.getTypeParams().get().length);
param.addAll(Arrays.asList(funnty.getTypeParams().get()));
UnifyType resultType = param.remove(param.size()-1);
Integer htInverse = inverseVariance(ht);
param = param.stream()
.map(x -> x.accept(this, htInverse))
.collect(Collectors.toCollection(ArrayList::new));
param.add(resultType.accept(this, ht));
return FunNType.getFunNType(new TypeParams(param));
}
}

View File

@ -0,0 +1,15 @@
package de.dhbwstuttgart.typeinference.unify;
import java.util.HashMap;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
public class freshPlaceholder extends visitUnifyTypeVisitor<HashMap<PlaceholderType,PlaceholderType>> {
@Override
public PlaceholderType visit(PlaceholderType phty, HashMap<PlaceholderType,PlaceholderType> ht) {
return ht.get(phty);
}
}

View File

@ -5,6 +5,7 @@ import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typeinference.unify.model.FunNType; import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType; import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import de.dhbwstuttgart.typeinference.unify.model.SuperType; import de.dhbwstuttgart.typeinference.unify.model.SuperType;
@ -20,45 +21,47 @@ public interface IFiniteClosure {
* Returns all types of the finite closure that are subtypes of the argument. * Returns all types of the finite closure that are subtypes of the argument.
* @return The set of subtypes of the argument. * @return The set of subtypes of the argument.
*/ */
public Set<UnifyType> smaller(UnifyType type); public Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded);
/** /**
* Returns all types of the finite closure that are supertypes of the argument. * Returns all types of the finite closure that are supertypes of the argument.
* @return The set of supertypes of the argument. * @return The set of supertypes of the argument.
*/ */
public Set<UnifyType> greater(UnifyType type); public Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded);
/** /**
* Wo passt Type rein? * Wo passt Type rein?
* @param type * @param type
* @return * @return
*/ */
public Set<UnifyType> grArg(UnifyType type); public Set<UnifyType> grArg(UnifyType type, Set<UnifyType> fBounded);
/** /**
* Was passt in Type rein? * Was passt in Type rein?
* @param type * @param type
* @return * @return
*/ */
public Set<UnifyType> smArg(UnifyType type); public Set<UnifyType> smArg(UnifyType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(ReferenceType type); public Set<UnifyType> grArg(ReferenceType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(ReferenceType type); public Set<UnifyType> smArg(ReferenceType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(ExtendsType type); public Set<UnifyType> grArg(ExtendsType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(ExtendsType type); public Set<UnifyType> smArg(ExtendsType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(SuperType type); public Set<UnifyType> grArg(SuperType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(SuperType type); public Set<UnifyType> smArg(SuperType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(PlaceholderType type); public Set<UnifyType> grArg(PlaceholderType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(PlaceholderType type); public Set<UnifyType> smArg(PlaceholderType type, Set<UnifyType> fBounded);
public Set<UnifyType> grArg(FunNType type); public Set<UnifyType> grArg(FunNType type, Set<UnifyType> fBounded);
public Set<UnifyType> smArg(FunNType type); public Set<UnifyType> smArg(FunNType type, Set<UnifyType> fBounded);
public Optional<UnifyType> getLeftHandedType(String typeName); public Optional<UnifyType> getLeftHandedType(String typeName);
public Set<UnifyType> getAncestors(UnifyType t); public Set<UnifyType> getAncestors(UnifyType t);
public Set<UnifyType> getChildren(UnifyType t); public Set<UnifyType> getChildren(UnifyType t);
public Set<UnifyType> getAllTypesByName(String typeName); public Set<UnifyType> getAllTypesByName(String typeName);
public int compare(UnifyType rhsType, UnifyType rhsType2, PairOperator pairop);
} }

View File

@ -13,23 +13,17 @@ import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
/** /**
* Match * Match
* @author Martin Pluemicke * @author Martin Pluemicke
* abgeleitet aus IUnify.java
*/ */
public interface IMatch { public interface IMatch {
/** /**
* Finds the most general unifier sigma of the set {t1,...,tn} so that * Finds the most general matcher sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = sigma(t2) = ... = sigma(tn). * sigma(t1) = t1' , ... sigma(tn) = tn'.
* @param terms The set of terms to be unified * @param terms The set of terms to be matched
* @return An optional of the most general unifier if it exists or an empty optional if there is no unifier. * @return An optional of the most general matcher if it exists or an empty optional if there is no matcher.
*/ */
public Optional<Unifier> match(ArrayList<UnifyPair> termsList); public Optional<Unifier> match(ArrayList<UnifyPair> termsList);
/**
* Finds the most general unifier sigma of the set {t1,...,tn} so that
* sigma(t1) = sigma(t2) = ... = sigma(tn).
* @param terms The set of terms to be unified
* @return An optional of the most general unifier if it exists or an empty optional if there is no unifier.
*/
} }

View File

@ -27,9 +27,13 @@ public interface IRuleSet {
public Optional<UnifyPair> reduceWildcardLowRight(UnifyPair pair); public Optional<UnifyPair> reduceWildcardLowRight(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUp(UnifyPair pair); public Optional<UnifyPair> reduceWildcardUp(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUpRight(UnifyPair pair); public Optional<UnifyPair> reduceWildcardUpRight(UnifyPair pair);
/*
* vgl. JAVA_BSP/Wildcard6.java
public Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair); public Optional<UnifyPair> reduceWildcardLowUp(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardUpLow(UnifyPair pair); public Optional<UnifyPair> reduceWildcardUpLow(UnifyPair pair);
public Optional<UnifyPair> reduceWildcardLeft(UnifyPair pair); public Optional<UnifyPair> reduceWildcardLeft(UnifyPair pair);
*/
/* /*
* Additional Rules which replace cases of the cartesian product * Additional Rules which replace cases of the cartesian product

View File

@ -15,16 +15,16 @@ import de.dhbwstuttgart.typeinference.unify.model.Unifier;
public interface IUnify { public interface IUnify {
/** /**
* Finds the most general unifier sigma of the set {t1,...,tn} so that * Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = sigma(t2) = ... = sigma(tn). * sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn').
* @param terms The set of terms to be unified * @param terms The set of terms to be unified
* @return An optional of the most general unifier if it exists or an empty optional if there is no unifier. * @return An optional of the most general unifier if it exists or an empty optional if there is no unifier.
*/ */
public Optional<Unifier> unify(Set<UnifyType> terms); public Optional<Unifier> unify(Set<UnifyType> terms);
/** /**
* Finds the most general unifier sigma of the set {t1,...,tn} so that * Finds the most general unifier sigma of the set {t1 =. t1',...,tn =. tn'} so that
* sigma(t1) = sigma(t2) = ... = sigma(tn). * sigma(t1) = sigma(t1') , ... sigma(tn) = sigma(tn').
* @param terms The set of terms to be unified * @param terms The set of terms to be unified
* @return An optional of the most general unifier if it exists or an empty optional if there is no unifier. * @return An optional of the most general unifier if it exists or an empty optional if there is no unifier.
*/ */

View File

@ -0,0 +1,23 @@
package de.dhbwstuttgart.typeinference.unify.interfaces;
import java.util.HashMap;
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
public interface UnifyTypeVisitor<T> {
public ReferenceType visit(ReferenceType refty, T ht);
public PlaceholderType visit(PlaceholderType phty, T ht);
public FunNType visit(FunNType funnty, T ht);
public SuperType visit(SuperType suty, T ht);
public ExtendsType visit(ExtendsType extty, T ht);
}

View File

@ -2,21 +2,30 @@ package de.dhbwstuttgart.typeinference.unify.model;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/** /**
* An extends wildcard type "? extends T". * An extends wildcard type "? extends T".
*/ */
public final class ExtendsType extends WildcardType { public final class ExtendsType extends WildcardType {
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/** /**
* Creates a new extends wildcard type. * Creates a new extends wildcard type.
* @param extendedType The extended type e.g. Integer in "? extends Integer" * @param extendedType The extended type e.g. Integer in "? extends Integer"
*/ */
public ExtendsType(UnifyType extendedType) { public ExtendsType(UnifyType extendedType) {
super("? extends " + extendedType.getName(), extendedType); super("? extends " + extendedType.getName(), extendedType);
if (extendedType instanceof ExtendsType) {
System.out.print("");
}
} }
/** /**
@ -38,13 +47,13 @@ public final class ExtendsType extends WildcardType {
} }
@Override @Override
Set<UnifyType> smArg(IFiniteClosure fc) { Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.smArg(this); return fc.smArg(this, fBounded);
} }
@Override @Override
Set<UnifyType> grArg(IFiniteClosure fc) { Set<UnifyType> grArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.grArg(this); return fc.grArg(this, fBounded);
} }
@Override @Override

View File

@ -4,15 +4,21 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Hashtable;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors; import java.util.stream.Collectors;
//PL 18-02-05 Unifier durch Matcher ersetzt import com.google.common.collect.Ordering;
//mus greater noch erstezt werden
//PL 18-02-05/18-04-05 Unifier durch Matcher ersetzt
//muss greater noch ersetzt werden ja erledigt 18--04-05
import de.dhbwstuttgart.typeinference.unify.MartelliMontanariUnify; import de.dhbwstuttgart.typeinference.unify.MartelliMontanariUnify;
import de.dhbwstuttgart.typeinference.unify.Match; import de.dhbwstuttgart.typeinference.unify.Match;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
@ -20,7 +26,7 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
* The finite closure for the type unification * The finite closure for the type unification
* @author Florian Steurer * @author Florian Steurer
*/ */
public class FiniteClosure implements IFiniteClosure { public class FiniteClosure extends Ordering<UnifyType> implements IFiniteClosure {
/** /**
* A map that maps every type to the node in the inheritance graph that contains that type. * A map that maps every type to the node in the inheritance graph that contains that type.
@ -89,36 +95,43 @@ public class FiniteClosure implements IFiniteClosure {
* @return The set of subtypes of the argument. * @return The set of subtypes of the argument.
*/ */
@Override @Override
public Set<UnifyType> smaller(UnifyType type) { public Set<UnifyType> smaller(UnifyType type, Set<UnifyType> fBounded) {
if(type instanceof FunNType) if(type instanceof FunNType)
return computeSmallerFunN((FunNType) type); return computeSmallerFunN((FunNType) type, fBounded);
Set<UnifyType> ts = new HashSet<>(); Set<Pair<UnifyType,Set<UnifyType>>> ts = new HashSet<>();
ts.add(type); ts.add(new Pair<>(type, fBounded));
return computeSmaller(ts); return computeSmaller(ts);
} }
/** /**
* Computes the smaller functions for every type except FunNTypes. * Computes the smaller functions for every type except FunNTypes.
*/ */
private Set<UnifyType> computeSmaller(Set<UnifyType> types) { private Set<UnifyType> computeSmaller(Set<Pair<UnifyType,Set<UnifyType>>> types) {
HashSet<UnifyType> result = new HashSet<>(); Set<Pair<UnifyType,Set<UnifyType>>> result = new HashSet<>();
//PL 18-02-05 Unifier durch Matcher ersetzt //PL 18-02-05 Unifier durch Matcher ersetzt
//IUnify unify = new MartelliMontanariUnify(); //IUnify unify = new MartelliMontanariUnify();
Match match = new Match(); Match match = new Match();
for(UnifyType t : types) { for(Pair<UnifyType,Set<UnifyType>> pt : types) {
UnifyType t = pt.getKey();
Set<UnifyType> fBounded = pt.getValue().get();
// if T = T' then T <* T' // if T = T' then T <* T'
result.add(t); try {
result.add(new Pair<>(t, fBounded));
}
catch (StackOverflowError e) {
System.out.println("");
}
// if C<...> <* C<...> then ... (third case in definition of <*) // if C<...> <* C<...> then ... (third case in definition of <*)
if(t.getTypeParams().size() > 0) { if(t.getTypeParams().size() > 0) {
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>(); ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
for (int i = 0; i < t.getTypeParams().size(); i++) for (int i = 0; i < t.getTypeParams().size(); i++)
paramCandidates.add(smArg(t.getTypeParams().get(i))); paramCandidates.add(smArg(t.getTypeParams().get(i), fBounded));
permuteParams(paramCandidates).forEach(x -> result.add(t.setTypeParams(x))); permuteParams(paramCandidates).forEach(x -> result.add(new Pair<>(t.setTypeParams(x), fBounded)));
} }
if(!strInheritanceGraph.containsKey(t.getName())) if(!strInheritanceGraph.containsKey(t.getName()))
@ -144,19 +157,20 @@ public class FiniteClosure implements IFiniteClosure {
Set<UnifyType> theta1Set = candidate.getContentOfDescendants(); Set<UnifyType> theta1Set = candidate.getContentOfDescendants();
for(UnifyType theta1 : theta1Set) for(UnifyType theta1 : theta1Set)
result.add(theta1.apply(sigma)); result.add(new Pair<>(theta1.apply(sigma), fBounded));
} }
} }
if(result.equals(types)) HashSet<UnifyType> resut = result.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new));
return result; if(resut.equals(types.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new))))
return resut;
return computeSmaller(result); return computeSmaller(result);
} }
/** /**
* Computes the smaller-Function for FunNTypes. * Computes the smaller-Function for FunNTypes.
*/ */
private Set<UnifyType> computeSmallerFunN(FunNType type) { private Set<UnifyType> computeSmallerFunN(FunNType type, Set<UnifyType> fBounded) {
Set<UnifyType> result = new HashSet<>(); Set<UnifyType> result = new HashSet<>();
// if T = T' then T <=* T' // if T = T' then T <=* T'
@ -165,9 +179,9 @@ public class FiniteClosure implements IFiniteClosure {
// Because real function types are implicitly variant // Because real function types are implicitly variant
// it is enough to permute the params with the values of greater / smaller. // it is enough to permute the params with the values of greater / smaller.
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>(); ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
paramCandidates.add(smaller(type.getTypeParams().get(0))); paramCandidates.add(smaller(type.getTypeParams().get(0), fBounded));
for (int i = 1; i < type.getTypeParams().size(); i++) for (int i = 1; i < type.getTypeParams().size(); i++)
paramCandidates.add(greater(type.getTypeParams().get(i))); paramCandidates.add(greater(type.getTypeParams().get(i), new HashSet<>()));
permuteParams(paramCandidates).forEach(x -> result.add(type.setTypeParams(x))); permuteParams(paramCandidates).forEach(x -> result.add(type.setTypeParams(x)));
return result; return result;
@ -178,34 +192,139 @@ public class FiniteClosure implements IFiniteClosure {
* @return The set of supertypes of the argument. * @return The set of supertypes of the argument.
*/ */
@Override @Override
public Set<UnifyType> greater(UnifyType type) { //Eingefuegt PL 2018-05-24 F-Bounded Problematik
if(type instanceof FunNType) public Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded) {
return computeGreaterFunN((FunNType) type);
Set<UnifyType> ts = new HashSet<>(); if(type instanceof FunNType) {
ts.add(type); return computeGreaterFunN((FunNType) type, fBounded);
}
Set<UnifyType> result = new HashSet<>();
Set<Pair<UnifyType,Set<UnifyType>>> PairResultFBounded = new HashSet<>();
Match match = new Match();
// if T = T' then T <=* T'
result.add(type);
if(!strInheritanceGraph.containsKey(type.getName()))
return result;
// if T <* T' then sigma(T) <* sigma(T')
Set<Node<UnifyType>> candidates = strInheritanceGraph.get(type.getName());
for(Node<UnifyType> candidate : candidates) {
UnifyType theta1 = candidate.getContent();
//PL 18-04-05 Unifier durch Matcher ersetzt ANFANG
ArrayList<UnifyPair> termList= new ArrayList<UnifyPair>();
termList.add(new UnifyPair(theta1,type, PairOperator.EQUALSDOT));
Optional<Unifier> optSigma = match.match(termList);
//PL 18-04-05 Unifier durch Matcher ersetzt ENDE
if(!optSigma.isPresent())
continue;
Unifier sigma = optSigma.get();
sigma.swapPlaceholderSubstitutionsReverse(theta1.getTypeParams());
Set<UnifyType> fBoundedNew = new HashSet<>(fBounded);
fBoundedNew.add(theta1);
Set<UnifyType> theta2Set = candidate.getContentOfPredecessors();
//System.out.println("");
for(UnifyType theta2 : theta2Set) {
result.add(theta2.apply(sigma));
PairResultFBounded.add(new Pair<>(theta2.apply(sigma), fBoundedNew));
}
}
for(Pair<UnifyType,Set<UnifyType>> pt : PairResultFBounded) {
UnifyType t = pt.getKey();
Set<UnifyType> lfBounded = pt.getValue().get();
// if C<...> <* C<...> then ... (third case in definition of <*)
//TypeParams typeparams = t.getTypeParams();
if(t.getTypeParams().size() > 0) {
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
for (int i = 0; i < t.getTypeParams().size(); i++) {
//UnifyType parai = t.getTypeParams().get(i);
int i_ef = i;
BiFunction<Boolean,UnifyType,Boolean> f = (x,y) ->
{
ArrayList<UnifyPair> termList = new ArrayList<UnifyPair>();
termList.add(new UnifyPair(y,t.getTypeParams().get(i_ef), PairOperator.EQUALSDOT));
return ((match.match(termList).isPresent()) || x);
};
//if (parai.getName().equals("java.lang.Integer")) {
// System.out.println("");
//}
BinaryOperator<Boolean> bo = (a,b) -> (a || b);
if (lfBounded.stream().reduce(false,f,bo)) {
//F-Bounded Endlosrekursion
HashSet<UnifyType> res = new HashSet<UnifyType>();
paramCandidates.add(res);
}
else {
paramCandidates.add(grArg(t.getTypeParams().get(i), new HashSet<>(fBounded) ));
}
}
permuteParams(paramCandidates).forEach(x -> result.add(t.setTypeParams(x)));
//System.out.println("");
}
}
return result;
}
/* auskommentiert PL 2018-05-24
/**
* Returns all types of the finite closure that are supertypes of the argument.
* @return The set of supertypes of the argument.
*
//@Override
public Set<UnifyType> oldgreater(UnifyType type, Set<UnifyType> fBounded) {
if(type instanceof FunNType)
return computeGreaterFunN((FunNType) type, fBounded);
Set<Pair<UnifyType,Set<UnifyType>>> ts = new HashSet<>();
ts.add(new Pair<>(type, fBounded));
return computeGreater(ts); return computeGreater(ts);
} }
/** /**
* Computes the greater function for all types except function types. * Computes the greater function for all types except function types.
*/ *
protected Set<UnifyType> computeGreater(Set<UnifyType> types) { protected Set<UnifyType> computeGreater(Set<Pair<UnifyType,Set<UnifyType>>> types) {
HashSet<UnifyType> result = new HashSet<>(); Set<Pair<UnifyType,Set<UnifyType>>> result = new HashSet<>();
IUnify unify = new MartelliMontanariUnify(); //PL 18-04-05 Unifier durch Matcher ersetzt
//IUnify unify = new MartelliMontanariUnify();
for(UnifyType t : types) { Match match = new Match();
for(Pair<UnifyType,Set<UnifyType>> pt : types) {
UnifyType t = pt.getKey();
Set<UnifyType> fBounded = pt.getValue().get();
// if T = T' then T <=* T' // if T = T' then T <=* T'
result.add(t); result.add(pt);
// if C<...> <* C<...> then ... (third case in definition of <*) // if C<...> <* C<...> then ... (third case in definition of <*)
if(t.getTypeParams().size() > 0) { if(t.getTypeParams().size() > 0) {
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>(); ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
for (int i = 0; i < t.getTypeParams().size(); i++) for (int i = 0; i < t.getTypeParams().size(); i++) {
paramCandidates.add(grArg(t.getTypeParams().get(i))); UnifyType parai = t.getTypeParams().get(i);
permuteParams(paramCandidates).forEach(x -> result.add(t.setTypeParams(x))); int i_ef = i;
BiFunction<Boolean,UnifyType,Boolean> f = (x,y) ->
{
ArrayList<UnifyPair> termList = new ArrayList<UnifyPair>();
termList.add(new UnifyPair(y,t.getTypeParams().get(i_ef), PairOperator.EQUALSDOT));
return ((match.match(termList).isPresent()) || x);
};
if (parai.getName().equals("java.lang.Integer")) {
System.out.println("");
}
BinaryOperator<Boolean> bo = (a,b) -> (a || b);
if (fBounded.stream().reduce(false,f,bo)) continue; //F-Bounded Endlosrekursion
paramCandidates.add(grArg(t.getTypeParams().get(i), new HashSet<>(fBounded) ));
}
permuteParams(paramCandidates).forEach(x -> result.add(new Pair<>(t.setTypeParams(x), new HashSet<>(fBounded))));
} }
if(!strInheritanceGraph.containsKey(t.getName())) if(!strInheritanceGraph.containsKey(t.getName()))
@ -215,30 +334,40 @@ public class FiniteClosure implements IFiniteClosure {
Set<Node<UnifyType>> candidates = strInheritanceGraph.get(t.getName()); Set<Node<UnifyType>> candidates = strInheritanceGraph.get(t.getName());
for(Node<UnifyType> candidate : candidates) { for(Node<UnifyType> candidate : candidates) {
UnifyType theta1 = candidate.getContent(); UnifyType theta1 = candidate.getContent();
Optional<Unifier> optSigma = unify.unify(theta1, t);
//PL 18-04-05 Unifier durch Matcher ersetzt ANFANG
ArrayList<UnifyPair> termList= new ArrayList<UnifyPair>();
termList.add(new UnifyPair(theta1,t, PairOperator.EQUALSDOT));
Optional<Unifier> optSigma = match.match(termList);
//PL 18-04-05 Unifier durch Matcher ersetzt ENDE
if(!optSigma.isPresent()) if(!optSigma.isPresent())
continue; continue;
Unifier sigma = optSigma.get(); Unifier sigma = optSigma.get();
sigma.swapPlaceholderSubstitutionsReverse(theta1.getTypeParams()); sigma.swapPlaceholderSubstitutionsReverse(theta1.getTypeParams());
Set<UnifyType> fBoundedNew = new HashSet<>(fBounded);
fBoundedNew.add(theta1);
Set<UnifyType> theta2Set = candidate.getContentOfPredecessors(); Set<UnifyType> theta2Set = candidate.getContentOfPredecessors();
for(UnifyType theta2 : theta2Set) for(UnifyType theta2 : theta2Set)
result.add(theta2.apply(sigma)); result.add(new Pair<>(theta2.apply(sigma), fBoundedNew));
} }
} }
if(result.equals(types)) HashSet<UnifyType> resut = result.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new));
return result; System.out.println(resut);
if(resut.equals(types.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new))))
return resut;
return computeGreater(result); return computeGreater(result);
} }
*/
/** /**
* Computes the greater function for FunN-Types * Computes the greater function for FunN-Types
*/ */
protected Set<UnifyType> computeGreaterFunN(FunNType type) { protected Set<UnifyType> computeGreaterFunN(FunNType type, Set<UnifyType> fBounded) {
Set<UnifyType> result = new HashSet<>(); Set<UnifyType> result = new HashSet<>();
// if T = T' then T <=* T' // if T = T' then T <=* T'
@ -247,88 +376,88 @@ public class FiniteClosure implements IFiniteClosure {
// Because real function types are implicitly variant // Because real function types are implicitly variant
// it is enough to permute the params with the values of greater / smaller. // it is enough to permute the params with the values of greater / smaller.
ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>(); ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
paramCandidates.add(greater(type.getTypeParams().get(0))); paramCandidates.add(greater(type.getTypeParams().get(0), new HashSet<>()));
for (int i = 1; i < type.getTypeParams().size(); i++) for (int i = 1; i < type.getTypeParams().size(); i++)
paramCandidates.add(smaller(type.getTypeParams().get(i))); paramCandidates.add(smaller(type.getTypeParams().get(i), fBounded));
permuteParams(paramCandidates).forEach(x -> result.add(type.setTypeParams(x))); permuteParams(paramCandidates).forEach(x -> result.add(type.setTypeParams(x)));
return result; return result;
} }
@Override @Override
public Set<UnifyType> grArg(UnifyType type) { public Set<UnifyType> grArg(UnifyType type, Set<UnifyType> fBounded) {
return type.grArg(this); return type.grArg(this, fBounded);
} }
@Override @Override
public Set<UnifyType> grArg(ReferenceType type) { public Set<UnifyType> grArg(ReferenceType type, Set<UnifyType> fBounded) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
smaller(type).forEach(x -> result.add(new SuperType(x))); smaller(type, fBounded).forEach(x -> result.add(new SuperType(x)));
greater(type).forEach(x -> result.add(new ExtendsType(x))); greater(type,fBounded).forEach(x -> result.add(new ExtendsType(x)));
return result; return result;
} }
@Override @Override
public Set<UnifyType> grArg(FunNType type) { public Set<UnifyType> grArg(FunNType type, Set<UnifyType> fBounded) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
smaller(type).forEach(x -> result.add(new SuperType(x))); smaller(type, fBounded).forEach(x -> result.add(new SuperType(x)));
greater(type).forEach(x -> result.add(new ExtendsType(x))); greater(type, fBounded).forEach(x -> result.add(new ExtendsType(x)));
return result; return result;
} }
@Override @Override
public Set<UnifyType> grArg(ExtendsType type) { public Set<UnifyType> grArg(ExtendsType type, Set<UnifyType> fBounded) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
UnifyType t = type.getExtendedType(); UnifyType t = type.getExtendedType();
greater(t).forEach(x -> result.add(new ExtendsType(x))); greater(t, fBounded).forEach(x -> result.add(new ExtendsType(x)));
return result; return result;
} }
@Override @Override
public Set<UnifyType> grArg(SuperType type) { public Set<UnifyType> grArg(SuperType type, Set<UnifyType> fBounded) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
UnifyType t = type.getSuperedType(); UnifyType t = type.getSuperedType();
smaller(t).forEach(x -> result.add(new SuperType(x))); smaller(t, fBounded).forEach(x -> result.add(new SuperType(x)));
return result; return result;
} }
@Override @Override
public Set<UnifyType> grArg(PlaceholderType type) { public Set<UnifyType> grArg(PlaceholderType type, Set<UnifyType> fBounded) {
HashSet<UnifyType> result = new HashSet<>(); HashSet<UnifyType> result = new HashSet<>();
result.add(type); result.add(type);
return result; return result;
} }
@Override @Override
public Set<UnifyType> smArg(UnifyType type) { public Set<UnifyType> smArg(UnifyType type, Set<UnifyType> fBounded) {
return type.smArg(this); return type.smArg(this, fBounded);
} }
@Override @Override
public Set<UnifyType> smArg(ReferenceType type) { public Set<UnifyType> smArg(ReferenceType type, Set<UnifyType> fBounded) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
return result; return result;
} }
@Override @Override
public Set<UnifyType> smArg(FunNType type) { public Set<UnifyType> smArg(FunNType type, Set<UnifyType> fBounded) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
return result; return result;
} }
@Override @Override
public Set<UnifyType> smArg(ExtendsType type) { public Set<UnifyType> smArg(ExtendsType type, Set<UnifyType> fBounded) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
UnifyType t = type.getExtendedType(); UnifyType t = type.getExtendedType();
result.add(t); result.add(t);
smaller(t).forEach(x -> { smaller(t, fBounded).forEach(x -> {
result.add(new ExtendsType(x)); result.add(new ExtendsType(x));
result.add(x); result.add(x);
}); });
@ -337,12 +466,13 @@ public class FiniteClosure implements IFiniteClosure {
@Override @Override
public Set<UnifyType> smArg(SuperType type) { public Set<UnifyType> smArg(SuperType type, Set<UnifyType> fBounded) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
UnifyType t = type.getSuperedType(); UnifyType t = type.getSuperedType();
result.add(t); result.add(t);
greater(t).forEach(x -> { //*** ACHTUNG das koennte FALSCH sein PL 2018-05-23 evtl. HashSet durch smArg durchschleifen
greater(t, fBounded).forEach(x -> {
result.add(new SuperType(x)); result.add(new SuperType(x));
result.add(x); result.add(x);
}); });
@ -350,7 +480,7 @@ public class FiniteClosure implements IFiniteClosure {
} }
@Override @Override
public Set<UnifyType> smArg(PlaceholderType type) { public Set<UnifyType> smArg(PlaceholderType type, Set<UnifyType> fBounded) {
HashSet<UnifyType> result = new HashSet<>(); HashSet<UnifyType> result = new HashSet<>();
result.add(type); result.add(type);
return result; return result;
@ -369,7 +499,7 @@ public class FiniteClosure implements IFiniteClosure {
return Optional.empty(); return Optional.empty();
for(UnifyPair pair : pairs) for(UnifyPair pair : pairs)
if(pair.getLhsType().getName().equals(typeName)) if(pair.getLhsType().getName().equals(typeName) && pair.getLhsType().typeParams.arePlaceholders())
return Optional.of(pair.getLhsType()); return Optional.of(pair.getLhsType());
return Optional.empty(); return Optional.empty();
@ -430,4 +560,33 @@ public class FiniteClosure implements IFiniteClosure {
public String toString(){ public String toString(){
return this.inheritanceGraph.toString(); return this.inheritanceGraph.toString();
} }
public int compare (UnifyType left, UnifyType right) {
return compare(left, right, PairOperator.SMALLERDOT);
}
public int compare (UnifyType left, UnifyType right, PairOperator pairop) {
if ((left instanceof ExtendsType && right instanceof ReferenceType)
|| (right instanceof ExtendsType && left instanceof ReferenceType))
System.out.println("");
UnifyPair up = new UnifyPair(left, right, pairop);
TypeUnifyTask unifyTask = new TypeUnifyTask();
HashSet<UnifyPair> hs = new HashSet<>();
hs.add(up);
Set<UnifyPair> smallerRes = unifyTask.applyTypeUnificationRules(hs, this);
//Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok.
long smallerLen = smallerRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)).count();
if (smallerLen == 0) return -1;
else {
up = new UnifyPair(right, left, pairop);
//TypeUnifyTask unifyTask = new TypeUnifyTask();
hs = new HashSet<>();
hs.add(up);
Set<UnifyPair> greaterRes = unifyTask.applyTypeUnificationRules(hs, this);
//Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok.
long greaterLen = greaterRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)).count();
if (greaterLen == 0) return 1;
else return 0;
}
}
} }

View File

@ -1,8 +1,12 @@
package de.dhbwstuttgart.typeinference.unify.model; package de.dhbwstuttgart.typeinference.unify.model;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/** /**
* A real function type in java. * A real function type in java.
@ -10,6 +14,10 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
*/ */
public class FunNType extends UnifyType { public class FunNType extends UnifyType {
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/** /**
* Creates a FunN-Type with the specified TypeParameters. * Creates a FunN-Type with the specified TypeParameters.
*/ */
@ -47,13 +55,13 @@ public class FunNType extends UnifyType {
} }
@Override @Override
Set<UnifyType> smArg(IFiniteClosure fc) { Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.smArg(this); return fc.smArg(this, fBounded);
} }
@Override @Override
Set<UnifyType> grArg(IFiniteClosure fc) { Set<UnifyType> grArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.grArg(this); return fc.grArg(this, fBounded);
} }
@Override @Override
@ -67,11 +75,18 @@ public class FunNType extends UnifyType {
return new FunNType(newParams); return new FunNType(newParams);
} }
@Override
public Boolean wrongWildcard() {
return (new ArrayList<UnifyType>(Arrays.asList(getTypeParams()
.get())).stream().filter(x -> (x instanceof WildcardType)).findFirst().isPresent());
}
@Override @Override
public int hashCode() { public int hashCode() {
return 181 + typeParams.hashCode(); return 181 + typeParams.hashCode();
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof FunNType)) if(!(obj instanceof FunNType))

View File

@ -0,0 +1,228 @@
package de.dhbwstuttgart.typeinference.unify.model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Optional;
import java.util.Set;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.google.common.collect.Ordering;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
public class OrderingUnifyPair extends Ordering<Set<UnifyPair>> {
protected IFiniteClosure fc;
public OrderingUnifyPair(IFiniteClosure fc) {
this.fc = fc;
}
/*
* vergleicht Paare (a =. Theta) und (a =. Theta')
* in dem compare(Theta, Theta') aufgerufen wird.
*/
public int compareEq (UnifyPair left, UnifyPair right) {
if (left.getRhsType() instanceof WildcardType || right.getRhsType() instanceof WildcardType) {
return fc.compare(left.getRhsType(), right.getRhsType(), PairOperator.SMALLERDOTWC);
}
else {
return fc.compare(left.getRhsType(), right.getRhsType(), PairOperator.SMALLERDOT);
}
}
/*
public int compareEq (UnifyPair left, UnifyPair right) {
if (left == null || right == null)
System.out.println("Fehler");
if (left.getLhsType() instanceof PlaceholderType) {
return fc.compare(left.getRhsType(), right.getRhsType(), left.getPairOp());
}
else {
return fc.compare(left.getLhsType(), right.getLhsType(), left.getPairOp());
}
}
*/
public Pair<Integer,Set<UnifyPair>> compare (UnifyType left, UnifyType right) {
UnifyPair up;
if (left instanceof WildcardType || right instanceof WildcardType) {
up = new UnifyPair(left, right, PairOperator.SMALLERDOTWC);
}
else {
up = new UnifyPair(left, right, PairOperator.SMALLERDOT);
}
TypeUnifyTask unifyTask = new TypeUnifyTask();
HashSet<UnifyPair> hs = new HashSet<>();
hs.add(up);
Set<UnifyPair> smallerRes = unifyTask.applyTypeUnificationRules(hs, fc);
long smallerLen = smallerRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType && x.getRhsType() instanceof PlaceholderType)).count();
if (smallerLen == 0) return new Pair<>(-1, smallerRes);
else {
if (left instanceof WildcardType || right instanceof WildcardType) {
up = new UnifyPair(right, left, PairOperator.SMALLERDOTWC);
}
else {
up = new UnifyPair(right, left, PairOperator.SMALLERDOT);
}
//TypeUnifyTask unifyTask = new TypeUnifyTask();
hs = new HashSet<>();
hs.add(up);
Set<UnifyPair> greaterRes = unifyTask.applyTypeUnificationRules(hs, fc);
long greaterLen = greaterRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType && x.getRhsType() instanceof PlaceholderType)).count();
if (greaterLen == 0) return new Pair<>(1, greaterRes);
else return new Pair<>(0, new HashSet<>());
}
}
/* TODO muss noch verifiziert werden PL 2018-03-21
* (non-Javadoc)
* fuehrt zu Fehlern bei Arrays.sort (contract nicht erfuellt)
* @see com.google.common.collect.Ordering#compare(java.lang.Object, java.lang.Object)
*/
public int compare (Set<UnifyPair> left, Set<UnifyPair> right) {
Set<UnifyPair> lefteq = left.stream()
.filter(x -> (x.getLhsType() instanceof PlaceholderType && x.getPairOp() == PairOperator.EQUALSDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> righteq = right.stream()
.filter(x -> (x.getLhsType() instanceof PlaceholderType && x.getPairOp() == PairOperator.EQUALSDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> leftle = left.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> rightle = right.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> leftlewc = left.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOTWC))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> rightlewc = right.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOTWC))
.collect(Collectors.toCollection(HashSet::new));
//System.out.println(left.toString());
//Fall 2 und 3
//if (lefteq.iterator().next().getLhsType().getName().equals("AJO")) {
// System.out.print("");
//}
if (lefteq.size() == 1 && leftle.size() == 1 && righteq.size() == 0 && rightle.size() == 1) {
return 1;
}
//Fall 2 und 3
if (lefteq.size() == 0 && leftle.size() == 1 && righteq.size() == 1 && rightle.size() == 1) {
return -1;
}
//Fall 5
if (lefteq.size() == 1 && leftle.size() == 0 && righteq.size() == 1 && rightle.size() == 1) {
return -1;
}
//Fall 5
if (lefteq.size() == 1 && leftle.size() == 1 && righteq.size() == 1 && rightle.size() == 0) {
return 1;
}
//Fall 5
if (lefteq.size() == 1 && leftle.size() == 1 && righteq.size() == 1 && rightle.size() == 1) {
return 0;
}
// Nur Paare a =. Theta
if (leftle.size() == 0 && rightle.size() == 0 && leftlewc.size() == 0 && rightlewc.size() ==0) {
Stream<UnifyPair> lseq = lefteq.stream(); //left.filter(x -> (x.getLhsType() instanceof PlaceholderType && x.getPairOp() == PairOperator.EQUALSDOT));
Stream<UnifyPair> rseq = righteq.stream(); //right.filter(x -> (x.getLhsType() instanceof PlaceholderType && x.getPairOp() == PairOperator.EQUALSDOT));
BinaryOperator<HashMap<UnifyType,UnifyPair>> combiner = (x,y) -> { x.putAll(y); return x;};
HashMap<UnifyType,UnifyPair> hm = rseq.reduce(new HashMap<UnifyType,UnifyPair>(), (x, y)-> { x.put(y.getLhsType(),y); return x; }, combiner);
lseq = lseq.filter(x -> !(hm.get(x.getLhsType()) == null));//NOCHMALS UEBERPRUEFEN!!!!
lseq = lseq.filter(x -> !x.equals(hm.get(x.getLhsType()))); //Elemente die gleich sind muessen nicht verglichen werden
Optional<Integer> si = lseq.map(x -> compareEq(x, hm.get(x.getLhsType()))).reduce((x,y)-> { if (x == y) return x; else return 0; } );
if (!si.isPresent()) return 0;
else return si.get();
}
//Fall 1 und 4
if (lefteq.size() >= 1 && righteq.size() >= 1 && (leftlewc.size() > 0 || rightlewc.size() > 0)) {
if (lefteq.iterator().next().getLhsType().getName().equals("D"))
System.out.print("");
//Set<PlaceholderType> varsleft = lefteq.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new));
//Set<PlaceholderType> varsright = righteq.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new));
//filtern des Paares a = Theta, das durch a <. Thata' generiert wurde (nur im Fall 1 relevant)
lefteq.removeIf(x -> !(x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName())
||x.getLhsType().getName().equals(x.getBasePair().getRhsType().getName())));//removeIf(x -> !varsright.contains(x.getLhsType()));
righteq.removeIf(x -> !(x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName())
||x.getLhsType().getName().equals(x.getBasePair().getRhsType().getName())));//.removeIf(x -> !varsleft.contains(x.getLhsType()));
UnifyPair lseq = lefteq.iterator().next();
UnifyPair rseq = righteq.iterator().next();
if (lseq.getRhsType().getName().equals("Object")) {
if (rseq.getRhsType().getName().equals("Object")) return 0;
else return 1;
}
else {
if (rseq.getRhsType().getName().equals("Object")) return -1;
}
if (leftlewc.size() == rightlewc.size()) {
//TODO: Hier wird bei Wildcards nicht das richtige compare aufgerufen PL 18-04-20
Pair<Integer, Set<UnifyPair>> int_Unifier = compare(lseq.getRhsType(), rseq.getRhsType());
Unifier uni = new Unifier();
int_Unifier.getValue().get().forEach(x -> uni.add((PlaceholderType) x.getLhsType(), x.getRhsType()));
if (!lseq.getRhsType().getName().equals(rseq.getRhsType().getName())
|| leftlewc.size() == 0 || rightlewc.size() == 0) return int_Unifier.getKey();
else {
Set <UnifyPair> lsleuni = leftlewc.stream().map(x -> uni.apply(x)).collect(Collectors.toCollection(HashSet::new));
Set <UnifyPair> rsleuni = rightlewc.stream().map(x -> uni.apply(x)).collect(Collectors.toCollection(HashSet::new));
BinaryOperator<HashMap<UnifyType,UnifyPair>> combiner = (x,y) -> { x.putAll(y); return x;};
HashMap<UnifyType,UnifyPair> hm;
Optional<Integer> si;
//1. Fall
if (leftlewc.iterator().next().getLhsType() instanceof PlaceholderType) {
hm = rsleuni.stream().reduce(new HashMap<UnifyType,UnifyPair>(), (x, y)-> { x.put(y.getLhsType(),y); return x; }, combiner);
Stream<UnifyPair> lslewcstr = lsleuni.stream().filter(x -> !(hm.get(x.getLhsType()) == null));
si = lslewcstr.map(x -> fc.compare(x.getRhsType(), hm.get(x.getLhsType()).getRhsType(), PairOperator.SMALLERDOTWC)).reduce((x,y)-> { if (x == y) return x; else return 0; } );
}
//4. Fall
else {
hm = rsleuni.stream().reduce(new HashMap<UnifyType,UnifyPair>(), (x, y)-> { x.put(y.getRhsType(),y); return x; }, combiner);
Stream<UnifyPair> lslewcstr = lsleuni.stream().filter(x -> !(hm.get(x.getRhsType()) == null));
si = lslewcstr.map(x -> fc.compare(x.getLhsType(), hm.get(x.getRhsType()).getLhsType(), PairOperator.SMALLERDOTWC)).reduce((x,y)-> { if (x == y) return x; else return 0; } );
}
if (!si.isPresent()) return 0;
else return si.get();
}
} else {
if (leftlewc.size() > 0) {
Set<UnifyPair> subst;
if (leftlewc.iterator().next().getLhsType() instanceof PlaceholderType) {
subst = leftlewc.stream().map(x -> new UnifyPair(x.getLhsType(), x.getRhsType(), PairOperator.EQUALSDOT)).collect(Collectors.toCollection(HashSet::new));
}
else {
subst = leftlewc.stream().map(x -> new UnifyPair(x.getRhsType(), x.getLhsType(), PairOperator.EQUALSDOT)).collect(Collectors.toCollection(HashSet::new));
}
Unifier uni = new Unifier();
subst.stream().forEach(x -> uni.add((PlaceholderType) x.getLhsType(), x.getRhsType()));
lseq = uni.apply(lseq);
}
else {
Set<UnifyPair> subst;
if (rightlewc.iterator().next().getLhsType() instanceof PlaceholderType) {
subst = rightlewc.stream().map(x -> new UnifyPair(x.getLhsType(), x.getRhsType(), PairOperator.EQUALSDOT)).collect(Collectors.toCollection(HashSet::new));
}
else {
subst = rightlewc.stream().map(x -> new UnifyPair(x.getRhsType(), x.getLhsType(), PairOperator.EQUALSDOT)).collect(Collectors.toCollection(HashSet::new));
}
Unifier uni = new Unifier();
subst.stream().forEach(x -> uni.add((PlaceholderType) x.getLhsType(), x.getRhsType()));
rseq = uni.apply(rseq);
}
return compareEq(lseq, rseq);
}
}
return 0;
}
}

View File

@ -0,0 +1,21 @@
package de.dhbwstuttgart.typeinference.unify.model;
import java.util.Optional;
public class Pair<T, T1> {
private final T key;
private final T1 value;
public Pair(T a, T1 b) {
this.value = b;
this.key = a;
}
public Optional<T1> getValue() {
return Optional.of(value);
}
public T getKey() {
return key;
}
}

View File

@ -17,6 +17,12 @@ public enum PairOperator {
*/ */
SMALLERDOT, SMALLERDOT,
/**
* The smallernedot operator for arguments (T <!=. P) is the same as SMALLERDOT without
* T == P. It is used for operations + / - / * / < / > / ... with the Supertype Number
*/
SMALLERNEQDOT,
/** /**
* The smallerdot operator for arguments (T <.? P) is used to express that * The smallerdot operator for arguments (T <.? P) is used to express that
* T is an element of smArg(P) (or P is an element of grArg(T)) in a CONSTRAINT * T is an element of smArg(P) (or P is an element of grArg(T)) in a CONSTRAINT
@ -35,6 +41,7 @@ public enum PairOperator {
switch (this) { switch (this) {
case SMALLER: return "<"; case SMALLER: return "<";
case SMALLERDOT: return "<."; case SMALLERDOT: return "<.";
case SMALLERNEQDOT: return "<!=.";
case SMALLERDOTWC: return "<.?"; case SMALLERDOTWC: return "<.?";
default: return "=."; // EQUALSDOT default: return "=."; // EQUALSDOT
} }

View File

@ -2,11 +2,14 @@ package de.dhbwstuttgart.typeinference.unify.model;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/** /**
* An unbounded placeholder type. * An unbounded placeholder type.
@ -35,6 +38,21 @@ public final class PlaceholderType extends UnifyType{
*/ */
private final boolean IsGenerated; private final boolean IsGenerated;
/**
* isWildcardable gibt an, ob ein Wildcardtyp dem PlaceholderType zugeordnet werden darf
*/
private boolean wildcardable = true;
/**
* variance shows the variance of the pair
* -1: contravariant
* 1 covariant
* 0 invariant
* PL 2018-03-21
*/
private int variance = 0;
/** /**
* Creates a new placeholder type with the specified name. * Creates a new placeholder type with the specified name.
*/ */
@ -54,6 +72,10 @@ public final class PlaceholderType extends UnifyType{
IsGenerated = isGenerated; IsGenerated = isGenerated;
} }
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/** /**
* Creates a fresh placeholder type with a name that does so far not exist. * Creates a fresh placeholder type with a name that does so far not exist.
* A user could later instantiate a type using the same name that is equivalent to this type. * A user could later instantiate a type using the same name that is equivalent to this type.
@ -67,6 +89,7 @@ public final class PlaceholderType extends UnifyType{
return new PlaceholderType(name, true); return new PlaceholderType(name, true);
} }
/** /**
* True if this placeholder is auto-generated, false if it is user-generated. * True if this placeholder is auto-generated, false if it is user-generated.
*/ */
@ -74,14 +97,29 @@ public final class PlaceholderType extends UnifyType{
return IsGenerated; return IsGenerated;
} }
@Override public void setVariance(int v) {
Set<UnifyType> smArg(IFiniteClosure fc) { variance = v;
return fc.smArg(this); }
public int getVariance() {
return variance;
}
public Boolean isWildcardable() {
return wildcardable;
}
public void disableWildcardtable() {
wildcardable = false;
} }
@Override @Override
Set<UnifyType> grArg(IFiniteClosure fc) { Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.grArg(this); return fc.smArg(this, fBounded);
}
@Override
Set<UnifyType> grArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.grArg(this, fBounded);
} }
@Override @Override
@ -96,8 +134,13 @@ public final class PlaceholderType extends UnifyType{
@Override @Override
UnifyType apply(Unifier unif) { UnifyType apply(Unifier unif) {
if(unif.hasSubstitute(this)) if(unif.hasSubstitute(this)) {
return unif.getSubstitute(this); UnifyType ret = unif.getSubstitute(this);
//PL 2018-05-17 Auskommentierung muesste korrekt sein,
//bereits in JavaTXComplier Variancen gesetzt werden.
//ret.accept(new distributeVariance(), this.getVariance());
return ret;
}
return this; return this;
} }

View File

@ -1,8 +1,10 @@
package de.dhbwstuttgart.typeinference.unify.model; package de.dhbwstuttgart.typeinference.unify.model;
import java.util.HashMap;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/** /**
* A reference type e.q. Integer or List<T>. * A reference type e.q. Integer or List<T>.
@ -16,6 +18,11 @@ public final class ReferenceType extends UnifyType {
*/ */
private final int hashCode; private final int hashCode;
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
public ReferenceType(String name, UnifyType... params) { public ReferenceType(String name, UnifyType... params) {
super(name, new TypeParams(params)); super(name, new TypeParams(params));
hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode(); hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
@ -27,13 +34,13 @@ public final class ReferenceType extends UnifyType {
} }
@Override @Override
Set<UnifyType> smArg(IFiniteClosure fc) { Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.smArg(this); return fc.smArg(this, fBounded);
} }
@Override @Override
Set<UnifyType> grArg(IFiniteClosure fc) { Set<UnifyType> grArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.grArg(this); return fc.grArg(this, fBounded);
} }
@Override @Override

View File

@ -1,8 +1,10 @@
package de.dhbwstuttgart.typeinference.unify.model; package de.dhbwstuttgart.typeinference.unify.model;
import java.util.HashMap;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/** /**
* A super wildcard type e.g. ? super Integer. * A super wildcard type e.g. ? super Integer.
@ -10,6 +12,10 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
*/ */
public final class SuperType extends WildcardType { public final class SuperType extends WildcardType {
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht);
}
/** /**
* Creates a new instance "? extends superedType" * Creates a new instance "? extends superedType"
* @param superedType The type that is supered e.g. Integer in "? super Integer" * @param superedType The type that is supered e.g. Integer in "? super Integer"
@ -42,13 +48,13 @@ public final class SuperType extends WildcardType {
} }
@Override @Override
Set<UnifyType> smArg(IFiniteClosure fc) { Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.smArg(this); return fc.smArg(this, fBounded);
} }
@Override @Override
Set<UnifyType> grArg(IFiniteClosure fc) { Set<UnifyType> grArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.grArg(this); return fc.grArg(this, fBounded);
} }
@Override @Override

View File

@ -115,6 +115,14 @@ public final class TypeParams implements Iterable<UnifyType>{
return typeParams[i]; return typeParams[i];
} }
/**
* Returns the parameters of this object.
* PL 2018-03-17
*/
public UnifyType[] get() {
return typeParams;
}
/** /**
* Sets the the type t as the i-th parameter and returns a new object * Sets the the type t as the i-th parameter and returns a new object
* that equals this object, except for the i-th type. * that equals this object, except for the i-th type.

View File

@ -1,8 +1,10 @@
package de.dhbwstuttgart.typeinference.unify.model; package de.dhbwstuttgart.typeinference.unify.model;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
/** /**
@ -63,7 +65,44 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
* @return A new pair where the left and right-hand side are applied * @return A new pair where the left and right-hand side are applied
*/ */
public UnifyPair apply(UnifyPair p) { public UnifyPair apply(UnifyPair p) {
return new UnifyPair(this.apply(p.getLhsType()), this.apply(p.getRhsType()), p.getPairOp()); UnifyType newLhs = this.apply(p.getLhsType());
UnifyType newRhs = this.apply(p.getRhsType());
return new UnifyPair(newLhs, newRhs, p.getPairOp());
}
/**
* Applies the unifier to the two terms of the pair.
* works only for single subsitution
* @return A new pair where the left and right-hand side are applied
*/
public UnifyPair apply(UnifyPair thisAsPair, UnifyPair p) {
UnifyType newLhs = this.apply(p.getLhsType());
UnifyType newRhs = this.apply(p.getRhsType());
//Varianceweitergabe wird nicht benoetigt.
//PlaceholderType lhsph = (PlaceholderType)thisAsPair.getLhsType();
//if (lhsph.getVariance() != 0) {
// if (p.getLhsType().equals(lhsph)) {
// if (p.getRhsType() instanceof PlaceholderType) {
// ((PlaceholderType)p.getRhsType()).setVariance(lhsph.getVariance());
// }
// }
// if (p.getRhsType().equals(lhsph)) {
// if (p.getLhsType() instanceof PlaceholderType) {
// ((PlaceholderType)p.getLhsType()).setVariance(lhsph.getVariance());
// }
// }
//}
if (!(p.getLhsType().equals(newLhs)) || !(p.getRhsType().equals(newRhs))) {//Die Anwendung von this hat was veraendert PL 2018-04-01
Set<UnifyPair> suniUnifyPair = new HashSet<>();
suniUnifyPair.addAll(thisAsPair.getAllSubstitutions());
suniUnifyPair.add(thisAsPair);
if (p.getLhsType() instanceof PlaceholderType //&& newLhs instanceof PlaceholderType entfernt PL 2018-04-13
&& p.getPairOp() == PairOperator.EQUALSDOT) {
suniUnifyPair.add(p); //p koennte auch subsitution sein
}
return new UnifyPair(newLhs, newRhs, p.getPairOp(), suniUnifyPair, p);
}
return new UnifyPair(newLhs, newRhs, p.getPairOp(), p.getSubstitution(), p.getBasePair());
} }
/** /**

View File

@ -2,7 +2,10 @@ package de.dhbwstuttgart.typeinference.unify.model;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* A pair which contains two types and an operator, e.q. (Integer <. a). * A pair which contains two types and an operator, e.q. (Integer <. a).
@ -25,6 +28,29 @@ public class UnifyPair {
*/ */
private PairOperator pairOp; private PairOperator pairOp;
/** wieder loesecn wird nicht mehr benoetigt PL 2018-03-31
* variance shows the variance of the pair
* -1: contravariant
* 1 covariant
* 0 invariant
* PL 2018-03-21
*/
private byte variance = 0;
private boolean undefinedPair = false;
/**
* Unifier/substitute that generated this pair
* PL 2018-03-15
*/
private Set<UnifyPair> substitution;
/**
* Base on which the the unifier is applied
* PL 2018-03-15
*/
private UnifyPair basePair;
private final int hashCode; private final int hashCode;
/** /**
@ -37,6 +63,20 @@ public class UnifyPair {
this.lhs = lhs; this.lhs = lhs;
this.rhs = rhs; this.rhs = rhs;
pairOp = op; pairOp = op;
substitution = new HashSet<>();
// Caching hashcode
hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode();
}
public UnifyPair(UnifyType lhs, UnifyType rhs, PairOperator op, Set<UnifyPair> uni, UnifyPair base) {
this.lhs = lhs;
this.rhs = rhs;
pairOp = op;
substitution = uni;
basePair = base;
this.variance = variance;
// Caching hashcode // Caching hashcode
hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode(); hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode();
@ -63,6 +103,41 @@ public class UnifyPair {
return pairOp; return pairOp;
} }
public byte getVariance() {
return variance;
}
public void setVariance(byte v) {
variance = v;
}
public void setUndefinedPair() {
undefinedPair = true;
}
public Set<UnifyPair> getSubstitution() {
return substitution;
}
public UnifyPair getBasePair() {
return basePair;
}
public boolean isUndefinedPair() {
return undefinedPair;
}
public Set<UnifyPair> getAllSubstitutions () {
Set<UnifyPair> ret = new HashSet<>();
ret.addAll(getSubstitution());
if (basePair != null) {
ret.addAll(basePair.getAllSubstitutions());
}
return ret;
}
public Boolean wrongWildcard() {
return lhs.wrongWildcard() || rhs.wrongWildcard();
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof UnifyPair)) if(!(obj instanceof UnifyPair))
@ -73,6 +148,16 @@ public class UnifyPair {
UnifyPair other = (UnifyPair) obj; UnifyPair other = (UnifyPair) obj;
if (isUndefinedPair()) {
if (other.getBasePair() != basePair || (other.getBasePair() == null && basePair == null)) {
return false;
}
if (!other.getBasePair().equals(basePair) ||
!other.getAllSubstitutions().equals(getAllSubstitutions())) {
return false;
}
}
return other.getPairOp() == pairOp return other.getPairOp() == pairOp
&& other.getLhsType().equals(lhs) && other.getLhsType().equals(lhs)
&& other.getRhsType().equals(rhs); && other.getRhsType().equals(rhs);
@ -85,7 +170,14 @@ public class UnifyPair {
@Override @Override
public String toString() { public String toString() {
return "(" + lhs + " " + pairOp + " " + rhs + ")"; String ret = "";
if (lhs instanceof PlaceholderType) {
ret = new Integer(((PlaceholderType)lhs).getVariance()).toString();
}
if (rhs instanceof PlaceholderType) {
ret = ret + ", " + new Integer(((PlaceholderType)rhs).getVariance()).toString();
}
return "(" + lhs + " " + pairOp + " " + rhs + ", " + ret + ")";
} }
/* /*

View File

@ -2,10 +2,13 @@ package de.dhbwstuttgart.typeinference.unify.model;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
/** /**
* Represents a java type. * Represents a java type.
@ -33,6 +36,9 @@ public abstract class UnifyType {
typeParams = p; typeParams = p;
} }
abstract public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht);
/** /**
* Returns the name of the type. * Returns the name of the type.
* @return The name e.q. List for List<T>, Integer or ? extends Integer * @return The name e.q. List for List<T>, Integer or ? extends Integer
@ -62,7 +68,7 @@ public abstract class UnifyType {
* @param fc The FC that is called. * @param fc The FC that is called.
* @return The set that is smArg(this) * @return The set that is smArg(this)
*/ */
abstract Set<UnifyType> smArg(IFiniteClosure fc); abstract Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded);
/** /**
* Implementation of the visitor-pattern. Returns the set of grArg * Implementation of the visitor-pattern. Returns the set of grArg
@ -70,7 +76,7 @@ public abstract class UnifyType {
* @param fc The FC that is called. * @param fc The FC that is called.
* @return The set that is grArg(this) * @return The set that is grArg(this)
*/ */
abstract Set<UnifyType> grArg(IFiniteClosure fc); abstract Set<UnifyType> grArg(IFiniteClosure fc, Set<UnifyType> fBounded);
/** /**
* Applies a unifier to this object. * Applies a unifier to this object.
@ -97,6 +103,10 @@ public abstract class UnifyType {
return ret; return ret;
} }
public Boolean wrongWildcard() {//default
return false;
}
@Override @Override
public int hashCode() { public int hashCode() {
return this.toString().hashCode(); return this.toString().hashCode();

View File

@ -40,6 +40,11 @@ public abstract class WildcardType extends UnifyType {
return wildcardedType.getTypeParams(); return wildcardedType.getTypeParams();
} }
@Override
public Boolean wrongWildcard () {//This is an error
return (wildcardedType instanceof WildcardType);
}
@Override @Override
public int hashCode() { public int hashCode() {
return wildcardedType.hashCode() + getName().hashCode() + 17; return wildcardedType.hashCode() + getName().hashCode() + 17;

View File

@ -0,0 +1,47 @@
package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.HashMap;
import java.util.stream.Collectors;
import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
public class visitUnifyTypeVisitor<T> implements UnifyTypeVisitor<T> {
public ReferenceType visit(ReferenceType refty, T ht) {
return new ReferenceType(refty.getName(),
new TypeParams(
Arrays.stream(refty.getTypeParams().get())
.map(x -> x.accept(this, ht))
.collect(Collectors.toCollection(ArrayList::new))));
}
public PlaceholderType visit(PlaceholderType phty, T ht) {
return phty;
}
public FunNType visit(FunNType funnty, T ht) {
return FunNType.getFunNType(
new TypeParams(
Arrays.stream(funnty.getTypeParams().get())
.map(x -> x.accept(this, ht))
.collect(Collectors.toCollection(ArrayList::new)))
);
}
public SuperType visit(SuperType suty, T ht) {
return new SuperType(suty.getWildcardedType().accept(this, ht));
}
public ExtendsType visit(ExtendsType extty, T ht) {
return new ExtendsType(extty.getWildcardedType().accept(this, ht));
}
}

Binary file not shown.

4
target/repository/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

View File

@ -1,8 +0,0 @@
package bytecode;
public class ATest extends JavaTXCompilerTest {
public ATest() {
fileName = "Example";
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class AssignToLitTest extends JavaTXCompilerTest {
public AssignToLitTest() {
this.fileName = "AssignToLit";
}
}

View File

@ -0,0 +1,40 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class BinaryTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/BinaryInMeth.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode();
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("BinaryInMeth");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
@Test
public void test() {
fail("Not yet implemented");
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class DuMethodTest extends JavaTXCompilerTest{
public DuMethodTest() {
this.fileName = "DuMethod";
}
}

View File

@ -0,0 +1,44 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class FacTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Fac.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode();
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("Fac");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
@Test
public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method getFac = classToTest.getDeclaredMethod("getFac", Integer.class);
Integer result = (Integer) getFac.invoke(instanceOfClass,3);
assertEquals(result, 6);
}
}

View File

@ -1,11 +0,0 @@
package bytecode;
import org.objectweb.asm.Opcodes;
public class ForTest extends JavaTXCompilerTest {
public ForTest() {
this.fileName = "For";
}
}

View File

@ -0,0 +1,41 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class GenTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Gen.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode();
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("Gen");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
@Test
public void test() {
fail("Not yet implemented");
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class Generics2Test extends JavaTXCompilerTest{
public Generics2Test() {
this.fileName = "Generics2";
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class GenericsTest extends JavaTXCompilerTest {
public GenericsTest() {
this.fileName = "Generics";
}
}

View File

@ -0,0 +1,140 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class GreaterEqualTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/GreaterEqual.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode();
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
loader = new URLClassLoader(new URL[] {new URL("File://"+pathToClassFile)});
classToTest = loader.loadClass("GreaterEqual");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
@Test
public void testName() {
assertEquals("GreaterEqual", classToTest.getName());
}
@Test
public void testIntegers() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gE = classToTest.getDeclaredMethod("gE", Integer.class, Integer.class);
Boolean result = (Boolean) gE.invoke(instanceOfClass, 7, 5);
assertTrue(result);
}
@Test
public void testIntegers2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gE = classToTest.getDeclaredMethod("gE", Integer.class, Integer.class);
Boolean result = (Boolean) gE.invoke(instanceOfClass, 5, 7);
assertFalse(result);
}
@Test
public void testEqIntegers() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gE = classToTest.getDeclaredMethod("gE", Integer.class, Integer.class);
Boolean result = (Boolean) gE.invoke(instanceOfClass, 5, 5);
assertTrue(result);
}
@Test
public void testLongs() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gE = classToTest.getDeclaredMethod("gE", Long.class, Long.class);
Boolean result = (Boolean) gE.invoke(instanceOfClass, 10L,7L);
assertTrue(result);
}
@Test
public void testFloats() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gE = classToTest.getDeclaredMethod("gE", Float.class, Float.class);
Boolean result = (Boolean) gE.invoke(instanceOfClass, 5F,7F);
assertFalse(result);
}
@Test
public void testDoubles() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gE = classToTest.getDeclaredMethod("gE", Double.class, Double.class);
Boolean result = (Boolean) gE.invoke(instanceOfClass, 5.0,7.0);
assertFalse(result);
}
@Test
public void testLongInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gE = classToTest.getDeclaredMethod("gE", Long.class, Integer.class);
Boolean result = (Boolean) gE.invoke(instanceOfClass, 15L,7);
assertTrue(result);
}
@Test
public void testFloatInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gE = classToTest.getDeclaredMethod("gE", Float.class, Integer.class);
Boolean result = (Boolean) gE.invoke(instanceOfClass, 5F,7);
assertFalse(result);
}
@Test
public void testDoubleInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gE = classToTest.getDeclaredMethod("gE", Double.class, Integer.class);
Boolean result = (Boolean) gE.invoke(instanceOfClass, 25.0,17);
assertTrue(result);
}
@Test
public void testFloatLong() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gE = classToTest.getDeclaredMethod("gE", Float.class, Long.class);
Boolean result = (Boolean) gE.invoke(instanceOfClass, 75F,70L);
assertTrue(result);
}
@Test
public void testDoubleLong() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gE = classToTest.getDeclaredMethod("gE", Double.class, Long.class);
Boolean result = (Boolean) gE.invoke(instanceOfClass, 5.0,7L);
assertFalse(result);
}
@Test
public void testEqDoubleFloat() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gE = classToTest.getDeclaredMethod("gE", Double.class, Float.class);
Boolean result = (Boolean) gE.invoke(instanceOfClass, 7.0,7F);
assertTrue(result);
}
@Test
public void testDoubleFloat() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gE = classToTest.getDeclaredMethod("gE", Double.class, Float.class);
Boolean result = (Boolean) gE.invoke(instanceOfClass, 15.0,7F);
assertTrue(result);
}
@Test
public void testDoubleFloat3() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gE = classToTest.getDeclaredMethod("gE", Double.class, Float.class);
Boolean result = (Boolean) gE.invoke(instanceOfClass, 9.0,17F);
assertFalse(result);
}
}

View File

@ -0,0 +1,139 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class GreaterThanTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/GreaterThan.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode();
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
loader = new URLClassLoader(new URL[] {new URL("File://"+pathToClassFile)});
classToTest = loader.loadClass("GreaterThan");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
@Test
public void testName() {
assertEquals("GreaterThan", classToTest.getName());
}
public void testIntegers() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gT = classToTest.getDeclaredMethod("gT", Integer.class, Integer.class);
Boolean result = (Boolean) gT.invoke(instanceOfClass, 7, 5);
assertTrue(result);
}
@Test
public void testIntegers2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gT = classToTest.getDeclaredMethod("gT", Integer.class, Integer.class);
Boolean result = (Boolean) gT.invoke(instanceOfClass, 5, 7);
assertFalse(result);
}
@Test
public void testEqIntegers() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gT = classToTest.getDeclaredMethod("gT", Integer.class, Integer.class);
Boolean result = (Boolean) gT.invoke(instanceOfClass, 5, 5);
assertFalse(result);
}
@Test
public void testLongs() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gT = classToTest.getDeclaredMethod("gT", Long.class, Long.class);
Boolean result = (Boolean) gT.invoke(instanceOfClass, 10L,7L);
assertTrue(result);
}@Test
public void testFloats() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gT = classToTest.getDeclaredMethod("gT", Float.class, Float.class);
Boolean result = (Boolean) gT.invoke(instanceOfClass, 5F,7F);
assertFalse(result);
}
@Test
public void testDoubles() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gT = classToTest.getDeclaredMethod("gT", Double.class, Double.class);
Boolean result = (Boolean) gT.invoke(instanceOfClass, 5.0,7.0);
assertFalse(result);
}
@Test
public void testLongInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gT = classToTest.getDeclaredMethod("gT", Long.class, Integer.class);
Boolean result = (Boolean) gT.invoke(instanceOfClass, 15L,7);
assertTrue(result);
}
@Test
public void testFloatInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gT = classToTest.getDeclaredMethod("gT", Float.class, Integer.class);
Boolean result = (Boolean) gT.invoke(instanceOfClass, 5F,7);
assertFalse(result);
}
@Test
public void testDoubleInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gT = classToTest.getDeclaredMethod("gT", Double.class, Integer.class);
Boolean result = (Boolean) gT.invoke(instanceOfClass, 25.0,17);
assertTrue(result);
}
@Test
public void testFloatLong() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gT = classToTest.getDeclaredMethod("gT", Float.class, Long.class);
Boolean result = (Boolean) gT.invoke(instanceOfClass, 75F,70L);
assertTrue(result);
}
@Test
public void testDoubleLong() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gT = classToTest.getDeclaredMethod("gT", Double.class, Long.class);
Boolean result = (Boolean) gT.invoke(instanceOfClass, 5.0,7L);
assertFalse(result);
}
@Test
public void testEqDoubleFloat() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gT = classToTest.getDeclaredMethod("gT", Double.class, Float.class);
Boolean result = (Boolean) gT.invoke(instanceOfClass, 7.0,7F);
assertFalse(result);
}
@Test
public void testDoubleFloat() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gT = classToTest.getDeclaredMethod("gT", Double.class, Float.class);
Boolean result = (Boolean) gT.invoke(instanceOfClass, 15.0,7F);
assertTrue(result);
}
@Test
public void testDoubleFloat3() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method gT = classToTest.getDeclaredMethod("gT", Double.class, Float.class);
Boolean result = (Boolean) gT.invoke(instanceOfClass, 9.0,17F);
assertFalse(result);
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class ImportTest extends JavaTXCompilerTest{
public ImportTest() {
this.fileName = "Import";
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class InterfaceTest extends JavaTXCompilerTest{
public InterfaceTest() {
this.fileName = "Interface1";
}
}

View File

@ -1,90 +0,0 @@
package bytecode;
import de.dhbwstuttgart.bytecode.BytecodeGen;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.typeinference.result.ResultPair;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import org.junit.Test;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import static org.junit.Assert.*;
public class JavaTXCompilerTest {
private static final String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/";
private static final List<File> filesToTest = new ArrayList<>();
protected String fileName = "";
@Test
public void test() throws IOException, java.lang.ClassNotFoundException {
System.out.println(rootDirectory);
filesToTest.add(new File(rootDirectory+fileName+".jav"));
System.out.println(rootDirectory+fileName+".jav");
JavaTXCompiler compiler = new JavaTXCompiler(filesToTest);
for(File f : filesToTest){
String content = readFile(f.getPath(), StandardCharsets.UTF_8);
List<ResultSet> typeinferenceResult = compiler.typeInference();
HashMap<String,byte[]> bytecode = this.getBytecode(compiler.sourceFiles.get(f), typeinferenceResult.get(0));
// for(ResultPair ep : typeinferenceResult.get(0).results) {
// System.out.println(ep.getLeft() + " ->" + ep.getRight());
// }
String name;
int pos = f.getName().lastIndexOf(".");
if(pos != -1) {
name = f.getName().substring(0, pos);
}
this.writeClassFile(bytecode);
}
}
public HashMap<String,byte[]> getBytecode(SourceFile sf, ResultSet resultSet) {
HashMap<String,byte[]> classFiles = new HashMap<>();
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,resultSet);
bytecodeGen.visit(sf);
return bytecodeGen.getClassFiles();
}
public void writeClassFile(HashMap<String,byte[]> classFiles) {
FileOutputStream output;
for(String name : classFiles.keySet()) {
byte[] bytecode = classFiles.get(name);
try {
System.out.println("generating "+name+ ".class file ...");
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class"));
output.write(bytecode);
output.close();
System.out.println(name+".class file generated");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class LamAssignTest extends JavaTXCompilerTest{
public LamAssignTest() {
this.fileName = "LamAssign";
}
}

View File

@ -0,0 +1,23 @@
package bytecode;
import java.io.File;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class LambdaTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
@Test
public void generateBC() throws Exception {
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Lambda.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode();
}
}

View File

@ -0,0 +1,133 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class LessEqualTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/LessEqual.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode();
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("LessEqual");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
@Test
public void testName() {
assertEquals("LessEqual", classToTest.getName());
}
@Test
public void testIntegers() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Integer.class, Integer.class);
Boolean result = (Boolean) lessEqual.invoke(instanceOfClass, 5,7);
assertTrue(result);
}
@Test
public void testEqualIntegers() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Integer.class, Integer.class);
Boolean result = (Boolean) lessEqual.invoke(instanceOfClass, 5,5);
assertTrue(result);
}
@Test
public void testLongs() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Long.class, Long.class);
Boolean result = (Boolean) lessEqual.invoke(instanceOfClass, 5L,7L);
assertTrue(result);
}@Test
public void testFloats() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Float.class, Float.class);
Boolean result = (Boolean) lessEqual.invoke(instanceOfClass, 5F,7F);
assertTrue(result);
}
@Test
public void testDoubles() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Double.class, Double.class);
Boolean result = (Boolean) lessEqual.invoke(instanceOfClass, 5.0,7.0);
assertTrue(result);
}
@Test
public void testLongInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Long.class, Integer.class);
Boolean result = (Boolean) lessEqual.invoke(instanceOfClass, 5L,7);
assertTrue(result);
}
@Test
public void testFloatInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Float.class, Integer.class);
Boolean result = (Boolean) lessEqual.invoke(instanceOfClass, 5F,7);
assertTrue(result);
}
@Test
public void testDoubleInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Double.class, Integer.class);
Boolean result = (Boolean) lessEqual.invoke(instanceOfClass, 5.0,7);
assertTrue(result);
}
@Test
public void testFloatLong() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Float.class, Long.class);
Boolean result = (Boolean) lessEqual.invoke(instanceOfClass, 5F,7L);
assertTrue(result);
}
@Test
public void testDoubleLong() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Double.class, Long.class);
Boolean result = (Boolean) lessEqual.invoke(instanceOfClass, 5.0,7L);
assertTrue(result);
}
@Test
public void testEqDoubleFloat() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Double.class, Float.class);
Boolean result = (Boolean) lessEqual.invoke(instanceOfClass, 7.0,7F);
assertTrue(result);
}
@Test
public void testDoubleFloat() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Double.class, Float.class);
Boolean result = (Boolean) lessEqual.invoke(instanceOfClass, 5.0,7F);
assertTrue(result);
}
@Test
public void testDoubleFloat3() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Double.class, Float.class);
Boolean result = (Boolean) lessEqual.invoke(instanceOfClass, 9.0,7F);
assertFalse(result);
}
}

Some files were not shown because too many files have changed in this diff Show More