Typ-Unifikation jetzt in eigenem Thread.

This commit is contained in:
Michael Uhl 2019-01-16 22:34:42 +01:00
parent 14c49c22a7
commit c351cd4adf
2 changed files with 143 additions and 119 deletions

View File

@ -13,6 +13,9 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.Vector; import java.util.Vector;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.eclipse.core.runtime.ILog; import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
@ -22,15 +25,15 @@ import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typedeployment.TypeInsert; import de.dhbwstuttgart.typedeployment.TypeInsert;
import de.dhbwstuttgart.typedeployment.TypeInsertFactory; import de.dhbwstuttgart.typedeployment.TypeInsertFactory;
import de.dhbwstuttgart.typeinference.result.ResolvedType;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import typinferenzplugin.editor.JavEditor; import typinferenzplugin.editor.JavEditor;
import typinferenzplugin.error.ErrorOutput; import typinferenzplugin.error.ErrorOutput;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
public class Typinferenz { public class Typinferenz {
private static final ILog LOG = Activator.getDefault().getLog(); private static final ILog LOG = Activator.getDefault().getLog();
@ -47,10 +50,9 @@ public class Typinferenz {
public Vector<TypeReplaceMarker> run() throws TypeinferenceException { public Vector<TypeReplaceMarker> run() throws TypeinferenceException {
Vector<TypeReplaceMarker> ret = new Vector<TypeReplaceMarker>(); Vector<TypeReplaceMarker> ret = new Vector<TypeReplaceMarker>();
try { try {
// JavaTXCompiler compiler = new
// JavaTXCompiler(Arrays.asList(editor.getFilePath().toFile()), false);
JavaTXCompiler compiler = new JavaTXCompiler(editor.getFilePath().toFile(), false); JavaTXCompiler compiler = new JavaTXCompiler(editor.getFilePath().toFile(), false);
this.parsedSource = compiler.sourceFiles.get(editor.getFilePath().toFile()); this.parsedSource = compiler.sourceFiles.get(editor.getFilePath().toFile());
tiResults = compiler.typeInference(); tiResults = compiler.typeInference();
Set<TypeInsert> tips = new HashSet<>(); Set<TypeInsert> tips = new HashSet<>();
for (ResultSet tiResult : tiResults) { for (ResultSet tiResult : tiResults) {
@ -65,21 +67,7 @@ public class Typinferenz {
} }
} }
} }
/*
* //Bytecode generieren: String outputDirectory =
* editor.getFilePath().toString(); outputDirectory =
* outputDirectory.substring(0,
* outputDirectory.length()-editor.getFilePath().lastSegment().length());//
* ".jav" hat länge 4 List<ByteCodeResult> bytecodeResults =
* compiler.generateBytecode(parsedSourceFiles, new
* TypeinferenceResults(results)); for(ByteCodeResult result: bytecodeResults){
* JavaClass javaClass = result.getByteCode().getJavaClass(); javaClass.dump(new
* File(outputDirectory+javaClass.getClassName()+".class"));
*
* for(ClassGenerator cg: result.getByteCode().getExtraClasses().values()){
* JavaClass jc = cg.getJavaClass(); jc.dump(new
* File(outputDirectory+jc.getClassName()+".class")); } }
*/
String outputDirectory = editor.getFilePath().toString(); String outputDirectory = editor.getFilePath().toString();
outputDirectory = outputDirectory.substring(0, outputDirectory = outputDirectory.substring(0,
outputDirectory.length() - editor.getFilePath().lastSegment().length());// ".jav" hat Länge 4 outputDirectory.length() - editor.getFilePath().lastSegment().length());// ".jav" hat Länge 4

View File

@ -3,16 +3,24 @@ package typinferenzplugin.editor;
import java.util.Vector; import java.util.Vector;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.inject.Inject;
import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ICoreRunnable;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.e4.ui.di.UISynchronize;
import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position; import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation; import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.editors.text.TextEditor; import org.eclipse.ui.editors.text.TextEditor;
@ -39,6 +47,9 @@ import typinferenzplugin.Typinferenz;
import typinferenzplugin.error.ErrorOutput; import typinferenzplugin.error.ErrorOutput;
import static java.util.stream.Collectors.toSet; import static java.util.stream.Collectors.toSet;
import static org.eclipse.core.runtime.IStatus.ERROR;
import static org.eclipse.core.runtime.IStatus.INFO;
import static typinferenzplugin.Activator.PLUGIN_ID;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -46,12 +57,19 @@ import java.util.TreeSet;
//Example from: http://help.eclipse.org/indigo/index.jsp //Example from: http://help.eclipse.org/indigo/index.jsp
/** /**
* Editor f<EFBFBD>r .jav-Dateien * Editor f<EFBFBD>r .jav-Dateien Anmerkung: F<EFBFBD>r jede ge<EFBFBD>ffntete Datei wird eine
* Anmerkung: F<EFBFBD>r jede ge<EFBFBD>ffntete Datei wird eine Instanz des Editors erstellt * Instanz des Editors erstellt
*
* @author janulrich * @author janulrich
* *
*/ */
public class JavEditor extends TextEditor{ public class JavEditor extends TextEditor {
private static final ILog LOG = Activator.getDefault().getLog();
// get UISynchronize injected as field
@Inject
UISynchronize sync;
private Typinferenz typeinference; private Typinferenz typeinference;
private JavOutline outlinePage; private JavOutline outlinePage;
@ -67,13 +85,14 @@ public class JavEditor extends TextEditor{
private Vector<TypeReplaceMarker> typeReplaceMarkers = new Vector<TypeReplaceMarker>(); private Vector<TypeReplaceMarker> typeReplaceMarkers = new Vector<TypeReplaceMarker>();
//Help: http://wiki.eclipse.org/FAQ_How_do_I_get_started_with_creating_a_custom_text_editor%3F // Help:
public JavEditor(){ // http://wiki.eclipse.org/FAQ_How_do_I_get_started_with_creating_a_custom_text_editor%3F
public JavEditor() {
super(); super();
//install the source configuration // install the source configuration
//setSourceViewerConfiguration(new HTMLConfiguration()); // setSourceViewerConfiguration(new HTMLConfiguration());
//install the document provider // install the document provider
//setDocumentProvider(new HTMLDocumentProvider()); // setDocumentProvider(new HTMLDocumentProvider());
typeinference = new Typinferenz(this); typeinference = new Typinferenz(this);
} }
@ -83,20 +102,20 @@ public class JavEditor extends TextEditor{
this.typeReconstruction(); // Marker generieren this.typeReconstruction(); // Marker generieren
} }
/* (non-Javadoc) /*
* Method declared on AbstractTextEditor * (non-Javadoc) Method declared on AbstractTextEditor
*/ */
protected void initializeEditor() { protected void initializeEditor() {
super.initializeEditor(); super.initializeEditor();
setSourceViewerConfiguration(new JavViewerConfiguration(this)); setSourceViewerConfiguration(new JavViewerConfiguration(this));
//install the document provider // install the document provider
//setDocumentProvider(new JavFileProvider()); // setDocumentProvider(new JavFileProvider());
} }
@Override @Override
public void doSave(IProgressMonitor monitor) { public void doSave(IProgressMonitor monitor) {
super.doSave(monitor); super.doSave(monitor);
//Wird aufgerufen, sobald das Dokument gespeichert wird. // Wird aufgerufen, sobald das Dokument gespeichert wird.
this.removeMarkers(); this.removeMarkers();
this.typeReconstruction(); this.typeReconstruction();
} }
@ -105,54 +124,64 @@ public class JavEditor extends TextEditor{
* Startet den Typinferenzalgorithmus, zuvor sollten alle Marker entfernt werden * Startet den Typinferenzalgorithmus, zuvor sollten alle Marker entfernt werden
*/ */
private void typeReconstruction() { private void typeReconstruction() {
Vector<JavMarker> markers= new Vector<JavMarker>(); Job job = Job.create("Update table", (ICoreRunnable) monitor -> {
if(!this.typeReplaceMarkers.isEmpty() || !this.errorMarkers.isEmpty()){ // do something long running
new ErrorOutput("Fehler: Zuerst Marker l<>schen, bevor Typinferenz durchgef<65>hrt werden kann"); Vector<JavMarker> markers = new Vector<JavMarker>();
return; if (!this.typeReplaceMarkers.isEmpty() || !this.errorMarkers.isEmpty()) {
} LOG.log(new Status(ERROR, PLUGIN_ID, "Fehler: Zuerst Marker löschen, bevor Typinferenz durchgef<65>hrt werden kann"));
//this.typeReplaceMarkers = new Vector<TypeReplaceMarker>(); return;
//this.errorMarkers = new Vector<JavMarker>(); }
try{
this.typeReplaceMarkers = typeinference.run();
for(TypeReplaceMarker m : this.getTypeReplaceMarkers()){
markers.add(m);
};
}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<65>hrt. Berechnete Marker:\n"+markers);
IResource activeDocument = extractResource(); try {
if(activeDocument == null){ this.typeReplaceMarkers = typeinference.run();
new ErrorOutput("Kann das aktive Dokument nicht ermitteln"); for (TypeReplaceMarker m : this.getTypeReplaceMarkers()) {
}else{ markers.add(m);
this.placeMarkers(activeDocument, markers); }
} ;
this.sourceFile = typeinference.getSourceFile(); } catch (TypeinferenceException texc) {
this.errorMarkers.addAll(markers); markers.add(new ErrorMarker(texc.getMessage(), new CodePoint(texc.getOffset())));
this.updateOutlinePage(); }
//this.outlinePage.update(this.sourceFile,this.markers); // Anschließend die TypeReplaceMarker im Quellcode anzeigen:
// https://stackoverflow.com/questions/8945371/how-to-implement-quick-fix-quick-assist-for-custom-eclipse-editor
LOG.log(new Status(INFO, PLUGIN_ID, "Typinferez durchgeführt. Berechnete Marker:\n" + markers));
Display.getDefault().asyncExec(() -> {
// do something in the user interface
IResource activeDocument = extractResource();
if (activeDocument == null) {
LOG.log(new Status(ERROR, PLUGIN_ID, "Kann das aktive Dokument nicht ermitteln"));
} else {
this.placeMarkers(activeDocument, markers);
}
this.sourceFile = typeinference.getSourceFile();
this.errorMarkers.addAll(markers);
this.updateOutlinePage();
// this.outlinePage.update(this.sourceFile,this.markers);
});
});
// Start the Job
job.schedule();
} }
IResource extractResource() { IResource extractResource() {
IEditorInput input = this.getEditorInput(); IEditorInput input = this.getEditorInput();
if (!(input instanceof IFileEditorInput)) if (!(input instanceof IFileEditorInput))
return null; return null;
return ((IFileEditorInput)input).getFile(); return ((IFileEditorInput) input).getFile();
} }
private void placeMarkers(IResource inDocument, Vector<? extends JavMarker> markers){ private void placeMarkers(IResource inDocument, Vector<? extends JavMarker> markers) {
//Marker Tut: http://wiki.eclipse.org/FAQ_How_do_I_create_my_own_tasks,_problems,_bookmarks,_and_so_on%3F // Marker Tut:
//ResourceMarkerAnnotationModel model = new ResourceMarkerAnnotationModel(inDocument.); // http://wiki.eclipse.org/FAQ_How_do_I_create_my_own_tasks,_problems,_bookmarks,_and_so_on%3F
for(JavMarker rm : markers){ // ResourceMarkerAnnotationModel model = new
// ResourceMarkerAnnotationModel(inDocument.);
for (JavMarker rm : markers) {
CodePoint point = rm.getPoint(); CodePoint point = rm.getPoint();
try { try {
IMarker m = inDocument.createMarker(Activator.TYPINFERENZMARKER_NAME); IMarker m = inDocument.createMarker(Activator.TYPINFERENZMARKER_NAME);
m.setAttribute(IMarker.CHAR_START, point.getPositionInCode()); m.setAttribute(IMarker.CHAR_START, point.getPositionInCode());
m.setAttribute(IMarker.CHAR_END, point.getPositionInCode()+1); m.setAttribute(IMarker.CHAR_END, point.getPositionInCode() + 1);
String message = rm.getMessage(); String message = rm.getMessage();
m.setAttribute(IMarker.MESSAGE, message); m.setAttribute(IMarker.MESSAGE, message);
m.setAttribute(IMarker.SEVERITY, 1); m.setAttribute(IMarker.SEVERITY, 1);
@ -165,24 +194,25 @@ public class JavEditor extends TextEditor{
} }
private Annotation addAnnotation(IMarker marker, int offset) { private Annotation addAnnotation(IMarker marker, int offset) {
//The DocumentProvider enables to get the document currently loaded in the editor // The DocumentProvider enables to get the document currently loaded in the
// editor
IDocumentProvider idp = this.getDocumentProvider(); IDocumentProvider idp = this.getDocumentProvider();
//This is the document we want to connect to. This is taken from // This is the document we want to connect to. This is taken from
//the current editor input. // the current editor input.
IDocument document = idp.getDocument(this.getEditorInput()); IDocument document = idp.getDocument(this.getEditorInput());
//The IannotationModel enables to add/remove/change annotation to a Document // The IannotationModel enables to add/remove/change annotation to a Document
//loaded in an Editor // loaded in an Editor
IAnnotationModel iamf = idp.getAnnotationModel(this.getEditorInput()); IAnnotationModel iamf = idp.getAnnotationModel(this.getEditorInput());
//Note: The annotation type id specify that you want to create one of your // Note: The annotation type id specify that you want to create one of your
//annotations // annotations
SimpleMarkerAnnotation ma = new SimpleMarkerAnnotation("typinferenzplugin.annotation",marker); SimpleMarkerAnnotation ma = new SimpleMarkerAnnotation("typinferenzplugin.annotation", marker);
//Finally add the new annotation to the model // Finally add the new annotation to the model
iamf.connect(document); iamf.connect(document);
iamf.addAnnotation(ma,new Position(offset,1)); iamf.addAnnotation(ma, new Position(offset, 1));
iamf.disconnect(document); iamf.disconnect(document);
return ma; return ma;
@ -190,9 +220,10 @@ public class JavEditor extends TextEditor{
/** /**
* Löscht die zu marker geh<EFBFBD>rende Annotation * Löscht die zu marker geh<EFBFBD>rende Annotation
*
* @param marker * @param marker
*/ */
private void deleteAnnotation(JavMarker marker){ private void deleteAnnotation(JavMarker marker) {
IDocumentProvider idp = this.getDocumentProvider(); IDocumentProvider idp = this.getDocumentProvider();
IDocument document = idp.getDocument(this.getEditorInput()); IDocument document = idp.getDocument(this.getEditorInput());
IAnnotationModel iamf = idp.getAnnotationModel(this.getEditorInput()); IAnnotationModel iamf = idp.getAnnotationModel(this.getEditorInput());
@ -208,7 +239,7 @@ public class JavEditor extends TextEditor{
public Object getAdapter(Class required) { public Object getAdapter(Class required) {
if (IContentOutlinePage.class.equals(required)) { if (IContentOutlinePage.class.equals(required)) {
if (outlinePage == null) { if (outlinePage == null) {
outlinePage= new JavOutline(this.sourceFile, this.getTypeReplaceMarkers()); outlinePage = new JavOutline(this.sourceFile, this.getTypeReplaceMarkers());
} }
this.updateOutlinePage(); this.updateOutlinePage();
return outlinePage; return outlinePage;
@ -216,40 +247,42 @@ public class JavEditor extends TextEditor{
return super.getAdapter(required); return super.getAdapter(required);
} }
/** /**
* Diese Funktion f<EFBFBD>hrt einen ReplaceMarker aus. * Diese Funktion f<EFBFBD>hrt einen ReplaceMarker aus.
*
* @param typeReplaceMarker * @param typeReplaceMarker
*/ */
public void runReplaceMarker(TypeReplaceMarker typeReplaceMarker) { public void runReplaceMarker(TypeReplaceMarker typeReplaceMarker) {
IDocument document = this.getDocumentProvider().getDocument(this.getEditorInput()); IDocument document = this.getDocumentProvider().getDocument(this.getEditorInput());
document.set(typeReplaceMarker.insertType(document.get())); document.set(typeReplaceMarker.insertType(document.get()));
this.removeMarkers(); this.removeMarkers();
//Erneut den Typinferenzalgorithmus ausf<EFBFBD>hren: // Erneut den Typinferenzalgorithmus ausf<EFBFBD>hren:
this.typeReconstruction(); this.typeReconstruction();
} }
private void removeMarkers(){ private void removeMarkers() {
IResource document = this.extractResource(); IResource document = this.extractResource();
try { try {
document.deleteMarkers(Activator.TYPINFERENZMARKER_NAME, true, IProject.DEPTH_INFINITE); document.deleteMarkers(Activator.TYPINFERENZMARKER_NAME, true, IProject.DEPTH_INFINITE);
} catch (CoreException e) { } catch (CoreException e) {
e.printStackTrace(); e.printStackTrace();
} }
for(JavMarker jm : errorMarkers)this.deleteAnnotation(jm); for (JavMarker jm : errorMarkers)
for(JavMarker jm : typeReplaceMarkers)this.deleteAnnotation(jm); this.deleteAnnotation(jm);
for (JavMarker jm : typeReplaceMarkers)
this.deleteAnnotation(jm);
this.errorMarkers.removeAllElements(); this.errorMarkers.removeAllElements();
this.typeReplaceMarkers.removeAllElements(); this.typeReplaceMarkers.removeAllElements();
this.updateOutlinePage(); this.updateOutlinePage();
//this.outlinePage.update(sourceFile, markers); // this.outlinePage.update(sourceFile, markers);
} }
/** /**
* Aktualisiert die OutlinePage, falls vorhanden. * Aktualisiert die OutlinePage, falls vorhanden. Muss nach <EFBFBD>nderungen an
* Muss nach <EFBFBD>nderungen an markers aufgerufen werden. * markers aufgerufen werden.
*/ */
private void updateOutlinePage() { private void updateOutlinePage() {
if(this.outlinePage!= null && this.sourceFile != null && this.errorMarkers != null) if (this.outlinePage != null && this.sourceFile != null && this.errorMarkers != null)
this.outlinePage.update(sourceFile, this.getTypeReplaceMarkers()); this.outlinePage.update(sourceFile, this.getTypeReplaceMarkers());
} }
@ -257,8 +290,8 @@ public class JavEditor extends TextEditor{
return this.getDocumentProvider().getDocument(this.getEditorInput()).get(); return this.getDocumentProvider().getDocument(this.getEditorInput()).get();
} }
private Vector<TypeReplaceMarker> getTypeReplaceMarkers(){ private Vector<TypeReplaceMarker> getTypeReplaceMarkers() {
return typeReplaceMarkers ; return typeReplaceMarkers;
} }
public Collection<String> resolveTypeInserts(String identifier, int line) { public Collection<String> resolveTypeInserts(String identifier, int line) {
@ -277,12 +310,15 @@ public class JavEditor extends TextEditor{
} }
/** /**
* Ermittelt die momentan an dem Dokument, für welches dieser Editor zust<EFBFBD>ndig ist, angebrachten TypeReplaceMarker. * Ermittelt die momentan an dem Dokument, für welches dieser Editor zust<EFBFBD>ndig
* Dabei werden die ReplaceMarker herausgefiltert, welche mindestens einen Typ an dem übergebenen offset einsetzen. * ist, angebrachten TypeReplaceMarker. Dabei werden die ReplaceMarker
* herausgefiltert, welche mindestens einen Typ an dem übergebenen offset
* einsetzen.
*
* @param offset * @param offset
* @return * @return
*/ */
public Vector<TypeReplaceMarker> getMarkersAt(int offset){ public Vector<TypeReplaceMarker> getMarkersAt(int offset) {
return null; return null;
} }