Commit ab07e0b7 authored by petter's avatar petter

Project outline, Declaration-Use Analyse and Decl-Use-Hyperlinks

parent 537ca7ee
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry exported="true" kind="lib" path="Compiler.jar" sourcepath="/MiniJava/src"/>
<classpathentry exported="true" kind="lib" path="java-cup-11b-runtime.jar" sourcepath="/CUP/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="/MiniJava/dist/Compiler.jar" sourcepath="/MiniJava/src"/>
<classpathentry kind="lib" path="Compiler.jar" sourcepath="/MiniJava/src"/>
<classpathentry kind="lib" path="java-cup-11b-runtime.jar"/>
<classpathentry kind="output" path="bin"/>
<referencedentry kind="lib" path="/MiniJava/dist/java-cup-11b-runtime.jar" sourcepath="/CUP/java"/>
</classpath>
......@@ -13,10 +13,12 @@ Require-Bundle: org.eclipse.ui,
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Import-Package: org.eclipse.jface.text,
org.eclipse.jface.text.hyperlink,
org.eclipse.jface.text.presentation,
org.eclipse.jface.text.rules,
org.eclipse.jface.text.source,
org.eclipse.ui.editors.text
org.eclipse.ui.editors.text,
org.eclipse.ui.views.contentoutline
Bundle-ClassPath: java-cup-11b-runtime.jar,
.,
Compiler.jar
package mjplugin.ast;
import java.util.HashMap;
import java.util.Map;
import minijava.Decl;
import minijava.Expr.Identifier;
import minijava.MinijavaVisitor;
import mjplugin.editors.GUIErrorReporter;
public class DeclarationUse extends MinijavaVisitor {
private GUIErrorReporter reporter;
public DeclarationUse(GUIErrorReporter reporter) {
this.reporter=reporter;
}
Map<String, Decl> declarations = new HashMap<>();
Map<Identifier,Decl> id2decl = new HashMap<>();
public Map<Identifier,Decl> getBindings(){ return id2decl; }
@Override
public boolean preVisit(Decl d) {
for (Identifier i : d.varlist){
id2decl.put(i,d);
declarations.put(i.i, d);
}
return false;
}
@Override
public void visit(Identifier d) {
if (!declarations.containsKey(d.i)) {
reporter.report("Identifier not declared", d.getLeft(), d.getRight(),null);
return;
}
id2decl.put(d, declarations.get(d.i));
}
}
package mjplugin.ast;
import java.util.Map;
import minijava.Decl;
import minijava.Expr.Identifier;
import minijava.Program;
public class MiniJavaAST {
public Program program;
public MiniJavaAST(Program program) {
private Map<Identifier, Decl> bindings;
public MiniJavaAST(Program program,Map<Identifier, Decl> bindings) {
this.program = program;
this.bindings=bindings;
}
public Decl getBinding(Identifier id){
return bindings.get(id);
}
}
......@@ -45,6 +45,10 @@ public class Controller {
documentEvents = new LinkedList<DocumentEvent>();
}
public void initialRun(){
addJobToDo(JobsToDo.parseCode);
job.schedule(0);
}
private Set<IRegisterForControllerChanges> controllerObservers = Collections
.newSetFromMap(new WeakHashMap<IRegisterForControllerChanges, Boolean>());
......
......@@ -7,8 +7,10 @@ import java.util.Date;
import java.util.EnumSet;
import java.util.List;
import java_cup.runtime.ComplexSymbolFactory.Location;
import minijava.Program;
import miniparser.InMemoryParser;
import mjplugin.ast.DeclarationUse;
import mjplugin.ast.MiniJavaAST;
import mjplugin.controller.Controller.JobsToDo;
import mjplugin.editors.GUIErrorReporter;
......@@ -82,7 +84,9 @@ public class DocumentDidChangeJob extends Job {
result = null;
try {
Program program = parser.parse();
result = new MiniJavaAST(program);
DeclarationUse typing = new DeclarationUse(reporter);
program.accept(typing);
result = new MiniJavaAST(program,typing.getBindings());
}catch (InMemoryParser.NoRecoveryException nre){
hasParserErrors = true;
}catch(ClassCastException cce){
......
......@@ -23,9 +23,9 @@ public class LocationPatchVisitor extends MinijavaVisitor{
if (pos != null && pos.getOffset() >= fixAfterOffset) {
int cols = diffColumns;
if (fixColumnUntilOffset != -1 && pos.getOffset() >= fixColumnUntilOffset) cols = 0;
System.out.print("fixing (diffColumns: " + diffColumns + ", cols: " + cols + ") " + "... from " + pos);
// System.out.print("fixing (diffColumns: " + diffColumns + ", cols: " + cols + ") " + "... from " + pos);
pos.move(diffLines, cols, diffOffset);
System.out.println(" to " + pos);
// System.out.println(" to " + pos);
}
}
// fix start and end locations of visited nodes
......
......@@ -63,13 +63,13 @@ public class MJDocumentListener implements IDocumentListener {
fixColumnUntilOffset = document.getLineInformationOfOffset(offset).getLength()+document.getLineInformationOfOffset(offset).getOffset();
System.out.println("PROCESSING DocumentEvent: ");
System.out.println(" Offset: " + offset);
System.out.println(" Replaced: " + event.getLength());
System.out.println(" New: " + event.getText().length());
System.out.println(" linesRemoved: " + linesRemoved);
System.out.println(" linesAdded: " + linesAdded);
// System.out.println("PROCESSING DocumentEvent: ");
// System.out.println(" Offset: " + offset);
// System.out.println(" Replaced: " + event.getLength());
// System.out.println(" New: " + event.getText().length());
//
// System.out.println(" linesRemoved: " + linesRemoved);
// System.out.println(" linesAdded: " + linesAdded);
} catch (BadLocationException e) {
e.printStackTrace();
......
......@@ -24,6 +24,7 @@ import org.eclipse.ui.PartInitException;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.texteditor.AbstractTextEditor;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
public class MJEditor extends TextEditor implements IMJParserChangeObserver,IRegisterForControllerChanges {
......@@ -89,6 +90,7 @@ public class MJEditor extends TextEditor implements IMJParserChangeObserver,IReg
IDocument doc = dp.getDocument(getEditorInput());
if (doc == null) return;
doc.addDocumentListener(new MJDocumentListener(this));
Controller.getInstance(this).initialRun();
}
/**
......@@ -103,7 +105,22 @@ public class MJEditor extends TextEditor implements IMJParserChangeObserver,IReg
protected boolean isOverviewRulerVisible() {
return true;
}
/**
* Dispatches to own Implementations of specific things;
* in our case: Content Outline Page
* @author Petter
*/
@Override
public Object getAdapter(Class required) {
if (IContentOutlinePage.class.equals(required)) {
if (myOutline==null){
myOutline=new MJOutlinePage(this);
}
return myOutline;
}
return super.getAdapter(required);
}
private MJOutlinePage myOutline;
@Override
public void modelChanged(Model model) {
if (hasRequestedPostSaveSyntaxRefresh) {
......
package mjplugin.editors;
import java.util.LinkedList;
import java.util.List;
import java_cup.runtime.ComplexSymbolFactory.Location;
import minijava.Decl;
import minijava.IASTNode;
import minijava.MinijavaVisitor;
import minijava.Expr.Identifier;
import minijava.Stmt.Assign;
import mjplugin.ast.MiniJavaAST;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
public class MJHyperlinkDetector implements IHyperlinkDetector {
private MJEditor editor;
public MJHyperlinkDetector(MJEditor editor) {
this.editor = editor;
}
@Override
public IHyperlink[] detectHyperlinks(ITextViewer textViewer,
IRegion region, boolean canShowMultipleHyperlinks) {
MiniJavaAST ast = editor.getModel().getAstModel();
IASTNode node = ast.program.findAtPosition(new Location(0,0,region.getOffset()));
if (!(node instanceof Identifier)) return null;
Decl d = ast.getBinding((Identifier)node);
if (d== null) return null;
return new IHyperlink[] { new MJDeclarationHyperlink(region,textViewer,d.getLeft().getOffset(),((Identifier)node).i.length()) };
}
}
class MJDeclarationHyperlink extends MJHyperlink{
public MJDeclarationHyperlink(IRegion region, ITextViewer viewer, int targetOffset,
int targetLength) {
super(region, viewer, targetOffset, targetLength);
}
@Override
public String getHyperlinkText() {
return "Open Declaration";
}
}
abstract class MJHyperlink implements IHyperlink {
ITextViewer textViewer;
IRegion region;
private int targetOffset;
private int targetLength;
public MJHyperlink(IRegion region, ITextViewer viewer, int targetOffset, int targetLength) {
this.region=region;
this.textViewer=viewer;
this.targetOffset = targetOffset;
this.targetLength = targetLength;
}
@Override
public IRegion getHyperlinkRegion() {
return region;
}
@Override
public String getTypeLabel() {
return null;
}
@Override
public void open() {
textViewer.revealRange(targetOffset, targetLength);
textViewer.setSelectedRange(targetOffset, targetLength);
}
}
\ No newline at end of file
package mjplugin.editors;
import minijava.IASTNode;
import minijava.MinijavaVisitor;
import minijava.Program;
import minijava.Cond.BoolConst;
import minijava.Expr.Identifier;
import minijava.Expr.IntConst;
import mjplugin.model.IMJModelObserverBase;
import mjplugin.model.IMJParserChangeObserver;
import mjplugin.model.Model;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
/**
* Very basic naming of Outline nodes!
* @author petter
*/
class MiniJavaLabelProvider extends LabelProvider {
private static class ExtractData extends MinijavaVisitor {
private String data;
public String getData(){ return data; }
@Override
public void visit(BoolConst d) {
data=d.b+"";
}
@Override
public void visit(Identifier d) {
data=d.i;
}
@Override
public void visit(IntConst d) {
data=d.i+"";
}
}
@Override
public String getText(Object element) {
if (!(element instanceof IASTNode)) {
return element.toString();
}
ExtractData ex = new ExtractData();
IASTNode node = (IASTNode)element;
if (node.isLeaf()){
String data;
node.accept(ex);
return node.getClass().getSimpleName()+": "+ex.getData();
}
else
return element.getClass().getSimpleName();
}
}
/**
* Scans the model for the AST structure and creates appropirate Eclipse data structures
* @author petter
*/
class ASTasOutline implements ITreeContentProvider {
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
@Override
public Object getParent(Object element) {
return null;
}
@Override
public boolean hasChildren(Object element) {
IASTNode node = (IASTNode)element;
return !node.isLeaf();
}
@Override
public Object[] getElements(Object inputElement) {
Program program =(Program)inputElement;
return program.getChildren().toArray();
}
@Override
public Object[] getChildren(Object parentElement) {
IASTNode node = (IASTNode)parentElement;
if (node.isLeaf()) return null;
return node.getChildren().toArray();
}
}
/**
* OutlinePage with direct AST display
* @author petter
*/
public class MJOutlinePage extends ContentOutlinePage implements IMJParserChangeObserver {
Model model;
public MJOutlinePage(MJEditor mjEditor) {
model=mjEditor.getModel();
model.registerModelObserver(this);
}
@Override
public void createControl(Composite parent) {
super.createControl(parent);
TreeViewer viewer= getTreeViewer();
viewer.setContentProvider(new ASTasOutline());
viewer.setLabelProvider(new MiniJavaLabelProvider());
viewer.addSelectionChangedListener(this);
//viewer.setInput(model.getAstModel().program);
}
@Override
public void modelChanged(Model model) {
System.out.println("got the change!");
getTreeViewer().setInput(model.getAstModel().program);
}
}
......@@ -12,6 +12,9 @@ import miniparser.sym;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlinkPresenter;
import org.eclipse.jface.text.hyperlink.MultipleHyperlinkPresenter;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.IToken;
......@@ -25,6 +28,16 @@ public class MJSourceViewerConfiguration extends SourceViewerConfiguration {
private MJEditor editor;
@Override
public IHyperlinkPresenter getHyperlinkPresenter(ISourceViewer sourceViewer) {
return new MultipleHyperlinkPresenter(MJEditor.HYPERLINK.getRGB());
}
@Override
public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
return new IHyperlinkDetector[] { new MJHyperlinkDetector(editor) };
}
public MJSourceViewerConfiguration(MJEditor mjEditor) {
this.editor=mjEditor;
}
......
......@@ -58,9 +58,13 @@ public class Model {
private List<IMJModelObserverBase> modelObservers;
private <T> void notifyObservers (Class<T> cls) {
for(IMJModelObserverBase observer : modelObservers)
if(cls.isAssignableFrom(observer.getClass()))
for(IMJModelObserverBase observer : modelObservers){
System.out.println("Notify!!!!!");
if(cls.isAssignableFrom(observer.getClass())){
observer.modelChanged(this);
System.out.println("Notify observer!!!!!");
}
}
}
public void registerModelObserver(IMJModelObserverBase modelObserver) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment