Commit 02943e3b authored by Benedikt Engeser's avatar Benedikt Engeser

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

Conflicts:
	CupPlugin/META-INF/MANIFEST.MF
parents 6cf9f65e 9cd4a522
......@@ -968,9 +968,9 @@ prod_part ::=
Range range = new Range (Position.fromLocation(symidxleft),
Position.fromLocation(symidxright));
if (labid == null)
ref = new LabeledProductionSymbolRef(new Name(symid, range), labid, range);
else
ref = new ProductionSymbolRef(new Name(symid, range), range);
else
ref = new LabeledProductionSymbolRef(new Name(symid, range), labid, range);
ast_add_rhs_part(ref);
}
:}
......
package de.in.tum.www2.cup;
import java.util.HashMap;
import java.util.HashSet;
public class Declarations {
......@@ -7,6 +8,24 @@ public class Declarations {
private HashSet<String> terminals = new HashSet<String>();
private HashSet<String> non_terminals = new HashSet<String>();
// This map stores the declared symbols for a right hand side at a
// particular index within the production definition.
//
// Note, that this is a superset of the valid symbols for a particular
// action block. Therefore, blocks will still need to compute their own sets.
// However this is a good approximation to avoid refreshing the syntax
// unnecessarily.
// Won't work if: righthand sides are reordered or declared symbols name
// within a righthand side are moved in front of an action block.
//
// The key in this map is computed like as:
// Non-Terminal-Name + "::" + number of right hand
// sides + "::" + right hand side index.
//
// see also: DeclarationsExtractorVisitor
//
private HashMap<String,HashSet<String>> locals = new HashMap<String,HashSet<String>>();
public HashSet<String> getTerminals() {
return terminals;
}
......@@ -14,19 +33,36 @@ public class Declarations {
public HashSet<String> getNonTerminals() {
return non_terminals;
}
public boolean isDeclaredTerminal(String name) {
return terminals.contains(name);
}
public boolean isDeclaredNonTerminal(String name) {
return non_terminals.contains(name);
}
public boolean isDeclaredLocal(String name) {
for (HashSet<String> s : locals.values())
if (s.contains(name))
return true;
return false;
}
public boolean isDeclared(String name) {
return isDeclaredTerminal(name) || isDeclaredNonTerminal (name);
return isDeclaredTerminal(name)
|| isDeclaredNonTerminal (name)
|| isDeclaredLocal(name);
}
public HashMap<String,HashSet<String>> getLocals() {
return locals;
}
public HashSet<String> getLocalsFor(String path) {
return locals.get(path);
}
@Override
public boolean equals(Object other) {
if (other == null)
......@@ -37,8 +73,9 @@ public class Declarations {
if (this.getClass().equals(other.getClass())) {
Declarations o = (Declarations) other;
return terminals.equals(o.terminals) &&
non_terminals.equals(o.non_terminals);
return terminals.equals(o.terminals)
&& non_terminals.equals(o.non_terminals)
&& locals.equals(o.locals);
}
return false;
......
package de.in.tum.www2.cup.analysis;
import java.util.HashMap;
import java.util.HashSet;
import de.in.tum.www2.cup.Declarations;
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.NonTerminal;
import de.in.tum.www2.cup.ast.NonTerminalDeclaration;
import de.in.tum.www2.cup.ast.Production;
import de.in.tum.www2.cup.ast.ProductionRight;
import de.in.tum.www2.cup.ast.ProductionSymbolRef;
import de.in.tum.www2.cup.ast.Terminal;
import de.in.tum.www2.cup.ast.TerminalDeclaration;
import de.in.tum.www2.cup.ast.TypedNonTerminalDeclaration;
......@@ -17,6 +25,40 @@ public class DeclarationsExtractorVisitor extends Visitor<Object>
return result;
}
@Override
public void postVisit (ProductionRight node, Object data) {
Production parent = (Production) node.getParent();
int index=0;
for (ProductionRight pr : parent.getRightHandSides()) {
if (pr == node)
break;
index++;
}
StringBuilder builder = new StringBuilder();
builder.append (parent.getName().name);
builder.append ("::");
builder.append (parent.getRightHandSides().size());
builder.append ("::");
builder.append (index);
String key = builder.toString();
HashMap<String,HashSet<String>> locals = result.getLocals();
if (!locals.containsKey(key))
locals.put(key, new HashSet<String>());
HashSet<String> set = locals.get(key);
for (IProductionRightPart part : node.getList()) {
if (part instanceof LabeledProductionSymbolRef) {
LabeledProductionSymbolRef lpsr = (LabeledProductionSymbolRef) part;
set.add(lpsr.label);
}
}
}
@Override
public void postVisit (TerminalDeclaration node, Object data) {
if (node != null && node.getTerminals() != null) {
......@@ -50,11 +92,5 @@ public class DeclarationsExtractorVisitor extends Visitor<Object>
result.getNonTerminals().add(nt.getName().name);
}
}
@Override
public Object preVisit (Production node, Object data) {
// We don't want to visit the productions.
noDescend();
return data;
}
}
......@@ -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)
......
......@@ -2,8 +2,7 @@ package de.in.tum.www2.cup.analysis;
import de.in.tum.www2.cup.ast.*;
public class FindNextCodeBlockLineVisitor extends Visitor<Object>
{
public class FindNextCodeBlockLineVisitor extends Visitor<Object> {
private int line;
private int result;
......@@ -15,28 +14,34 @@ public class FindNextCodeBlockLineVisitor extends Visitor<Object>
this.line = line;
this.result = -1;
}
private void doCheck(AbstractNode node) {
if (node == null || result != -1)
if (node == null) {
return;
int blockLine = node.getBegin().getLine();
if (line >= blockLine && line <= node.getEnd().getLine()) {
}
int blockLine = node.getBegin().getLine();
int blockEndLine = node.getEnd().getLine();
if (line >= blockLine && line <= blockEndLine) {
System.out.println("Block begins: " + blockLine + " Block ends: "
+ blockEndLine);// TODO: DELETE
result = line;
return;
}
if (blockLine > line)
if (blockLine > line
&& ((result != -1 && (result - line) > (blockLine - line)) || result == -1)) {
result = blockLine;
}
}
@Override
public void postVisit (ActionCodeBlock node, Object data) {
public void postVisit(ActionCodeBlock node, Object data) {
doCheck(node);
}
@Override
public void postVisit (SpecialCodeBlock node, Object data) {
public void postVisit(SpecialCodeBlock node, Object data) {
doCheck(node);
}
......
......@@ -4,12 +4,15 @@ 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;
public class ParserResult extends AbstractNode {
private boolean resolved;
public Package pack;
public List<Import> imports = new ArrayList<Import> ();
......@@ -44,10 +47,19 @@ public class ParserResult extends AbstractNode {
return declVisitor.getResult();
}
// TODO: cache in a safe way!
public void resolveReferences() {
if (resolved)
return;
RefResolutionVisitor resRefVisitor = new RefResolutionVisitor();
this.accept(resRefVisitor, null);
resolved = true;
}
// 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) {
......
......@@ -21,6 +21,10 @@ public class Production extends AbstractNode
public AbstractNode getDeclaration() {
return declarationRef;
}
public List<ProductionRight> getRightHandSides() {
return rhs;
}
@Override
public void setDeclaration(AbstractNode node) {
......
//----------------------------------------------------
// The following code was generated by CUP v0.11b 20140808 (SVN rev 54)
// The following code was generated by CUP v0.11b 20140902 (SVN rev )
//----------------------------------------------------
package de.in.tum.www2.cup.internal;
......
......@@ -37,7 +37,7 @@ public class JavaScanner
private Lexer lexer;
public JavaScanner(Reader r) {
this.lexer = new Lexer(r);
this.lexer = new Lexer(r, true);
}
public JavaSymbol next_token() throws IOException {
......
......@@ -34,6 +34,42 @@ 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;
}
public boolean isComment() {
if (s == null)
return false;
return s.sym == Sym.COMMENT;
}
private static final HashSet<Integer> keywords = new HashSet<Integer>();
......@@ -90,16 +126,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;
......
......@@ -5,6 +5,7 @@ import java.io.Reader;
import java.io.LineNumberReader;
import java_cup.runtime.ComplexSymbolFactory;
import java_cup.runtime.Symbol;
import de.in.tum.www2.cup.ErrorManager;
import de.in.tum.www2.java.internal.onefivelexer.Sym;
......@@ -23,9 +24,11 @@ public class Lexer implements java_cup.runtime.Scanner {
int line_pos = 1;
int line_num = 0;
LineList lineL = new LineList(-line_pos, null); // sentinel for line #0
public Lexer(Reader reader) {
boolean acceptComments;
public Lexer(Reader reader, boolean acceptComments) {
this(reader, 2); // by default, use a Java 1.2-compatible lexer.
this.acceptComments = acceptComments;
}
public Lexer(Reader reader, int java_minor_version) {
this.reader = new LineNumberReader(new EscapedUnicodeReader(reader));
......@@ -104,11 +107,22 @@ public class Lexer implements java_cup.runtime.Scanner {
do {
startpos = lineL.head + line_pos;
ie = getInputElement();
if (ie instanceof DocumentationComment)
comment = ((Comment)ie).getComment();
if (ie instanceof DocumentationComment) {
comment = ((Comment)ie).getComment();
}
if (ie instanceof Comment && acceptComments)
break;
} while (!(ie instanceof Token));
endpos = lineL.head + line_pos - 1;
if (ie instanceof Comment) {
java_cup.runtime.Symbol sym = new Symbol(Sym.COMMENT, comment);
sym.left = startpos; sym.right = endpos;
return sym;
}
//System.out.println(ie.toString()); // uncomment to debug lexer.
java_cup.runtime.Symbol sym = ((Token)ie).token();
// fix up left/right positions.
......
package de.in.tum.www2.java.internal.onefivelexer;
public interface Sym {
// manually added.
public static final int COMMENT = 107;
/* terminals */
public static final int AT = 94;
public static final int SHORT = 4;
......@@ -216,7 +221,8 @@ public interface Sym {
"STRICTFP",
"ASSERT",
"ELLIPSIS",
"ENUM"
"ENUM",
"COMMENT"
};
}
......@@ -18,8 +18,13 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.core.expressions;bundle-version="3.4.600",
org.eclipse.debug.core;bundle-version="3.9.1",
org.eclipse.debug.ui;bundle-version="3.10.1",
<<<<<<< HEAD
org.eclipse.jdt;bundle-version="3.10.0",
org.eclipse.jdt.debug;bundle-version="3.8.101"
=======
org.eclipse.jdt.core;bundle-version="3.10.0",
org.eclipse.jdt.ui;bundle-version="3.10.1"
>>>>>>> branch 'master' of git@github.com:jroith/cup-eclipse.git
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
......@@ -132,4 +132,26 @@
value="true">
</persistent>
</extension>
<extension
point="org.eclipse.ui.newWizards">
<category
id="de.tum.in.www2.CupPlugin"
name="Cup">
</category>
<wizard
category="de.tum.in.www2.CupPlugin"
class="de.tum.in.www2.cupplugin.wizards.CupFileWizard"
icon="icons/cup_icon.png"
id="de.tum.in.www2.cupplugin.wizards.CupFileWizard"
name="Cup File">
</wizard>
<wizard
category="de.tum.in.www2.CupPlugin"
class="de.tum.in.www2.cupplugin.wizards.CupJavaProjectWizard"
icon="icons/cup_icon.png"
id="de.tum.in.www2.cupplugin.wizards.CupJavaProjectWizard"
name="Cup Java Project"
project="true">
</wizard>
</extension>
</plugin>
......@@ -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;
......
......@@ -142,36 +142,28 @@ public class Controller {
ITypedRegion region = document.getPartition(event.getOffset());
//TODO: Space for performance improvements
if (event.getText().trim().length() == 0 && (document.getLength()<=(event.getOffset()+1) || document.getChar(event.getOffset()+1) == (' '))) {
System.out.println("0 Trim detected");
if (event.getText().equals(
System.getProperty("line.separator"))) {
// Some debug outut...
System.out.println("new line");
addJobToDo(JobsToDo.locationPatch);
}
if (event.getText().equals("")) {
System.out.println("delete");
char beforeDelete = '+'; // DUMMY
int offset = event.getOffset();
if (offset > 0)
beforeDelete = document.get().charAt(offset - 1);
//System.out.println(beforeDelete);
if (region.getType().equals(CupPartionScanner.JAVA_CODE)) {
if (beforeDelete == '{') {
System.out.println("comment delete");
addJobToDo(JobsToDo.parseCode);
addJobToDo(JobsToDo.buildTable);
}
} else if (region.getType().equals(CupPartionScanner.SINGLE_COMMENT)){
if (beforeDelete == '/') {
System.out.println("comment delete");
addJobToDo(JobsToDo.parseCode);
addJobToDo(JobsToDo.buildTable);
}
} else if (region.getType().equals(CupPartionScanner.MULTILINE_COMMENT)){
if (beforeDelete == '/' || beforeDelete == '*') {
System.out.println("comment delete");
addJobToDo(JobsToDo.parseCode);
addJobToDo(JobsToDo.buildTable);
}
......
......@@ -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();
......
......@@ -13,7 +13,17 @@ import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.swt.custom.StyleRange;
import de.in.tum.www2.cup.Range;
import de.in.tum.www2.cup.analysis.Visitor;
import de.in.tum.www2.cup.analysis.WildcardVisitor;
import de.in.tum.www2.cup.ast.AbstractNode;
import de.in.tum.www2.cup.ast.IHasDeclarationReference;
import de.in.tum.www2.cup.ast.IHasDefinitionReference;
import de.in.tum.www2.cup.ast.IWithName;
import de.in.tum.www2.cup.ast.Name;
import de.in.tum.www2.cup.ast.NonTerminal;
import de.in.tum.www2.cup.ast.ParserResult;
import de.in.tum.www2.cup.ast.Production;
public class CupHyperlinkDetector implements IHyperlinkDetector {
......@@ -23,27 +33,103 @@ public class CupHyperlinkDetector implements IHyperlinkDetector {
this.editor = editor;
}
static public class HyperlinkingVisitor extends Visitor<Object> {
static public class HyperlinkingVisitor extends WildcardVisitor<Object> {
// TODO: we should assume that references have been resolved,
// which means, we can easily look up the declaration
// and definition locations.
ITextViewer textViewer;
List<IHyperlink> links;
private int offset;
public List<IHyperlink> getLinks() {
return links;
}
public HyperlinkingVisitor(IRegion region, ITextViewer textViewer)
{
this.links = new ArrayList<IHyperlink>();
this.textViewer = textViewer;
offset = region.getOffset() + region.getLength();
}
@Override
public void postVisitWildcard(AbstractNode node, Object data) {
if (node == null)
return;
if (!(node instanceof IHasDefinitionReference ||
node instanceof IHasDeclarationReference))
return;
if (node instanceof IWithName) {
Name name = ((IWithName) node).getName();
if (name != null && name.name != null) {
int length = name.name.length();
int offsetFromStart = name.getBegin().getOffsetFromStart();
if (offset < offsetFromStart || offset > offsetFromStart + length)
return;
Region outputRegion = new Region(offsetFromStart, length);
AbstractNode targetNode;
if (node instanceof IHasDefinitionReference) {
targetNode = ((IHasDefinitionReference) node).getDefinition();
if (targetNode != null)
links.add(new CupDefinitionHyperlink(outputRegion, textViewer,
targetNode.getBegin().getOffsetFromStart(), 1));
}
if (node instanceof IHasDeclarationReference) {
targetNode = ((IHasDeclarationReference) node).getDeclaration();
if (targetNode != null)
links.add(new CupDeclarationHyperlink(outputRegion, textViewer,
targetNode.getBegin().getOffsetFromStart(), 1));
}
}
}
}
@Override
public Object preVisitWildcard(AbstractNode node, Object data) {
return data;
}
}
static public class CupDefinitionHyperlink extends CupHyperlink
{
public CupDefinitionHyperlink(IRegion region, ITextViewer textViewer,
int targetOffset, int targetLength) {
super(region, textViewer, targetOffset, targetLength);
}
@Override
public String getHyperlinkText() {
return "Open Definition";
}
}
static public class CupDeclarationHyperlink extends CupHyperlink