diff --git a/src/mycompiler/mytype/Pair.java b/src/mycompiler/mytype/Pair.java index 1db66f94..f594797d 100755 --- a/src/mycompiler/mytype/Pair.java +++ b/src/mycompiler/mytype/Pair.java @@ -380,7 +380,8 @@ public class Pair */ public Vector getTypePlaceholder() { Vector ret = new Vector(); - + if(this.TA1 instanceof TypePlaceholder)ret.add((TypePlaceholder)TA1); + if(this.TA2 instanceof TypePlaceholder)ret.add((TypePlaceholder)TA2); return ret; } } diff --git a/src/mycompiler/mytype/TypePlaceholder.java b/src/mycompiler/mytype/TypePlaceholder.java index 49fdd18d..c1ef7abd 100755 --- a/src/mycompiler/mytype/TypePlaceholder.java +++ b/src/mycompiler/mytype/TypePlaceholder.java @@ -10,6 +10,7 @@ import java.util.Vector; import typinferenz.JavaCodeResult; import typinferenz.ResultSet; import typinferenz.TypeInsertPoint; +import typinferenz.TypeInsertSet; import typinferenz.TypeInsertable; import mycompiler.MyCompiler; import mycompiler.mytypereconstruction.replacementlistener.CReplaceTypeEvent; @@ -511,11 +512,11 @@ public class TypePlaceholder extends Type implements IReplaceTypeEventProvider return equalType.printJavaCode(resultSet); } - public Vector getTypeInsertPoints(ResultSet result) { - Vector ret = new Vector(); + public TypeInsertSet getTypeInsertPoints(ResultSet result) { + TypeInsertSet ret = new TypeInsertSet(); for(ITypeReplacementListener ti : this.m_ReplacementListeners){ if(ti instanceof TypeInsertable){ - new TypeInsertPoint(this, ti, result.getTypeEqualTo(this)); + ret.add(new TypeInsertPoint(this, (TypeInsertable)ti, result.getTypeEqualTo(this), result)); } } return ret; diff --git a/src/mycompiler/mytypereconstruction/TypeinferenceResultSet.java b/src/mycompiler/mytypereconstruction/TypeinferenceResultSet.java index e3e9fb31..5a6cb72c 100755 --- a/src/mycompiler/mytypereconstruction/TypeinferenceResultSet.java +++ b/src/mycompiler/mytypereconstruction/TypeinferenceResultSet.java @@ -10,6 +10,7 @@ import java.util.Vector; import typinferenz.ConstraintsSet; import typinferenz.ResultSet; import typinferenz.TypeInsertPoint; +import typinferenz.TypeInsertSet; import typinferenz.TypinferenzException; import typinferenz.assumptions.TypeAssumptions; import mycompiler.mytype.GenericTypeVar; @@ -116,11 +117,11 @@ public class TypeinferenceResultSet * Berechnet alle möglichen Punkte zum Einsetzen eines Typs im Quelltext an der Stelle dieses TypePlaceholders * @return */ - public Vector getTypeInsertionPoints(){ - Vector ret = new Vector(); + public Vector getTypeInsertionPoints(){ + Vector ret = new Vector(); for(Pair p : constraints){ for(TypePlaceholder tph : p.getTypePlaceholder()){ - ret.addAll(tph.getTypeInsertPoints(this.unifiedConstraints)); + ret.add(tph.getTypeInsertPoints(this.unifiedConstraints)); } } return ret; diff --git a/src/typinferenz/TypeInsertPoint.java b/src/typinferenz/TypeInsertPoint.java index 94ead554..1d46012d 100644 --- a/src/typinferenz/TypeInsertPoint.java +++ b/src/typinferenz/TypeInsertPoint.java @@ -1,11 +1,42 @@ package typinferenz; import mycompiler.mytype.*; +import mycompiler.mytypereconstruction.replacementlistener.ITypeReplacementListener; + public class TypeInsertPoint { - public TypeInsertPoint(TypePlaceholder tph, TypeInsertable insertPoint, Type insertType){ - + private TypePlaceholder tph; + private TypeInsertable point; + private Type type; + private ResultSet resultSet; + + public TypeInsertPoint(TypePlaceholder tph, TypeInsertable insertPoint, Type insertType, ResultSet resultSet){ + this.tph = tph; + this.point = insertPoint; + this.type = insertType; + this.resultSet = resultSet; + } + + /** + * Setzt den Typ dieses TypeInsertPoint in den übergebenen Quelltext ein. + * @param fileContent - der Quelltext + * @param additionalOffset - Falls mehrere Typen in einen Quellcode eingesetzet werden muss die Verschiebung der Offsets mit einbezogen werden. + * @return + */ + public String insertType(String fileContent, int additionalOffset) { + String anfang = fileContent.substring(0, point.getOffset()+additionalOffset); + String mitte = this.getTypeInsertString(); + String ende = fileContent.substring(point.getOffset()+additionalOffset); + return anfang + mitte + ende; + } + + public int getInsertLength() { + return this.getTypeInsertString().length(); } + private String getTypeInsertString(){ + String ret = type.printJavaCode(this.resultSet).toString()+" "; + return ret; + } } diff --git a/src/typinferenz/TypeInsertSet.java b/src/typinferenz/TypeInsertSet.java new file mode 100644 index 00000000..fa80ab87 --- /dev/null +++ b/src/typinferenz/TypeInsertSet.java @@ -0,0 +1,41 @@ +package typinferenz; + +import java.util.Vector; + +/** + * Bündelt ein Set von TypeInsertPoints, die alle zu einem TypePlaceholder gehören. + * Diese müssen gemeinsam eingesetzt werden. + * @author janulrich + * + */ +public class TypeInsertSet { + + Vector points = new Vector(); + + public TypeInsertSet(TypeInsertPoint p){ + points.add(p); + } + + public TypeInsertSet() { + } + + public void add(TypeInsertPoint typeInsertPoint) { + points.add(typeInsertPoint); + } + + /** + * Fügt alle Typen dieses TypeInsertSets in den übergebenen Quellcode ein + * @param fileContent + * @return + */ + public String insertAllTypes(String fileContent) { + int additionalOffset = 0; + String ret = fileContent; + for(TypeInsertPoint p : points){ + ret = p.insertType(ret, additionalOffset); + additionalOffset += p.getInsertLength(); + } + return ret; + } + +} diff --git a/test/plugindevelopment/TypeInsertTester.java b/test/plugindevelopment/TypeInsertTester.java new file mode 100644 index 00000000..644c970d --- /dev/null +++ b/test/plugindevelopment/TypeInsertTester.java @@ -0,0 +1,56 @@ +package plugindevelopment; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Vector; + +import typinferenz.TypeInsertPoint; +import typinferenz.TypeInsertSet; +import junit.framework.TestCase; +import mycompiler.MyCompiler; +import mycompiler.MyCompilerAPI; +import mycompiler.myparser.JavaParser.yyException; +import mycompiler.mytypereconstruction.TypeinferenceResultSet; + + +public class TypeInsertTester extends TestCase { + + private static final String rootDirectory = System.getProperty("user.dir")+"/test/plugindevelopment/"; + + public static void test(String sourceFileToInfere, String solutionFile){ + String inferedSource = ""; + MyCompilerAPI compiler = MyCompiler.getAPI(); + try { + compiler.parse(new File(rootDirectory + sourceFileToInfere)); + Vector results = compiler.typeReconstruction(); + assertTrue("Es darf nicht mehr als eine Lösungsmöglichkeit geben", results.size()==1); + for(TypeinferenceResultSet result : results){ + Vector points = result.getTypeInsertionPoints(); + assertTrue("Es muss genau ein TypeInsertSet vorhanden sein", points.size()==1); + for(TypeInsertSet point : points){ + inferedSource = point.insertAllTypes(getFileContent(rootDirectory + sourceFileToInfere)); + String solutionSource = getFileContent(rootDirectory + solutionFile); + System.out.println("\nInferierter Source:\n"+inferedSource); + assertTrue("Nicht das erwartete Ergebnis", inferedSource.equals(solutionSource)); + } + } + + } catch (IOException | yyException e) { + e.printStackTrace(); + fail(); + } + } + + //Source: https://stackoverflow.com/questions/326390/how-to-create-a-java-string-from-the-contents-of-a-file + private static String getFileContent(String path)throws IOException + { + byte[] encoded = Files.readAllBytes(Paths.get(path)); + return StandardCharsets.UTF_8.decode(ByteBuffer.wrap(encoded)).toString(); + } +} diff --git a/test/plugindevelopment/VariableTypeInsertTest.jav b/test/plugindevelopment/VariableTypeInsertTest.jav new file mode 100644 index 00000000..228c7fc1 --- /dev/null +++ b/test/plugindevelopment/VariableTypeInsertTest.jav @@ -0,0 +1,4 @@ + +class VariableTypeInsertTest{ + var = "test"; +} diff --git a/test/plugindevelopment/VariableTypeInsertTest.java b/test/plugindevelopment/VariableTypeInsertTest.java new file mode 100644 index 00000000..f59bcf2e --- /dev/null +++ b/test/plugindevelopment/VariableTypeInsertTest.java @@ -0,0 +1,15 @@ +package plugindevelopment; + +import org.junit.Test; + +public class VariableTypeInsertTest { + + private static final String TEST_FILE = "VariableTypeInsertTest.jav"; + private static final String SOLUTION_FILE = "VariableTypeInsertTestSolution.jav"; + + @Test + public void run(){ + TypeInsertTester.test(this.TEST_FILE, this.SOLUTION_FILE); + } + +} diff --git a/test/plugindevelopment/VariableTypeInsertTestSolution.jav b/test/plugindevelopment/VariableTypeInsertTestSolution.jav new file mode 100644 index 00000000..626e5345 --- /dev/null +++ b/test/plugindevelopment/VariableTypeInsertTestSolution.jav @@ -0,0 +1,4 @@ + +class VariableTypeInsertTest{ + String var = "test"; +}