From c351cd4adfcfcc72272d22f2f74a610997608d13 Mon Sep 17 00:00:00 2001 From: Michael Uhl Date: Wed, 16 Jan 2019 22:34:42 +0100 Subject: [PATCH] Typ-Unifikation jetzt in eigenem Thread. --- .../src/typinferenzplugin/Typinferenz.java | 26 +- .../typinferenzplugin/editor/JavEditor.java | 236 ++++++++++-------- 2 files changed, 143 insertions(+), 119 deletions(-) diff --git a/JavaCompilerPlugin/bundles/JavaCompilerPlugin.Plugin/src/typinferenzplugin/Typinferenz.java b/JavaCompilerPlugin/bundles/JavaCompilerPlugin.Plugin/src/typinferenzplugin/Typinferenz.java index 70f4917..a55d93d 100644 --- a/JavaCompilerPlugin/bundles/JavaCompilerPlugin.Plugin/src/typinferenzplugin/Typinferenz.java +++ b/JavaCompilerPlugin/bundles/JavaCompilerPlugin.Plugin/src/typinferenzplugin/Typinferenz.java @@ -13,6 +13,9 @@ import java.util.List; import java.util.Set; import java.util.TreeSet; 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.Status; @@ -22,15 +25,15 @@ 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; +import static java.util.concurrent.Executors.newSingleThreadExecutor; + public class Typinferenz { private static final ILog LOG = Activator.getDefault().getLog(); @@ -47,10 +50,9 @@ public class Typinferenz { public Vector run() throws TypeinferenceException { Vector ret = new Vector(); try { - // JavaTXCompiler compiler = new - // JavaTXCompiler(Arrays.asList(editor.getFilePath().toFile()), false); JavaTXCompiler compiler = new JavaTXCompiler(editor.getFilePath().toFile(), false); this.parsedSource = compiler.sourceFiles.get(editor.getFilePath().toFile()); + tiResults = compiler.typeInference(); Set tips = new HashSet<>(); 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 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(); outputDirectory = outputDirectory.substring(0, outputDirectory.length() - editor.getFilePath().lastSegment().length());// ".jav" hat Länge 4 diff --git a/JavaCompilerPlugin/bundles/JavaCompilerPlugin.Plugin/src/typinferenzplugin/editor/JavEditor.java b/JavaCompilerPlugin/bundles/JavaCompilerPlugin.Plugin/src/typinferenzplugin/editor/JavEditor.java index 8516b8b..1025c41 100644 --- a/JavaCompilerPlugin/bundles/JavaCompilerPlugin.Plugin/src/typinferenzplugin/editor/JavEditor.java +++ b/JavaCompilerPlugin/bundles/JavaCompilerPlugin.Plugin/src/typinferenzplugin/editor/JavEditor.java @@ -3,16 +3,24 @@ package typinferenzplugin.editor; import java.util.Vector; import java.util.stream.Collectors; +import javax.inject.Inject; + import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; 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.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.Position; import org.eclipse.jface.text.source.Annotation; import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.editors.text.TextEditor; @@ -39,6 +47,9 @@ import typinferenzplugin.Typinferenz; import typinferenzplugin.error.ErrorOutput; 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.Collection; @@ -46,20 +57,27 @@ 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�r .jav-Dateien Anmerkung: F�r jede ge�ffntete Datei wird eine + * Instanz des Editors erstellt + * * @author janulrich * */ -public class JavEditor extends TextEditor{ - private Typinferenz typeinference; +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 JavOutline outlinePage; /** * Der SyntaxBaum f�r das aktuell ge�ffnete Dokument. */ private SourceFile sourceFile; - + /** * Die TypeReplaceMarker f�r das aktuell geöffnete Dokument */ @@ -67,13 +85,14 @@ public class JavEditor extends TextEditor{ private Vector typeReplaceMarkers = new Vector(); - //Help: http://wiki.eclipse.org/FAQ_How_do_I_get_started_with_creating_a_custom_text_editor%3F - public JavEditor(){ + // Help: + // http://wiki.eclipse.org/FAQ_How_do_I_get_started_with_creating_a_custom_text_editor%3F + public JavEditor() { super(); - //install the source configuration - //setSourceViewerConfiguration(new HTMLConfiguration()); - //install the document provider - //setDocumentProvider(new HTMLDocumentProvider()); + // install the source configuration + // setSourceViewerConfiguration(new HTMLConfiguration()); + // install the document provider + // setDocumentProvider(new HTMLDocumentProvider()); typeinference = new Typinferenz(this); } @@ -83,20 +102,20 @@ public class JavEditor extends TextEditor{ this.typeReconstruction(); // Marker generieren } - /* (non-Javadoc) - * Method declared on AbstractTextEditor + /* + * (non-Javadoc) Method declared on AbstractTextEditor */ protected void initializeEditor() { super.initializeEditor(); setSourceViewerConfiguration(new JavViewerConfiguration(this)); - //install the document provider - //setDocumentProvider(new JavFileProvider()); + // install the document provider + // setDocumentProvider(new JavFileProvider()); } - + @Override public void doSave(IProgressMonitor monitor) { super.doSave(monitor); - //Wird aufgerufen, sobald das Dokument gespeichert wird. + // Wird aufgerufen, sobald das Dokument gespeichert wird. this.removeMarkers(); this.typeReconstruction(); } @@ -105,54 +124,64 @@ public class JavEditor extends TextEditor{ * Startet den Typinferenzalgorithmus, zuvor sollten alle Marker entfernt werden */ private void typeReconstruction() { - Vector markers= new Vector(); - if(!this.typeReplaceMarkers.isEmpty() || !this.errorMarkers.isEmpty()){ - new ErrorOutput("Fehler: Zuerst Marker l�schen, bevor Typinferenz durchgef�hrt werden kann"); - return; - } - //this.typeReplaceMarkers = new Vector(); - //this.errorMarkers = new Vector(); - 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�hrt. Berechnete Marker:\n"+markers); + Job job = Job.create("Update table", (ICoreRunnable) monitor -> { + // do something long running + Vector markers = new Vector(); + if (!this.typeReplaceMarkers.isEmpty() || !this.errorMarkers.isEmpty()) { + LOG.log(new Status(ERROR, PLUGIN_ID, "Fehler: Zuerst Marker löschen, bevor Typinferenz durchgef�hrt werden kann")); + return; + } + + 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 + 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); + }); + }); - IResource activeDocument = extractResource(); - if(activeDocument == null){ - new ErrorOutput("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() { - IEditorInput input = this.getEditorInput(); - if (!(input instanceof IFileEditorInput)) - return null; - return ((IFileEditorInput)input).getFile(); - } - - private void placeMarkers(IResource inDocument, Vector markers){ - //Marker Tut: http://wiki.eclipse.org/FAQ_How_do_I_create_my_own_tasks,_problems,_bookmarks,_and_so_on%3F - //ResourceMarkerAnnotationModel model = new ResourceMarkerAnnotationModel(inDocument.); - for(JavMarker rm : markers){ + IEditorInput input = this.getEditorInput(); + if (!(input instanceof IFileEditorInput)) + return null; + return ((IFileEditorInput) input).getFile(); + } + + private void placeMarkers(IResource inDocument, Vector markers) { + // Marker Tut: + // http://wiki.eclipse.org/FAQ_How_do_I_create_my_own_tasks,_problems,_bookmarks,_and_so_on%3F + // ResourceMarkerAnnotationModel model = new + // ResourceMarkerAnnotationModel(inDocument.); + for (JavMarker rm : markers) { CodePoint point = rm.getPoint(); try { IMarker m = inDocument.createMarker(Activator.TYPINFERENZMARKER_NAME); 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(); m.setAttribute(IMarker.MESSAGE, message); m.setAttribute(IMarker.SEVERITY, 1); @@ -163,52 +192,54 @@ public class JavEditor extends TextEditor{ } } } - + 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(); - - //This is the document we want to connect to. This is taken from - //the current editor input. + + // This is the document we want to connect to. This is taken from + // the current editor input. IDocument document = idp.getDocument(this.getEditorInput()); - - //The IannotationModel enables to add/remove/change annotation to a Document - //loaded in an Editor + + // The IannotationModel enables to add/remove/change annotation to a Document + // loaded in an Editor IAnnotationModel iamf = idp.getAnnotationModel(this.getEditorInput()); - - //Note: The annotation type id specify that you want to create one of your - //annotations - SimpleMarkerAnnotation ma = new SimpleMarkerAnnotation("typinferenzplugin.annotation",marker); - - //Finally add the new annotation to the model + + // Note: The annotation type id specify that you want to create one of your + // annotations + SimpleMarkerAnnotation ma = new SimpleMarkerAnnotation("typinferenzplugin.annotation", marker); + + // Finally add the new annotation to the model iamf.connect(document); - iamf.addAnnotation(ma,new Position(offset,1)); + iamf.addAnnotation(ma, new Position(offset, 1)); iamf.disconnect(document); - + return ma; } - + /** * Löscht die zu marker geh�rende Annotation + * * @param marker */ - private void deleteAnnotation(JavMarker marker){ + private void deleteAnnotation(JavMarker marker) { IDocumentProvider idp = this.getDocumentProvider(); IDocument document = idp.getDocument(this.getEditorInput()); IAnnotationModel iamf = idp.getAnnotationModel(this.getEditorInput()); - + iamf.connect(document); iamf.removeAnnotation(marker.getAnnotation()); iamf.disconnect(document); } - + /** * Erzeugt die Outline-View */ public Object getAdapter(Class required) { if (IContentOutlinePage.class.equals(required)) { if (outlinePage == null) { - outlinePage= new JavOutline(this.sourceFile, this.getTypeReplaceMarkers()); + outlinePage = new JavOutline(this.sourceFile, this.getTypeReplaceMarkers()); } this.updateOutlinePage(); return outlinePage; @@ -216,78 +247,83 @@ public class JavEditor extends TextEditor{ return super.getAdapter(required); } - /** * Diese Funktion f�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�hren: this.typeReconstruction(); } - - private void removeMarkers(){ + + private void removeMarkers() { IResource document = this.extractResource(); try { document.deleteMarkers(Activator.TYPINFERENZMARKER_NAME, true, IProject.DEPTH_INFINITE); } catch (CoreException e) { e.printStackTrace(); } - for(JavMarker jm : errorMarkers)this.deleteAnnotation(jm); - for(JavMarker jm : typeReplaceMarkers)this.deleteAnnotation(jm); + for (JavMarker jm : errorMarkers) + this.deleteAnnotation(jm); + for (JavMarker jm : typeReplaceMarkers) + this.deleteAnnotation(jm); this.errorMarkers.removeAllElements(); this.typeReplaceMarkers.removeAllElements(); this.updateOutlinePage(); - //this.outlinePage.update(sourceFile, markers); + // this.outlinePage.update(sourceFile, markers); } /** - * Aktualisiert die OutlinePage, falls vorhanden. - * Muss nach �nderungen an markers aufgerufen werden. + * Aktualisiert die OutlinePage, falls vorhanden. Muss nach �nderungen an + * markers aufgerufen werden. */ 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()); } public String getSourceCode() { return this.getDocumentProvider().getDocument(this.getEditorInput()).get(); } - - private Vector getTypeReplaceMarkers(){ - return typeReplaceMarkers ; + + private Vector getTypeReplaceMarkers() { + return typeReplaceMarkers; } - + public Collection resolveTypeInserts(String identifier, int line) { Collection typesToInsert = new TreeSet<>(); - + IdentifierFinder identifierFinder = new IdentifierFinder(identifier, line); typeinference.getSourceFile().accept(identifierFinder); TypePlaceholder typePlaceHolder = identifierFinder.getResult(); - + 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. - * Dabei werden die ReplaceMarker herausgefiltert, welche mindestens einen Typ an dem übergebenen offset einsetzen. + * Ermittelt die momentan an dem Dokument, für welches dieser Editor zust�ndig + * ist, angebrachten TypeReplaceMarker. Dabei werden die ReplaceMarker + * herausgefiltert, welche mindestens einen Typ an dem übergebenen offset + * einsetzen. + * * @param offset * @return */ - public Vector getMarkersAt(int offset){ + public Vector getMarkersAt(int offset) { return null; } public IPath getFilePath() { return ((FileEditorInput) this.getEditorInput()).getPath(); } - + }