Commit c40ae431 authored by Clemens Pflaum's avatar Clemens Pflaum

Java Syntax Highlighting v1.0 + beginnings of error Reporting

parent b995ccb9
......@@ -42,7 +42,7 @@ public class CupParser {
return null;
}
result = parser.getResult();
result.parseJava(classpathEntries);
result.parseJava(classpathEntries, context.getErrorManager());
// TODO add java parsing call
return result;
}
......
......@@ -6,6 +6,8 @@ public class NoopErrorReporter implements IErrorReporter
public void report(ErrorType type, ErrorSource source, ErrorCode errorCode,
String message, Position start, Position end)
{
System.out.println("Noop: you have an Error: \n" +
"start:"+start+" end:"+end+" " + message);
}
}
......
package de.in.tum.www2.cup.analysis;
import de.in.tum.www2.cup.ErrorManager;
import de.in.tum.www2.cup.ast.ActionCodeBlock;
import de.in.tum.www2.cup.ast.SpecialCodeBlock;
public class ParseJavaVisitor extends Visitor<Object> {
private final String[] classpathEntries;
public ParseJavaVisitor(String[] classpathEntries) {
private ErrorManager errMan;
public ParseJavaVisitor(String[] classpathEntries, ErrorManager errMan) {
this.classpathEntries = classpathEntries;
this.errMan = errMan;
}
public void postVisit(ActionCodeBlock node, Object data) {
node.parseJavaCode(classpathEntries);
node.parseJavaCode(classpathEntries, errMan);
};
public void postVisit(SpecialCodeBlock node, Object data) {
node.parseJavaCode(classpathEntries);
node.parseJavaCode(classpathEntries, errMan);
};
}
......@@ -5,6 +5,7 @@ import java.util.List;
import org.eclipse.jdt.core.dom.CompilationUnit;
import de.in.tum.www2.cup.ErrorManager;
import de.in.tum.www2.cup.Range;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.analysis.LabelToVariableVisitor;
......@@ -13,6 +14,18 @@ public class ActionCodeBlock extends CodeBlock implements IProductionRightPart {
private List<LabeledProductionSymbolRef> variableLabels = new LinkedList<>();
private String returnType;
public List<String> getVariableLabels() {
List<String> varLabels = new LinkedList<String>();
for(LabeledProductionSymbolRef node : variableLabels){
varLabels.add(node.label);
varLabels.add(node.label +"xleft");
varLabels.add(node.label +"xright");
varLabels.add(node.label +"left");
varLabels.add(node.label +"right");
}
return varLabels;
}
public ActionCodeBlock(int debugId, BlockType bt, String blob, Range range) {
super(debugId, bt, blob, range);
}
......@@ -29,17 +42,17 @@ public class ActionCodeBlock extends CodeBlock implements IProductionRightPart {
}
@Override
public void parseJavaCode(String[] classpathEntries) {
public void parseJavaCode(String[] classpathEntries, ErrorManager errMan) {
LabelToVariableVisitor visitor = new LabelToVariableVisitor(this);
this.getParent().accept(visitor, null);
this.cu = (CompilationUnit) JavaCompiler.parseJava(getBlob(), this, classpathEntries);
BindingCollector variableCollector = new BindingCollector();
this.cu.accept(variableCollector);
this.problems = this.cu.getProblems();
this.variableMap = variableCollector.getVariableMap();
this.methodList = variableCollector.getMethodList();
this.setCupOffset(this.getRange().getBegin().getOffsetFromStart());
reportProblems(errMan);
variablePositions();
}
public void addVariable(LabeledProductionSymbolRef l) {
......
......@@ -33,9 +33,10 @@ public class BindingCollector extends ASTVisitor {
for (Iterator iter = node.fragments().iterator(); iter.hasNext();) {
VariableDeclarationFragment fragment = (VariableDeclarationFragment) iter.next();
IVariableBinding binding= (IVariableBinding) fragment.resolveBinding();
variableMap.put( binding, new LinkedList<SimpleName>());
if(binding != null)
variableMap.put( binding, new LinkedList<SimpleName>());
System.out.println("found FieldDeclaration " + fragment.getName().getIdentifier());
// System.out.println("found FieldDeclaration " + fragment.getName().getIdentifier());
}
return true;
}
......@@ -45,9 +46,9 @@ public class BindingCollector extends ASTVisitor {
for (Iterator iter = node.fragments().iterator(); iter.hasNext();) {
VariableDeclarationFragment fragment = (VariableDeclarationFragment) iter.next();
IVariableBinding binding= (IVariableBinding) fragment.resolveBinding();
variableMap.put( binding, new LinkedList<SimpleName>());
System.out.println("found VariableDeclarationStatement " + fragment.getName().getIdentifier());
if(binding != null)
variableMap.put( binding, new LinkedList<SimpleName>());
// System.out.println("found VariableDeclarationStatement " + fragment.getName().getIdentifier());
}
return false;
}
......@@ -58,7 +59,7 @@ public class BindingCollector extends ASTVisitor {
if(binding != null){
variableMap.put( binding, new LinkedList<SimpleName>());
System.out.println("found SingleVariableDeclaration " + binding.getName());
// System.out.println("found SingleVariableDeclaration " + binding.getName());
}
......@@ -75,13 +76,13 @@ public class BindingCollector extends ASTVisitor {
variableMap.get(binding).add(node);
}
System.out.println("found variableBinding " + nodeBinding.getName());
// System.out.println("found variableBinding " + nodeBinding.getName());
}else if(nodeBinding instanceof IMethodBinding) {
methodList.add(node);
System.out.println("found methodBinding " + nodeBinding.getName());
// System.out.println("found methodBinding " + nodeBinding.getName());
}else{
System.out.println("found SimpleName " + node.getIdentifier());
// System.out.println("found SimpleName " + node.getIdentifier());
}
return false;
......
......@@ -11,6 +11,9 @@ import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.SimpleName;
import de.in.tum.www2.cup.ErrorManager;
import de.in.tum.www2.cup.ErrorSource;
import de.in.tum.www2.cup.Position;
import de.in.tum.www2.cup.Range;
public abstract class CodeBlock extends AbstractNode {
......@@ -100,7 +103,12 @@ public abstract class CodeBlock extends AbstractNode {
HashSet<Integer> variablePositions = new HashSet<Integer>();
for(Iterator iter = variableMap.keySet().iterator(); iter.hasNext();){
IVariableBinding binding = (IVariableBinding) iter.next();
//TODO: add position of
//TODO: add position of declaration
ASTNode node = this.cu.findDeclaringNode(binding);
Integer offset = new Integer (node.getStartPosition() - dummyClassOffset);
if(offset > 0){
variablePositions.add(offset);
}
LinkedList<SimpleName> lst = variableMap.get(binding);
for(Iterator lstIter = lst.iterator(); lstIter.hasNext();){
SimpleName elem = (SimpleName) lstIter.next();
......@@ -118,6 +126,16 @@ public abstract class CodeBlock extends AbstractNode {
builder.append(bt + " " + tree);
}
public abstract void parseJavaCode(String[] classpathEntries);
public abstract void parseJavaCode(String[] classpathEntries, ErrorManager errMan);
public void reportProblems(ErrorManager errMan){
IProblem[] problems = cu.getProblems();
for(IProblem problem : problems){
//Adding 2 here is a hack: "{:"
//TODO: Position needs line and column number
errMan.Warning(ErrorSource.Parser, problem.getMessage(),
Position.fromOffset(problem.getSourceStart() - dummyClassOffset+ cupOffset + 2),
Position.fromOffset(problem.getSourceEnd() - dummyClassOffset+ cupOffset + 2));
}
}
}
......@@ -16,6 +16,8 @@ import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import de.in.tum.www2.cup.ErrorManager;
import de.in.tum.www2.cup.ErrorSource;
import de.in.tum.www2.cup.ast.CodeBlock.BlockType;
......@@ -53,12 +55,17 @@ public class JavaCompiler {
case Action:
case Parser:
dummyClass = DUMMY_CLASS_DEF + userCode + RWING;
codeblock.setDummyClassOffset(DUMMY_CLASS_DEF.length());
break;
case Init:
case Scan:
// TODO Add return Type for Scan with codeblock
dummyClass = DUMMY_CLASS_DEF + DUMMY_METHOD_DEF + DUMMY_METHOD_ARGS_END + userCode + DUMMY_METHOD_END
dummyClass = DUMMY_CLASS_DEF + DUMMY_METHOD_DEF + DUMMY_METHOD_ARGS_END;
codeblock.setDummyClassOffset(dummyClass.length());
dummyClass += userCode + DUMMY_METHOD_END
+ DUMMY_CLASS_DEF_END;
break;
case ActionCode:
......@@ -86,4 +93,5 @@ public class JavaCompiler {
node = parser.createAST(null);
return node;
}
}
......@@ -5,6 +5,7 @@ import java.util.List;
import de.in.tum.www2.cup.CupContext;
import de.in.tum.www2.cup.Declarations;
import de.in.tum.www2.cup.ErrorManager;
import de.in.tum.www2.cup.Position;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.analysis.DeclarationsExtractorVisitor;
......@@ -109,8 +110,8 @@ public class ParserResult extends AbstractNode {
throw new RuntimeException("not yet implemented.");
}
public void parseJava(String[] classpathEntries) {
ParseJavaVisitor visitor = new ParseJavaVisitor(classpathEntries);
public void parseJava(String[] classpathEntries, ErrorManager errMan) {
ParseJavaVisitor visitor = new ParseJavaVisitor(classpathEntries, errMan);
this.accept(visitor, null);
}
......
......@@ -2,6 +2,7 @@ package de.in.tum.www2.cup.ast;
import org.eclipse.jdt.core.dom.CompilationUnit;
import de.in.tum.www2.cup.ErrorManager;
import de.in.tum.www2.cup.Range;
import de.in.tum.www2.cup.analysis.AbstractVisitor;
import de.in.tum.www2.cup.analysis.LabelToVariableVisitor;
......@@ -32,14 +33,14 @@ public class SpecialCodeBlock extends CodeBlock implements IProductionRightPart
}
@Override
public void parseJavaCode(String[] classpathEntries) {
public void parseJavaCode(String[] classpathEntries, ErrorManager errMan) {
this.cu = (CompilationUnit) JavaCompiler.parseJava(getBlob(), this, classpathEntries);
BindingCollector variableCollector = new BindingCollector();
this.cu.accept(variableCollector);
this.problems = cu.getProblems();
this.variableMap = variableCollector.getVariableMap();
this.methodList = variableCollector.getMethodList();
this.setCupOffset(this.getRange().getBegin().getOffsetFromStart());
reportProblems(errMan);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="/CupParser/bin/jar/CupParser.jar" sourcepath="/CupParser/src"/>
......
......@@ -125,7 +125,6 @@ public class CupSourceViewerConfiguration extends SourceViewerConfiguration {
ParserResult result = model.getAstModel();
if (result != null) {
javaTokenScanner.updateParserResult(result);
Declarations newDecls = result.findDeclarations();
if (newDecls != null) {
if (!newDecls.equals(cupTokenScanner.getDeclarations())) {
......
......@@ -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.rules.IToken;
......@@ -15,6 +16,10 @@ 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.ParserResult;
import de.tum.in.www2.cupplugin.editors.CupTextEditor;
public class CupTokenScanner implements ITokenScanner {
......@@ -24,6 +29,7 @@ public class CupTokenScanner implements ITokenScanner {
private int offset;
private Declarations decls;
private HashSet<Integer> constants;
private ParserResult ast;
public Declarations getDeclarations() {
return decls;
......@@ -55,7 +61,8 @@ public class CupTokenScanner implements ITokenScanner {
scanner = new CupScanner(new NoopErrorReporter(), reader);
this.last = null;
this.offset = offset;
this.offset = offset;
if(this.ast != null){}
}
public IToken nextToken() {
......
package de.tum.in.www2.cupplugin.syntax;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.IntStream;
import org.eclipse.jdt.core.ToolFactory;
......@@ -18,20 +16,19 @@ import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.ITokenScanner;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import de.in.tum.www2.cup.Position;
import de.in.tum.www2.cup.Range;
import de.in.tum.www2.cup.ast.AbstractNode;
import de.in.tum.www2.cup.ast.ActionCodeBlock;
import de.in.tum.www2.cup.ast.CodeBlock;
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.tum.in.www2.cupplugin.editors.CupTextEditor;
/**
* This file handles java token scanning for syntax highlighting.
* It uses org.eclipse.jface.text.rules.ITokenScanner to scan Java Tokens.
*/
public class JavaTokenScanner implements ITokenScanner {
private ParserResult ast;
......@@ -40,9 +37,13 @@ public class JavaTokenScanner implements ITokenScanner {
private int offset;
private Range previousCodeBlockRange;
private HashSet<Integer> methodSet = new HashSet<Integer>();
private HashSet<Integer> variableSet = new HashSet<Integer>();
private HashSet<Integer> methodSet;
private HashSet<Integer> variableSet;
private List<String> cupVars;
/**
* Definition of all Java Keywords + boolean + null
*/
private int[] keywords = {
ITerminalSymbols.TokenNameabstract,
ITerminalSymbols.TokenNameassert,
......@@ -98,12 +99,11 @@ public class JavaTokenScanner implements ITokenScanner {
ITerminalSymbols.TokenNamefalse,
ITerminalSymbols.TokenNamenull};
private HashSet<String> currentLabels = null;
public JavaTokenScanner() {
this.currentLabels = new HashSet<String>();
this.variableSet = new HashSet<Integer>();
this.methodSet = new HashSet<Integer>();
this.cupVars = new LinkedList<String>();
}
public void updateParserResult(ParserResult result) {
......@@ -111,45 +111,42 @@ public class JavaTokenScanner implements ITokenScanner {
this.previousCodeBlockRange = null;
}
/**
* refreshes the Positions of Java variables, Cup variables and java methods from the
* current CodeBlock
*
* @param pos
*/
private void refreshSpecialSymbols(Position pos) {
// System.out.println("TRYING TO FIND POSITION: " + pos);
this.currentLabels.clear();
AbstractNode node = ast.findAtPosition(pos);
if (node == null)
return;
previousCodeBlockRange = node.getRange();
if (node instanceof ActionCodeBlock) {
if (node instanceof CodeBlock) {
ActionCodeBlock codeBlock = (ActionCodeBlock) node;
CodeBlock codeBlock = (CodeBlock) node;
methodSet = codeBlock.methodPositions();
variableSet = codeBlock.variablePositions();
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");
}
}
if(codeBlock instanceof ActionCodeBlock){
cupVars = ((ActionCodeBlock)codeBlock).getVariableLabels();
}else{
cupVars.clear();
}
}
}
/**
* Sets the Range to be scanned
*/
public void setRange(IDocument document, int offset, int length) {
//Create eclipse javascanner
this.scanner = ToolFactory.createScanner(true, false, false, false);
this.scanner.setSource(document.get().substring(
offset, offset + length).toCharArray());
......@@ -158,7 +155,6 @@ public class JavaTokenScanner implements ITokenScanner {
this.offset = offset;
if (ast == null) {
this.currentLabels.clear();
} else {
// TODO: we convert offset to line number / position.
......@@ -212,6 +208,9 @@ public class JavaTokenScanner implements ITokenScanner {
static final Token cupDefinedVariable = new Token(new TextAttribute(
CupTextEditor.JAVA_CUP_DEFINED, null, SWT.ITALIC));
/**
* returns next IToken with TextAttribute (eg color/font)
*/
public IToken nextToken() {
int token;
try {
......@@ -258,17 +257,28 @@ public class JavaTokenScanner implements ITokenScanner {
if(variableSet.contains(offset)){
//TODO: differentiate between javaVars and cupVars
return javaVariable;
if(cupVars.contains(name)){
return cupDefinedVariable;
}else{
return javaVariable;
}
}
}
return Token.UNDEFINED;
}
/**
* gets complete offest of current Token
*/
public int getTokenOffset() {
return this.offset + scanner.getCurrentTokenStartPosition();
}
/**
* gets length of current Token
*/
public int getTokenLength() {
return scanner.getCurrentTokenEndPosition() - scanner.getCurrentTokenStartPosition() + 1;
}
......
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