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.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<TypeReplaceMarker> run() throws TypeinferenceException {
Vector<TypeReplaceMarker> ret = new Vector<TypeReplaceMarker>();
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<TypeInsert> 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<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();
outputDirectory = outputDirectory.substring(0,
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.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<EFBFBD>r .jav-Dateien
* Anmerkung: F<EFBFBD>r jede ge<EFBFBD>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
*
*/
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<EFBFBD>r das aktuell ge<EFBFBD>ffnete Dokument.
*/
private SourceFile sourceFile;
/**
* Die TypeReplaceMarker f<EFBFBD>r das aktuell geöffnete Dokument
*/
@ -67,13 +85,14 @@ public class JavEditor extends TextEditor{
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
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<JavMarker> markers= new Vector<JavMarker>();
if(!this.typeReplaceMarkers.isEmpty() || !this.errorMarkers.isEmpty()){
new ErrorOutput("Fehler: Zuerst Marker l<>schen, bevor Typinferenz durchgef<65>hrt werden kann");
return;
}
//this.typeReplaceMarkers = new Vector<TypeReplaceMarker>();
//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);
Job job = Job.create("Update table", (ICoreRunnable) monitor -> {
// do something long running
Vector<JavMarker> markers = new Vector<JavMarker>();
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"));
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<? extends JavMarker> 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<? extends JavMarker> 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<EFBFBD>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<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<EFBFBD>hren:
// Erneut den Typinferenzalgorithmus ausf<EFBFBD>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 <EFBFBD>nderungen an markers aufgerufen werden.
* Aktualisiert die OutlinePage, falls vorhanden. Muss nach <EFBFBD>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<TypeReplaceMarker> getTypeReplaceMarkers(){
return typeReplaceMarkers ;
private Vector<TypeReplaceMarker> getTypeReplaceMarkers() {
return typeReplaceMarkers;
}
public Collection<String> resolveTypeInserts(String identifier, int line) {
Collection<String> 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<EFBFBD>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<EFBFBD>ndig
* ist, angebrachten TypeReplaceMarker. Dabei werden die ReplaceMarker
* herausgefiltert, welche mindestens einen Typ an dem übergebenen offset
* einsetzen.
*
* @param offset
* @return
*/
public Vector<TypeReplaceMarker> getMarkersAt(int offset){
public Vector<TypeReplaceMarker> getMarkersAt(int offset) {
return null;
}
public IPath getFilePath() {
return ((FileEditorInput) this.getEditorInput()).getPath();
}
}