Fehler bei der Einsetzung von GenericVarDeclarations beheben

This commit is contained in:
JanUlrich 2014-07-23 17:24:08 +02:00
parent f51b5d5b7c
commit dbf493424e
11 changed files with 156 additions and 28 deletions

7
bin/.gitignore vendored
View File

@ -1 +1,8 @@
/mycompiler
/typinferenz
/userinterface
/bytecode
/myJvmDisassembler
/parser
/plugindevelopment
/syntaxTree

View File

@ -105,4 +105,9 @@ public abstract class SyntaxTreeNode{
}
public boolean seesType(Type tA2) {
//TODO: Implementieren. Hier sollte ein Lookup in die Assumptions dieses Knotens erfolgen
return false;
}
}

View File

@ -112,7 +112,7 @@ public abstract class Field extends SyntaxTreeNode implements TypeInsertable, Ty
@Override
public TypeInsertPoint createTypeInsertPoint(TypePlaceholder tph,
ResultSet resultSet) {
return new TypeInsertPoint(this, resultSet.getTypeEqualTo(tph), resultSet);
return new TypeInsertPoint(this, this, resultSet.getTypeEqualTo(tph), resultSet);
}
/**

View File

@ -267,7 +267,7 @@ public class FormalParameter extends SyntaxTreeNode implements ITypeReplacementL
ResultSet resultSet) {
if(this.getOffset()<=0)return null;
Type t = resultSet.getTypeEqualTo(tph);
return new TypeInsertPoint(this, t, resultSet);
return new TypeInsertPoint(this, this, t, resultSet);
}

View File

@ -519,7 +519,7 @@ public class LocalVarDecl extends Statement implements TypeInsertable
@Override
public TypeInsertPoint createTypeInsertPoint(TypePlaceholder tph,
ResultSet resultSet) {
return new TypeInsertPoint(this, resultSet.getTypeEqualTo(tph),resultSet);
return new TypeInsertPoint(this, this, resultSet.getTypeEqualTo(tph),resultSet);
}
}
// ino.end

View File

@ -27,12 +27,6 @@ public class GenericTypeInsertPoint extends SourcePatchPoint {
private GenericVarPatch patch;
private GenericTypeInsertable genericInsertPoint;
/*
* TODO: Der Generic Type Insert Point sollte mit Generics konstruiert werden.
* Dabei hält jeder InsertPoint nur ein Generic. Die <>-Klammern fügt das insertSet in den Quellcode ein.
* Die Reihenfolge der GenericTIPs ist beim Einsetzen dann egal.
*/
public GenericTypeInsertPoint(GenericTypeInsertable syntaxTreeNode,
GenericVarPatch gtv ,ResultSet resultSet) {
this.resultSet = resultSet;
@ -177,6 +171,7 @@ public class GenericTypeInsertPoint extends SourcePatchPoint {
*/
class GenericVarPatch {
private Vector<GenericVarExtendsDeclarationPatch> genericVarExtendDeclarations = new Vector<GenericVarExtendsDeclarationPatch>();
private Vector<GenericVarDeclarationPatch> genericVarDeclarations = new Vector<GenericVarDeclarationPatch>();
/**
@ -184,33 +179,48 @@ class GenericVarPatch {
* @param p
*/
public void add(Pair p){
GenericVarDeclarationPatch toAdd = new GenericVarDeclarationPatch(p);
GenericVarExtendsDeclarationPatch toAdd = new GenericVarExtendsDeclarationPatch(p);
if(!this.genericVarExtendDeclarations.contains(toAdd))this.genericVarExtendDeclarations.add(toAdd);
}
public void addTPH(TypePlaceholder tph){
GenericVarDeclarationPatch toAdd = new GenericVarDeclarationPatch(tph);
if(!this.genericVarDeclarations.contains(toAdd))this.genericVarDeclarations.add(toAdd);
}
public String getInsertString(ResultSet rs){
String ret = "";
Iterator<GenericVarDeclarationPatch> it = this.genericVarDeclarations.iterator();
while(it.hasNext()){
GenericVarDeclarationPatch p = it.next();
Iterator<GenericVarDeclarationPatch> it1 = this.genericVarDeclarations.iterator();
while(it1.hasNext()){
GenericVarDeclarationPatch p = it1.next();
ret += p.getInsertString(rs);
if(it.hasNext())ret += ", ";
if(it1.hasNext())ret += ", ";
}
if(this.genericVarDeclarations.size()>0)ret+=", ";
Iterator<GenericVarExtendsDeclarationPatch> it2 = this.genericVarExtendDeclarations.iterator();
while(it2.hasNext()){
GenericVarExtendsDeclarationPatch p = it2.next();
ret += p.getInsertString(rs);
if(it2.hasNext())ret += ", ";
}
return ret;
}
public void add(TypePlaceholder tph) {
}
}
/**
* Eine Hilfsklasse zur Einsetzung einer Generischen Variable.
* Eine Hilfsklasse zur Einsetzung einer Generischen Variable mit extend Bedingung.
* @author janulrich
*
*/
class GenericVarDeclarationPatch {
class GenericVarExtendsDeclarationPatch {
private Pair genericPair;
public GenericVarDeclarationPatch(Pair p) {
public GenericVarExtendsDeclarationPatch(Pair p) {
this.genericPair = p;
}
@ -224,11 +234,39 @@ class GenericVarDeclarationPatch {
return ret;
}
@Override
public boolean equals(Object o){
if(!(o instanceof GenericVarExtendsDeclarationPatch))return false;
if(!(this.genericPair.equals(((GenericVarExtendsDeclarationPatch)o).genericPair)))return false;
return true;
}
}
/**
* Eine Hilfsklasse zur Einsetzung einer Generischen Variable.
* @author janulrich
*
*/
class GenericVarDeclarationPatch {
private TypePlaceholder genericPair;
public GenericVarDeclarationPatch(TypePlaceholder p) {
this.genericPair = p;
}
public String getInsertString(ResultSet resultSet){
String ret = "";
if(this.genericPair != null){
ret += this.genericPair.printJavaCode(resultSet);
}
return ret;
}
@Override
public boolean equals(Object o){
if(!(o instanceof GenericVarDeclarationPatch))return false;
if(!(this.genericPair.equals(((GenericVarDeclarationPatch)o).genericPair)))return false;
return true;
}
}

View File

@ -25,18 +25,21 @@ public class TypeInsertPoint extends SourcePatchPoint {
public Type type;
private TypeInsertable point;
private SyntaxTreeNode node;
/**
* Dieser Konstruktor erstellt einen TypInsertPoint
* @param insertPoint
* @param insertNode - muss das gleiche sein wie "insertPoint"
* @param insertType
* @param resultSet
* @param generics - die generischen Parameter des einzusetzenden Typs
*/
public TypeInsertPoint(TypeInsertable insertPoint, Type insertType, ResultSet resultSet){
public TypeInsertPoint(TypeInsertable insertPoint, SyntaxTreeNode insertNode, Type insertType, ResultSet resultSet){
this.point = insertPoint;
this.type = insertType;
this.resultSet = resultSet;
this.node = insertNode;
}
/**
@ -46,9 +49,9 @@ public class TypeInsertPoint extends SourcePatchPoint {
* @return
*/
public JavaCodeResult patch(String fileContent, int additionalOffset) {
String anfang = fileContent.substring(0, this.getInsertNode().getOffset()+additionalOffset);
String anfang = fileContent.substring(0, this.getInsertPoint().getOffset()+additionalOffset);
JavaCodeResult mitte = this.getTypeInsertString();
String ende = fileContent.substring(this.getInsertNode().getOffset()+additionalOffset);
String ende = fileContent.substring(this.getInsertPoint().getOffset()+additionalOffset);
return new JavaCodeResult(anfang).attach(mitte).attach(ende);
}
@ -67,7 +70,7 @@ public class TypeInsertPoint extends SourcePatchPoint {
* @return Der Offset des TypeInsertPoints in dem geparsten Source für dessen Klasse er erstellt wurde.
*/
public int getOffset(){
return this.getInsertNode().getOffset();
return this.getInsertPoint().getOffset();
}
protected Type getInsertType(){
@ -86,15 +89,19 @@ public class TypeInsertPoint extends SourcePatchPoint {
/**
* @return - Der Punkt (Knoten) im Syntaxbaum, für den dieser TypeInsertPoint gilt.
*/
public IItemWithOffset getInsertNode(){
public IItemWithOffset getInsertPoint(){
return this.point;
}
public SyntaxTreeNode getInsertNode(){
return this.node;
}
@Override
public boolean equals(Object obj){
if(! (obj instanceof TypeInsertPoint))return false;
TypeInsertPoint equals = (TypeInsertPoint) obj;
if(!(equals.getInsertNode().equals(this.getInsertNode())))return false;
if(!(equals.getInsertPoint().equals(this.getInsertPoint())))return false;
if(!(equals.getResultSet().equals(this.getResultSet())))return false; //ResultSet spielt bei Equals keine Rolle
if(!(equals.getInsertType().equals(this.getInsertType())))return false;
@ -108,7 +115,7 @@ public class TypeInsertPoint extends SourcePatchPoint {
while(!(ret instanceof Field || ret instanceof Class)){
ret = ret.getParent();
if(ret == null){
throw new DebugException(this.getInsertNode().toString()+" hat kein Feld oder Klasse als Elternelement");
throw new DebugException(this.getInsertPoint().toString()+" hat kein Feld oder Klasse als Elternelement");
}
}
return (GenericTypeInsertable) ret;

View File

@ -75,16 +75,35 @@ public class TypeInsertSet {
* @param tip
* @param tpj
*/
public void insertType(TypeInsertPoint tip, TypePatchJob tpj){
private void insertType(TypeInsertPoint tip, TypePatchJob tpj){
GenericVarPatch gPatch = new GenericVarPatch();//Set der Einzusetzenden generischen Variablendeklarationen
Vector<Pair> pairs = new Vector<>();
for(Pair pair : this.resultSet.getConstraintsFor(tip.getInsertType().getInvolvedTypePlaceholder())){
gPatch.add(pair);
pairs.add(pair);
}
//Kontrollieren ob alle in den Paaren vorhandenen Generischen Variablen in dem Bereich vorkommen:
for(Pair pair : pairs){
if(! tip.getInsertNode().seesType(pair.TA2)){
for(TypePlaceholder tph : pair.getTypePlaceholder()){
if(! pairsDeclareTPH(pairs, tph)){
gPatch.addTPH(tph);
}
}
}
}
GenericTypeInsertPoint gip = new GenericTypeInsertPoint(tip.getGenericTypeVarInsertNode(), gPatch, resultSet);
tpj.add(tip);
tpj.add(gip);
}
private boolean pairsDeclareTPH(Vector<Pair> ps, TypePlaceholder tph){
for(Pair p : ps){
if(p.TA1.equals(tph))return true;
}
return false;
}
/**
* Fügt alle Typen dieses TypeInsertSets in den übergebenen Quellcode ein
* @param fileContent
@ -140,7 +159,7 @@ public class TypeInsertSet {
*/
public TypeInsertPoint getInsertPointFor(TypeInsertable node){
for(TypeInsertPoint point : points){
if(point.getInsertNode().equals(node))return point;
if(point.getInsertPoint().equals(node))return point;
}
return null;
}

View File

@ -0,0 +1,5 @@
class Matrix{
op(m){
return (f) -> f.apply(m,this);
}
}

View File

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

View File

@ -10,6 +10,7 @@ import mycompiler.MyCompiler;
import mycompiler.MyCompilerAPI;
import mycompiler.myparser.JavaParser.yyException;
import mycompiler.mytypereconstruction.TypeinferenceResultSet;
import typinferenz.typedeployment.TypeInsertPoint;
import typinferenz.typedeployment.TypeInsertSet;
public class MultipleTypesInsertTester extends TypeInsertTester{
@ -46,4 +47,34 @@ public class MultipleTypesInsertTester extends TypeInsertTester{
}
}
public static void testSingleInsert(String sourceFileToInfere, Vector<String> mustContain){
String gesamterSrc = "";
String inferedSource = "";
MyCompilerAPI compiler = MyCompiler.getAPI();
try {
compiler.parse(new File(rootDirectory + sourceFileToInfere));
Vector<TypeinferenceResultSet> results = compiler.typeReconstruction();
//TestCase.assertTrue("Es darf nicht mehr als eine Lösungsmöglichkeit geben und nicht "+results.size(), results.size()==1);
for(TypeinferenceResultSet result : results){
TypeInsertSet point = result.getTypeInsertionPoints();
//TestCase.assertTrue("Es muss mindestens ein TypeInsertSet vorhanden sein", points.size()>0);
//TestCase.assertTrue("Es muss mindestens ein TypeInsertPoint vorhanden sein", point.points.size()>0);
if(point.points.size()>0){
for(TypeInsertPoint tip : point.points){
System.out.println("Setze " + tip + " ein:");
inferedSource = point.insertType(tip, TypeInsertTester.getFileContent(rootDirectory + sourceFileToInfere));
System.out.println(inferedSource);
}
gesamterSrc += inferedSource;
}
}
} catch (IOException | yyException e) {
e.printStackTrace();
TestCase.fail();
}
for(String containString : mustContain){
TestCase.assertTrue("\""+containString+"\" muss in den inferierten Lösungen vorkommen",gesamterSrc.contains(containString));
}
}
}