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.
3
.gitignore
vendored
@ -20,3 +20,6 @@ bin
|
|||||||
.project
|
.project
|
||||||
.settings/
|
.settings/
|
||||||
/target/
|
/target/
|
||||||
|
|
||||||
|
#
|
||||||
|
manually/
|
||||||
|
19
README.md
Normal 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
88
Website/index.html
Normal 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
After Width: | Height: | Size: 25 KiB |
BIN
Website/install/availableSoftware1.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
Website/install/availableSoftware2.png
Normal file
After Width: | Height: | Size: 109 KiB |
40
Website/install/instal.html
Normal 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>
|
40
Website/install/install.html
Normal 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>
|
BIN
Website/install/installAnyway.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
Website/install/installationDetails.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
Website/install/licenseAgreement.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
Website/install/newsoftware.png
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
Website/install/selectInstallation.png
Normal file
After Width: | Height: | Size: 93 KiB |
BIN
Website/newJavaTXProject/addLibrary2.png
Normal file
After Width: | Height: | Size: 163 KiB |
BIN
Website/newJavaTXProject/buildPath1.png
Normal file
After Width: | Height: | Size: 163 KiB |
BIN
Website/newJavaTXProject/buildPath2.png
Normal file
After Width: | Height: | Size: 88 KiB |
BIN
Website/newJavaTXProject/buildPath3.png
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
Website/newJavaTXProject/buildPath4.png
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
Website/newJavaTXProject/newJavFile.png
Normal file
After Width: | Height: | Size: 102 KiB |
BIN
Website/newJavaTXProject/newJavFolder1.png
Normal file
After Width: | Height: | Size: 100 KiB |
BIN
Website/newJavaTXProject/newJavFolder2.png
Normal file
After Width: | Height: | Size: 76 KiB |
34
Website/newJavaTXProject/newJavaTXProject.html
Normal 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>
|
BIN
Website/newJavaTXProject/newJavaTXProject.png
Normal file
After Width: | Height: | Size: 150 KiB |
24
Website/usePlugin/usePlugin.html
Normal 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>
|
BIN
Website/usePlugin/usePlugin1.png
Normal file
After Width: | Height: | Size: 112 KiB |
BIN
Website/usePlugin/usePlugin2.png
Normal file
After Width: | Height: | Size: 33 KiB |
84
pom.xml
@ -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>
|
||||||
|
30
src/de/dhbwstuttgart/bytecode/AStatement.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
11
src/de/dhbwstuttgart/bytecode/ArgumentExpr.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
src/de/dhbwstuttgart/bytecode/AssignStmt.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,12 @@ import java.util.Iterator;
|
|||||||
|
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr.Operator;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr.Operation;
|
||||||
|
|
||||||
import org.objectweb.asm.ClassWriter;
|
import org.objectweb.asm.ClassWriter;
|
||||||
import org.objectweb.asm.Handle;
|
import org.objectweb.asm.Handle;
|
||||||
|
import org.objectweb.asm.Label;
|
||||||
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 org.objectweb.asm.Type;
|
||||||
@ -25,15 +29,14 @@ import org.objectweb.asm.signature.SignatureWriter;
|
|||||||
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.TypeToSignature;
|
import de.dhbwstuttgart.bytecode.utilities.KindOfLambda;
|
||||||
import de.dhbwstuttgart.bytecode.signature.TypeToString;
|
import de.dhbwstuttgart.bytecode.utilities.Lambda;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.SamMethod;
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
@ -51,10 +54,13 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
private HashMap<String, String> genericsAndBounds;
|
private HashMap<String, String> genericsAndBounds;
|
||||||
private boolean isBinaryExp = false;
|
private boolean isBinaryExp = false;
|
||||||
|
|
||||||
|
private IStatement statement = null;
|
||||||
|
|
||||||
// for tests **
|
// for tests **
|
||||||
private String fieldName;
|
private String fieldName;
|
||||||
private String fieldDesc;
|
private String fieldDesc;
|
||||||
private Expression rightSideTemp;
|
private Expression rightSideTemp;
|
||||||
|
|
||||||
private boolean isRightSideALambda = false;
|
private boolean isRightSideALambda = false;
|
||||||
private KindOfLambda kindOfLambda;
|
private KindOfLambda kindOfLambda;
|
||||||
private HashMap<String, byte[]> classFiles;
|
private HashMap<String, byte[]> classFiles;
|
||||||
@ -103,11 +109,9 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
|
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Block block) {
|
public void visit(Block block) {
|
||||||
for (Statement stmt : block.getStatements()) {
|
for (Statement stmt : block.getStatements()) {
|
||||||
// System.out.println(where);
|
|
||||||
stmt.accept(this);
|
stmt.accept(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,17 +120,23 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
public void visit(SuperCall superCall) {
|
public void visit(SuperCall superCall) {
|
||||||
superCall.receiver.accept(this);
|
superCall.receiver.accept(this);
|
||||||
superCall.arglist.accept(this);
|
superCall.arglist.accept(this);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, "()V",isInterface);
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, "()V",
|
||||||
|
isInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ??
|
// ??
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVar localVar) {
|
public void visit(LocalVar localVar) {
|
||||||
|
// wenn String + String zuerst wird ein StringBuilder initialisiert dann
|
||||||
|
// wird die lokale Var geladen. Sonst wird zuerst die lokale Var geladen.
|
||||||
|
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name));
|
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name));
|
||||||
|
|
||||||
if (isBinaryExp) {
|
if (isBinaryExp) {
|
||||||
getVlaue(getResolvedType(localVar.getType()));
|
doUnboxing(getResolvedType(localVar.getType()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ??
|
// ??
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVarDecl localVarDecl) {
|
public void visit(LocalVarDecl localVarDecl) {
|
||||||
@ -135,6 +145,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Assign assign) {
|
public void visit(Assign assign) {
|
||||||
|
statement = new AssignStmt(assign.rightSide);
|
||||||
// if the right side is a lambda => the left side must be a functional interface
|
// if the right side is a lambda => the left side must be a functional interface
|
||||||
if (assign.rightSide instanceof LambdaExpression) {
|
if (assign.rightSide instanceof LambdaExpression) {
|
||||||
isRightSideALambda = true;
|
isRightSideALambda = true;
|
||||||
@ -142,8 +153,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
isRightSideALambda = false;
|
isRightSideALambda = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(assign.rightSide instanceof BinaryExpr)
|
isBinaryExp = statement.isExprBinary();
|
||||||
isBinaryExp = true;
|
|
||||||
|
|
||||||
if (assign.lefSide instanceof AssignToField) {
|
if (assign.lefSide instanceof AssignToField) {
|
||||||
// load_0, ldc or .. then putfield
|
// load_0, ldc or .. then putfield
|
||||||
@ -152,19 +162,76 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
assign.rightSide.accept(this);
|
assign.rightSide.accept(this);
|
||||||
}
|
}
|
||||||
if (isBinaryExp) {
|
if (isBinaryExp) {
|
||||||
doAssign(getResolvedType(assign.lefSide.getType()));
|
BinaryExpr binary = (BinaryExpr) assign.rightSide;
|
||||||
|
String binaryType = getResolvedType(binary.getType());
|
||||||
|
doBoxing(binaryType);
|
||||||
isBinaryExp = false;
|
isBinaryExp = false;
|
||||||
}
|
}
|
||||||
assign.lefSide.accept(this);
|
assign.lefSide.accept(this);
|
||||||
|
|
||||||
|
statement = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(BinaryExpr binary) {
|
public void visit(BinaryExpr binary) {
|
||||||
|
|
||||||
|
String lexpType = getResolvedType(binary.lexpr.getType());
|
||||||
|
String rexpType = getResolvedType(binary.rexpr.getType());
|
||||||
|
|
||||||
|
String largerType = getLargerType(lexpType, rexpType);
|
||||||
|
String typeOfBinary = getResolvedType(binary.getType());
|
||||||
|
|
||||||
|
if (typeOfBinary.equals(Type.getInternalName(String.class))) {
|
||||||
|
mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(StringBuilder.class));
|
||||||
|
mv.visitInsn(Opcodes.DUP);
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(StringBuilder.class), "<init>", "()V",
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Label endLabel = new Label();
|
||||||
|
// this case for while loops
|
||||||
|
if (statement instanceof LoopStmt)
|
||||||
|
mv.visitLabel(endLabel);
|
||||||
|
|
||||||
binary.lexpr.accept(this);
|
binary.lexpr.accept(this);
|
||||||
|
|
||||||
|
if (!lexpType.equals(rexpType) && !lexpType.equals(largerType))
|
||||||
|
doCast(lexpType, largerType);
|
||||||
|
|
||||||
binary.rexpr.accept(this);
|
binary.rexpr.accept(this);
|
||||||
switch (binary.operation.toString()) {
|
|
||||||
case "ADD":
|
if (!lexpType.equals(rexpType) && !rexpType.equals(largerType))
|
||||||
mv.visitInsn(Opcodes.IADD);
|
doCast(rexpType, largerType);
|
||||||
|
|
||||||
|
Operator op = binary.operation;
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case ADD:
|
||||||
|
doVisitAddOpInsn(largerType);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SUB:
|
||||||
|
doVisitSubOpInsn(typeOfBinary);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MUL:
|
||||||
|
doVisitMulOpInsn(typeOfBinary);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DIV:
|
||||||
|
doVisitDivOpInsn(typeOfBinary);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MOD:
|
||||||
|
doVisitModOpInsn(typeOfBinary);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LESSTHAN:
|
||||||
|
case LESSEQUAL:
|
||||||
|
case BIGGERTHAN:
|
||||||
|
case BIGGEREQUAL:
|
||||||
|
Label branchLabel = new Label();
|
||||||
|
doVisitRelOpInsn(op, largerType, branchLabel, endLabel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -173,23 +240,245 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Diese Methode wird nicht mehr gebraucht, da es jetzt nicht möglich ist, dass
|
||||||
|
* solche Fälle: Integer -> Integer (OP) Short ,... usw, nicht vorkommen!
|
||||||
|
*/
|
||||||
|
private String getLargerType(String lexpType, String rexpType) {
|
||||||
|
if (lexpType.equals(Type.getInternalName(String.class))
|
||||||
|
|| rexpType.equals(Type.getInternalName(String.class))) {
|
||||||
|
return Type.getInternalName(String.class);
|
||||||
|
} else if (lexpType.equals(Type.getInternalName(Double.class))
|
||||||
|
|| rexpType.equals(Type.getInternalName(Double.class))) {
|
||||||
|
return Type.getInternalName(Double.class);
|
||||||
|
} else if (lexpType.equals(Type.getInternalName(Float.class))
|
||||||
|
|| rexpType.equals(Type.getInternalName(Float.class))) {
|
||||||
|
return Type.getInternalName(Float.class);
|
||||||
|
} else if (lexpType.equals(Type.getInternalName(Long.class))
|
||||||
|
|| rexpType.equals(Type.getInternalName(Long.class))) {
|
||||||
|
return Type.getInternalName(Long.class);
|
||||||
|
} else {
|
||||||
|
return Type.getInternalName(Integer.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doCast(String sourceType, String dest) {
|
||||||
|
switch (dest) {
|
||||||
|
case "java/lang/Long":
|
||||||
|
mv.visitInsn(Opcodes.I2L);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "java/lang/Double":
|
||||||
|
if (sourceType.equals(Type.getInternalName(Long.class))) {
|
||||||
|
mv.visitInsn(Opcodes.L2D);
|
||||||
|
} else if (sourceType.equals(Type.getInternalName(Float.class))) {
|
||||||
|
mv.visitInsn(Opcodes.F2D);
|
||||||
|
} else {
|
||||||
|
mv.visitInsn(Opcodes.I2D);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "java/lang/Float":
|
||||||
|
if (sourceType.equals(Type.getInternalName(Long.class))) {
|
||||||
|
mv.visitInsn(Opcodes.L2F);
|
||||||
|
} else {
|
||||||
|
mv.visitInsn(Opcodes.I2F);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// braucht man eigentlic nicht, muss getestet werden
|
||||||
|
case "java/lang/String":
|
||||||
|
if (sourceType.equals(Type.getInternalName(Double.class))) {
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf",
|
||||||
|
"(D)Ljava/lang/String;", false);
|
||||||
|
} else if (sourceType.equals(Type.getInternalName(Long.class))) {
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf",
|
||||||
|
"(J)Ljava/lang/String;", false);
|
||||||
|
} else if (sourceType.equals(Type.getInternalName(Float.class))) {
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf",
|
||||||
|
"(F)Ljava/lang/String;", false);
|
||||||
|
} else {
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf",
|
||||||
|
"(I)Ljava/lang/String;", false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doVisitRelOpInsn(Operator op, String typeOfBinary, Label branchLabel, Label endLabel) {
|
||||||
|
|
||||||
|
switch (typeOfBinary) {
|
||||||
|
case "java/lang/Long":
|
||||||
|
mv.visitInsn(Opcodes.LCMP);
|
||||||
|
doVisitIfInRelOp(op, branchLabel, endLabel);
|
||||||
|
break;
|
||||||
|
case "java/lang/Double":
|
||||||
|
mv.visitInsn(Opcodes.DCMPG);
|
||||||
|
doVisitIfInRelOp(op, branchLabel, endLabel);
|
||||||
|
break;
|
||||||
|
case "java/lang/Float":
|
||||||
|
mv.visitInsn(Opcodes.FCMPG);
|
||||||
|
doVisitIfInRelOp(op, branchLabel, endLabel);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
switch (op) {
|
||||||
|
case LESSTHAN:
|
||||||
|
mv.visitJumpInsn(Opcodes.IF_ICMPGE, branchLabel);
|
||||||
|
break;
|
||||||
|
case LESSEQUAL:
|
||||||
|
mv.visitJumpInsn(Opcodes.IF_ICMPGT, branchLabel);
|
||||||
|
break;
|
||||||
|
case BIGGERTHAN:
|
||||||
|
mv.visitJumpInsn(Opcodes.IF_ICMPLE, branchLabel);
|
||||||
|
break;
|
||||||
|
case BIGGEREQUAL:
|
||||||
|
mv.visitJumpInsn(Opcodes.IF_ICMPLT, branchLabel);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
statement.genBCForRelOp(mv, branchLabel, endLabel, this);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doVisitIfInRelOp(Operator op, Label branchLabel, Label endLabel) {
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case LESSTHAN:
|
||||||
|
mv.visitJumpInsn(Opcodes.IFGE, branchLabel);
|
||||||
|
break;
|
||||||
|
case LESSEQUAL:
|
||||||
|
mv.visitJumpInsn(Opcodes.IFGT, branchLabel);
|
||||||
|
break;
|
||||||
|
case BIGGERTHAN:
|
||||||
|
mv.visitJumpInsn(Opcodes.IFLE, branchLabel);
|
||||||
|
break;
|
||||||
|
case BIGGEREQUAL:
|
||||||
|
mv.visitJumpInsn(Opcodes.IFLT, branchLabel);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
statement.genBCForRelOp(mv, branchLabel, endLabel, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doVisitModOpInsn(String typeOfBinary) {
|
||||||
|
switch (typeOfBinary) {
|
||||||
|
case "java/lang/Long":
|
||||||
|
mv.visitInsn(Opcodes.LREM);
|
||||||
|
break;
|
||||||
|
case "java/lang/Double":
|
||||||
|
mv.visitInsn(Opcodes.DREM);
|
||||||
|
break;
|
||||||
|
case "java/lang/Float":
|
||||||
|
mv.visitInsn(Opcodes.FREM);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mv.visitInsn(Opcodes.IREM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doVisitDivOpInsn(String typeOfBinary) {
|
||||||
|
switch (typeOfBinary) {
|
||||||
|
case "java/lang/Long":
|
||||||
|
mv.visitInsn(Opcodes.LDIV);
|
||||||
|
break;
|
||||||
|
case "java/lang/Double":
|
||||||
|
mv.visitInsn(Opcodes.DDIV);
|
||||||
|
break;
|
||||||
|
case "java/lang/Float":
|
||||||
|
mv.visitInsn(Opcodes.FDIV);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mv.visitInsn(Opcodes.IDIV);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doVisitMulOpInsn(String typeOfBinary) {
|
||||||
|
switch (typeOfBinary) {
|
||||||
|
case "java/lang/Long":
|
||||||
|
mv.visitInsn(Opcodes.LMUL);
|
||||||
|
break;
|
||||||
|
case "java/lang/Double":
|
||||||
|
mv.visitInsn(Opcodes.DMUL);
|
||||||
|
break;
|
||||||
|
case "java/lang/Float":
|
||||||
|
mv.visitInsn(Opcodes.FMUL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mv.visitInsn(Opcodes.IMUL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doVisitSubOpInsn(String typeOfBinary) {
|
||||||
|
switch (typeOfBinary) {
|
||||||
|
case "java/lang/Long":
|
||||||
|
mv.visitInsn(Opcodes.LSUB);
|
||||||
|
break;
|
||||||
|
case "java/lang/Double":
|
||||||
|
mv.visitInsn(Opcodes.DSUB);
|
||||||
|
break;
|
||||||
|
case "java/lang/Float":
|
||||||
|
mv.visitInsn(Opcodes.FSUB);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mv.visitInsn(Opcodes.ISUB);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doVisitAddOpInsn(String typeOfBinary) {
|
||||||
|
switch (typeOfBinary) {
|
||||||
|
case "java/lang/Byte":
|
||||||
|
mv.visitInsn(Opcodes.IADD);
|
||||||
|
break;
|
||||||
|
case "java/lang/Short":
|
||||||
|
mv.visitInsn(Opcodes.IADD);
|
||||||
|
break;
|
||||||
|
case "java/lang/Integer":
|
||||||
|
mv.visitInsn(Opcodes.IADD);
|
||||||
|
break;
|
||||||
|
case "java/lang/Long":
|
||||||
|
mv.visitInsn(Opcodes.LADD);
|
||||||
|
break;
|
||||||
|
case "java/lang/Double":
|
||||||
|
mv.visitInsn(Opcodes.DADD);
|
||||||
|
break;
|
||||||
|
case "java/lang/Float":
|
||||||
|
mv.visitInsn(Opcodes.FADD);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LambdaExpression lambdaExpression) {
|
public void visit(LambdaExpression lambdaExpression) {
|
||||||
this.lamCounter++;
|
this.lamCounter++;
|
||||||
|
|
||||||
Lambda lam = new Lambda(lambdaExpression);
|
Lambda lam = new Lambda(lambdaExpression);
|
||||||
String lamDesc = lam.accept(new DescriptorToString(resultSet));
|
String lamDesc = lam.accept(new DescriptorToString(resultSet));
|
||||||
//Call site, which, when invoked, returns an instance of the functional interface to which
|
// Call site, which, when invoked, returns an instance of the functional
|
||||||
|
// interface to which
|
||||||
// the lambda is being converted
|
// the lambda is being converted
|
||||||
MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
|
MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
|
||||||
MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
|
MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
|
||||||
|
|
||||||
|
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory",
|
||||||
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory",
|
mt.toMethodDescriptorString(), false);
|
||||||
"metafactory", mt.toMethodDescriptorString(), false);
|
|
||||||
String methodName = "lambda$new$" + this.lamCounter;
|
String methodName = "lambda$new$" + this.lamCounter;
|
||||||
|
|
||||||
// Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die Typlöschung)
|
// Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die
|
||||||
|
// Typlöschung)
|
||||||
|
|
||||||
String typeErasure = "(";
|
String typeErasure = "(";
|
||||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||||
@ -220,8 +509,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// first check if capturing lambda then invokestatic or invokespecial
|
// first check if capturing lambda then invokestatic or invokespecial
|
||||||
Handle arg2 = new Handle(staticOrSpecial, this.className, methodName,
|
Handle arg2 = new Handle(staticOrSpecial, this.className, methodName, arg3.toString(), false);
|
||||||
arg3.toString(),false);
|
|
||||||
// Descriptor of functional interface methode
|
// Descriptor of functional interface methode
|
||||||
SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType());
|
SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType());
|
||||||
// Desc: (this/nothing)TargetType
|
// Desc: (this/nothing)TargetType
|
||||||
@ -239,7 +527,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
|
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
|
||||||
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL);
|
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL);
|
||||||
|
|
||||||
// generateBCForFunN(lambdaExpression,typeErasure);
|
generateBCForFunN(lambdaExpression, typeErasure);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) {
|
private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) {
|
||||||
@ -259,11 +547,11 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
methSig.visitReturnType().visitTypeVariable("R");
|
methSig.visitReturnType().visitTypeVariable("R");
|
||||||
// ")"+lam.getReturn.getBounds
|
// ")"+lam.getReturn.getBounds
|
||||||
Signature sig = new Signature(lambdaExpression, numberOfParams);
|
Signature sig = new Signature(lambdaExpression, numberOfParams);
|
||||||
String name = "Fun"+numberOfParams;
|
String name = "Fun" + numberOfParams + "$$";
|
||||||
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_INTERFACE+Opcodes.ACC_ABSTRACT, name,
|
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
||||||
sig.toString(), Type.getInternalName(Object.class), null);
|
Type.getInternalName(Object.class), null);
|
||||||
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_ABSTRACT, "apply",
|
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
|
||||||
methDesc, methSig.toString(), null);
|
methSig.toString(), null);
|
||||||
mvApply.visitEnd();
|
mvApply.visitEnd();
|
||||||
writeClassFile(classWriter.toByteArray(), name);
|
writeClassFile(classWriter.toByteArray(), name);
|
||||||
}
|
}
|
||||||
@ -272,7 +560,8 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
FileOutputStream output;
|
FileOutputStream output;
|
||||||
try {
|
try {
|
||||||
System.out.println("generating " + name + ".class file...");
|
System.out.println("generating " + name + ".class file...");
|
||||||
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/examples/" +name+".class"));
|
output = new FileOutputStream(
|
||||||
|
new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" + name + ".class"));
|
||||||
output.write(bytecode);
|
output.write(bytecode);
|
||||||
output.close();
|
output.close();
|
||||||
System.out.println(name + ".class file generated");
|
System.out.println(name + ".class file generated");
|
||||||
@ -305,11 +594,11 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
fieldVar.receiver.accept(this);
|
fieldVar.receiver.accept(this);
|
||||||
// test (if)
|
// test (if)
|
||||||
if (!fieldVar.receiver.getClass().equals(StaticClassName.class)) {
|
if (!fieldVar.receiver.getClass().equals(StaticClassName.class)) {
|
||||||
mv.visitFieldInsn(Opcodes.GETFIELD,getResolvedType(fieldVar.receiver.getType()),
|
mv.visitFieldInsn(Opcodes.GETFIELD, getResolvedType(fieldVar.receiver.getType()), fieldName, fieldDesc);
|
||||||
fieldName ,fieldDesc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mv.visitFieldInsn(Opcodes.GETSTATIC, fieldVar.receiver.getType().toString().replace(".", "/"),
|
// mv.visitFieldInsn(Opcodes.GETSTATIC,
|
||||||
|
// fieldVar.receiver.getType().toString().replace(".", "/"),
|
||||||
// fieldVar.fieldVarName, fieldVar.getType().toString());
|
// fieldVar.fieldVarName, fieldVar.getType().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,6 +621,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(MethodCall methodCall) {
|
public void visit(MethodCall methodCall) {
|
||||||
|
|
||||||
methodCall.receiver.accept(this);
|
methodCall.receiver.accept(this);
|
||||||
methodCall.arglist.accept(this);
|
methodCall.arglist.accept(this);
|
||||||
|
|
||||||
@ -341,11 +631,11 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
// is methodCall.receiver functional Interface)?
|
// is methodCall.receiver functional Interface)?
|
||||||
if (varsFunInterface.contains(methodCall.receiver.getType())) {
|
if (varsFunInterface.contains(methodCall.receiver.getType())) {
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()),
|
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), methodCall.name,
|
||||||
methodCall.name, mDesc, false);
|
mDesc, false);
|
||||||
} else {
|
} else {
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()),
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()), methodCall.name,
|
||||||
methodCall.name, mDesc, isInterface);
|
mDesc, isInterface);
|
||||||
}
|
}
|
||||||
// test
|
// test
|
||||||
// if(!methodCall.getType().toString().equals("V")) {
|
// if(!methodCall.getType().toString().equals("V")) {
|
||||||
@ -382,13 +672,101 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(UnaryExpr unaryExpr) {
|
public void visit(UnaryExpr unaryExpr) {
|
||||||
System.out.println(unaryExpr.operation.toString());
|
unaryExpr.expr.accept(this);
|
||||||
|
Operation op = unaryExpr.operation;
|
||||||
|
|
||||||
|
String typeOfUnary = getResolvedType(unaryExpr.getType());
|
||||||
|
|
||||||
|
boolean isIncOrDec = false;
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case POSTDECREMENT:
|
||||||
|
case POSTINCREMENT:
|
||||||
|
if (statement instanceof AssignStmt)
|
||||||
|
mv.visitInsn(Opcodes.DUP);
|
||||||
|
genBCForIncAndDec(op, typeOfUnary);
|
||||||
|
doBoxing(typeOfUnary);
|
||||||
|
isIncOrDec = true;
|
||||||
|
break;
|
||||||
|
case PREDECREMENT:
|
||||||
|
case PREINCREMENT:
|
||||||
|
genBCForIncAndDec(op, typeOfUnary);
|
||||||
|
doBoxing(typeOfUnary);
|
||||||
|
if (statement instanceof AssignStmt)
|
||||||
|
mv.visitInsn(Opcodes.DUP);
|
||||||
|
isIncOrDec = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MINUS:
|
||||||
|
doVisitNegIns(typeOfUnary);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Für Byte und Short muss noch einen Cast geben i2b, i2s
|
||||||
|
// das wird später gemacht, da bytecode für cast noch nicht erzeugt wird
|
||||||
|
|
||||||
|
if (isIncOrDec && (unaryExpr.expr instanceof LocalVar)) {
|
||||||
|
LocalVar local = (LocalVar) unaryExpr.expr;
|
||||||
|
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.get(local.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doVisitNegIns(String typeOfUnary) {
|
||||||
|
switch (typeOfUnary) {
|
||||||
|
case "java/lang/Long":
|
||||||
|
mv.visitInsn(Opcodes.LNEG);
|
||||||
|
break;
|
||||||
|
case "java/lang/Double":
|
||||||
|
mv.visitInsn(Opcodes.DNEG);
|
||||||
|
break;
|
||||||
|
case "java/lang/Float":
|
||||||
|
mv.visitInsn(Opcodes.FNEG);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mv.visitInsn(Opcodes.INEG);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void genBCForIncAndDec(Operation op, String typeOfUnary) {
|
||||||
|
|
||||||
|
doUnboxing(typeOfUnary);
|
||||||
|
loadValue(typeOfUnary, 1.0, true);
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case POSTDECREMENT:
|
||||||
|
case PREDECREMENT:
|
||||||
|
doVisitSubOpInsn(typeOfUnary);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case POSTINCREMENT:
|
||||||
|
case PREINCREMENT:
|
||||||
|
doVisitAddOpInsn(typeOfUnary);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Return aReturn) {
|
public void visit(Return aReturn) {
|
||||||
|
statement = new ReturnStmt(aReturn.retexpr);
|
||||||
|
isBinaryExp = statement.isExprBinary();
|
||||||
|
|
||||||
aReturn.retexpr.accept(this);
|
aReturn.retexpr.accept(this);
|
||||||
|
|
||||||
|
if (isBinaryExp) {
|
||||||
|
BinaryExpr binary = (BinaryExpr) aReturn.retexpr;
|
||||||
|
doBoxing(getResolvedType(binary.getType()));
|
||||||
|
isBinaryExp = false;
|
||||||
|
}
|
||||||
|
|
||||||
mv.visitInsn(Opcodes.ARETURN);
|
mv.visitInsn(Opcodes.ARETURN);
|
||||||
|
statement = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -398,10 +776,12 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StaticClassName staticClassName) {
|
public void visit(StaticClassName staticClassName) {
|
||||||
// mv.visitMethodInsn(Opcodes.INVOKESTATIC, staticClassName.getType().toString().replace(".", "/"),
|
// mv.visitMethodInsn(Opcodes.INVOKESTATIC,
|
||||||
|
// staticClassName.getType().toString().replace(".", "/"),
|
||||||
// staticClassName.toString(), staticClassName.getType().toString(), false);
|
// staticClassName.toString(), staticClassName.getType().toString(), false);
|
||||||
mv.visitFieldInsn(Opcodes.GETSTATIC, getResolvedType(staticClassName.getType()),
|
// mv.visitFieldInsn(Opcodes.GETSTATIC,
|
||||||
fieldName, fieldDesc);
|
// getResolvedType(staticClassName.getType()), fieldName, fieldDesc);
|
||||||
|
throw new NotImplementedException("Static noch nicht implementiert!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -416,63 +796,66 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(WhileStmt whileStmt) {
|
public void visit(WhileStmt whileStmt) {
|
||||||
|
statement = new LoopStmt(whileStmt.expr, whileStmt.loopBlock);
|
||||||
|
isBinaryExp = statement.isExprBinary();
|
||||||
whileStmt.expr.accept(this);
|
whileStmt.expr.accept(this);
|
||||||
whileStmt.loopBlock.accept(this);
|
isBinaryExp = false;
|
||||||
|
statement = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(DoStmt whileStmt) {
|
public void visit(DoStmt whileStmt) {
|
||||||
// TODO Auto-generated method stub
|
whileStmt.expr.accept(this);
|
||||||
|
// TODO:
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Literal literal) {
|
public void visit(Literal literal) {
|
||||||
Object value = literal.value;
|
Object value = literal.value;
|
||||||
String typeOfLiteral = resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String typeOfLiteral = getResolvedType(literal.getType());
|
||||||
if(this.isBinaryExp) {
|
// Der Wert des Literals wird auf den Stack geladen und
|
||||||
getVlaue(typeOfLiteral);
|
// geboxt, wenn es nötig ist.
|
||||||
}else {
|
loadValue(typeOfLiteral, value, false);
|
||||||
doAssign(typeOfLiteral, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unboxing: RefType -> prim
|
||||||
}
|
private void doUnboxing(String type) {
|
||||||
|
switch (type) {
|
||||||
private void getVlaue(String typeOfLiteral) {
|
|
||||||
switch (typeOfLiteral) {
|
|
||||||
case "java/lang/String":
|
case "java/lang/String":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append",
|
||||||
|
"(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Boolean":
|
case "java/lang/Boolean":
|
||||||
break;
|
break;
|
||||||
case "java/lang/Byte":
|
case "java/lang/Byte":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
|
||||||
"(B)Ljava/lang/Byte;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Short":
|
case "java/lang/Short":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
|
||||||
"(S)Ljava/lang/Short;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Integer":
|
case "java/lang/Integer":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue",
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
|
||||||
"()I", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Long":
|
case "java/lang/Long":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
|
||||||
"(J)Ljava/lang/Long;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case "java/lang/Float":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case "java/lang/Double":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Character":
|
case "java/lang/Character":
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
// mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue",
|
||||||
|
// "()I", false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doAssign(String type, Object value) {
|
private void loadValue(String type, Object value, boolean isOperator) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "java/lang/String":
|
case "java/lang/String":
|
||||||
mv.visitLdcInsn(String.valueOf(value));
|
mv.visitLdcInsn(String.valueOf(value));
|
||||||
@ -482,24 +865,16 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
break;
|
break;
|
||||||
case "java/lang/Byte":
|
case "java/lang/Byte":
|
||||||
visitByteLiteral(((Double) value).byteValue(), false);
|
visitByteLiteral(((Double) value).byteValue(), false);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf",
|
|
||||||
"(B)Ljava/lang/Byte;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Short":
|
case "java/lang/Short":
|
||||||
visitShortLiteral(((Double) value).shortValue(), false);
|
visitShortLiteral(((Double) value).shortValue(), false);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf",
|
|
||||||
"(S)Ljava/lang/Short;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Integer":
|
case "java/lang/Integer":
|
||||||
// zweite Argument isLong
|
// zweite Argument isLong
|
||||||
visitIntegerLiteral(((Double) value).intValue(), false);
|
visitIntegerLiteral(((Double) value).intValue(), false);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf",
|
|
||||||
"(I)Ljava/lang/Integer;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Long":
|
case "java/lang/Long":
|
||||||
visitLongLiteral(((Double) value).longValue(), true);
|
visitLongLiteral(((Double) value).longValue(), true);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf",
|
|
||||||
"(J)Ljava/lang/Long;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case "java/lang/Float":
|
||||||
visitFloatLiteral(((Double) value).floatValue());
|
visitFloatLiteral(((Double) value).floatValue());
|
||||||
@ -511,37 +886,50 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
visitCharLiteral((Character) value);
|
visitCharLiteral((Character) value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
// wenn die Typ des Literals = Number ist, wird integer-value
|
||||||
|
// verwendet
|
||||||
|
// visitIntegerLiteral(((Double) value).intValue(), false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Boxing
|
||||||
|
if (!type.equals("java/lang/String") && !type.equals("java/lang/Boolean")) {
|
||||||
|
if (!this.isBinaryExp && !isOperator)
|
||||||
|
doBoxing(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doAssign(String type) {
|
}
|
||||||
|
|
||||||
|
// Boxing: prim -> RefType
|
||||||
|
private void doBoxing(String type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "java/lang/String":
|
case "java/lang/String":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;",
|
||||||
|
false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Boolean":
|
case "java/lang/Boolean":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Byte":
|
case "java/lang/Byte":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
|
||||||
"(B)Ljava/lang/Byte;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Short":
|
case "java/lang/Short":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
|
||||||
"(S)Ljava/lang/Short;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Integer":
|
case "java/lang/Integer":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
|
||||||
"(I)Ljava/lang/Integer;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Long":
|
case "java/lang/Long":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
|
||||||
"(J)Ljava/lang/Long;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case "java/lang/Float":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case "java/lang/Double":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Character":
|
case "java/lang/Character":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;",
|
||||||
|
false);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -550,8 +938,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
private void visitCharLiteral(Character value) {
|
private void visitCharLiteral(Character value) {
|
||||||
mv.visitIntInsn(Opcodes.BIPUSH, (int) value);
|
mv.visitIntInsn(Opcodes.BIPUSH, (int) value);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf",
|
|
||||||
"(C)Ljava/lang/Character;", false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitDoubleLiteral(Double value) {
|
private void visitDoubleLiteral(Double value) {
|
||||||
@ -562,8 +949,6 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
} else {
|
} else {
|
||||||
mv.visitLdcInsn(value);
|
mv.visitLdcInsn(value);
|
||||||
}
|
}
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf",
|
|
||||||
"(D)Ljava/lang/Double;", false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitFloatLiteral(Float value) {
|
private void visitFloatLiteral(Float value) {
|
||||||
@ -573,8 +958,6 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
} else {
|
} else {
|
||||||
mv.visitLdcInsn(value);
|
mv.visitLdcInsn(value);
|
||||||
}
|
}
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf",
|
|
||||||
"(F)Ljava/lang/Float;", false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitLongLiteral(Long value, boolean isLong) {
|
private void visitLongLiteral(Long value, boolean isLong) {
|
||||||
@ -622,14 +1005,16 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
} else {
|
} else {
|
||||||
mv.visitInsn(Opcodes.ICONST_0);
|
mv.visitInsn(Opcodes.ICONST_0);
|
||||||
}
|
}
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf",
|
// muss noch getestet werden.
|
||||||
"(Z)Ljava/lang/Boolean;", false);
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ArgumentList argumentList) {
|
public void visit(ArgumentList argumentList) {
|
||||||
for (Expression al : argumentList.getArguments()) {
|
for (Expression al : argumentList.getArguments()) {
|
||||||
|
statement = new ArgumentExpr(al);
|
||||||
al.accept(this);
|
al.accept(this);
|
||||||
|
statement = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -651,7 +1036,14 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
public void visit(AssignToLocal assignLeftSide) {
|
public void visit(AssignToLocal assignLeftSide) {
|
||||||
if (isRightSideALambda)
|
if (isRightSideALambda)
|
||||||
varsFunInterface.add(assignLeftSide.localVar.getType());
|
varsFunInterface.add(assignLeftSide.localVar.getType());
|
||||||
paramsAndLocals.put(assignLeftSide.localVar.name, paramsAndLocals.size()+1);
|
int index = paramsAndLocals.size();
|
||||||
|
String var = assignLeftSide.localVar.name;
|
||||||
|
if (!paramsAndLocals.containsKey(var)) {
|
||||||
|
paramsAndLocals.put(var, index + 1);
|
||||||
|
} else {
|
||||||
|
paramsAndLocals.put(var, index);
|
||||||
|
}
|
||||||
|
|
||||||
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.size());
|
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.size());
|
||||||
// Debug:::
|
// Debug:::
|
||||||
|
|
||||||
|
9
src/de/dhbwstuttgart/bytecode/IStatement.java
Normal 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);
|
||||||
|
}
|
25
src/de/dhbwstuttgart/bytecode/LoopStmt.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
14
src/de/dhbwstuttgart/bytecode/ReturnStmt.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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())+ ";";
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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+";";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.*;
|
@ -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;
|
@ -1,4 +1,4 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
package de.dhbwstuttgart.bytecode.utilities;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
package de.dhbwstuttgart.bytecode.utilities;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
package de.dhbwstuttgart.bytecode.utilities;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
package de.dhbwstuttgart.bytecode.utilities;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
@ -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*/
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
}
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
21
src/de/dhbwstuttgart/typeinference/unify/model/Pair.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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 + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
BIN
target/JavaTXcompiler-0.1-jar-with-dependencies.jar
Normal file
4
target/repository/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
@ -1,8 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class ATest extends JavaTXCompilerTest {
|
|
||||||
public ATest() {
|
|
||||||
fileName = "Example";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class AssignToLitTest extends JavaTXCompilerTest {
|
|
||||||
public AssignToLitTest() {
|
|
||||||
this.fileName = "AssignToLit";
|
|
||||||
}
|
|
||||||
}
|
|
40
test/bytecode/BinaryTest.java
Normal 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class DuMethodTest extends JavaTXCompilerTest{
|
|
||||||
public DuMethodTest() {
|
|
||||||
this.fileName = "DuMethod";
|
|
||||||
}
|
|
||||||
}
|
|
44
test/bytecode/FacTest.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
import org.objectweb.asm.Opcodes;
|
|
||||||
|
|
||||||
public class ForTest extends JavaTXCompilerTest {
|
|
||||||
|
|
||||||
public ForTest() {
|
|
||||||
this.fileName = "For";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
41
test/bytecode/GenTest.java
Normal 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class Generics2Test extends JavaTXCompilerTest{
|
|
||||||
public Generics2Test() {
|
|
||||||
this.fileName = "Generics2";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class GenericsTest extends JavaTXCompilerTest {
|
|
||||||
public GenericsTest() {
|
|
||||||
this.fileName = "Generics";
|
|
||||||
}
|
|
||||||
}
|
|
140
test/bytecode/GreaterEqualTest.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
139
test/bytecode/GreaterThanTest.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class ImportTest extends JavaTXCompilerTest{
|
|
||||||
public ImportTest() {
|
|
||||||
this.fileName = "Import";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class InterfaceTest extends JavaTXCompilerTest{
|
|
||||||
public InterfaceTest() {
|
|
||||||
this.fileName = "Interface1";
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class LamAssignTest extends JavaTXCompilerTest{
|
|
||||||
public LamAssignTest() {
|
|
||||||
this.fileName = "LamAssign";
|
|
||||||
}
|
|
||||||
}
|
|
23
test/bytecode/LambdaTest.java
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
133
test/bytecode/LessEqualTest.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|