forked from JavaTX/JavaCompilerCore
Fehler bei der Einsetzung von GenericVarDeclarations beheben
This commit is contained in:
parent
f51b5d5b7c
commit
dbf493424e
7
bin/.gitignore
vendored
7
bin/.gitignore
vendored
@ -1 +1,8 @@
|
|||||||
/mycompiler
|
/mycompiler
|
||||||
|
/typinferenz
|
||||||
|
/userinterface
|
||||||
|
/bytecode
|
||||||
|
/myJvmDisassembler
|
||||||
|
/parser
|
||||||
|
/plugindevelopment
|
||||||
|
/syntaxTree
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ public abstract class Field extends SyntaxTreeNode implements TypeInsertable, Ty
|
|||||||
@Override
|
@Override
|
||||||
public TypeInsertPoint createTypeInsertPoint(TypePlaceholder tph,
|
public TypeInsertPoint createTypeInsertPoint(TypePlaceholder tph,
|
||||||
ResultSet resultSet) {
|
ResultSet resultSet) {
|
||||||
return new TypeInsertPoint(this, resultSet.getTypeEqualTo(tph), resultSet);
|
return new TypeInsertPoint(this, this, resultSet.getTypeEqualTo(tph), resultSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -267,7 +267,7 @@ public class FormalParameter extends SyntaxTreeNode implements ITypeReplacementL
|
|||||||
ResultSet resultSet) {
|
ResultSet resultSet) {
|
||||||
if(this.getOffset()<=0)return null;
|
if(this.getOffset()<=0)return null;
|
||||||
Type t = resultSet.getTypeEqualTo(tph);
|
Type t = resultSet.getTypeEqualTo(tph);
|
||||||
return new TypeInsertPoint(this, t, resultSet);
|
return new TypeInsertPoint(this, this, t, resultSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -519,7 +519,7 @@ public class LocalVarDecl extends Statement implements TypeInsertable
|
|||||||
@Override
|
@Override
|
||||||
public TypeInsertPoint createTypeInsertPoint(TypePlaceholder tph,
|
public TypeInsertPoint createTypeInsertPoint(TypePlaceholder tph,
|
||||||
ResultSet resultSet) {
|
ResultSet resultSet) {
|
||||||
return new TypeInsertPoint(this, resultSet.getTypeEqualTo(tph),resultSet);
|
return new TypeInsertPoint(this, this, resultSet.getTypeEqualTo(tph),resultSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ino.end
|
// ino.end
|
||||||
|
@ -27,12 +27,6 @@ public class GenericTypeInsertPoint extends SourcePatchPoint {
|
|||||||
private GenericVarPatch patch;
|
private GenericVarPatch patch;
|
||||||
private GenericTypeInsertable genericInsertPoint;
|
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,
|
public GenericTypeInsertPoint(GenericTypeInsertable syntaxTreeNode,
|
||||||
GenericVarPatch gtv ,ResultSet resultSet) {
|
GenericVarPatch gtv ,ResultSet resultSet) {
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
@ -177,40 +171,56 @@ public class GenericTypeInsertPoint extends SourcePatchPoint {
|
|||||||
*/
|
*/
|
||||||
class GenericVarPatch {
|
class GenericVarPatch {
|
||||||
|
|
||||||
|
private Vector<GenericVarExtendsDeclarationPatch> genericVarExtendDeclarations = new Vector<GenericVarExtendsDeclarationPatch>();
|
||||||
private Vector<GenericVarDeclarationPatch> genericVarDeclarations = new Vector<GenericVarDeclarationPatch>();
|
private Vector<GenericVarDeclarationPatch> genericVarDeclarations = new Vector<GenericVarDeclarationPatch>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fügt eine generische Variable in Form eines Pairs an.
|
* Fügt eine generische Variable in Form eines Pairs an.
|
||||||
* @param p
|
* @param p
|
||||||
*/
|
*/
|
||||||
public void add(Pair 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);
|
if(!this.genericVarDeclarations.contains(toAdd))this.genericVarDeclarations.add(toAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getInsertString(ResultSet rs){
|
public String getInsertString(ResultSet rs){
|
||||||
String ret = "";
|
String ret = "";
|
||||||
Iterator<GenericVarDeclarationPatch> it = this.genericVarDeclarations.iterator();
|
Iterator<GenericVarDeclarationPatch> it1 = this.genericVarDeclarations.iterator();
|
||||||
while(it.hasNext()){
|
while(it1.hasNext()){
|
||||||
GenericVarDeclarationPatch p = it.next();
|
GenericVarDeclarationPatch p = it1.next();
|
||||||
ret += p.getInsertString(rs);
|
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;
|
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
|
* @author janulrich
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class GenericVarDeclarationPatch {
|
class GenericVarExtendsDeclarationPatch {
|
||||||
|
|
||||||
private Pair genericPair;
|
private Pair genericPair;
|
||||||
|
|
||||||
public GenericVarDeclarationPatch(Pair p) {
|
public GenericVarExtendsDeclarationPatch(Pair p) {
|
||||||
this.genericPair = p;
|
this.genericPair = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,11 +234,39 @@ class GenericVarDeclarationPatch {
|
|||||||
return ret;
|
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
|
@Override
|
||||||
public boolean equals(Object o){
|
public boolean equals(Object o){
|
||||||
if(!(o instanceof GenericVarDeclarationPatch))return false;
|
if(!(o instanceof GenericVarDeclarationPatch))return false;
|
||||||
if(!(this.genericPair.equals(((GenericVarDeclarationPatch)o).genericPair)))return false;
|
if(!(this.genericPair.equals(((GenericVarDeclarationPatch)o).genericPair)))return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,18 +25,21 @@ public class TypeInsertPoint extends SourcePatchPoint {
|
|||||||
|
|
||||||
public Type type;
|
public Type type;
|
||||||
private TypeInsertable point;
|
private TypeInsertable point;
|
||||||
|
private SyntaxTreeNode node;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dieser Konstruktor erstellt einen TypInsertPoint
|
* Dieser Konstruktor erstellt einen TypInsertPoint
|
||||||
* @param insertPoint
|
* @param insertPoint
|
||||||
|
* @param insertNode - muss das gleiche sein wie "insertPoint"
|
||||||
* @param insertType
|
* @param insertType
|
||||||
* @param resultSet
|
* @param resultSet
|
||||||
* @param generics - die generischen Parameter des einzusetzenden Typs
|
* @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.point = insertPoint;
|
||||||
this.type = insertType;
|
this.type = insertType;
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
|
this.node = insertNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,9 +49,9 @@ public class TypeInsertPoint extends SourcePatchPoint {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public JavaCodeResult patch(String fileContent, int additionalOffset) {
|
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();
|
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);
|
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.
|
* @return Der Offset des TypeInsertPoints in dem geparsten Source für dessen Klasse er erstellt wurde.
|
||||||
*/
|
*/
|
||||||
public int getOffset(){
|
public int getOffset(){
|
||||||
return this.getInsertNode().getOffset();
|
return this.getInsertPoint().getOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Type getInsertType(){
|
protected Type getInsertType(){
|
||||||
@ -86,15 +89,19 @@ public class TypeInsertPoint extends SourcePatchPoint {
|
|||||||
/**
|
/**
|
||||||
* @return - Der Punkt (Knoten) im Syntaxbaum, für den dieser TypeInsertPoint gilt.
|
* @return - Der Punkt (Knoten) im Syntaxbaum, für den dieser TypeInsertPoint gilt.
|
||||||
*/
|
*/
|
||||||
public IItemWithOffset getInsertNode(){
|
public IItemWithOffset getInsertPoint(){
|
||||||
return this.point;
|
return this.point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SyntaxTreeNode getInsertNode(){
|
||||||
|
return this.node;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj){
|
public boolean equals(Object obj){
|
||||||
if(! (obj instanceof TypeInsertPoint))return false;
|
if(! (obj instanceof TypeInsertPoint))return false;
|
||||||
TypeInsertPoint equals = (TypeInsertPoint) obj;
|
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.getResultSet().equals(this.getResultSet())))return false; //ResultSet spielt bei Equals keine Rolle
|
||||||
if(!(equals.getInsertType().equals(this.getInsertType())))return false;
|
if(!(equals.getInsertType().equals(this.getInsertType())))return false;
|
||||||
|
|
||||||
@ -108,7 +115,7 @@ public class TypeInsertPoint extends SourcePatchPoint {
|
|||||||
while(!(ret instanceof Field || ret instanceof Class)){
|
while(!(ret instanceof Field || ret instanceof Class)){
|
||||||
ret = ret.getParent();
|
ret = ret.getParent();
|
||||||
if(ret == null){
|
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;
|
return (GenericTypeInsertable) ret;
|
||||||
|
@ -75,16 +75,35 @@ public class TypeInsertSet {
|
|||||||
* @param tip
|
* @param tip
|
||||||
* @param tpj
|
* @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
|
GenericVarPatch gPatch = new GenericVarPatch();//Set der Einzusetzenden generischen Variablendeklarationen
|
||||||
|
Vector<Pair> pairs = new Vector<>();
|
||||||
for(Pair pair : this.resultSet.getConstraintsFor(tip.getInsertType().getInvolvedTypePlaceholder())){
|
for(Pair pair : this.resultSet.getConstraintsFor(tip.getInsertType().getInvolvedTypePlaceholder())){
|
||||||
gPatch.add(pair);
|
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);
|
GenericTypeInsertPoint gip = new GenericTypeInsertPoint(tip.getGenericTypeVarInsertNode(), gPatch, resultSet);
|
||||||
tpj.add(tip);
|
tpj.add(tip);
|
||||||
tpj.add(gip);
|
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
|
* Fügt alle Typen dieses TypeInsertSets in den übergebenen Quellcode ein
|
||||||
* @param fileContent
|
* @param fileContent
|
||||||
@ -140,7 +159,7 @@ public class TypeInsertSet {
|
|||||||
*/
|
*/
|
||||||
public TypeInsertPoint getInsertPointFor(TypeInsertable node){
|
public TypeInsertPoint getInsertPointFor(TypeInsertable node){
|
||||||
for(TypeInsertPoint point : points){
|
for(TypeInsertPoint point : points){
|
||||||
if(point.getInsertNode().equals(node))return point;
|
if(point.getInsertPoint().equals(node))return point;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
5
test/plugindevelopment/TypeInsertTests/LambdaTest13.jav
Normal file
5
test/plugindevelopment/TypeInsertTests/LambdaTest13.jav
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
class Matrix{
|
||||||
|
op(m){
|
||||||
|
return (f) -> f.apply(m,this);
|
||||||
|
}
|
||||||
|
}
|
16
test/plugindevelopment/TypeInsertTests/LambdaTest13.java
Normal file
16
test/plugindevelopment/TypeInsertTests/LambdaTest13.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ import mycompiler.MyCompiler;
|
|||||||
import mycompiler.MyCompilerAPI;
|
import mycompiler.MyCompilerAPI;
|
||||||
import mycompiler.myparser.JavaParser.yyException;
|
import mycompiler.myparser.JavaParser.yyException;
|
||||||
import mycompiler.mytypereconstruction.TypeinferenceResultSet;
|
import mycompiler.mytypereconstruction.TypeinferenceResultSet;
|
||||||
|
import typinferenz.typedeployment.TypeInsertPoint;
|
||||||
import typinferenz.typedeployment.TypeInsertSet;
|
import typinferenz.typedeployment.TypeInsertSet;
|
||||||
|
|
||||||
public class MultipleTypesInsertTester extends TypeInsertTester{
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user