Syntaxvervollständigung (Autocomplete) direkt am Punkt funktioniert.

This commit is contained in:
Michael Uhl 2019-01-02 20:22:06 +01:00
parent 1dd755bc0a
commit c6c3be7cae
3 changed files with 75 additions and 28 deletions

View File

@ -11,17 +11,22 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.Vector;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.Status;
import de.dhbwstuttgart.bytecode.BytecodeGen;
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typedeployment.TypeInsert;
import de.dhbwstuttgart.typedeployment.TypeInsertFactory;
import de.dhbwstuttgart.typeinference.result.ResolvedType;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import typinferenzplugin.editor.JavEditor;
import typinferenzplugin.error.ErrorOutput;
@ -33,6 +38,8 @@ public class Typinferenz {
private JavEditor editor;
private SourceFile parsedSource;
private List<ResultSet> tiResults;
public Typinferenz(JavEditor forEditor) {
this.editor = forEditor;
}
@ -44,11 +51,11 @@ public class Typinferenz {
// JavaTXCompiler(Arrays.asList(editor.getFilePath().toFile()), false);
JavaTXCompiler compiler = new JavaTXCompiler(editor.getFilePath().toFile(), false);
this.parsedSource = compiler.sourceFiles.get(editor.getFilePath().toFile());
List<ResultSet> tiResults = compiler.typeInference();
tiResults = compiler.typeInference();
Set<TypeInsert> tips = new HashSet<>();
for (ResultSet tiResult : tiResults) {
tips.addAll(TypeInsertFactory.createTypeInsertPoints(parsedSource, tiResult));
int numberOfSolutions = 0; // Zählt mit, wie viele verschiedene Lösungen angeboten werden
int numberOfSolutions = 0; // Zählt mit, wie viele verschiedene Lösungen angeboten werden
for (TypeInsert p : tips) {
TypeReplaceMarker toAdd = new TypeReplaceMarker(editor, p);
if (!ret.contains(toAdd)) {
@ -75,7 +82,7 @@ public class Typinferenz {
*/
String outputDirectory = editor.getFilePath().toString();
outputDirectory = outputDirectory.substring(0,
outputDirectory.length() - editor.getFilePath().lastSegment().length());// ".jav" hat ¤nge 4
outputDirectory.length() - editor.getFilePath().lastSegment().length());// ".jav" hat nge 4
// if(tips.size() == 0 && tiResults.size()>0) {
if (tiResults.size() > 0) {
for (SourceFile sf : compiler.sourceFiles.values()) {
@ -93,7 +100,23 @@ public class Typinferenz {
return ret;
}
public Set<String> resolve(TypePlaceholder tph) throws TypeinferenceException {
Set<String> ret = new TreeSet<>();
try {
for (ResultSet tiResult : tiResults) {
ret.add(tiResult.resolveType(tph).resolvedType.acceptTV(new TypeToDescriptor()));
}
} catch (TypeinferenceException texc) {
throw texc; // Die aufrufende Instanz sollte daraus dann einen ErrorMarker generieren.
} catch (Exception exc) {
exc.printStackTrace(); // Hier wird kein Marker generiert... nur Debug-Output
new ErrorOutput("Fehler beim Parsen und Inferieren");
}
return ret;
}
public HashMap<String, byte[]> getBytecode(SourceFile sf, List<ResultSet> resultSets, String path) {
HashMap<String, byte[]> classFiles = new HashMap<>();
BytecodeGen bytecodeGen = new BytecodeGen(classFiles, resultSets, sf, path);

View File

@ -1,5 +1,8 @@
package typinferenzplugin.editor;
import java.util.Set;
import java.util.TreeSet;
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
@ -14,6 +17,7 @@ import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
public class IdentifierFinder extends AbstractASTWalker implements ASTVisitor, ResultSetVisitor {
private RefTypeOrTPHOrWildcardOrGeneric result;
private Set<String> names = new TreeSet<>();
private String identifier;
private int line;
@ -23,15 +27,15 @@ public class IdentifierFinder extends AbstractASTWalker implements ASTVisitor, R
this.line = line;
}
public RefTypeOrTPHOrWildcardOrGeneric getResult() {
return result;
public TypePlaceholder getResult() {
return (TypePlaceholder)result;
}
@Override
public void visit(LocalVar localVar) {
if (localVar.name.equals(identifier)) {
this.result = localVar.getType();
localVar.getType().accept((ResultSetVisitor)this);
((TypePlaceholder)localVar.getType()).accept((ASTVisitor)this);
}
}
@ -39,25 +43,43 @@ public class IdentifierFinder extends AbstractASTWalker implements ASTVisitor, R
public void visit(LocalVarDecl localVar) {
if (localVar.getName().equals(identifier)) {
this.result = localVar.getType();
localVar.getType().accept((ResultSetVisitor)this);
((TypePlaceholder)localVar.getType()).accept((ASTVisitor)this);
}
}
@Override
@Override
public void visit(TypePlaceholder typePlaceholder) {
}
public void visit(PairTPHsmallerTPH p) {
p.getLeft().accept((ResultSetVisitor)this);
p.getRight().accept((ResultSetVisitor)this);
names.add(((TypePlaceholder)p.getRight()).getName());
names.add(((TypePlaceholder)p.getLeft()).getName());
System.out.println();
}
@Override
public void visit(PairTPHequalRefTypeOrWildcardType p) {
p.getLeft().accept((ResultSetVisitor)this);
p.getRight().accept((ResultSetVisitor)this);
names.add(((TypePlaceholder)p.getLeft()).getName());
System.out.println();
}
@Override
public void visit(PairTPHEqualTPH p) {
p.getLeft().accept((ResultSetVisitor)this);
p.getRight().accept((ResultSetVisitor)this);
names.add(((TypePlaceholder)p.getRight()).getName());
names.add(((TypePlaceholder)p.getLeft()).getName());
System.out.println();
}
}

View File

@ -21,10 +21,15 @@ import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.SimpleMarkerAnnotation;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import com.google.common.collect.Sets;
import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typedeployment.TypeInsert;
import de.dhbwstuttgart.typeinference.result.ResolvedType;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import typinferenzplugin.Activator;
import typinferenzplugin.CodePoint;
import typinferenzplugin.ErrorMarker;
@ -41,8 +46,8 @@ import java.util.TreeSet;
//Example from: http://help.eclipse.org/indigo/index.jsp
/**
* Editor für .jav-Dateien
* Anmerkung: Für jede geöffntete Datei wird eine Instanz des Editors erstellt
* Editor f<EFBFBD>r .jav-Dateien
* Anmerkung: F<EFBFBD>r jede ge<EFBFBD>ffntete Datei wird eine Instanz des Editors erstellt
* @author janulrich
*
*/
@ -51,12 +56,12 @@ public class JavEditor extends TextEditor{
private JavOutline outlinePage;
/**
* Der SyntaxBaum für das aktuell geöffnete Dokument.
* Der SyntaxBaum f<EFBFBD>r das aktuell ge<EFBFBD>ffnete Dokument.
*/
private SourceFile sourceFile;
/**
* Die TypeReplaceMarker für das aktuell geÃffnete Dokument
* Die TypeReplaceMarker f<EFBFBD>r das aktuell geöffnete Dokument
*/
private Vector<JavMarker> errorMarkers = new Vector<JavMarker>();
@ -102,7 +107,7 @@ public class JavEditor extends TextEditor{
private void typeReconstruction() {
Vector<JavMarker> markers= new Vector<JavMarker>();
if(!this.typeReplaceMarkers.isEmpty() || !this.errorMarkers.isEmpty()){
new ErrorOutput("Fehler: Zuerst Marker löschen, bevor Typinferenz durchgeführt werden kann");
new ErrorOutput("Fehler: Zuerst Marker l<EFBFBD>schen, bevor Typinferenz durchgef<65>hrt werden kann");
return;
}
//this.typeReplaceMarkers = new Vector<TypeReplaceMarker>();
@ -115,8 +120,8 @@ public class JavEditor extends TextEditor{
}catch(TypeinferenceException texc){
markers.add(new ErrorMarker(texc.getMessage(),new CodePoint(texc.getOffset())));
}
//Anschließend die TypeReplaceMarker im Quellcode anzeigen: https://stackoverflow.com/questions/8945371/how-to-implement-quick-fix-quick-assist-for-custom-eclipse-editor
System.out.println("Typinferez durchgeführt. Berechnete Marker:\n"+markers);
//Anschlie<EFBFBD>end die TypeReplaceMarker im Quellcode anzeigen: https://stackoverflow.com/questions/8945371/how-to-implement-quick-fix-quick-assist-for-custom-eclipse-editor
System.out.println("Typinferez durchgef<EFBFBD>hrt. Berechnete Marker:\n"+markers);
IResource activeDocument = extractResource();
if(activeDocument == null){
@ -182,7 +187,7 @@ public class JavEditor extends TextEditor{
}
/**
* Löscht die zu marker gehörende Annotation
* L<EFBFBD>scht die zu marker geh<EFBFBD>rende Annotation
* @param marker
*/
private void deleteAnnotation(JavMarker marker){
@ -211,14 +216,14 @@ public class JavEditor extends TextEditor{
/**
* Diese Funktion führt einen ReplaceMarker aus.
* Diese Funktion f<EFBFBD>hrt einen ReplaceMarker aus.
* @param typeReplaceMarker
*/
public void runReplaceMarker(TypeReplaceMarker typeReplaceMarker) {
IDocument document = this.getDocumentProvider().getDocument(this.getEditorInput());
document.set(typeReplaceMarker.insertType(document.get()));
this.removeMarkers();
//Erneut den Typinferenzalgorithmus ausführen:
//Erneut den Typinferenzalgorithmus ausf<EFBFBD>hren:
this.typeReconstruction();
}
@ -239,7 +244,7 @@ public class JavEditor extends TextEditor{
/**
* Aktualisiert die OutlinePage, falls vorhanden.
* Muss nach Änderungen an markers aufgerufen werden.
* Muss nach <EFBFBD>nderungen an markers aufgerufen werden.
*/
private void updateOutlinePage() {
if(this.outlinePage!= null && this.sourceFile != null && this.errorMarkers != null)
@ -259,21 +264,18 @@ public class JavEditor extends TextEditor{
IdentifierFinder identifierFinder = new IdentifierFinder(identifier, line);
typeinference.getSourceFile().accept(identifierFinder);
RefTypeOrTPHOrWildcardOrGeneric result = identifierFinder.getResult();
TypePlaceholder typePlaceHolder = identifierFinder.getResult();
int type = result.getOffset().getTokenIndex();
for (TypeReplaceMarker trm : typeinference.run()) {
int tp = trm.getPoint().getPositionInCode();
typesToInsert.add(trm.getInsertPoint().getInsertString());
for (String trm : typeinference.resolve(typePlaceHolder)) {
String typeName = trm.replace("/", ".");
typesToInsert.add(typeName);
}
return typesToInsert;
}
/**
* Ermittelt die momentan an dem Dokument, für welches dieser Editor zuständig ist, angebrachten TypeReplaceMarker.
* Ermittelt die momentan an dem Dokument, f<EFBFBD>r welches dieser Editor zust<EFBFBD>ndig ist, angebrachten TypeReplaceMarker.
* Dabei werden die ReplaceMarker herausgefiltert, welche mindestens einen Typ an dem übergebenen offset einsetzen.
* @param offset
* @return