Commit 4cbbf3fc authored by Johannes Roith's avatar Johannes Roith
Browse files

Java syntax highlighting works now.

parent 27c5cc60
......@@ -31,6 +31,20 @@ public class FindAtPositionVisitor extends Visitor<Object>
}
}
@Override
public void postVisit (ActionCodeBlock node, Object data) {
if (node == null)
return;
updateIfMatch(node);
}
@Override
public void postVisit (SpecialCodeBlock node, Object data) {
if (node == null)
return;
updateIfMatch(node);
}
@Override
public void postVisit (Name node, Object data) {
if (node == null)
......
......@@ -4,8 +4,10 @@ import java.util.*;
import de.in.tum.www2.cup.CupContext;
import de.in.tum.www2.cup.Declarations;
import de.in.tum.www2.cup.Position;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.analysis.DeclarationsExtractorVisitor;
import de.in.tum.www2.cup.analysis.FindAtPositionVisitor;
import de.in.tum.www2.cup.analysis.RefResolutionVisitor;
import de.in.tum.www2.cup.internal.production;
......@@ -49,6 +51,13 @@ public class ParserResult extends AbstractNode {
RefResolutionVisitor resRefVisitor = new RefResolutionVisitor();
this.accept(resRefVisitor, null);
}
// TODO: it would be better to use a hashtable here.
public AbstractNode findAtPosition(Position pos) {
FindAtPositionVisitor pf = new FindAtPositionVisitor(pos);
accept(pf, null);
return pf.getResult();
}
public ProductionRight getMatchingProductonRight(CupContext context, production p) {
throw new RuntimeException("not yet implemented.");
......
......@@ -34,6 +34,36 @@ public class JavaSymbol {
return -1;
return s.right;
}
public boolean isKeyword() {
if (s != null)
return keywords.contains(s.sym);
return false;
}
public boolean isIdentifier() {
if (s == null)
return false;
return s.sym == Sym.IDENTIFIER;
}
public boolean isTextualLiteral() {
if (s == null)
return false;
return s.sym == Sym.STRING_LITERAL || s.sym == Sym.CHARACTER_LITERAL;
}
public boolean isNullLiteral() {
if (s == null)
return false;
return s.sym == Sym.NULL_LITERAL;
}
public boolean isBooleanLiteral() {
if (s == null)
return false;
return s.sym == Sym.BOOLEAN_LITERAL;
}
private static final HashSet<Integer> keywords = new HashSet<Integer>();
......@@ -90,16 +120,19 @@ public class JavaSymbol {
keywords.add(Sym.WHILE);
}
public boolean isKeyword() {
if (s != null)
return keywords.contains(s.sym);
return false;
}
public JavaSymbol(Symbol s) {
this.s = s;
}
public String toString() {
if (s == null)
return "null";
StringBuilder builder = new StringBuilder();
builder.append (getValue());
builder.append (", ");
builder.append (s.sym);
return builder.toString();
}
public boolean isEOF() {
return getSymbolId() == Sym.EOF;
......
......@@ -36,10 +36,7 @@ public class OpenDeclarationHandler extends AbstractHandler {
if (result != null) {
result.resolveReferences();
FindAtPositionVisitor pf = new FindAtPositionVisitor(range.getBegin());
result.accept(pf, null);
AbstractNode node = pf.getResult();
AbstractNode node = result.findAtPosition(range.getBegin());
if (node != null) {
AbstractNode parent = node.getParent();
if (parent != null && parent instanceof IHasDeclarationReference) {
......
......@@ -41,10 +41,7 @@ public class OpenDefinitionHandler extends AbstractHandler {
if (result != null) {
result.resolveReferences();
FindAtPositionVisitor pf = new FindAtPositionVisitor(range.getBegin());
result.accept(pf, null);
AbstractNode node = pf.getResult();
AbstractNode node = result.findAtPosition(range.getBegin());
if (node != null) {
AbstractNode parent = node.getParent();
if (parent != null && parent instanceof IHasDefinitionReference) {
......
......@@ -112,10 +112,7 @@ public class RenameSymbolHandler extends AbstractHandler {
if (result == null)
return null;
FindAtPositionVisitor pf = new FindAtPositionVisitor(range.getBegin());
result.accept(pf, null);
AbstractNode node = pf.getResult();
AbstractNode node = result.findAtPosition(range.getBegin());
if (node != null && node instanceof Name) {
Name nameNode = (Name) node;
String oldName = nameNode.name;
......
......@@ -38,11 +38,20 @@ public class CupDamagerRepairer extends DefaultDamagerRepairer {
fScanner.setRange(fDocument, lastStart, region.getLength());
while (true) {
IToken token= fScanner.nextToken();
if (token.isEOF())
IToken token;
try {
token = fScanner.nextToken();
if (token.isEOF())
break;
} catch (Exception e) {
e.printStackTrace();
break;
} catch (Error err) {
err.printStackTrace();
break;
}
TextAttribute attribute= getTokenTextAttribute(token);
TextAttribute attribute = getTokenTextAttribute(token);
/*
if (lastAttribute != null && lastAttribute.equals(attribute)) {
length += fScanner.getTokenLength();
......
......@@ -4,6 +4,7 @@ import java.io.IOException;
import java.io.StringReader;
import java.util.HashSet;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.contentassist.ContentAssistant;
......@@ -24,7 +25,13 @@ import de.in.tum.www2.cup.CupScanner;
import de.in.tum.www2.cup.CupSymbol;
import de.in.tum.www2.cup.Declarations;
import de.in.tum.www2.cup.NoopErrorReporter;
import de.in.tum.www2.cup.Position;
import de.in.tum.www2.cup.ast.AbstractNode;
import de.in.tum.www2.cup.ast.ActionCodeBlock;
import de.in.tum.www2.cup.ast.IProductionRightPart;
import de.in.tum.www2.cup.ast.LabeledProductionSymbolRef;
import de.in.tum.www2.cup.ast.ParserResult;
import de.in.tum.www2.cup.ast.ProductionRight;
import de.in.tum.www2.cup.internal.sym;
import de.in.tum.www2.java.JavaScanner;
import de.in.tum.www2.java.JavaSymbol;
......@@ -33,11 +40,11 @@ import de.tum.in.www2.cupplugin.model.Model;
public class CupSourceViewerConfiguration extends SourceViewerConfiguration {
CupTextEditor editor;
private static final int AUTO_ACTIVATION_DELAY = 500;
public CupSourceViewerConfiguration(CupTextEditor editor) {
this.editor = editor;
this.editor = editor;
}
public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
......@@ -49,8 +56,10 @@ public class CupSourceViewerConfiguration extends SourceViewerConfiguration {
ContentAssistant assistant = new ContentAssistant();
// TODO: correct to get the doc like that?
IDocument doc = editor.getDocumentProvider().getDocument(editor.getEditorInput());
IContentAssistProcessor tagContentAssistProcessor = new CupContentAssistProcessor(doc);
IDocument doc = editor.getDocumentProvider().getDocument(
editor.getEditorInput());
IContentAssistProcessor tagContentAssistProcessor = new CupContentAssistProcessor(
doc);
assistant.setContentAssistProcessor(tagContentAssistProcessor,
IDocument.DEFAULT_CONTENT_TYPE);
......@@ -62,17 +71,20 @@ public class CupSourceViewerConfiguration extends SourceViewerConfiguration {
.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_BELOW);
return assistant;
}
public class DeclarationPresentationObserver implements CupParserASTChangeObserver
{
private CupTokenScanner tokenScanner;
public class PresentationModelObserver implements
CupParserASTChangeObserver {
private CupTokenScanner cupTokenScanner;
private JavaTokenScanner javaTokenScanner;
private ISourceViewer sourceViewer;
private boolean updatedFromModelOnce;
public DeclarationPresentationObserver(
CupTokenScanner tokenScanner,
public PresentationModelObserver(CupTokenScanner cupTokenScanner,
JavaTokenScanner javaTokenScanner,
ISourceViewer sourceViewer) {
this.tokenScanner = tokenScanner;
this.cupTokenScanner = cupTokenScanner;
this.javaTokenScanner = javaTokenScanner;
this.sourceViewer = sourceViewer;
Model model = editor.getModel();
......@@ -81,24 +93,31 @@ public class CupSourceViewerConfiguration extends SourceViewerConfiguration {
// TODO: this model will likely be empty on first call?!
ParserResult result = model.getAstModel();
if (result != null)
tokenScanner.updateDeclarations(result.findDeclarations());
cupTokenScanner.updateDeclarations(result.findDeclarations());
}
@Override
public void modelChanged(Model model) {
ParserResult result = model.getAstModel();
if (result != null) {
Declarations newDecls = result.findDeclarations();
if (newDecls != null) {
if (!newDecls.equals(tokenScanner.getDeclarations())) {
tokenScanner.updateDeclarations(result.findDeclarations());
sourceViewer.invalidateTextPresentation();
if (!newDecls.equals(cupTokenScanner.getDeclarations())) {
cupTokenScanner.updateDeclarations(result
.findDeclarations());
if (updatedFromModelOnce)
sourceViewer.invalidateTextPresentation();
}
}
if (!updatedFromModelOnce) {
javaTokenScanner.updateParserResult(result);
System.out.println(">>>>>>>>>>>>>>>>> INITIAL invalidateTextPresentation !!!!");
sourceViewer.invalidateTextPresentation();
updatedFromModelOnce = true;
}
}
}
}
@Override
public PresentationReconciler getPresentationReconciler(
......@@ -107,13 +126,17 @@ public class CupSourceViewerConfiguration extends SourceViewerConfiguration {
CupTokenScanner cupTokenScanner = new CupTokenScanner();
JavaTokenScanner javaTokenScanner = new JavaTokenScanner();
// will observe new declarations and trigger rescan of document
new DeclarationPresentationObserver(cupTokenScanner, sourceViewer);
// also handles changes to declared cup symbols in java blocks.
new PresentationModelObserver(cupTokenScanner, javaTokenScanner, sourceViewer);
CupDamagerRepairer cupDamagerRepairer = new CupDamagerRepairer(cupTokenScanner);
CupDamagerRepairer cupDamagerRepairer = new CupDamagerRepairer(
cupTokenScanner);
pr.setRepairer(cupDamagerRepairer, IDocument.DEFAULT_CONTENT_TYPE);
pr.setDamager(cupDamagerRepairer, IDocument.DEFAULT_CONTENT_TYPE);
DefaultDamagerRepairer mLCommentDamagerRepairer = new DefaultDamagerRepairer(
new SingleTokenScanner(new TextAttribute(CupTextEditor.COMMENT)));
......@@ -130,8 +153,6 @@ public class CupSourceViewerConfiguration extends SourceViewerConfiguration {
pr.setDamager(sLCommentDamagerRepairer,
CupPartionScanner.SINGLE_COMMENT);
JavaTokenScanner javaTokenScanner = new JavaTokenScanner();
// DefaultDamagerRepairer javaCommentDamagerRepairer = new
// DefaultDamagerRepairer(new SingleTokenScanner(new
// TextAttribute(CupTextEditor.KEYWORD)));
......@@ -141,50 +162,132 @@ public class CupSourceViewerConfiguration extends SourceViewerConfiguration {
// pr.setDamager(javaCommentDamagerRepairer,
// CupPartionScanner.JAVA_CODE);
CupDamagerRepairer javaDamagerRepairer = new CupDamagerRepairer(javaTokenScanner);
CupDamagerRepairer javaDamagerRepairer = new CupDamagerRepairer(
javaTokenScanner);
pr.setRepairer(javaDamagerRepairer, CupPartionScanner.JAVA_CODE);
pr.setDamager(javaDamagerRepairer, CupPartionScanner.JAVA_CODE);
return pr;
}
static class JavaTokenScanner implements ITokenScanner {
private ParserResult ast;
private JavaScanner scanner;
private JavaSymbol last;
private int offset;
public JavaTokenScanner () {
private HashSet<String> currentLabels = null;
public JavaTokenScanner() {
this.currentLabels = new HashSet<String> ();
}
public void setRange(IDocument document, int offset, int length) {
public void updateParserResult(ParserResult result) {
this.ast = result;
}
public void setRange(IDocument document, int offset, int length) {
StringReader reader = new StringReader(document.get().substring(
offset, offset + length));
scanner = new JavaScanner(reader);
this.scanner = new JavaScanner(reader);
this.last = null;
this.offset = offset;
this.currentLabels.clear();
if (ast != null) {
// TODO: find a way to avoid computing all this on every keystroke!
// TODO: we convert offset to line number / position.
// TODO: centralize this type of code, so we have our bugs in
// one place :-)
int line;
int column;
try {
line = document.getLineOfOffset(offset);
column = offset - document.getLineOffset(line);
} catch (BadLocationException e) {
e.printStackTrace();
return;
}
line += 1;
column += 2; // TODO: adding two here is a hack!
System.out.println("TRYING TO FIND POSITION: " + line + ", "
+ column);
AbstractNode node = ast.findAtPosition(new Position(line,
column, -1));
if (node != null && node instanceof ActionCodeBlock) {
ActionCodeBlock codeBlock = (ActionCodeBlock) node;
AbstractNode parent = codeBlock.getParent();
if (parent instanceof ProductionRight) {
ProductionRight pr = (ProductionRight) parent;
for (IProductionRightPart part : pr.getList()) {
if (part instanceof LabeledProductionSymbolRef) {
LabeledProductionSymbolRef lpsr = (LabeledProductionSymbolRef) part;
String label = lpsr.label;
currentLabels.add(label);
currentLabels.add(label + "xleft");
currentLabels.add(label + "xright");
currentLabels.add(label + "left");
currentLabels.add(label + "right");
}
}
}
}
}
}
static final Token javaKeyword = new Token(new TextAttribute(
CupTextEditor.JAVA_KEYWORD));
static final Token javaTextualLiteral = new Token(new TextAttribute(
CupTextEditor.JAVA_TEXTUAL));
static final Token cupDefinedVariable = new Token(new TextAttribute(
CupTextEditor.JAVA_CUP_DEFINED, null, SWT.ITALIC));
public IToken nextToken() {
try {
last = scanner.next_token();
} catch (IOException e) {
} catch (Exception e) {
last = null;
return Token.EOF;
} catch (Error err) {
last = null;
return Token.EOF;
}
if (last.isEOF())
return Token.EOF;
if (last.isBooleanLiteral() || last.isNullLiteral())
return cupDefinedVariable;
if (last.isTextualLiteral())
return javaTextualLiteral;
if (last.getValue() instanceof String) {
String lastValueStr = (String) last.getValue();
if (lastValueStr.equals("RESULT"))
return cupDefinedVariable;
if (currentLabels.contains(lastValueStr))
return cupDefinedVariable;
}
if (last.isKeyword())
return javaKeyword;
return Token.UNDEFINED;
}
......@@ -197,7 +300,7 @@ public class CupSourceViewerConfiguration extends SourceViewerConfiguration {
}
}
// TODO: move the TokenScanner into a separate file, along with a custom
// presentation reconciler.
static class CupTokenScanner implements ITokenScanner {
......@@ -207,19 +310,19 @@ public class CupSourceViewerConfiguration extends SourceViewerConfiguration {
private int offset;
private Declarations decls;
private HashSet<Integer> constants;
public Declarations getDeclarations() {
return decls;
}
public void updateDeclarations(Declarations decls) {
this.decls = decls;
}
public CupTokenScanner () {
public CupTokenScanner() {
constants = new HashSet<Integer>();
}
static final Token keyword = new Token(new TextAttribute(
CupTextEditor.KEYWORD, null, SWT.BOLD));
static final Token literal = new Token(new TextAttribute(
......@@ -231,7 +334,6 @@ public class CupSourceViewerConfiguration extends SourceViewerConfiguration {
static final Token specialErrorTerminal = new Token(new TextAttribute(
CupTextEditor.SPECIAL_ERROR_TERMINAL));
public void setRange(IDocument document, int offset, int length) {
StringReader reader = new StringReader(document.get().substring(
......
......@@ -31,9 +31,11 @@ public class CupTextEditor extends TextEditor {
static Color gray;
static Color blue;
static Color brightBlue;
static Color green;
static Color orange;
static Color purple;
static Color blueGreen;
static Color red;
static Color pink;
static Color brown;
......@@ -43,10 +45,11 @@ public class CupTextEditor extends TextEditor {
gray = new Color (display, 150, 150, 150);
blue = new Color (display, 53, 87, 197);
// green = new Color (display, 53, 197, 67);
brightBlue = new Color (display, 38, 99, 236);
green = new Color (display, 44, 173, 57);
orange = new Color (display, 220, 150, 50);
purple = new Color (display, 177, 33, 114);
blueGreen = new Color (display, 43, 126, 136);
red = new Color (display, 255, 0, 0);
pink = new Color (display, 255, 0, 255);
brown = new Color (display, 132, 90, 49);
......@@ -61,6 +64,8 @@ public class CupTextEditor extends TextEditor {
public static final Color STRING = red;
public static final Color IDENTIFIER = pink;
public static final Color JAVA_KEYWORD = brown;
public static final Color JAVA_TEXTUAL = brightBlue;
public static final Color JAVA_CUP_DEFINED = blueGreen;
public CupTextEditor() {
super();
......
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