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

This commit is contained in:
Dr. Martin Pluemicke 2015-02-25 12:05:05 +01:00
commit c315def167
18 changed files with 188 additions and 64 deletions

View File

@ -4,6 +4,6 @@
<classpathentry excluding=".classpath|.cvsignore|.externalToolBuilders/|.project|.settings/|Papers/|bin/|doc/|examples/|lib/|notizen/|src/|test/|tools/" including="log4j.xml" kind="src" path=""/>
<classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/CDC-1.0%Foundation-1.0"/>
<classpathentry kind="lib" path="lib/junit-4.0.jar"/>
<classpathentry kind="lib" path="lib/junit-4.0.jar" sourcepath="/home/janulrich/.m2/repository/junit/junit/4.0/junit-4.0-sources.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -1,15 +0,0 @@
# Typinferenz für Java 8
## Programmablauf
1. SourceFile parst die Java-Dateien
2. SourceFile erstellt die Basic/Global Assumptions
3. Das Globale AssumptionSet wird anschließend jeder Klasse im Syntaxbaum mit dem TRProg aufruf übergeben
4. Jede Klasse verwaltet lokale Variablen in ihrem eigenen AssumptionSet. Das Globale ist Klassenübergreifend und jede AssumptionType darf darin nur einmalig gesetzt werden.
5. Haben alle Klassen ihrer Constraints erstellt können diese Unifiziert werden.
## Overloading
* Die Overloading Klasse generiert Constraints aus einem Methodenaufruf.

View File

@ -1,42 +0,0 @@
# Typinferenz
## ResultSet
* Spezifisch für jedes SourceFile (nicht für jede Klasse)
* mehrere ResultSets pro Klasse
*
* Enthält:
* constraintPairs
* unifiedConstraints
## TypeInsertSet
* Stellt die Typeinsetzung für eine der generierten Lösungen dar
* Setzt alle Typen und generischen Variablen ein, welche zu dieser Lösung gehören
## Ablauf Typinferenz:
1. Parsen
* (Parser postProcessing)
2. Typinferenz
* Anfangspunkt SourceFile
* löst geparste Typen zu richtigen Typen auf (RefTypes, GenericVar)
* setzt TPHs ein
* bildet Constraints, welche in ResultSet gesammelt werden. ResultSet wird durch Syntaxbaum gereicht.
* Assumptions generieren
* Wird im Syntaxbaum für jeden Knoten ausgeführt und die Assumptions für darunterliegende Knoten gebildet
*
3. Unifizierung
* wird im SourceFile aufgerufen
* unifiziert Constraints aller im SourceFile vorkommenden Klassen
4. Erstellen von TypeInsertSet
* Durchlaufen des Syntaxbaumes
* Jeder Knoten erstellt TypeInsertSets anhand des ResultSets.
* Bei Knoten, welche Generische Variablen beinhalten können werden GenericTypeInsertPoints erstellt
5. Einsetzen eines TypeInsertSet (optional)
1. Auf allen TypeInsertPoints die getUnresolvedTPHs-Methoden aufrufen
2. Alle Abhängigkeiten dieser

71
doc/documentation.md Normal file
View File

@ -0,0 +1,71 @@
# Typinferenz
## Generische Variablen
### GTVs in Constraints
* GTVs können in Constraints auf 2 Arten auftauchen.
* Als GTZ und als TPH
* In folgenden Fällen als TPH:
* Die Generische Variable ist nicht in dem Bereich definiert, in dem sie benutzt wird.
* Es kann auch vorkommen, dass die Generische Variable in der gleichen Klasse definiert wurde, aber für eine andere Methode gilt.
* In folgenden Fällen als GTV:
* Die Generische Variable ist für den Bereich definiert, in dem der Constraint generiert wird.
* In der selben Methode oder der selben Klasse. Dies lässt sich überprüfen, indem man die Klasse in welcher die GTV deklariert wurde mit der Klasse in welcher deren Typ benutzt wird vergleicht.
* Ist die GTV als Klassenparameter definiert und aus der selben Klasse wird darauf zugegriffen.
* Die GTV ist in einer Methode oder FieldDeclaration definiert, aber nicht dem selben wie darauf zugegriffen wird.
## ResultSet
* Spezifisch für jedes SourceFile (nicht für jede Klasse)
* mehrere ResultSets pro Klasse
*
* Enthält:
* constraintPairs
* unifiedConstraints
## TypeInsertSet
* Stellt die Typeinsetzung für eine der generierten Lösungen dar
* Setzt alle Typen und generischen Variablen ein, welche zu dieser Lösung gehören
## Ablauf Typinferenz:
1. Parsen
* (Parser postProcessing)
2. Typinferenz
* Anfangspunkt SourceFile
* löst geparste Typen zu richtigen Typen auf (RefTypes, GenericVar)
* setzt TPHs ein
* bildet Constraints, welche in ResultSet gesammelt werden. ResultSet wird durch Syntaxbaum gereicht.
* Assumptions generieren
* Wird im Syntaxbaum für jeden Knoten ausgeführt und die Assumptions für darunterliegende Knoten gebildet
*
3. Unifizierung
* wird im SourceFile aufgerufen
* unifiziert Constraints aller im SourceFile vorkommenden Klassen
4. Erstellen von TypeInsertSet
* Durchlaufen des Syntaxbaumes
* Jeder Knoten erstellt TypeInsertSets anhand des ResultSets.
* Bei Knoten, welche Generische Variablen beinhalten können werden GenericTypeInsertPoints erstellt
5. Einsetzen eines TypeInsertSet (optional)
1. Auf allen TypeInsertPoints die getUnresolvedTPHs-Methoden aufrufen
2. Alle Abhängigkeiten dieser
# Typinferenz für Java 8
## Programmablauf
1. SourceFile parst die Java-Dateien
2. SourceFile erstellt die Basic/Global Assumptions
3. Das Globale AssumptionSet wird anschließend jeder Klasse im Syntaxbaum mit dem TRProg aufruf übergeben
4. Jede Klasse verwaltet lokale Variablen in ihrem eigenen AssumptionSet. Das Globale ist Klassenübergreifend und jede AssumptionType darf darin nur einmalig gesetzt werden.
5. Haben alle Klassen ihrer Constraints erstellt können diese Unifiziert werden.
## Overloading
* Die Overloading Klasse generiert Constraints aus einem Methodenaufruf.

View File

@ -36,7 +36,7 @@ import de.dhbwstuttgart.typeinference.unify.Unify;
// ino.class.Class.23010.declaration
public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWithOffset, Generic, GenericTypeInsertable
public class Class extends GTVDeclarationContext implements AClassOrInterface, IItemWithOffset, Generic, GenericTypeInsertable
// ino.end
// ino.class.Class.23010.body
{
@ -1298,5 +1298,9 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWit
public Type getSuperClass(){
return this.superClass;
}
@Override
public boolean isClass() {
return true;
}
}
// ino.end

View File

@ -18,7 +18,7 @@ import de.dhbwstuttgart.typeinference.Typeable;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint;
public abstract class Field extends SyntaxTreeNode implements TypeInsertable, Typeable, Generic, GenericTypeInsertable{
public abstract class Field extends GTVDeclarationContext implements TypeInsertable, Typeable, Generic, GenericTypeInsertable{
protected Vector<DeclId> declid = new Vector<DeclId>(); // Vector, da 'int a, b, c, ...' auch eingeparst werden muss
@ -166,4 +166,8 @@ public abstract class Field extends SyntaxTreeNode implements TypeInsertable, Ty
public void setGenericParameter(GenericDeclarationList params) {
this.genericParameters = params;
}
@Override
public boolean isClass() {
return false;
}
}

View File

@ -137,6 +137,7 @@ public class FieldDeclaration extends Field{
//TypeCheck, falls es sich um einen RefType handelt:
ConstraintType thisType = this.getType().TYPE(localAssumptions, this);
this.setType(thisType.getType());
/*
if(this.getType()!=null && (this.getType() instanceof RefType)){
Type replaceType = null;

View File

@ -0,0 +1,15 @@
package de.dhbwstuttgart.syntaxtree;
import java.util.Vector;
/**
* Beischreibt eine SyntaxTreeNode, welcher die Eigenschaft besitzt,
* dass bei seiner Deklaration auch Generische Typvariablen deklariert wurden.
*/
public abstract class GTVDeclarationContext extends SyntaxTreeNode {
@Override
public GTVDeclarationContext getGTVDeclarationContext(){
return this;
}
public abstract boolean isClass();
}

View File

@ -110,4 +110,20 @@ public abstract class SyntaxTreeNode implements IItemWithOffset{
//TODO: Implementieren. Hier sollte ein Lookup in die Assumptions dieses Knotens erfolgen
return false;
}
public SyntaxTreeNode getMatchingParentNode(SyntaxTreeNode inNode) {
SyntaxTreeNode node = inNode;
while(node!=null){
if(node.equals(this))return this;
node = inNode.getParent();
}
if(this.getParent()!=null)return this.getParent().getMatchingParentNode(inNode);
return null;
}
public GTVDeclarationContext getGTVDeclarationContext(){
if(this.getParent()==null)return null;
return this.getParent().getGTVDeclarationContext();
}
}

View File

@ -185,7 +185,6 @@ public class LocalOrFieldVar extends Expr
public String getTypeInformation(){
return this.getType()+" "+this.get_Name();
}
@Override

View File

@ -20,6 +20,7 @@ import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint;
import de.dhbwstuttgart.parser.JavaClassName;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.GTVDeclarationContext;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
// ino.class.GenericTypeVar.26505.description type=javadoc
/**
@ -225,6 +226,10 @@ public class GenericTypeVar extends Type
super.parserPostProcessing(parent);
//if(parentTemp != null)this.parent = parentTemp; //Der Parenttype einer GenericVar soll sich nicht ändern können, falls einmal gesetzt.
}
public GTVDeclarationContext getDeclarationContext() {
return this.getGTVDeclarationContext();
}
}

View File

@ -4,6 +4,7 @@ import de.dhbwstuttgart.parser.JavaClassName;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.Field;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
public class FieldAssumption extends Assumption {
@ -38,5 +39,4 @@ public class FieldAssumption extends Assumption {
return true;
}
}

View File

@ -1,10 +1,15 @@
package de.dhbwstuttgart.typeinference.assumptions;
import de.dhbwstuttgart.parser.JavaClassName;
import de.dhbwstuttgart.syntaxtree.FieldDeclaration;
import de.dhbwstuttgart.syntaxtree.GTVDeclarationContext;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.Class;
public class GenericVarAssumption extends Assumption{

View File

@ -8,6 +8,7 @@ import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.parser.JavaClassName;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.GTVDeclarationContext;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
@ -327,7 +328,10 @@ public class TypeAssumptions {
for(GenericVarAssumption ass : this.genericVarAssumptions){
//if(ass.inheritsType(t))return t;
if(ass.getIdentifier().equals(t.getName())){
if(! ass.getAssumedType().getParentClass().equals(inNode.getParentClass())){ //hier muss nach der ParentClass von inNode gefragt werden, da die ParentClass von t nicht immer korrekt ist! (TODO: Überprüfen)
//Generische Variable gefunden!
GTVDeclarationContext gtvDeclNode = ass.getAssumedType().getDeclarationContext();
if(gtvDeclNode == null || gtvDeclNode.isClass()
|| !gtvDeclNode.equals(inNode.getGTVDeclarationContext())){ //hier muss nach der ParentClass von inNode gefragt werden, da die ParentClass von t nicht immer korrekt ist! (TODO: Überprüfen)
TypeAssumptions.log.debug(t+" ist NICHT in Klasse: "+ass.getAssumedType().getParentClass(), Section.ASSUMPTIONS);
//Ist die Generische Variable nicht aus dieser Klasse, so muss sie zu einem TPH umgewandelt werden:
return new ConstraintType(ass.getAssumedType().getTypePlaceHolder(inNode));
@ -389,7 +393,6 @@ public class TypeAssumptions {
*/
public void addGenericVarAssumption(
GenericTypeVar genericTypeVar) {
//TODO: Hier müssen alle Bounds einzeln geaddet werden. Die Bounds müssen hierbei nicht gespeichert werden, deren Constraints generiert die TYPE-Methode der GenericVarDeclarations
this.genericVarAssumptions.add(new GenericVarAssumption(genericTypeVar));
}

View File

@ -0,0 +1,12 @@
class Test {
String var;
<A> A m (A x) {
return x;
}
m2(){
return m(var);
}
}

View File

@ -0,0 +1,18 @@
package plugindevelopment.TypeInsertTests;
import java.util.Vector;
import org.junit.Test;
public class LambdaTest26 {
private static final String TEST_FILE = "LambdaTest26.jav";
@Test
public void run(){
Vector<String> mustContain = new Vector<String>();
//mustContain.add("A a");
MultipleTypesInsertTester.test(this.TEST_FILE, mustContain);
}
}

View File

@ -0,0 +1,5 @@
class LambdaTest<A,B>{
op = (m) -> (f) -> f.apply(this,m);
}

View File

@ -0,0 +1,23 @@
package plugindevelopment.TypeInsertTests;
import java.util.Vector;
import org.junit.Test;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.LoggerConfiguration;
import de.dhbwstuttgart.logger.Section;
public class LambdaTest2_2 {
private static final String TEST_FILE = "LambdaTest2_2.jav";
@Test
public void run(){
Logger.getConfiguration().setOutput(Section.ASSUMPTIONS, System.out);
Vector<String> mustContain = new Vector<String>();
//mustContain.add("S m");
MultipleTypesInsertTester.test(this.TEST_FILE, mustContain);
}
}