Commit 6abf08f3 authored by Sebastian Pretscher's avatar Sebastian Pretscher

Merge branch 'master' of git@github.com:jroith/cup-eclipse.git

parents 6768c93b 6dc02c98
......@@ -664,14 +664,18 @@ preced_type ::=
terminal_list ::= terminal_list:lst COMMA terminal_id:trm
{:
((List<Terminal>) lst).add(new Terminal(trm, null)); // jrTODO: positions
((List<Terminal>) lst).add(new Terminal(trm,
new Range(Position.fromLocation(trmxleft),
Position.fromLocation(trmxright)))); // jrTODO: positions
RESULT = lst;
:}
|
terminal_id:trm
{:
List<Terminal> lst = new ArrayList<Terminal>();
lst.add(new Terminal(trm, null)); // jrTODO: positions
lst.add(new Terminal(trm,
new Range(Position.fromLocation(trmxleft),
Position.fromLocation(trmxright)))); // jrTODO: positions
RESULT = lst;
:}
;
......@@ -941,11 +945,14 @@ prod_part ::=
/* add a labeled production part */
add_rhs_part(add_lab(symb, labid));
// jrTODO: we need to check if the production really is labeled!
ast_add_rhs_part(new LabeledProductionRef(
new Name(symid, null), // jrTODO: locations
labid,
null)); // jrTODO: locations
ProductionRef ref = null;
Range range = new Range (Position.fromLocation(symidxleft),
Position.fromLocation(symidxright));
if (labid == null)
ref = new LabeledProductionRef(new Name(symid, range), labid, range);
else
ref = new ProductionRef(new Name(symid, range), range);
ast_add_rhs_part(ref);
}
:}
|
......@@ -1079,7 +1086,7 @@ new_non_term_id ::=
else
{
if (multipart_name.equals("")) {
multipart_name ="Object";
multipart_name ="Object";
}
/* build the non terminal object */
non_terminal this_nt =
......@@ -1093,7 +1100,9 @@ new_non_term_id ::=
// jrTODO: positions!
// jrTODO: non_term_id vs. multipart_name
RESULT = new NonTerminal(non_term_id, null);
RESULT = new NonTerminal(non_term_id,
new Range(Position.fromLocation(non_term_idxleft),
Position.fromLocation(non_term_idxright)));
}
:}
;
......
......@@ -26,7 +26,6 @@ public class Range {
public boolean contains(Position pos, int removedLength) {
if (pos == null || begin == null || end == null)
return false;
if (pos.getLine() >= begin.getLine() && pos.getLine() <= end.getLine()) {
if (pos.getLine() == begin.getLine()
......@@ -35,16 +34,19 @@ public class Range {
// we are certainly past the start.
if (pos.getLine() == end.getLine()
&& pos.getColumn() > begin.getColumn())
&& pos.getColumn() > end.getColumn())
return false;
// we are certainly not past the end.
throw new RuntimeException("not implemented!");
// TODO: we really should check, that the amount of code
// remove is not too much.
// return true;
if (removedLength == 0) {
return true;
} else {
throw new RuntimeException("not implemented!");
// TODO: we really should check, that the amount of code
// remove is not too much.
// return true;
}
}
return false;
}
......@@ -53,5 +55,15 @@ public class Range {
return new Range(Position.fromLocation(begin),
Position.fromLocation(end));
}
public String toString() {
StringBuilder builder = new StringBuilder();
if (begin != null)
builder.append(begin.toString());
builder.append(";");
if (end != null)
builder.append(end.toString());
return builder.toString();
}
}
......@@ -3,7 +3,7 @@ package de.in.tum.www2.cup.analysis;
import de.in.tum.www2.cup.ast.*;
public abstract class AbstractVisitor<T>
{
{
private boolean descend = true;
public boolean resetDescend() {
......@@ -11,7 +11,7 @@ public abstract class AbstractVisitor<T>
descend = true;
return res;
}
// sets visitor state to prevent it from descending to next children.
protected void noDescend() {
descend = false;
......@@ -21,7 +21,6 @@ public abstract class AbstractVisitor<T>
public abstract T preVisit (ClassName node, T data);
public abstract T preVisit (SpecialCodeBlock node, T data);
public abstract T preVisit (Import node, T data);
public abstract T preVisit (LabeledProductionRef node, T data);
public abstract T preVisit (Name node, T data);
public abstract T preVisit (NonTerminal node, T data);
public abstract T preVisit (NonTerminalDeclaration node, T data);
......@@ -41,7 +40,6 @@ public abstract class AbstractVisitor<T>
public abstract void postVisit (ClassName node, T data);
public abstract void postVisit (SpecialCodeBlock node, T data);
public abstract void postVisit (Import node, T data);
public abstract void postVisit (LabeledProductionRef node, T data);
public abstract void postVisit (Name node, T data);
public abstract void postVisit (NonTerminal node, T data);
public abstract void postVisit (NonTerminalDeclaration node, T data);
......
package de.in.tum.www2.cup.analysis;
import de.in.tum.www2.cup.Position;
import de.in.tum.www2.cup.Range;
import de.in.tum.www2.cup.ast.*;
public class FindAtPositionVisitor extends Visitor<Object>
{
private AbstractNode result;
private Position pos;
/**
* @return The innermost node that corresponds to the position.
*/
public AbstractNode getResult() {
return result;
}
public FindAtPositionVisitor(Position pos) {
this.pos = pos;
}
// TODO: does not work for all elements, yet ...
private void updateIfMatch(AbstractNode node) {
Range range = node.getRange();
if (range == null)
return;
if (range.contains(pos))
result = node;
}
@Override
public void postVisit (Name node, Object data) {
if (node == null)
return;
updateIfMatch(node);
}
}
......@@ -21,7 +21,6 @@ public abstract class Visitor<T> extends AbstractVisitor<T>
@Override public T preVisit (ClassName node, T data) { return data; }
@Override public T preVisit (SpecialCodeBlock node, T data) { return data; }
@Override public T preVisit (Import node, T data) { return data; }
@Override public T preVisit (LabeledProductionRef node, T data) { return data; }
@Override public T preVisit (Name node, T data) { return data; }
@Override public T preVisit (NonTerminal node, T data) { return data; }
@Override public T preVisit (NonTerminalDeclaration node, T data) { return data; }
......@@ -41,7 +40,6 @@ public abstract class Visitor<T> extends AbstractVisitor<T>
@Override public void postVisit (ClassName node, T data) { }
@Override public void postVisit (SpecialCodeBlock node, T data) { }
@Override public void postVisit (Import node, T data) { }
@Override public void postVisit (LabeledProductionRef node, T data) { }
@Override public void postVisit (Name node, T data) { }
@Override public void postVisit (NonTerminal node, T data) { }
@Override public void postVisit (NonTerminalDeclaration node, T data) { }
......
......@@ -6,8 +6,17 @@ import de.in.tum.www2.cup.analysis.AbstractVisitor;
public abstract class AbstractNode {
private AbstractNode parent;
private Range range;
public AbstractNode getParent() {
return parent;
}
void setParent(AbstractNode parent) {
this.parent = parent;
}
public Range getRange() {
return range;
}
......@@ -26,6 +35,7 @@ public abstract class AbstractNode {
public AbstractNode (Range range) {
this.range = range;
this.parent = null;
}
public abstract <T> void accept(AbstractVisitor<T> visitor, T data);
......
......@@ -10,6 +10,8 @@ public class ClassName extends AbstractNode {
public ClassName(Name name, Range range) {
super(range);
this.name = name;
if (name != null)
name.setParent(this);
}
@Override protected String getNodeName() { return "ClassName"; }
......
......@@ -10,6 +10,8 @@ public class Import extends AbstractNode {
public Import(Name name, Range range) {
super(range);
this.name = name;
if (name != null)
name.setParent(this);
}
@Override protected String getNodeName() { return "Import"; }
......
......@@ -4,7 +4,6 @@ import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.Range;
public class LabeledProductionRef extends ProductionRef
implements IProductionRightPart
{
public String label; // TODO: Name class?
......@@ -18,12 +17,6 @@ public class LabeledProductionRef extends ProductionRef
@Override protected String getNodeName() { return "LabeledProductionRef"; }
@Override
public <T> void accept(AbstractVisitor<T> visitor, T data) {
visitor.preVisit(this, data);
visitor.postVisit(this, data);
}
@Override
protected void putDescription(StringBuilder builder) {
builder.append(label);
......
......@@ -16,6 +16,10 @@ public class NonTerminalDeclaration extends SymbolDeclaration {
public NonTerminalDeclaration(List<NonTerminal> nonTerminals, Range range) {
super(range);
this.nonTerminals = nonTerminals;
if (nonTerminals != null)
for (NonTerminal nt : nonTerminals)
if (nt != null)
nt.setParent(this);
}
@Override protected String getNodeName() { return "NonTerminalDeclaration"; }
......
......@@ -5,6 +5,7 @@ import java.util.*;
import de.in.tum.www2.cup.Declarations;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.analysis.DeclarationsExtractorVisitor;
import de.in.tum.www2.cup.analysis.RefResolutionVisitor;
public class ParserResult extends AbstractNode {
......@@ -13,6 +14,7 @@ public class ParserResult extends AbstractNode {
public ClassName className;
// TODO: these must be ordered as they occur, using a list!!
public CodeBlock actionCode;
public CodeBlock parserCode;
public CodeBlock initCode;
......@@ -39,6 +41,12 @@ public class ParserResult extends AbstractNode {
this.accept(declVisitor, null);
return declVisitor.getResult();
}
// TODO: cache in a safe way!
public void resolveReferences() {
RefResolutionVisitor resRefVisitor = new RefResolutionVisitor();
this.accept(resRefVisitor, null);
}
@Override
public <T> void accept(AbstractVisitor<T> visitor, T data) {
......
......@@ -32,6 +32,10 @@ public class Precedence extends AbstractNode {
super(range);
this.type = typeFromAssoc(assoc);
this.terminals = lst;
if (terminals != null)
for (Terminal t : terminals)
if (t != null)
t.setParent(this);
}
@Override protected String getNodeName() { return "Precedence"; }
......
......@@ -17,8 +17,14 @@ public class Production extends AbstractNode {
public Production(Name lhs,
List<ProductionRight> rhs, Range range) {
super(range);
this.rhs = rhs;
this.lhs = lhs;
if (lhs != null)
this.lhs.setParent(this);
this.rhs = rhs;
if (rhs != null)
for (ProductionRight pr : rhs)
if (pr != null)
pr.setParent(this);
}
@Override protected String getNodeName() { return "Production"; }
......
......@@ -3,7 +3,9 @@ package de.in.tum.www2.cup.ast;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.Range;
public class ProductionRef extends AbstractNode {
public class ProductionRef extends AbstractNode
implements IProductionRightPart
{
private Name name;
private Production definitionRef; // has to be resolved first.
......@@ -32,6 +34,8 @@ public class ProductionRef extends AbstractNode {
public ProductionRef(Name name, Range range) {
super(range);
this.name = name;
if (name != null)
name.setParent(this);
this.definitionRef = null;
this.declarationRef = null;
}
......
......@@ -13,6 +13,20 @@ public class ProductionRight extends AbstractNode {
return lst;
}
public ProductionRight(List<IProductionRightPart> lst, Range range) {
super(range);
this.lst = lst;
if (lst != null) {
for (IProductionRightPart prp : lst)
if (prp != null) {
if (prp instanceof AbstractNode)
((AbstractNode) prp).setParent(this);
}
}
}
@Override protected String getNodeName() { return "ProductionRight"; }
/*
* Concatenates the right-hand side into a human-readable string.
* */
......@@ -33,13 +47,6 @@ public class ProductionRight extends AbstractNode {
return builder.toString();
}
public ProductionRight(List<IProductionRightPart> lst, Range range) {
super(range);
this.lst = lst;
}
@Override protected String getNodeName() { return "ProductionRight"; }
@Override
public <T> void accept(AbstractVisitor<T> visitor, T data) {
T childArg = visitor.preVisit(this, data);
......
......@@ -10,6 +10,8 @@ public class StartWith extends AbstractNode {
public StartWith(NonTerminal nt, Range range) {
super(range);
this.nt = nt;
if (nt != null)
nt.setParent(this);
}
@Override protected String getNodeName() { return "StartWith"; }
......
......@@ -16,6 +16,10 @@ public class TerminalDeclaration extends SymbolDeclaration {
public TerminalDeclaration(List<Terminal> terminals, Range range) {
super(range);
this.terminals = terminals;
if (terminals != null)
for (Terminal t : terminals)
if (t != null)
t.setParent(this);
}
@Override protected String getNodeName() { return "TerminalDeclaration"; }
......
......@@ -12,7 +12,7 @@ public class OpenDeclarationHandler extends AbstractHandler {
public Object execute(ExecutionEvent event) throws ExecutionException {
PluginUtility.showMessage("OpenDeclarationHandler command called!");
return null;
}
......
......@@ -3,15 +3,67 @@ package de.tum.in.www2.cupplugin.commands;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.texteditor.IDocumentProvider;
import de.in.tum.www2.cup.Position;
import de.in.tum.www2.cup.Range;
import de.in.tum.www2.cup.analysis.FindAtPositionVisitor;
import de.in.tum.www2.cup.ast.AbstractNode;
import de.in.tum.www2.cup.ast.Name;
import de.in.tum.www2.cup.ast.NonTerminalDeclaration;
import de.in.tum.www2.cup.ast.ParserResult;
import de.in.tum.www2.cup.ast.Production;
import de.in.tum.www2.cup.ast.ProductionRef;
import de.tum.in.www2.cupplugin.controller.PluginUtility;
import de.tum.in.www2.cupplugin.editors.CupTextEditor;
import de.tum.in.www2.cupplugin.editors.MultiPageEditor;
import de.tum.in.www2.cupplugin.model.Model;
public class OpenDefinitionHandler extends AbstractHandler {
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
MultiPageEditor mpe = (MultiPageEditor) HandlerUtil.getActiveEditorChecked(event);
CupTextEditor editor = mpe.getEditor();
Range range = null;
try {
range = PluginUtility.getRangeFromSelection(editor);
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (range == null)
return null;
IDocument doc = editor.getDocumentProvider().getDocument(editor.getEditorInput());
Model model = Model.getInstanceForDocument(doc);
ParserResult result = model.getAstModel();
if (result != null) {
result.resolveReferences();
FindAtPositionVisitor pf = new FindAtPositionVisitor(range.getBegin());
result.accept(pf, null);
AbstractNode node = pf.getResult();
if (node != null) {
AbstractNode parent = node.getParent();
if (parent != null && parent instanceof ProductionRef) {
ProductionRef prodRef = (ProductionRef) parent;
PluginUtility.showMessage("OpenDefinitionHandler command called!");
Production definition = prodRef.getDefinition();
if (definition != null) {
Position targetPosition = definition.getBegin();
int length = definition.getName().name.length();
editor.selectAndReveal(targetPosition.getOffsetFromStart(), length);
}
}
}
}
return null;
}
......
......@@ -4,8 +4,17 @@ import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.core.resources.IResource;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import de.in.tum.www2.cup.Position;
import de.in.tum.www2.cup.Range;
import de.in.tum.www2.cup.ast.ParserResult;
import de.tum.in.www2.cupplugin.editors.CupTextEditor;
import de.tum.in.www2.cupplugin.model.Model;
public final class PluginUtility {
......@@ -15,6 +24,34 @@ public final class PluginUtility {
mb.open();
}
public static Range getRangeFromSelection (CupTextEditor editor)
throws BadLocationException
{
ITextSelection textSelection = (ITextSelection) editor
.getSite().getSelectionProvider().getSelection();
int offset = textSelection.getOffset();
IDocumentProvider provider = editor.getDocumentProvider();
IDocument document = provider.getDocument(editor
.getEditorInput());
// TODO: there might be off-by-one errors here.
// Check again!
int startLineNumber = document.getLineOfOffset(offset);
int startColumn = offset - document.getLineOffset(startLineNumber);
Position start = new Position(startLineNumber+1, startColumn+1, offset+1);
int endOffset = offset + textSelection.getLength();
int endLineNumber = document.getLineOfOffset(endOffset);
int endColumn = endOffset - document.getLineOffset(endLineNumber);
Position end = new Position(endLineNumber+1, endColumn+1, endOffset);
return new Range(start, end);
}
/**
* Find the generated file that matches our cup file.
* @param cupFile The original cup file.
......
......@@ -17,6 +17,12 @@ import de.in.tum.www2.cup.analysis.Visitor;
public class CupHyperlinkDetector implements IHyperlinkDetector {
private CupTextEditor editor;
public CupHyperlinkDetector(CupTextEditor editor) {
this.editor = editor;
}
static public class HyperlinkingVisitor extends Visitor<Object> {
// TODO: we should assume that references have been resolved,
......@@ -28,12 +34,16 @@ public class CupHyperlinkDetector implements IHyperlinkDetector {
static public class CupHyperlink implements IHyperlink {
private IRegion region;
private ITextViewer textViewer;
private CupTextEditor editor;
ITextViewer textViewer;
private int targetOffset;
private int targetLength;
public CupHyperlink(IRegion region, ITextViewer textViewer, int targetOffset, int targetLength) {
public CupHyperlink(IRegion region,
CupTextEditor editor, ITextViewer textViewer,
int targetOffset, int targetLength) {
this.region = region;
this.editor = editor;
this.textViewer = textViewer;
this.targetOffset = targetOffset;
this.targetLength = targetLength;
......@@ -174,7 +184,7 @@ public class CupHyperlinkDetector implements IHyperlinkDetector {
IRegion targetRegion = new Region(lineRegion.getOffset() + index, 7);
if ((targetRegion.getOffset() <= offset)
&& ((targetRegion.getOffset() + targetRegion.getLength()) > offset)) {
links.add(new CupHyperlink(region, textViewer, 100, 5));
links.add(new CupHyperlink(region, editor, textViewer, 100, 5));
}
}
......
......@@ -36,7 +36,7 @@ public class CupSourceViewerConfiguration extends SourceViewerConfiguration {
}
public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
return new IHyperlinkDetector[] { new CupHyperlinkDetector() };
return new IHyperlinkDetector[] { new CupHyperlinkDetector(editor) };
}
@Override
......
......@@ -27,8 +27,7 @@ public class MultiPageEditor extends MultiPageEditorPart implements IResourceCha
private CupOverviewView overviewView;
private CupActionTableView actionTableView;
private CupReduceTableView reduceTableView;
private final int OVERVIEW_PAGE_INDEX = 0;
private final int EDITOR_PAGE_INDEX = 1;
private final int GRAPH_PAGE_INDEX = 2;
......@@ -42,6 +41,10 @@ public class MultiPageEditor extends MultiPageEditorPart implements IResourceCha
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
}
public CupTextEditor getEditor() {
return editor;
}
void createEditorPage() {
try {
editor = new CupTextEditor();
......
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