forked from JavaTX/JavaCompilerCore
Merge remote-tracking branch 'origin/bytecode2' into plugin
# Conflicts: # pom.xml # src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java # src/test/resources/testBytecode/generatedBC/.gitignore # test/bytecode/FacultyTest.java # test/bytecode/LambdaTest.java # test/bytecode/MatrixOpTest.java # test/bytecode/YTest.java
This commit is contained in:
commit
a867231348
396
pom.xml
396
pom.xml
@ -1,218 +1,188 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||||
http://maven.apache.org/maven-v4_0_0.xsd">
|
http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>de.dhbwstuttgart</groupId>
|
<groupId>de.dhbwstuttgart</groupId>
|
||||||
<artifactId>JavaTXcompiler</artifactId>
|
<artifactId>JavaTXcompiler</artifactId>
|
||||||
<version>0.1.0</version>
|
<packaging>jar</packaging>
|
||||||
<name>JavaTXcompiler</name>
|
|
||||||
<url>http://maven.apache.org</url>
|
<version>0.1</version>
|
||||||
<packaging>jar</packaging>
|
<name>JavaTXcompiler</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.antlr</groupId>
|
||||||
|
<artifactId>antlr4</artifactId>
|
||||||
|
<version>4.7</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>2.6</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>22.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.reflections</groupId>
|
||||||
|
<artifactId>reflections</artifactId>
|
||||||
|
<version>0.9.11</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.ow2.asm</groupId>
|
||||||
|
<artifactId>asm</artifactId>
|
||||||
|
<version>7.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!--
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.ow2.asm</groupId>
|
||||||
|
<artifactId>asm-all</artifactId>
|
||||||
|
<version>[4.0.0,)</version>
|
||||||
|
</dependency>
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bitbucket.mstrobel</groupId>
|
||||||
|
<artifactId>procyon-reflection</artifactId>
|
||||||
|
<version>[0.5.32,)</version>
|
||||||
|
</dependency> -->
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<build>
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<directory>target</directory>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<outputDirectory>target/classes</outputDirectory>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<finalName>${project.artifactId}-${project.version}</finalName>
|
||||||
<tycho.version>1.2.0</tycho.version>
|
<testOutputDirectory>target/test-classes</testOutputDirectory>
|
||||||
</properties>
|
<sourceDirectory>src/</sourceDirectory>
|
||||||
<distributionManagement>
|
<testSourceDirectory>test/</testSourceDirectory>
|
||||||
<repository>
|
<plugins>
|
||||||
<id>maven-repository</id>
|
<plugin>
|
||||||
<name>MyCo Internal Repository</name>
|
<groupId>org.antlr</groupId>
|
||||||
<url>file:///${project.basedir}/maven-repository/</url>
|
<artifactId>antlr4-maven-plugin</artifactId>
|
||||||
</repository>
|
<version>4.7</version>
|
||||||
</distributionManagement>
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>antlr</id>
|
||||||
|
<goals>
|
||||||
|
<goal>antlr4</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<sourceDirectory>src/de/dhbwstuttgart/parser/antlr/</sourceDirectory>
|
||||||
|
<outputDirectory>src/de/dhbwstuttgart/parser/antlr/</outputDirectory>
|
||||||
|
<arguments> <argument>-package</argument> <argument>de.dhbwstuttgart.parser.antlr</argument> </arguments>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>aspParser</id>
|
||||||
|
<goals>
|
||||||
|
<goal>antlr4</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<sourceDirectory>src/de/dhbwstuttgart/sat/asp/parser/antlr/</sourceDirectory>
|
||||||
|
<outputDirectory>src/de/dhbwstuttgart/sat/asp/parser/antlr/</outputDirectory>
|
||||||
|
<arguments>
|
||||||
|
<argument>-package</argument>
|
||||||
|
<argument>de.dhbwstuttgart.sat.asp.parser.antlr</argument>
|
||||||
|
</arguments>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
|
||||||
|
</executions>
|
||||||
<dependencies>
|
</plugin>
|
||||||
<dependency>
|
<plugin>
|
||||||
<groupId>org.antlr</groupId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
<artifactId>antlr4</artifactId>
|
<executions>
|
||||||
<version>4.7</version>
|
<execution>
|
||||||
</dependency>
|
<phase>package</phase>
|
||||||
<dependency>
|
<goals>
|
||||||
<groupId>commons-io</groupId>
|
<goal>single</goal>
|
||||||
<artifactId>commons-io</artifactId>
|
</goals>
|
||||||
<version>2.6</version>
|
</execution>
|
||||||
</dependency>
|
</executions>
|
||||||
<dependency>
|
<configuration>
|
||||||
<groupId>com.google.guava</groupId>
|
<descriptorRefs>
|
||||||
<artifactId>guava</artifactId>
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
<version>27.0.1-jre</version>
|
</descriptorRefs>
|
||||||
</dependency>
|
</configuration>
|
||||||
<dependency>
|
</plugin>
|
||||||
<groupId>org.reflections</groupId>
|
<plugin>
|
||||||
<artifactId>reflections</artifactId>
|
<groupId>org.reficio</groupId>
|
||||||
<version>0.9.11</version>
|
<artifactId>p2-maven-plugin</artifactId>
|
||||||
</dependency>
|
<version>1.1.2-SNAPSHOT</version>
|
||||||
<dependency>
|
<executions>
|
||||||
<groupId>org.ow2.asm</groupId>
|
<execution>
|
||||||
<artifactId>asm</artifactId>
|
<id>default-cli</id>
|
||||||
<version>[6.1.1,)</version>
|
<configuration>
|
||||||
</dependency>
|
<artifacts>
|
||||||
<dependency>
|
<!-- specify your depencies here -->
|
||||||
<groupId>junit</groupId>
|
<!-- groupId:artifactId:version -->
|
||||||
<artifactId>junit</artifactId>
|
<artifact>
|
||||||
<version>4.12</version>
|
<id>de.dhbwstuttgart:JavaTXcompiler:0.1</id>
|
||||||
<scope>test</scope>
|
</artifact>
|
||||||
</dependency>
|
<artifact><id>org.reflections:reflections:0.9.11</id></artifact>
|
||||||
</dependencies>
|
<artifact><id>com.google.guava:guava:22.0</id></artifact>
|
||||||
|
<artifact><id>javax.annotation:javax.annotation-api:1.3.1</id></artifact>
|
||||||
<build>
|
<artifact><id>org.glassfish:javax.annotation:3.1.1</id></artifact>
|
||||||
<directory>target</directory>
|
</artifacts>
|
||||||
<outputDirectory>target/classes</outputDirectory>
|
</configuration>
|
||||||
<finalName>${project.artifactId}-${project.version}</finalName>
|
</execution>
|
||||||
<testOutputDirectory>target/test-classes</testOutputDirectory>
|
</executions>
|
||||||
<plugins>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.eclipse.tycho</groupId>
|
||||||
<artifactId>antlr4-maven-plugin</artifactId>
|
<artifactId>tycho-p2-repository-plugin</artifactId>
|
||||||
<version>4.7</version>
|
<version>${tycho.version}</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>antlr</id>
|
<phase>package</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>antlr4</goal>
|
<goal>archive-repository</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
</execution>
|
||||||
<sourceDirectory>src/main/antlr4/java8</sourceDirectory>
|
</executions>
|
||||||
<outputDirectory>${project.basedir}/target/generated-sources/antlr4/de/dhbwstuttgart/parser/antlr</outputDirectory>
|
</plugin>
|
||||||
<arguments>
|
<plugin>
|
||||||
<argument>-package</argument>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<argument>de.dhbwstuttgart.parser.antlr</argument>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
</arguments>
|
<configuration>
|
||||||
</configuration>
|
<source>9</source>
|
||||||
</execution>
|
<target>9</target>
|
||||||
<execution>
|
</configuration>
|
||||||
<id>aspParser</id>
|
</plugin>
|
||||||
<goals>
|
</plugins>
|
||||||
<goal>antlr4</goal>
|
</build>
|
||||||
</goals>
|
<pluginRepositories>
|
||||||
<configuration>
|
<pluginRepository>
|
||||||
<sourceDirectory>src/main/antlr4/sat/</sourceDirectory>
|
<id>reficio</id>
|
||||||
<outputDirectory>${project.basedir}/target/generated-sources/antlr4/de/dhbwstuttgart/sat/asp/parser/antlr</outputDirectory>
|
<url>http://repo.reficio.org/maven/</url>
|
||||||
<arguments>
|
</pluginRepository>
|
||||||
<argument>-package</argument>
|
</pluginRepositories>
|
||||||
<argument>de.dhbwstuttgart.sat.asp.parser.antlr</argument>
|
<repositories>
|
||||||
</arguments>
|
<repository>
|
||||||
</configuration>
|
<id>maven-repository</id>
|
||||||
</execution>
|
<url>file:///${project.basedir}/target</url>
|
||||||
|
</repository>
|
||||||
</executions>
|
</repositories>
|
||||||
</plugin>
|
<properties>
|
||||||
<plugin>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<tycho.version>0.23.0</tycho.version>
|
||||||
<version>3.0.0-M1</version>
|
</properties>
|
||||||
<configuration>
|
<distributionManagement>
|
||||||
<skipTests>true</skipTests>
|
<repository>
|
||||||
</configuration>
|
<id>maven-repository</id>
|
||||||
</plugin>
|
<name>MyCo Internal Repository</name>
|
||||||
<plugin>
|
<url>file:///${project.basedir}/maven-repository/</url>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
</repository>
|
||||||
<executions>
|
</distributionManagement>
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>single</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<descriptorRefs>
|
|
||||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
|
||||||
</descriptorRefs>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-site-plugin</artifactId>
|
|
||||||
<version>3.7.1</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
|
||||||
<version>3.0.0</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.reficio</groupId>
|
|
||||||
<artifactId>p2-maven-plugin</artifactId>
|
|
||||||
<version>1.3.0</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:27.0.1-jre</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.jetty</groupId>
|
|
||||||
<artifactId>jetty-maven-plugin</artifactId>
|
|
||||||
<version>9.4.14.v20181114</version>
|
|
||||||
<configuration>
|
|
||||||
<scanIntervalSeconds>10</scanIntervalSeconds>
|
|
||||||
<webAppSourceDirectory>${basedir}/target/repository/</webAppSourceDirectory>
|
|
||||||
<webApp>
|
|
||||||
<contextPath>/site</contextPath>
|
|
||||||
</webApp>
|
|
||||||
<supportedPackagings>
|
|
||||||
<supportedPackaging>jar</supportedPackaging>
|
|
||||||
</supportedPackagings>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.eclipse.tycho</groupId>
|
|
||||||
<artifactId>tycho-p2-repository-plugin</artifactId>
|
|
||||||
<version>${tycho.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>p2:site</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>archive-repository</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<!-- plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>3.8.0</version> <configuration> <source>9</source> <target>9</target>
|
|
||||||
</configuration> </plugin -->
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
<pluginRepositories>
|
|
||||||
<pluginRepository>
|
|
||||||
<id>reficio</id>
|
|
||||||
<url>http://repo.reficio.org/maven/</url>
|
|
||||||
</pluginRepository>
|
|
||||||
<pluginRepository>
|
|
||||||
<id>repo2_maven_org</id>
|
|
||||||
<url>http://repo2.maven.org/maven2</url>
|
|
||||||
</pluginRepository>
|
|
||||||
</pluginRepositories>
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>maven-repository</id>
|
|
||||||
<url>file:///${project.basedir}/target</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
</project>
|
</project>
|
||||||
|
78
src/de/dhbwstuttgart/bytecode/TPHExtractor.java
Normal file
78
src/de/dhbwstuttgart/bytecode/TPHExtractor.java
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fayez Abu Alia
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TPHExtractor extends AbstractASTWalker{
|
||||||
|
// Alle TPHs der Felder werden iKopf der Klasse definiert
|
||||||
|
// alle TPHs der Klasse: (TPH, is in Method?)
|
||||||
|
final HashMap<TypePlaceholder,Boolean> allTPHS = new HashMap<>();
|
||||||
|
MethodAndTPH methodAndTph;
|
||||||
|
Boolean inMethod = false;
|
||||||
|
public final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
|
||||||
|
final ArrayList<GenericInsertPair> allPairs = new ArrayList<>();
|
||||||
|
public final ArrayList<TPHConstraint> allCons = new ArrayList<>();
|
||||||
|
private ResultSet resultSet;
|
||||||
|
|
||||||
|
public TPHExtractor() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultSet(ResultSet resultSet) {
|
||||||
|
this.resultSet = resultSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(TypePlaceholder tph) {
|
||||||
|
if(resultSet.resolveType(tph).resolvedType instanceof TypePlaceholder) {
|
||||||
|
TypePlaceholder resolvedTPH = (TypePlaceholder) resultSet.resolveType(tph).resolvedType;
|
||||||
|
if(inMethod)
|
||||||
|
methodAndTph.getTphs().add(resolvedTPH.getName());
|
||||||
|
|
||||||
|
allTPHS.put(resolvedTPH,inMethod);
|
||||||
|
resultSet.resolveType(tph).additionalGenerics.forEach(ag ->{
|
||||||
|
if(ag.contains(resolvedTPH)&&ag.TA1.equals(resolvedTPH)&&!contains(allPairs,ag)) {
|
||||||
|
if(inMethod)
|
||||||
|
methodAndTph.getPairs().add(ag);
|
||||||
|
allPairs.add(ag);
|
||||||
|
TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
|
||||||
|
allCons.add(con);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
|
||||||
|
for(int i=0; i<pairs.size();++i) {
|
||||||
|
GenericInsertPair p = pairs.get(i);
|
||||||
|
if(p.TA1.equals(genPair.TA1) && p.TA2.equals(genPair.TA2))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void visit(Method method) {
|
||||||
|
inMethod = true;
|
||||||
|
methodAndTph = new MethodAndTPH(method.name);
|
||||||
|
super.visit(method);
|
||||||
|
inMethod = false;
|
||||||
|
ListOfMethodsAndTph.add(methodAndTph);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,6 +6,7 @@ import java.util.HashSet;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
@ -46,7 +47,8 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
ClassWriter cw =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
|
ClassWriter cw =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
|
||||||
|
|
||||||
String type;
|
String type;
|
||||||
|
|
||||||
|
public static RefTypeOrTPHOrWildcardOrGeneric THISTYPE = null;
|
||||||
String className;
|
String className;
|
||||||
private boolean isInterface;
|
private boolean isInterface;
|
||||||
private List<ResultSet> listOfResultSets;
|
private List<ResultSet> listOfResultSets;
|
||||||
@ -54,6 +56,8 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
private SourceFile sf;
|
private SourceFile sf;
|
||||||
private String path;
|
private String path;
|
||||||
|
|
||||||
|
private Optional<Constructor> fieldInitializations;
|
||||||
|
|
||||||
private int indexOfFirstParam = 0;
|
private int indexOfFirstParam = 0;
|
||||||
|
|
||||||
private String superClass;
|
private String superClass;
|
||||||
@ -118,6 +122,7 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
|
|
||||||
int acc = isInterface?classOrInterface.getModifiers()+Opcodes.ACC_ABSTRACT:classOrInterface.getModifiers()+Opcodes.ACC_SUPER;
|
int acc = isInterface?classOrInterface.getModifiers()+Opcodes.ACC_ABSTRACT:classOrInterface.getModifiers()+Opcodes.ACC_SUPER;
|
||||||
|
|
||||||
|
fieldInitializations = classOrInterface.getfieldInitializations();
|
||||||
|
|
||||||
// resultSet = listOfResultSets.get(0);
|
// resultSet = listOfResultSets.get(0);
|
||||||
boolean isConsWithNoParamsVisited = false;
|
boolean isConsWithNoParamsVisited = false;
|
||||||
@ -125,6 +130,7 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
for(ResultSet rs : listOfResultSets) {
|
for(ResultSet rs : listOfResultSets) {
|
||||||
superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor());
|
superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor());
|
||||||
resultSet = rs;
|
resultSet = rs;
|
||||||
|
tphExtractor.setResultSet(resultSet);
|
||||||
// Nur einmal ausführen!!
|
// Nur einmal ausführen!!
|
||||||
if(!isVisited) {
|
if(!isVisited) {
|
||||||
classOrInterface.accept(tphExtractor);
|
classOrInterface.accept(tphExtractor);
|
||||||
@ -154,10 +160,12 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(Constructor c : classOrInterface.getConstructors()) {
|
for(Constructor c : classOrInterface.getConstructors()) {
|
||||||
if(!isConsWithNoParamsVisited)
|
// if(!isConsWithNoParamsVisited) {
|
||||||
c.accept(this);
|
c.accept(this);
|
||||||
if(!c.getParameterList().iterator().hasNext())
|
// }
|
||||||
isConsWithNoParamsVisited = true;
|
|
||||||
|
// if(!c.getParameterList().iterator().hasNext())
|
||||||
|
// isConsWithNoParamsVisited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Method m : classOrInterface.getMethods()) {
|
for(Method m : classOrInterface.getMethods()) {
|
||||||
@ -192,7 +200,7 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
field.getParameterList().accept(this);
|
field.getParameterList().accept(this);
|
||||||
|
|
||||||
String methParamTypes = field.name+"%%";
|
String methParamTypes = field.name+"%%";
|
||||||
|
|
||||||
Iterator<FormalParameter> itr = field.getParameterList().iterator();
|
Iterator<FormalParameter> itr = field.getParameterList().iterator();
|
||||||
while(itr.hasNext()) {
|
while(itr.hasNext()) {
|
||||||
FormalParameter fp = itr.next();
|
FormalParameter fp = itr.next();
|
||||||
@ -201,6 +209,7 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(methodNameAndParamsT.contains(methParamTypes)) {
|
if(methodNameAndParamsT.contains(methParamTypes)) {
|
||||||
|
System.out.println("ignore - Method: "+field.name +" , paramsType: "+methParamTypes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
methodNameAndParamsT.add(methParamTypes);
|
methodNameAndParamsT.add(methParamTypes);
|
||||||
@ -223,13 +232,18 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
|
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
|
||||||
sig = signature.toString();
|
sig = signature.toString();
|
||||||
}
|
}
|
||||||
|
if(field.getParameterList().iterator().hasNext())
|
||||||
|
System.out.println(field.getParameterList().iterator().next().getType().acceptTV(new TypeToDescriptor()));
|
||||||
|
|
||||||
NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen);
|
NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen);
|
||||||
desc = constructor.accept(new DescriptorToString(resultSet));
|
desc = constructor.accept(new DescriptorToString(resultSet));
|
||||||
|
System.out.println("Constructor: " + field.getName() + " Sig: "+ sig + " Desc: " + desc);
|
||||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc, sig, null);
|
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc, sig, null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
Block block = fieldInitializations.get().block;
|
||||||
BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,field, mv,paramsAndLocals,cw,
|
BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,field, mv,paramsAndLocals,cw,
|
||||||
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles, sf,path);
|
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles, sf,path, block);
|
||||||
if(!field.getParameterList().iterator().hasNext()) {
|
if(!field.getParameterList().iterator().hasNext() && !(field.block.statements.get(field.block.statements.size()-1) instanceof ReturnVoid)) {
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
}
|
}
|
||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
@ -558,52 +572,5 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TPHExtractor extends AbstractASTWalker{
|
|
||||||
// Alle TPHs der Felder werden iKopf der Klasse definiert
|
|
||||||
// alle TPHs der Klasse: (TPH, is in Method?)
|
|
||||||
final HashMap<TypePlaceholder,Boolean> allTPHS = new HashMap<>();
|
|
||||||
MethodAndTPH methodAndTph;
|
|
||||||
Boolean inMethod = false;
|
|
||||||
public final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
|
|
||||||
final ArrayList<GenericInsertPair> allPairs = new ArrayList<>();
|
|
||||||
public final ArrayList<TPHConstraint> allCons = new ArrayList<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(TypePlaceholder tph) {
|
|
||||||
if(resultSet.resolveType(tph).resolvedType instanceof TypePlaceholder) {
|
|
||||||
TypePlaceholder resolvedTPH = (TypePlaceholder) resultSet.resolveType(tph).resolvedType;
|
|
||||||
if(inMethod)
|
|
||||||
methodAndTph.getTphs().add(resolvedTPH);
|
|
||||||
|
|
||||||
allTPHS.put(resolvedTPH,inMethod);
|
|
||||||
resultSet.resolveType(tph).additionalGenerics.forEach(ag ->{
|
|
||||||
if(ag.contains(resolvedTPH)&&ag.TA1.equals(resolvedTPH)&&!contains(allPairs,ag)) {
|
|
||||||
if(inMethod)
|
|
||||||
methodAndTph.getPairs().add(ag);
|
|
||||||
allPairs.add(ag);
|
|
||||||
TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
|
|
||||||
allCons.add(con);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
|
|
||||||
for(int i=0; i<pairs.size();++i) {
|
|
||||||
GenericInsertPair p = pairs.get(i);
|
|
||||||
if(p.TA1.equals(genPair.TA1) && p.TA2.equals(genPair.TA2))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void visit(Method method) {
|
|
||||||
inMethod = true;
|
|
||||||
methodAndTph = new MethodAndTPH(method.name);
|
|
||||||
super.visit(method);
|
|
||||||
inMethod = false;
|
|
||||||
ListOfMethodsAndTph.add(methodAndTph);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,8 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
private boolean needDUP = false;
|
private boolean needDUP = false;
|
||||||
|
|
||||||
|
private Block blockFieldInit = null;
|
||||||
|
private boolean isBlockFieldInitVisited = false;
|
||||||
// for tests **
|
// for tests **
|
||||||
private String fieldName;
|
private String fieldName;
|
||||||
private String fieldDesc;
|
private String fieldDesc;
|
||||||
@ -85,7 +87,32 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
private HashMap<String, byte[]> classFiles;
|
private HashMap<String, byte[]> classFiles;
|
||||||
|
|
||||||
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface = new ArrayList<>();;
|
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface = new ArrayList<>();;
|
||||||
|
// generate bytecode for constructor
|
||||||
|
public BytecodeGenMethod(String className, String superClass,ResultSet resultSet, Method m, MethodVisitor mv,
|
||||||
|
HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod,
|
||||||
|
HashMap<String, String> genericsAndBounds, boolean isInterface, HashMap<String, byte[]> classFiles,
|
||||||
|
SourceFile sf,String path, Block block) {
|
||||||
|
|
||||||
|
this.className = className;
|
||||||
|
this.superClass = superClass;
|
||||||
|
this.resultSet = resultSet;
|
||||||
|
this.m = m;
|
||||||
|
this.mv = mv;
|
||||||
|
this.paramsAndLocals = paramsAndLocals;
|
||||||
|
this.cw = cw;
|
||||||
|
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
|
||||||
|
this.genericsAndBounds = genericsAndBounds;
|
||||||
|
this.isInterface = isInterface;
|
||||||
|
this.classFiles = classFiles;
|
||||||
|
this.sf = sf;
|
||||||
|
this.path = path;
|
||||||
|
if(block != null)
|
||||||
|
this.blockFieldInit = block;
|
||||||
|
this.m.block.accept(this);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public BytecodeGenMethod(String className, String superClass,ResultSet resultSet, Method m, MethodVisitor mv,
|
public BytecodeGenMethod(String className, String superClass,ResultSet resultSet, Method m, MethodVisitor mv,
|
||||||
HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod,
|
HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod,
|
||||||
HashMap<String, String> genericsAndBounds, boolean isInterface, HashMap<String, byte[]> classFiles, SourceFile sf,String path) {
|
HashMap<String, String> genericsAndBounds, boolean isInterface, HashMap<String, byte[]> classFiles, SourceFile sf,String path) {
|
||||||
@ -109,8 +136,8 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BytecodeGenMethod(LambdaExpression lambdaExpression, ResultSet resultSet, MethodVisitor mv,
|
public BytecodeGenMethod(LambdaExpression lambdaExpression, ArrayList<String> usedVars, ResultSet resultSet, MethodVisitor mv,
|
||||||
int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles, String path, int lamCounter) {
|
int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles, String path, int lamCounter, SourceFile sf) {
|
||||||
|
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
this.mv = mv;
|
this.mv = mv;
|
||||||
@ -118,8 +145,15 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
this.classFiles = classFiles;
|
this.classFiles = classFiles;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.lamCounter = lamCounter;
|
this.lamCounter = lamCounter;
|
||||||
|
this.sf = sf;
|
||||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||||
int i = indexOfFirstParamLam;
|
int i = indexOfFirstParamLam;
|
||||||
|
|
||||||
|
for(String var : usedVars) {
|
||||||
|
this.paramsAndLocals.put(var, i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
FormalParameter fp = itr.next();
|
FormalParameter fp = itr.next();
|
||||||
this.paramsAndLocals.put(fp.getName(), i);
|
this.paramsAndLocals.put(fp.getName(), i);
|
||||||
@ -154,6 +188,17 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
superCall.arglist.accept(this);
|
superCall.arglist.accept(this);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, this.superClass, superCall.name, "()V",
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, this.superClass, superCall.name, "()V",
|
||||||
isInterface);
|
isInterface);
|
||||||
|
|
||||||
|
if(blockFieldInit!=null && !isBlockFieldInitVisited) {
|
||||||
|
isBlockFieldInitVisited =true;
|
||||||
|
//blockFieldInit.accept(this);
|
||||||
|
for(Statement stmt : blockFieldInit.statements) {
|
||||||
|
if(stmt instanceof SuperCall)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
stmt.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ??
|
// ??
|
||||||
@ -378,6 +423,12 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
case BIGGEREQUAL:
|
case BIGGEREQUAL:
|
||||||
mv.visitJumpInsn(Opcodes.IF_ICMPLT, branchLabel);
|
mv.visitJumpInsn(Opcodes.IF_ICMPLT, branchLabel);
|
||||||
break;
|
break;
|
||||||
|
case EQUAL:
|
||||||
|
mv.visitJumpInsn(Opcodes.IF_ICMPNE, branchLabel);
|
||||||
|
break;
|
||||||
|
case NOTEQUAL:
|
||||||
|
mv.visitJumpInsn(Opcodes.IFEQ, branchLabel);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -403,6 +454,12 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
case BIGGEREQUAL:
|
case BIGGEREQUAL:
|
||||||
mv.visitJumpInsn(Opcodes.IFLT, branchLabel);
|
mv.visitJumpInsn(Opcodes.IFLT, branchLabel);
|
||||||
break;
|
break;
|
||||||
|
case EQUAL:
|
||||||
|
mv.visitJumpInsn(Opcodes.IFNE, branchLabel);
|
||||||
|
break;
|
||||||
|
case NOTEQUAL:
|
||||||
|
mv.visitJumpInsn(Opcodes.IFEQ, branchLabel);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -507,7 +564,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(LambdaExpression lambdaExpression) {
|
public void visit(LambdaExpression lambdaExpression) {
|
||||||
this.lamCounter++;
|
this.lamCounter++;
|
||||||
|
|
||||||
String typeErasure = "(";
|
String typeErasure = "(";
|
||||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
@ -547,16 +604,31 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
this.kindOfLambda = new KindOfLambda(lambdaExpression);
|
this.kindOfLambda = new KindOfLambda(lambdaExpression);
|
||||||
|
|
||||||
if (kindOfLambda.isInstanceCapturingLambda()) {
|
if (kindOfLambda.isInstanceCapturingLambda()) {
|
||||||
|
// if(!kindOfLambda.getArgumentList().contains(BytecodeGen.THISTYPE))
|
||||||
|
// kindOfLambda.getArgumentList().add(0, BytecodeGen.THISTYPE);
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||||
|
for(String v : kindOfLambda.getUsedVars()) {
|
||||||
|
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(v));
|
||||||
|
}
|
||||||
staticOrSpecial = Opcodes.H_INVOKESPECIAL;
|
staticOrSpecial = Opcodes.H_INVOKESPECIAL;
|
||||||
indexOfFirstParamLam = 1;
|
indexOfFirstParamLam = 1;
|
||||||
} else {
|
} else {
|
||||||
staticOrSpecial = Opcodes.H_INVOKESTATIC;
|
staticOrSpecial = Opcodes.H_INVOKESTATIC;
|
||||||
staticOrInstance = Opcodes.ACC_STATIC;
|
staticOrInstance = Opcodes.ACC_STATIC;
|
||||||
}
|
}
|
||||||
|
String newDesc = "(";
|
||||||
|
int pos = 0;
|
||||||
|
if(kindOfLambda.isHasThis()) {
|
||||||
|
pos = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=pos;i<kindOfLambda.getArgumentList().size();i++) {
|
||||||
|
String t = "L" + getResolvedType(kindOfLambda.getArgumentList().get(i)) + ";";
|
||||||
|
newDesc += t;
|
||||||
|
}
|
||||||
|
newDesc += lamDesc.substring(1);
|
||||||
// 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, arg3.toString(), false);
|
Handle arg2 = new Handle(staticOrSpecial, this.className, methodName, newDesc, 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
|
||||||
@ -564,10 +636,12 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, arg1, arg2, arg3);
|
mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, arg1, arg2, arg3);
|
||||||
|
|
||||||
MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE + staticOrInstance + Opcodes.ACC_SYNTHETIC,
|
MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE + staticOrInstance + Opcodes.ACC_SYNTHETIC,
|
||||||
methodName, arg3.toString(), null, null);
|
methodName, newDesc, null, null);
|
||||||
|
|
||||||
new BytecodeGenMethod(lambdaExpression, this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface,
|
ArrayList<String> usedVars = kindOfLambda.getUsedVars();
|
||||||
classFiles,this.path, lamCounter);
|
|
||||||
|
new BytecodeGenMethod(lambdaExpression, usedVars,this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface,
|
||||||
|
classFiles,this.path, lamCounter, sf);
|
||||||
|
|
||||||
mvLambdaBody.visitMaxs(0, 0);
|
mvLambdaBody.visitMaxs(0, 0);
|
||||||
mvLambdaBody.visitEnd();
|
mvLambdaBody.visitEnd();
|
||||||
@ -641,7 +715,10 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
if (!fieldVar.receiver.getClass().equals(StaticClassName.class)) {
|
if (!fieldVar.receiver.getClass().equals(StaticClassName.class)) {
|
||||||
mv.visitFieldInsn(Opcodes.GETFIELD, getResolvedType(fieldVar.receiver.getType()), fieldName, fieldDesc);
|
mv.visitFieldInsn(Opcodes.GETFIELD, getResolvedType(fieldVar.receiver.getType()), fieldName, fieldDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isBinaryExp) {
|
||||||
|
doUnboxing(getResolvedType(fieldVar.getType()));
|
||||||
|
}
|
||||||
// mv.visitFieldInsn(Opcodes.GETSTATIC,
|
// mv.visitFieldInsn(Opcodes.GETSTATIC,
|
||||||
// fieldVar.receiver.getType().toString().replace(".", "/"),
|
// fieldVar.receiver.getType().toString().replace(".", "/"),
|
||||||
// fieldVar.fieldVarName, fieldVar.getType().toString());
|
// fieldVar.fieldVarName, fieldVar.getType().toString());
|
||||||
@ -794,10 +871,12 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
if(methodRefl != null && !methodRefl.getReturnType().isPrimitive()) {
|
if(methodRefl != null && !methodRefl.getReturnType().isPrimitive()) {
|
||||||
if(methodRefl.getReturnType().equals(Object.class)) {
|
if(methodRefl.getReturnType().equals(Object.class)) {
|
||||||
String checkCast = getResolvedType(methodCall.getType());
|
String checkCast = getResolvedType(methodCall.getType());
|
||||||
int pos = checkCast.length();
|
if(!checkCast.contains("TPH ")) {
|
||||||
if(checkCast.contains("<"))
|
int pos = checkCast.length();
|
||||||
pos = checkCast.indexOf("<");
|
if(checkCast.contains("<"))
|
||||||
mv.visitTypeInsn(Opcodes.CHECKCAST,checkCast.substring(0,pos));
|
pos = checkCast.indexOf("<");
|
||||||
|
mv.visitTypeInsn(Opcodes.CHECKCAST,checkCast.substring(0,pos));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(isBinaryExp)
|
if(isBinaryExp)
|
||||||
doUnboxing(getResolvedType(methodCall.getType()));
|
doUnboxing(getResolvedType(methodCall.getType()));
|
||||||
@ -850,11 +929,13 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
// methCallType = "L"+methCallType+";";
|
// methCallType = "L"+methCallType+";";
|
||||||
// }
|
// }
|
||||||
for(java.lang.reflect.Method m : methods) {
|
for(java.lang.reflect.Method m : methods) {
|
||||||
if(name.equals(m.getName()) && i == m.getParameterCount() && methCallType.equals(m.getReturnType().getName().replace(".", "/"))) {
|
if(name.equals(m.getName()) && i == m.getParameterCount() &&
|
||||||
|
(methCallType.equals(m.getReturnType().getName().replace(".", "/")) ||
|
||||||
|
m.getReturnType().getName().replace(".", "/").equals(Type.getInternalName(Object.class)))) {
|
||||||
boolean typesEqual = true;
|
boolean typesEqual = true;
|
||||||
Class<?>[] pTypes = m.getParameterTypes();
|
Class<?>[] pTypes = m.getParameterTypes();
|
||||||
for(int j = 0; j<typesOfParams.length; ++j) {
|
for(int j = 0; j<typesOfParams.length; ++j) {
|
||||||
if(!typesOfParams[j].equals(pTypes[j])) {
|
if(!typesOfParams[j].equals(pTypes[j].getName().replaceAll(".", "/")) && !pTypes[j].getName().replace(".", "/").equals(Type.getInternalName(Object.class))) {
|
||||||
typesEqual = false;
|
typesEqual = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1064,6 +1145,10 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(This aThis) {
|
public void visit(This aThis) {
|
||||||
|
|
||||||
|
if(BytecodeGen.THISTYPE == null)
|
||||||
|
BytecodeGen.THISTYPE = aThis.getType();
|
||||||
|
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ import de.dhbwstuttgart.syntaxtree.Constructor;
|
|||||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
@ -331,14 +332,16 @@ public class Signature {
|
|||||||
|
|
||||||
case "EWC":
|
case "EWC":
|
||||||
System.out.println("EWC---Signature");
|
System.out.println("EWC---Signature");
|
||||||
SuperWildcardType ewc = (SuperWildcardType) t;
|
ExtendsWildcardType ewc = (ExtendsWildcardType) t;
|
||||||
String esigInner = ewc.getInnerType().acceptTV(new TypeToSignature());
|
String esigInner = ewc.getInnerType().acceptTV(new TypeToSignature());
|
||||||
|
System.out.println(esigInner);
|
||||||
if(ewc.getInnerType() instanceof TypePlaceholder) {
|
if(ewc.getInnerType() instanceof TypePlaceholder) {
|
||||||
sv.visitTypeArgument('+').visitTypeVariable(esigInner.substring(1, esigInner.length()));
|
sv.visitTypeArgument('+').visitTypeVariable(esigInner.substring(1, esigInner.length()));
|
||||||
} else if(ewc.getInnerType() instanceof RefType) {
|
} else if(ewc.getInnerType() instanceof RefType) {
|
||||||
if(esigInner.contains("$$")) {
|
if(esigInner.contains("$$")) {
|
||||||
sv.visitTypeArgument('+').visitInterface().visitClassType(esigInner.substring(1,esigInner.length()));
|
sv.visitTypeArgument('+').visitInterface().visitClassType(esigInner.substring(1,esigInner.length()));
|
||||||
}else {
|
}else {
|
||||||
|
// sv.visitClassType(esigInner.substring(1,esigInner.length()));
|
||||||
sv.visitTypeArgument('+').visitClassType(esigInner.substring(1,esigInner.length()));
|
sv.visitTypeArgument('+').visitClassType(esigInner.substring(1,esigInner.length()));
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
|
@ -4,22 +4,34 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
|
|||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
||||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
|
|
||||||
public class KindOfLambda implements StatementVisitor{
|
public class KindOfLambda implements StatementVisitor{
|
||||||
|
private ParameterList params;
|
||||||
private boolean isInstanceCapturingLambda = false;
|
private boolean isInstanceCapturingLambda = false;
|
||||||
private List<RefTypeOrTPHOrWildcardOrGeneric> argumentList = new ArrayList<>();
|
private List<RefTypeOrTPHOrWildcardOrGeneric> argumentList = new ArrayList<>();
|
||||||
|
private ArrayList<String> usedVars = new ArrayList<>();
|
||||||
|
private boolean hasThis = false;
|
||||||
|
private ArrayList<String> definedLocals = new ArrayList<>();
|
||||||
|
|
||||||
public KindOfLambda(LambdaExpression lambdaExpression) {
|
public KindOfLambda(LambdaExpression lambdaExpression) {
|
||||||
|
this.params = lambdaExpression.params;
|
||||||
lambdaExpression.methodBody.accept(this);
|
lambdaExpression.methodBody.accept(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ArrayList<String> getUsedVars() {
|
||||||
|
return usedVars;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isInstanceCapturingLambda() {
|
public boolean isInstanceCapturingLambda() {
|
||||||
return this.isInstanceCapturingLambda;
|
return this.isInstanceCapturingLambda;
|
||||||
}
|
}
|
||||||
@ -28,6 +40,10 @@ public class KindOfLambda implements StatementVisitor{
|
|||||||
return argumentList;
|
return argumentList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isHasThis() {
|
||||||
|
return hasThis;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ArgumentList argumentList) {
|
public void visit(ArgumentList argumentList) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
@ -95,14 +111,31 @@ public class KindOfLambda implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVar localVar) {
|
public void visit(LocalVar localVar) {
|
||||||
// TODO Auto-generated method stub
|
if(!contain(params, localVar.name) && !definedLocals.contains(localVar.name)) {
|
||||||
|
argumentList.add(localVar.getType());
|
||||||
|
if(hasThis) {
|
||||||
|
usedVars.add(1, localVar.name);
|
||||||
|
} else {
|
||||||
|
usedVars.add(0, localVar.name);
|
||||||
|
}
|
||||||
|
if(!isInstanceCapturingLambda)
|
||||||
|
isInstanceCapturingLambda=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean contain(ParameterList params2, String name) {
|
||||||
|
Iterator<FormalParameter> itr = params2.iterator();
|
||||||
|
while(itr.hasNext()) {
|
||||||
|
FormalParameter fp = itr.next();
|
||||||
|
if(fp.getName().equals(name))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVarDecl localVarDecl) {
|
public void visit(LocalVarDecl localVarDecl) {
|
||||||
// TODO Auto-generated method stub
|
definedLocals.add(localVarDecl.getName());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -157,9 +190,13 @@ public class KindOfLambda implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(This aThis) {
|
public void visit(This aThis) {
|
||||||
|
if(!hasThis) {
|
||||||
|
hasThis = true;
|
||||||
|
this.argumentList.add(0,aThis.getType());
|
||||||
|
}
|
||||||
if(!isInstanceCapturingLambda) {
|
if(!isInstanceCapturingLambda) {
|
||||||
this.isInstanceCapturingLambda = true;
|
this.isInstanceCapturingLambda = true;
|
||||||
this.argumentList.add(aThis.getType());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,14 +8,14 @@ import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
|
|||||||
public class MethodAndTPH {
|
public class MethodAndTPH {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private final ArrayList<TypePlaceholder> tphs = new ArrayList<>();
|
private final ArrayList<String> tphs = new ArrayList<>();
|
||||||
private final ArrayList<GenericInsertPair> pairs = new ArrayList<>();
|
private final ArrayList<GenericInsertPair> pairs = new ArrayList<>();
|
||||||
|
|
||||||
public MethodAndTPH(String name) {
|
public MethodAndTPH(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<TypePlaceholder> getTphs() {
|
public ArrayList<String> getTphs() {
|
||||||
return tphs;
|
return tphs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import java.util.LinkedList;
|
|||||||
|
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.BytecodeGen.TPHExtractor;
|
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||||
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
@ -16,7 +16,7 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
|||||||
public class Simplify {
|
public class Simplify {
|
||||||
|
|
||||||
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor) {
|
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor) {
|
||||||
// 1. check if there are any cycles like L<R and R<L:
|
// 1. check if there are any simple cycles like L<R and R<L:
|
||||||
// a) yes => set L=R and:
|
// a) yes => set L=R and:
|
||||||
// * remove both constraints
|
// * remove both constraints
|
||||||
// * substitute L with R in all constraint
|
// * substitute L with R in all constraint
|
||||||
@ -28,8 +28,10 @@ public class Simplify {
|
|||||||
// b) no
|
// b) no
|
||||||
// 3. is
|
// 3. is
|
||||||
|
|
||||||
|
// all constraints that will be simplified
|
||||||
ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
|
ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
|
||||||
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
|
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
|
||||||
|
|
||||||
// step 1:
|
// step 1:
|
||||||
for(TPHConstraint c : allCons) {
|
for(TPHConstraint c : allCons) {
|
||||||
|
|
||||||
@ -39,12 +41,16 @@ public class Simplify {
|
|||||||
TPHConstraint revCon = getReverseConstraint(allCons,left,right);
|
TPHConstraint revCon = getReverseConstraint(allCons,left,right);
|
||||||
if(revCon != null) {
|
if(revCon != null) {
|
||||||
revCon.setRel(Relation.EQUAL);
|
revCon.setRel(Relation.EQUAL);
|
||||||
|
// the reverse constraint is removed because
|
||||||
|
// otherwise there is twice the same constraint
|
||||||
|
// (e.g. A<B and B<A => A=B and B=A)
|
||||||
consToRemove.add(revCon);
|
consToRemove.add(revCon);
|
||||||
c.setRel(Relation.EQUAL);
|
c.setRel(Relation.EQUAL);
|
||||||
substituteTPH(allCons,left, right);
|
substituteTPH(allCons,left, right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println();
|
System.out.println();
|
||||||
System.out.println("NEW ALL CONST: " + allCons.size());
|
System.out.println("NEW ALL CONST: " + allCons.size());
|
||||||
allCons.forEach(c->System.out.println(c.toString()));
|
allCons.forEach(c->System.out.println(c.toString()));
|
||||||
@ -59,17 +65,99 @@ public class Simplify {
|
|||||||
System.out.println("----------------");
|
System.out.println("----------------");
|
||||||
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||||
|
|
||||||
|
// check if there is any long cycle (e.g. A<B<C<A)
|
||||||
|
|
||||||
|
// to save all types that are in relation
|
||||||
|
LinkedList<String> allTypes = new LinkedList<>();
|
||||||
|
// we will put all constraints which are in the cycle, in this ArrayList.
|
||||||
|
// Later these contraints will be converted to equal-constraints
|
||||||
|
ArrayList<TPHConstraint> constraints = new ArrayList<>(size);
|
||||||
|
int visited = 0;
|
||||||
|
|
||||||
|
// contains all constraints
|
||||||
|
HashMap<String,String> ss1 = new HashMap<>();
|
||||||
|
|
||||||
|
for(TPHConstraint constr : allCons) {
|
||||||
|
ss1.put(constr.getLeft(), constr.getRight());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
|
||||||
|
if(visited >= size)
|
||||||
|
break;
|
||||||
|
// Only extends-constraints will be checked
|
||||||
|
if(c.getRel() == Relation.EXTENDS) {
|
||||||
|
++visited;
|
||||||
|
|
||||||
|
String left = c.getLeft();
|
||||||
|
String right = c.getRight();
|
||||||
|
// put the types in linked list
|
||||||
|
allTypes.add(left);
|
||||||
|
allTypes.add(right);
|
||||||
|
|
||||||
|
constraints.add(c);
|
||||||
|
|
||||||
|
boolean isCycle = false;
|
||||||
|
|
||||||
|
// iterate through the map to check if there is a cycle
|
||||||
|
while(ss1.containsKey(right)) {
|
||||||
|
++visited;
|
||||||
|
String oldRight = right;
|
||||||
|
right = ss1.get(right);
|
||||||
|
|
||||||
|
TPHConstraint toAdd = getConstraint(oldRight, right, allCons);
|
||||||
|
|
||||||
|
if(toAdd != null)
|
||||||
|
constraints.add(toAdd);
|
||||||
|
|
||||||
|
if(left.equals(right)) {
|
||||||
|
isCycle = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
allTypes.add(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isCycle) {
|
||||||
|
// convert all constraints to equal constraints
|
||||||
|
setAllEqual(constraints);
|
||||||
|
// these constraints will be removed from allCons
|
||||||
|
consToRemove.addAll(constraints);
|
||||||
|
// all equal types will be substitute with one type
|
||||||
|
substituteAllTPH(allCons,constraints,left);
|
||||||
|
|
||||||
|
HashSet<String> eq = new HashSet<>();
|
||||||
|
// put all equal types in a set
|
||||||
|
for(String t:allTypes) {
|
||||||
|
eq.add(t);
|
||||||
|
}
|
||||||
|
// generate a new constraint (left < Object)
|
||||||
|
TPHConstraint constraint = new ExtendsConstraint(left, Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||||
|
// put the generated constraint and its equal set into result set
|
||||||
|
result.put(constraint, eq);
|
||||||
|
constraints.clear();
|
||||||
|
}
|
||||||
|
allTypes.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// build an equal set that contains all types
|
||||||
|
// which are equal and for each equal constraint put left side and right side
|
||||||
|
// in this set Then generate a constraint type < Object and put it
|
||||||
|
// with the equal set into the result.
|
||||||
for(TPHConstraint c : allCons) {
|
for(TPHConstraint c : allCons) {
|
||||||
if(c.getRel()==Relation.EQUAL) {
|
if(c.getRel()==Relation.EQUAL) {
|
||||||
HashSet<String> equalTPHs = getEqualsTPHs(result, c);
|
if(!isTPHInResEqual(result, c.getLeft())) {
|
||||||
TPHConstraint constraint = getKeyConstraint(result,c);
|
HashSet<String> equalTPHs = getEqualsTPHs(result, c);
|
||||||
equalTPHs.add(c.getLeft());
|
TPHConstraint constraint = getKeyConstraint(result,c);
|
||||||
equalTPHs.add(c.getRight());
|
equalTPHs.add(c.getLeft());
|
||||||
result.put(constraint, equalTPHs);
|
equalTPHs.add(c.getRight());
|
||||||
|
result.put(constraint, equalTPHs);
|
||||||
|
}
|
||||||
consToRemove.add(c);
|
consToRemove.add(c);
|
||||||
size--;
|
size--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Step 2 Result: ");
|
System.out.println("Step 2 Result: ");
|
||||||
result.forEach((c,hs)->{
|
result.forEach((c,hs)->{
|
||||||
System.out.print(c.toString() + " -> ");
|
System.out.print(c.toString() + " -> ");
|
||||||
@ -79,7 +167,9 @@ public class Simplify {
|
|||||||
System.out.println();
|
System.out.println();
|
||||||
});
|
});
|
||||||
System.out.println("----------------");
|
System.out.println("----------------");
|
||||||
|
// remove all equal-constraints
|
||||||
allCons.removeAll(consToRemove);
|
allCons.removeAll(consToRemove);
|
||||||
|
// add all generated constraints to allCons
|
||||||
allCons.addAll(result.keySet());
|
allCons.addAll(result.keySet());
|
||||||
|
|
||||||
if(!allCons.isEmpty() && allCons.size()<2) {
|
if(!allCons.isEmpty() && allCons.size()<2) {
|
||||||
@ -91,19 +181,23 @@ public class Simplify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size += result.keySet().size();
|
size += result.keySet().size();
|
||||||
|
// all constraints which have Object on the right side will
|
||||||
|
// be ignored, because they are simplified and can not be changed.
|
||||||
for(TPHConstraint c : allCons) {
|
for(TPHConstraint c : allCons) {
|
||||||
if(c.getRight().equals(Type.getInternalName(Object.class)))
|
if(c.getRight().equals(Type.getInternalName(Object.class)))
|
||||||
size--;
|
size--;
|
||||||
}
|
}
|
||||||
ArrayList<TypePlaceholder> methodTphs = new ArrayList<>();
|
// get all tph of the method
|
||||||
|
ArrayList<String> methodTphs = new ArrayList<>();
|
||||||
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
|
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
|
||||||
if(m.getName().equals(name)) {
|
if(m.getName().equals(name)) {
|
||||||
methodTphs = m.getTphs();
|
methodTphs = m.getTphs();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// check if there are multiple constraint with the same left side.
|
||||||
|
// if yes => check if the super type in the method, if not
|
||||||
|
// then ignore it.
|
||||||
HashMap<String, String> subAndSuper = new HashMap<>();
|
HashMap<String, String> subAndSuper = new HashMap<>();
|
||||||
for(TPHConstraint c : allCons) {
|
for(TPHConstraint c : allCons) {
|
||||||
if(subAndSuper.containsKey(c.getLeft())) {
|
if(subAndSuper.containsKey(c.getLeft())) {
|
||||||
@ -155,6 +249,8 @@ public class Simplify {
|
|||||||
// Die größte Supertype
|
// Die größte Supertype
|
||||||
String superTphRes = tphInRel.getLast();
|
String superTphRes = tphInRel.getLast();
|
||||||
|
|
||||||
|
// if there is any constraint X < subTph, then
|
||||||
|
// add X at the beginning of the list.
|
||||||
while(subAndSuper.containsValue(subTphRes)) {
|
while(subAndSuper.containsValue(subTphRes)) {
|
||||||
for(String tph : subAndSuper.keySet()) {
|
for(String tph : subAndSuper.keySet()) {
|
||||||
if(containTPH(methodTphs,tph) && subAndSuper.get(tph).equals(subTphRes)) {
|
if(containTPH(methodTphs,tph) && subAndSuper.get(tph).equals(subTphRes)) {
|
||||||
@ -165,12 +261,18 @@ public class Simplify {
|
|||||||
if(subTphRes.equals(tphInRel.getFirst())) {
|
if(subTphRes.equals(tphInRel.getFirst())) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isTPHInConstraint(result, subTphRes))
|
||||||
|
break;
|
||||||
|
|
||||||
tphInRel.addFirst(subTphRes);
|
tphInRel.addFirst(subTphRes);
|
||||||
numOfVisitedPairs++;
|
numOfVisitedPairs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
subTphRes = tphInRel.getFirst();
|
subTphRes = tphInRel.getFirst();
|
||||||
|
// if the last type in the list not a type in method-types
|
||||||
|
// then find the last type in front of this type, which is
|
||||||
|
// a type in method-types
|
||||||
int i = 2;
|
int i = 2;
|
||||||
while(!containTPH(methodTphs,superTphRes) && (tphInRel.size()-i) >0) {
|
while(!containTPH(methodTphs,superTphRes) && (tphInRel.size()-i) >0) {
|
||||||
superTphRes = tphInRel.get(tphInRel.size()-i);
|
superTphRes = tphInRel.get(tphInRel.size()-i);
|
||||||
@ -181,13 +283,14 @@ public class Simplify {
|
|||||||
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
||||||
} else {
|
} else {
|
||||||
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), null);
|
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), null);
|
||||||
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
if(!isTPHInConstraint(result, superTphRes))
|
||||||
|
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(TypePlaceholder tph : methodTphs) {
|
for(String tph : methodTphs) {
|
||||||
if(!isTPHInConstraint(result, tph.getName())) {
|
if(!isTPHInConstraint(result, tph)) {
|
||||||
result.put(new ExtendsConstraint(tph.getName(), Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
result.put(new ExtendsConstraint(tph, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,6 +314,44 @@ public class Simplify {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static TPHConstraint getConstraint(String oldRight, String right, ArrayList<TPHConstraint> allCons) {
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
if(c.getLeft().equals(oldRight) && c.getRight().equals(right))
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isTPHInResEqual(HashMap<TPHConstraint, HashSet<String>> result, String left) {
|
||||||
|
for(HashSet<String> eq : result.values()) {
|
||||||
|
if(eq.contains(left)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void substituteAllTPH(ArrayList<TPHConstraint> allCons, ArrayList<TPHConstraint> constraints,
|
||||||
|
String first) {
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
for(TPHConstraint c2 : constraints) {
|
||||||
|
if(c.getRel() == Relation.EXTENDS) {
|
||||||
|
if(c2.getLeft().equals(c.getLeft()) || c2.getRight().equals(c.getLeft()))
|
||||||
|
c.setLeft(first);
|
||||||
|
if(c2.getLeft().equals(c.getRight()) || c2.getRight().equals(c.getRight()))
|
||||||
|
c.setRight(first);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setAllEqual(ArrayList<TPHConstraint> constraints) {
|
||||||
|
for(TPHConstraint c:constraints) {
|
||||||
|
c.setRel(Relation.EQUAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static HashMap<TPHConstraint, HashSet<String>> simplifyContraints(HashMap<TPHConstraint, HashSet<String>> allConstraints) {
|
public static HashMap<TPHConstraint, HashSet<String>> simplifyContraints(HashMap<TPHConstraint, HashSet<String>> allConstraints) {
|
||||||
// 1. check if there are any cycles like L<R and R<L:
|
// 1. check if there are any cycles like L<R and R<L:
|
||||||
// a) yes => set L=R and:
|
// a) yes => set L=R and:
|
||||||
@ -406,9 +547,9 @@ public class Simplify {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean containTPH(ArrayList<TypePlaceholder> methodTphs, String sub) {
|
private static boolean containTPH(ArrayList<String> methodTphs, String sub) {
|
||||||
for(TypePlaceholder tph : methodTphs) {
|
for(String tph : methodTphs) {
|
||||||
if(tph.getName().equals(sub))
|
if(tph.equals(sub))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -119,21 +119,37 @@ public class JavaTXCompiler {
|
|||||||
|
|
||||||
TypeUnify unify = new TypeUnify();
|
TypeUnify unify = new TypeUnify();
|
||||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||||
Set<List<Constraint<UnifyPair>>> cardProd = unifyCons.cartesianProduct();
|
try {
|
||||||
for (List<Constraint<UnifyPair>> xCons : cardProd ){
|
//FileWriter logFile = new FileWriter(new File(System.getProperty("user.dir")+"/test/logFiles/"+"log"));
|
||||||
Set<UnifyPair> xConsSet = new HashSet<>();
|
//logFile.write("FC:\\" + finiteClosure.toString()+"\n");
|
||||||
for (Constraint<UnifyPair> constraint : xCons) {
|
//for(SourceFile sf : this.sourceFiles.values()) {
|
||||||
xConsSet.addAll(constraint);
|
// logFile.write(ASTTypePrinter.print(sf));
|
||||||
}
|
//}
|
||||||
//.collect(Collectors.toCollection(ArrayList::new))))
|
//logFile.flush();
|
||||||
System.out.println(xConsSet);
|
Set<List<Constraint<UnifyPair>>> cardProd = unifyCons.cartesianProduct();
|
||||||
Set<String> paraTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist()
|
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> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist()
|
||||||
.stream().filter(z -> z.getType() instanceof TypePlaceholder)
|
.stream().filter(z -> z.getType() instanceof TypePlaceholder)
|
||||||
.map(z -> ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(HashSet::new)))
|
.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;}, (a,b) -> { a.addAll(b); return a;} ) )
|
||||||
.reduce(new HashSet<String>(), (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)
|
Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().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> paraTypeVarNames = methodParaTypeVarNames;
|
||||||
|
paraTypeVarNames.addAll(constructorParaTypeVarNames);
|
||||||
|
|
||||||
|
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();
|
.map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get();
|
||||||
|
|
||||||
Set<String> fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
|
Set<String> fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
|
||||||
|
@ -151,7 +151,7 @@ public class SyntaxTreeGenerator{
|
|||||||
block = stmtGen.convert(body.block(),true);
|
block = stmtGen.convert(body.block(),true);
|
||||||
}
|
}
|
||||||
if(parentClass.equals(new JavaClassName(name))){
|
if(parentClass.equals(new JavaClassName(name))){
|
||||||
return new Constructor(modifiers, name, retType, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations);
|
return new Constructor(modifiers, name, retType, parameterList, block, gtvDeclarations, header.getStart() /*, fieldInitializations geloescht PL 2018-11-24 */);
|
||||||
}else{
|
}else{
|
||||||
return new Method(modifiers, name, retType, parameterList,block, gtvDeclarations, header.getStart());
|
return new Method(modifiers, name, retType, parameterList,block, gtvDeclarations, header.getStart());
|
||||||
}
|
}
|
||||||
@ -198,14 +198,18 @@ public class SyntaxTreeGenerator{
|
|||||||
}
|
}
|
||||||
List<Field> fielddecl = convertFields(ctx.classBody(), generics);
|
List<Field> fielddecl = convertFields(ctx.classBody(), generics);
|
||||||
//fieldInitializations = generateFieldInitializations(ctx.classBody(), generics);
|
//fieldInitializations = generateFieldInitializations(ctx.classBody(), generics);
|
||||||
List<Method> methods = convertMethods(ctx.classBody(), name, superClass, generics);
|
List<Method> methodsAndConstructors = convertMethods(ctx.classBody(), name, superClass, generics);
|
||||||
|
List<Method> methods = new ArrayList<>();
|
||||||
List<Constructor> konstruktoren = new ArrayList<>();
|
List<Constructor> konstruktoren = new ArrayList<>();
|
||||||
for(int i = 0; i<methods.size();i++){
|
//int noOfMethods = methods.size();
|
||||||
Method m = methods.get(i);
|
for(int i = 0; i < methodsAndConstructors.size(); i++){
|
||||||
|
Method m = methodsAndConstructors.get(i);
|
||||||
if(m instanceof Constructor){
|
if(m instanceof Constructor){
|
||||||
methods.remove(i);
|
|
||||||
konstruktoren.add((Constructor) m);
|
konstruktoren.add((Constructor) m);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
methods.add(m);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(konstruktoren.size()<1){//Standardkonstruktor anfügen:
|
if(konstruktoren.size()<1){//Standardkonstruktor anfügen:
|
||||||
konstruktoren.add(
|
konstruktoren.add(
|
||||||
@ -217,7 +221,10 @@ public class SyntaxTreeGenerator{
|
|||||||
|
|
||||||
Boolean isInterface = false;
|
Boolean isInterface = false;
|
||||||
List<RefType> implementedInterfaces = convert(ctx.superinterfaces(), generics);
|
List<RefType> implementedInterfaces = convert(ctx.superinterfaces(), generics);
|
||||||
return new ClassOrInterface(modifiers, name, fielddecl, methods, konstruktoren, genericClassParameters, superClass,
|
|
||||||
|
return new ClassOrInterface(modifiers, name, fielddecl,
|
||||||
|
Optional.of(this.generatePseudoConstructor(ctx.Identifier().getText(), name, superClass, genericClassParameters, offset)),
|
||||||
|
methods, konstruktoren, genericClassParameters, superClass,
|
||||||
isInterface, implementedInterfaces, offset);
|
isInterface, implementedInterfaces, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,8 +274,16 @@ public class SyntaxTreeGenerator{
|
|||||||
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset);
|
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset);
|
||||||
ParameterList params = new ParameterList(new ArrayList<>(), offset);
|
ParameterList params = new ParameterList(new ArrayList<>(), offset);
|
||||||
Block block = new Block(new ArrayList<>(), offset);
|
Block block = new Block(new ArrayList<>(), offset);
|
||||||
return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset, fieldInitializations);
|
return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /*, fieldInitializations geloescht PL 2018-11-24 */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* fieldInitializations werden in einem Psedokonstruktor in der abstrakten Syntax gespeichert */
|
||||||
|
private Constructor generatePseudoConstructor(String className, JavaClassName parentClass, RefType superClass, GenericDeclarationList classGenerics, Token offset){
|
||||||
|
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset);
|
||||||
|
ParameterList params = new ParameterList(new ArrayList<>(), offset);
|
||||||
|
Block block = new Block(new ArrayList<>(fieldInitializations), offset);
|
||||||
|
return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /*, fieldInitializations geloescht PL 2018-11-24 */);
|
||||||
|
}
|
||||||
|
|
||||||
private RefType convert(Java8Parser.SuperclassContext superclass) {
|
private RefType convert(Java8Parser.SuperclassContext superclass) {
|
||||||
if(superclass.classType().classOrInterfaceType() != null){
|
if(superclass.classType().classOrInterfaceType() != null){
|
||||||
@ -441,7 +456,7 @@ public class SyntaxTreeGenerator{
|
|||||||
|
|
||||||
List<RefType> extendedInterfaces = convert(ctx.extendsInterfaces(), generics);
|
List<RefType> extendedInterfaces = convert(ctx.extendsInterfaces(), generics);
|
||||||
|
|
||||||
return new ClassOrInterface(modifiers, name, fields, methods, new ArrayList<>(),
|
return new ClassOrInterface(modifiers, name, fields, Optional.empty(), methods, new ArrayList<>(),
|
||||||
genericParams, superClass, true, extendedInterfaces, ctx.getStart());
|
genericParams, superClass, true, extendedInterfaces, ctx.getStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package de.dhbwstuttgart.syntaxtree;
|
|||||||
import de.dhbwstuttgart.core.IItemWithOffset;
|
import de.dhbwstuttgart.core.IItemWithOffset;
|
||||||
import de.dhbwstuttgart.exceptions.DebugException;
|
import de.dhbwstuttgart.exceptions.DebugException;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
||||||
@ -16,6 +17,7 @@ import java.lang.reflect.Modifier;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
|
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
|
||||||
@ -24,6 +26,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
|
|||||||
protected int modifiers;
|
protected int modifiers;
|
||||||
protected JavaClassName name;
|
protected JavaClassName name;
|
||||||
private List<Field> fields = new ArrayList<>();
|
private List<Field> fields = new ArrayList<>();
|
||||||
|
private Optional<Constructor> fieldInitializations; //PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen
|
||||||
private List<Method> methods = new ArrayList<>();
|
private List<Method> methods = new ArrayList<>();
|
||||||
private GenericDeclarationList genericClassParameters;
|
private GenericDeclarationList genericClassParameters;
|
||||||
private RefType superClass;
|
private RefType superClass;
|
||||||
@ -31,13 +34,14 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
|
|||||||
private List<RefType> implementedInterfaces;
|
private List<RefType> implementedInterfaces;
|
||||||
private List<Constructor> constructors;
|
private List<Constructor> constructors;
|
||||||
|
|
||||||
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters,
|
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters,
|
||||||
RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset){
|
RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset){
|
||||||
super(offset);
|
super(offset);
|
||||||
if(isInterface && !Modifier.isInterface(modifiers))modifiers += Modifier.INTERFACE;
|
if(isInterface && !Modifier.isInterface(modifiers))modifiers += Modifier.INTERFACE;
|
||||||
this.modifiers = modifiers;
|
this.modifiers = modifiers;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.fields = fielddecl;
|
this.fields = fielddecl;
|
||||||
|
this.fieldInitializations= fieldInitializations;
|
||||||
this.genericClassParameters = genericClassParameters;
|
this.genericClassParameters = genericClassParameters;
|
||||||
this.superClass = superClass;
|
this.superClass = superClass;
|
||||||
this.isInterface = isInterface;
|
this.isInterface = isInterface;
|
||||||
@ -59,6 +63,11 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
|
|||||||
public List<Field> getFieldDecl(){
|
public List<Field> getFieldDecl(){
|
||||||
return this.fields;
|
return this.fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<Constructor> getfieldInitializations(){
|
||||||
|
return this.fieldInitializations;
|
||||||
|
}
|
||||||
|
|
||||||
public List<Method> getMethods(){
|
public List<Method> getMethods(){
|
||||||
return this.methods;
|
return this.methods;
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@ public class Constructor extends Method {
|
|||||||
|
|
||||||
//TODO: Constructor braucht ein super-Statement
|
//TODO: Constructor braucht ein super-Statement
|
||||||
public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList parameterList, Block codeInsideConstructor,
|
public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList parameterList, Block codeInsideConstructor,
|
||||||
GenericDeclarationList gtvDeclarations, Token offset, List<Statement> fieldInitializations) {
|
GenericDeclarationList gtvDeclarations, Token offset /*, List<Statement> fieldInitializations geloescht PL 2018-11-24 */) {
|
||||||
super(modifier, name, returnType, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations), gtvDeclarations, offset);
|
super(modifier, name, returnType, parameterList, /*codeInsideConstructor,*/ prepareBlock(codeInsideConstructor ) /*,fieldInitializations )geloescht PL 2018-11-24 )*/, gtvDeclarations, offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,10 +25,10 @@ public class Constructor extends Method {
|
|||||||
* welche die Felder der zugehörigen Klasse dieses
|
* welche die Felder der zugehörigen Klasse dieses
|
||||||
* Konstruktor initialisieren
|
* Konstruktor initialisieren
|
||||||
*/
|
*/
|
||||||
protected static Block prepareBlock(Block constructorBlock, List<Statement> fieldInitializations){
|
protected static Block prepareBlock(Block constructorBlock /*, List<Statement> fieldInitializations new ArrayList<>() geloescht PL 2018-11-24 */){
|
||||||
List<Statement> statements = constructorBlock.getStatements();
|
List<Statement> statements = constructorBlock.getStatements();
|
||||||
statements.add(0, new SuperCall(constructorBlock.getOffset()));
|
statements.add(0, new SuperCall(constructorBlock.getOffset()));
|
||||||
statements.addAll(fieldInitializations);
|
/* statements.addAll(fieldInitializations); geloescht PL 2018-11-24 */
|
||||||
return new Block(statements, constructorBlock.getOffset());
|
return new Block(statements, constructorBlock.getOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import java.lang.reflect.*;
|
|||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
@ -65,7 +66,7 @@ public class ASTFactory {
|
|||||||
|
|
||||||
Token offset = new NullToken(); //Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
|
Token offset = new NullToken(); //Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
|
||||||
|
|
||||||
return new ClassOrInterface(modifier, name, felder, methoden, konstruktoren, genericDeclarationList, superClass,isInterface, implementedInterfaces, offset);
|
return new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */,methoden, konstruktoren, genericDeclarationList, superClass,isInterface, implementedInterfaces, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Field createField(java.lang.reflect.Field field, JavaClassName jreClass) {
|
private static Field createField(java.lang.reflect.Field field, JavaClassName jreClass) {
|
||||||
@ -98,7 +99,7 @@ public class ASTFactory {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new de.dhbwstuttgart.syntaxtree.Constructor(modifier, name,returnType, parameterList, block, gtvDeclarations, offset, new ArrayList<>());
|
return new de.dhbwstuttgart.syntaxtree.Constructor(modifier, name,returnType, parameterList, block, gtvDeclarations, offset /*, new ArrayList<>() geloescht PL 2018-11-24 */);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){
|
public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){
|
||||||
|
@ -17,10 +17,11 @@ import org.antlr.v4.runtime.Token;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class FunNClass extends ClassOrInterface {
|
public class FunNClass extends ClassOrInterface {
|
||||||
public FunNClass(List<GenericRefType> funNParams) {
|
public FunNClass(List<GenericRefType> funNParams) {
|
||||||
super(0, new JavaClassName("Fun"+(funNParams.size())), new ArrayList<>(),
|
super(0, new JavaClassName("Fun"+(funNParams.size())), new ArrayList<>(), Optional.empty() /* eingefuegt PL 2018-11-24 */,
|
||||||
createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams),
|
createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams),
|
||||||
ASTFactory.createObjectType(), true, new ArrayList<>(), new NullToken());
|
ASTFactory.createObjectType(), true, new ArrayList<>(), new NullToken());
|
||||||
|
|
||||||
|
@ -38,6 +38,9 @@ public class TYPE {
|
|||||||
for(Constructor m : cl.getConstructors()){
|
for(Constructor m : cl.getConstructors()){
|
||||||
ret.addAll(getConstraintsConstructor(m,info, cl));
|
ret.addAll(getConstraintsConstructor(m,info, cl));
|
||||||
}
|
}
|
||||||
|
if (cl.getfieldInitializations().isPresent()) {
|
||||||
|
ret.addAll(getConstraintsConstructor(cl.getfieldInitializations().get(), info, cl));
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -61,6 +64,7 @@ public class TYPE {
|
|||||||
return new TypeInferenceInformation(classes);
|
return new TypeInferenceInformation(classes);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private ConstraintSet getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) {
|
private ConstraintSet getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) {
|
||||||
if(m.block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints
|
if(m.block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints
|
||||||
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
|
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
|
||||||
|
43
src/test/resources/bytecode/LambdaCapturetest.java
Normal file
43
src/test/resources/bytecode/LambdaCapturetest.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author fayez
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class LambdaCapturetest {
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void generateBC() throws Exception {
|
||||||
|
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/LambdaCapture.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/");
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
classToTest = loader.loadClass("LambdaCapture");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
76
src/test/resources/bytecode/simplifyalgo/CycleTest.java
Normal file
76
src/test/resources/bytecode/simplifyalgo/CycleTest.java
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package bytecode.simplifyalgo;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.Simplify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fayez Abu Alia
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CycleTest {
|
||||||
|
|
||||||
|
private static TPHExtractor tphExtractor;
|
||||||
|
private static String methName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws java.lang.Exception
|
||||||
|
*/
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
tphExtractor = new TPHExtractor();
|
||||||
|
// A < B
|
||||||
|
TPHConstraint c1 = new ExtendsConstraint("A", "B", Relation.EXTENDS);
|
||||||
|
// B < C
|
||||||
|
TPHConstraint c2 = new ExtendsConstraint("B", "C", Relation.EXTENDS);
|
||||||
|
// C < D
|
||||||
|
TPHConstraint c3 = new ExtendsConstraint("C", "D", Relation.EXTENDS);
|
||||||
|
// D < A
|
||||||
|
TPHConstraint c4 = new ExtendsConstraint("D", "A", Relation.EXTENDS);
|
||||||
|
// name
|
||||||
|
methName = "m";
|
||||||
|
MethodAndTPH mtph = new MethodAndTPH("m");
|
||||||
|
mtph.getTphs().add("A");
|
||||||
|
mtph.getTphs().add("B");
|
||||||
|
mtph.getTphs().add("C");
|
||||||
|
mtph.getTphs().add("D");
|
||||||
|
tphExtractor.ListOfMethodsAndTph.add(mtph);
|
||||||
|
tphExtractor.allCons.add(c1);
|
||||||
|
tphExtractor.allCons.add(c2);
|
||||||
|
tphExtractor.allCons.add(c3);
|
||||||
|
tphExtractor.allCons.add(c4);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||||
|
HashSet<String> equals = new HashSet<>();
|
||||||
|
equals.add("A");
|
||||||
|
equals.add("B");
|
||||||
|
equals.add("C");
|
||||||
|
equals.add("D");
|
||||||
|
TPHConstraint k = new ExtendsConstraint("A", Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||||
|
result.put(k, equals);
|
||||||
|
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor);
|
||||||
|
boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
|
||||||
|
assertTrue(areEquals);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
97
src/test/resources/bytecode/simplifyalgo/SameLeftSide.java
Normal file
97
src/test/resources/bytecode/simplifyalgo/SameLeftSide.java
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
package bytecode.simplifyalgo;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.Simplify;
|
||||||
|
import de.dhbwstuttgart.typedeployment.TypeInsertPlacer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Fayez Abu Alia
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SameLeftSide {
|
||||||
|
// Typeplaceholders können nicht definiert werden, da die Konstruktor
|
||||||
|
// private ist => Test geht nicht
|
||||||
|
private static TPHExtractor tphExtractor;
|
||||||
|
private static String methName;
|
||||||
|
private static String methName2;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
tphExtractor = new TPHExtractor();
|
||||||
|
// A < B
|
||||||
|
TPHConstraint c1 = new ExtendsConstraint("A", "B", Relation.EXTENDS);
|
||||||
|
// A < C
|
||||||
|
TPHConstraint c2 = new ExtendsConstraint("A", "C", Relation.EXTENDS);
|
||||||
|
// B < D
|
||||||
|
TPHConstraint c3 = new ExtendsConstraint("B", "D", Relation.EXTENDS);
|
||||||
|
// C < E
|
||||||
|
TPHConstraint c4 = new ExtendsConstraint("C", "E", Relation.EXTENDS);
|
||||||
|
// name
|
||||||
|
methName = "m1";
|
||||||
|
MethodAndTPH m1 = new MethodAndTPH("m1");
|
||||||
|
|
||||||
|
methName2 = "m2";
|
||||||
|
MethodAndTPH m2 = new MethodAndTPH("m2");
|
||||||
|
|
||||||
|
m1.getTphs().add("A");
|
||||||
|
m1.getTphs().add("B");
|
||||||
|
m1.getTphs().add("D");
|
||||||
|
|
||||||
|
m2.getTphs().add("C");
|
||||||
|
m2.getTphs().add("E");
|
||||||
|
|
||||||
|
tphExtractor.ListOfMethodsAndTph.add(m1);
|
||||||
|
tphExtractor.ListOfMethodsAndTph.add(m2);
|
||||||
|
|
||||||
|
tphExtractor.allCons.add(c1);
|
||||||
|
tphExtractor.allCons.add(c2);
|
||||||
|
tphExtractor.allCons.add(c3);
|
||||||
|
tphExtractor.allCons.add(c4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testM1() {
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||||
|
|
||||||
|
TPHConstraint d = new ExtendsConstraint("D", Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||||
|
TPHConstraint a = new ExtendsConstraint("A", "D", Relation.EXTENDS);
|
||||||
|
TPHConstraint b = new ExtendsConstraint("B", "D", Relation.EXTENDS);
|
||||||
|
result.put(d, null);
|
||||||
|
result.put(a, null);
|
||||||
|
result.put(b, null);
|
||||||
|
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor);
|
||||||
|
boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
|
||||||
|
assertTrue(areEquals);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testM2() {
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||||
|
|
||||||
|
TPHConstraint e = new ExtendsConstraint("E", Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||||
|
TPHConstraint c = new ExtendsConstraint("C", "E", Relation.EXTENDS);
|
||||||
|
|
||||||
|
result.put(e, null);
|
||||||
|
result.put(c, null);
|
||||||
|
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName2, tphExtractor);
|
||||||
|
boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
|
||||||
|
assertTrue(areEquals);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
79
src/test/resources/bytecode/simplifyalgo/SimpleCycle.java
Normal file
79
src/test/resources/bytecode/simplifyalgo/SimpleCycle.java
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package bytecode.simplifyalgo;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.TPHExtractor;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.Simplify;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Fayez Abu Alia
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SimpleCycle {
|
||||||
|
private static TPHExtractor tphExtractor;
|
||||||
|
private static String methName;
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
tphExtractor = new TPHExtractor();
|
||||||
|
// A < B
|
||||||
|
TPHConstraint c1 = new ExtendsConstraint("A", "B", Relation.EXTENDS);
|
||||||
|
// B < A
|
||||||
|
TPHConstraint c2 = new ExtendsConstraint("B", "A", Relation.EXTENDS);
|
||||||
|
// name
|
||||||
|
methName = "m";
|
||||||
|
tphExtractor.allCons.add(c1);
|
||||||
|
tphExtractor.allCons.add(c2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||||
|
HashSet<String> equals = new HashSet<>();
|
||||||
|
equals.add("A");
|
||||||
|
equals.add("B");
|
||||||
|
TPHConstraint k = new ExtendsConstraint("B", Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||||
|
result.put(k, equals);
|
||||||
|
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor);
|
||||||
|
boolean areEquals = areMapsEqual(result, sim);
|
||||||
|
assertTrue(areEquals);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean areMapsEqual(HashMap<TPHConstraint, HashSet<String>> m1, HashMap<TPHConstraint, HashSet<String>> m2) {
|
||||||
|
|
||||||
|
for(TPHConstraint c : m1.keySet()) {
|
||||||
|
for(TPHConstraint c2 : m2.keySet()) {
|
||||||
|
if(c.getLeft().equals(c2.getLeft()) && c.getRight().equals(c2.getRight()) && c.getRel()==c2.getRel()) {
|
||||||
|
HashSet<String> eq1 = m1.get(c);
|
||||||
|
HashSet<String> eq2 = m2.get(c2);
|
||||||
|
|
||||||
|
if((eq1 == null && eq2 != null) || (eq1 != null && eq2 == null))
|
||||||
|
return false;
|
||||||
|
if(eq1 != null) {
|
||||||
|
if(eq1.size() != eq2.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for(String tph:eq1) {
|
||||||
|
if(!eq2.contains(tph))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,17 +4,19 @@ public class Faculty {
|
|||||||
public fact;
|
public fact;
|
||||||
Faculty() {
|
Faculty() {
|
||||||
fact = (x) -> {
|
fact = (x) -> {
|
||||||
if(x<0) {
|
if (x == 1) {
|
||||||
return 0;
|
return 1;
|
||||||
}else if (x < 1) {
|
}
|
||||||
return x;
|
else {
|
||||||
}
|
return x * (fact.apply(x-1));
|
||||||
else {
|
}
|
||||||
return x * (fact.apply(x-1));
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public getFact(x) {
|
||||||
|
return fact.apply(x);
|
||||||
|
}
|
||||||
// m (x) {
|
// m (x) {
|
||||||
//
|
//
|
||||||
//// var fact = (x) -> {
|
//// var fact = (x) -> {
|
||||||
|
12
src/test/resources/javFiles/bytecode/LambdaCapture.jav
Normal file
12
src/test/resources/javFiles/bytecode/LambdaCapture.jav
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
public class LambdaCapture {
|
||||||
|
Integer i = 8;
|
||||||
|
f;
|
||||||
|
public LambdaCapture(){
|
||||||
|
Integer w = 7;
|
||||||
|
f = j ->{
|
||||||
|
return w+i;};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -9,7 +9,7 @@ public class OL {
|
|||||||
m(x) { return x + x; }
|
m(x) { return x + x; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class OLMain {
|
public class OLMain {
|
||||||
@ -20,4 +20,3 @@ public class OLMain {
|
|||||||
return ol.m(x);
|
return ol.m(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@ public class Tph {
|
|||||||
|
|
||||||
m(a,b){
|
m(a,b){
|
||||||
var c = m2(b);
|
var c = m2(b);
|
||||||
return a;
|
// return a;
|
||||||
// return m2(b);
|
return m2(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
m2(b){
|
m2(b){
|
||||||
|
58
test/bytecode/FacultyTest.java
Normal file
58
test/bytecode/FacultyTest.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
public class FacultyTest {
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void generateBC() throws Exception {
|
||||||
|
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Faculty.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/");
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
classToTest = loader.loadClass("Faculty");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
Method getFact = classToTest.getDeclaredMethod("getFact", Integer.class);
|
||||||
|
// Field fact = classToTest.getDeclaredField("fact");
|
||||||
|
// Class<?> lambda = m.invoke(instanceOfClass).getClass();
|
||||||
|
// Class<?> lambda = fact.getType();
|
||||||
|
// System.out.println(fact.getType().getName());
|
||||||
|
// Method apply = lambda.getMethod("apply", Object.class);
|
||||||
|
// System.out.println(lambda.getMethods()[0]);
|
||||||
|
// System.out.println(instanceOfClass.toString());
|
||||||
|
// // Damit man auf die Methode zugreifen kann
|
||||||
|
// apply.setAccessible(true);
|
||||||
|
// Field value
|
||||||
|
// Object fieldVal = fact.get(instanceOfClass);
|
||||||
|
Integer i = 3;
|
||||||
|
// Method applyFromField = fieldVal.getClass().getDeclaredMethod("apply", Object.class);
|
||||||
|
// applyFromField.setAccessible(true);
|
||||||
|
// Integer result = (Integer) apply.invoke(lambda,i);
|
||||||
|
Integer result = (Integer) getFact.invoke(instanceOfClass,i);
|
||||||
|
|
||||||
|
assertEquals(6, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
50
test/bytecode/LambdaTest.java
Normal file
50
test/bytecode/LambdaTest.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
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.Test;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
public class LambdaTest {
|
||||||
|
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;
|
||||||
|
|
||||||
|
@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(System.getProperty("user.dir")+"/testBytecode/generatedBC/");
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
classToTest = loader.loadClass("Lambda");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
Method m = classToTest.getDeclaredMethod("m");
|
||||||
|
Class<?> lambda = m.invoke(instanceOfClass).getClass();
|
||||||
|
Method apply = lambda.getMethod("apply", Object.class);
|
||||||
|
|
||||||
|
// Damit man auf die Methode zugreifen kann
|
||||||
|
apply.setAccessible(true);
|
||||||
|
|
||||||
|
Integer i = 77;
|
||||||
|
System.out.println(m.invoke(instanceOfClass).toString());
|
||||||
|
Integer result = (Integer) apply.invoke(m.invoke(instanceOfClass), i);
|
||||||
|
|
||||||
|
assertEquals(77, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
91
test/bytecode/MatrixOpTest.java
Normal file
91
test/bytecode/MatrixOpTest.java
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
public class MatrixOpTest {
|
||||||
|
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_m1;
|
||||||
|
private static Object instanceOfClass_m2;
|
||||||
|
private static Object instanceOfClass_m3;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IOException, InstantiationException {
|
||||||
|
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/MatrixOP.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
compiler.generateBytecode(pathToClassFile);
|
||||||
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
classToTest = loader.loadClass("MatrixOP");
|
||||||
|
/*
|
||||||
|
Vector<Vector<Integer>> vv = new Vector<Vector<Integer>>();
|
||||||
|
Vector<Integer> v1 = new Vector<Integer> ();
|
||||||
|
v1.addElement(2);
|
||||||
|
v1.addElement(2);
|
||||||
|
Vector<Integer> v2 = new Vector<Integer> ();
|
||||||
|
v2.addElement(3);
|
||||||
|
v2.addElement(3);
|
||||||
|
//Matrix m1 = new Matrix();
|
||||||
|
//m1.addElement(v1);
|
||||||
|
//m1.addElement(v2);
|
||||||
|
vv.addElement(v1);
|
||||||
|
vv.addElement(v2);
|
||||||
|
instanceOfClass_m1 = classToTest.getDeclaredConstructor(Vector.class).newInstance(vv); //Matrix m1 = new Matrix(vv);
|
||||||
|
|
||||||
|
Vector<Vector<Integer>> vv1 = new Vector<Vector<Integer>>();
|
||||||
|
Vector<Integer> v3 = new Vector<Integer> ();
|
||||||
|
v3.addElement(2);
|
||||||
|
v3.addElement(2);
|
||||||
|
Vector<Integer> v4 = new Vector<Integer> ();
|
||||||
|
v4.addElement(3);
|
||||||
|
v4.addElement(3);
|
||||||
|
//Matrix m2 = new Matrix();
|
||||||
|
//m2.addElement(v3);
|
||||||
|
//m2.addElement(v4);
|
||||||
|
vv1.addElement(v3);
|
||||||
|
vv1.addElement(v4);
|
||||||
|
instanceOfClass_m2 = classToTest.getDeclaredConstructor(Vector.class).newInstance(vv1);//Matrix m2 = new Matrix(vv1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Matrix m3 = m1.mul(vv1);
|
||||||
|
Method mul = classToTest.getDeclaredMethod("mul", Vector.class);
|
||||||
|
Object result = mul.invoke(instanceOfClass_m1, instanceOfClass_m2);
|
||||||
|
System.out.println(instanceOfClass_m1.toString() + " * " + instanceOfClass_m2.toString() + " = " + result.toString());
|
||||||
|
|
||||||
|
Vector<Vector<Integer>> res = new Vector<Vector<Integer>>();
|
||||||
|
Vector<Integer> v5 = new Vector<Integer> ();
|
||||||
|
v5.addElement(10);
|
||||||
|
v5.addElement(10);
|
||||||
|
Vector<Integer> v6 = new Vector<Integer> ();
|
||||||
|
v6.addElement(15);
|
||||||
|
v6.addElement(15);
|
||||||
|
//Matrix m2 = new Matrix();
|
||||||
|
//m2.addElement(v3);
|
||||||
|
//m2.addElement(v4);
|
||||||
|
res.addElement(v5);
|
||||||
|
res.addElement(v6);
|
||||||
|
instanceOfClass_m3 = classToTest.getDeclaredConstructor(Vector.class).newInstance(res);
|
||||||
|
assertEquals(result, instanceOfClass_m3);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
52
test/bytecode/YTest.java
Normal file
52
test/bytecode/YTest.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
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.Test;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
public class YTest {
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void generateBC() throws Exception {
|
||||||
|
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Y.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
// compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
// compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/");
|
||||||
|
// pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
// loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
// classToTest = loader.loadClass("Y");
|
||||||
|
/*
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
Method m = classToTest.getDeclaredMethod("m");
|
||||||
|
Class<?> lambda = m.invoke(instanceOfClass).getClass();
|
||||||
|
Method apply = lambda.getMethod("apply", Object.class);
|
||||||
|
|
||||||
|
// Damit man auf die Methode zugreifen kann
|
||||||
|
apply.setAccessible(true);
|
||||||
|
|
||||||
|
Integer i = 77;
|
||||||
|
|
||||||
|
Integer result = (Integer) apply.invoke(m.invoke(instanceOfClass), i);
|
||||||
|
|
||||||
|
assertEquals(77, result);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user