Test & fix for Bug 313804 - [dom] [assist] add support for "precedence after" in DOM and quickfix
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
index 5a516d2..04ad4fd 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
@@ -3619,6 +3619,8 @@
for (org.eclipse.jdt.internal.compiler.ast.NameReference nameRef: aPrecedence.bindingNames) {
newPrecedence.elements().add(convert(nameRef));
}
+ if (aPrecedence.isAfter)
+ newPrecedence.setAfter(true);
return newPrecedence;
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
index 412ec41..2fb2bc9 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
@@ -2828,7 +2828,8 @@
}
PrecedenceDeclaration otherPrecedence = (PrecedenceDeclaration) other;
- return safeSubtreeMatch(node.elements(), otherPrecedence.elements());
+ return node.isAfter() == otherPrecedence.isAfter()
+ && safeSubtreeMatch(node.elements(), otherPrecedence.elements());
}
public boolean match(GuardPredicateDeclaration node, Object other) {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrecedenceDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrecedenceDeclaration.java
index a5b868e..4efdd48 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrecedenceDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrecedenceDeclaration.java
@@ -36,12 +36,21 @@
public static final ChildListPropertyDescriptor ELEMENTS_PROPERTY =
new ChildListPropertyDescriptor(PrecedenceDeclaration.class, "elements", Name.class, NO_CYCLE_RISK);
+ /**
+ * The "after" structural property of this node type.
+ * @since 0.7.0
+ */
+ @SuppressWarnings("nls")
+ public static final SimplePropertyDescriptor AFTER_PROPERTY =
+ new SimplePropertyDescriptor(PrecedenceDeclaration.class, "after", boolean.class, MANDATORY); //$NON-NLS-1$
+
private static final List PROPERTY_DESCRIPTORS_3_0;
static {
- List propertyList = new ArrayList(2);
+ List propertyList = new ArrayList(3);
createPropertyList(PrecedenceDeclaration.class, propertyList);
addProperty(ELEMENTS_PROPERTY, propertyList);
+ addProperty(AFTER_PROPERTY, propertyList);
PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
}
@@ -54,6 +63,11 @@
}
ASTNode.NodeList _elements = new ASTNode.NodeList(ELEMENTS_PROPERTY);
+
+ /**
+ * <code>true</code> for <code>precedence after</code>, else <code>false</code>.
+ */
+ boolean isAfter = false;
PrecedenceDeclaration(AST ast)
{
@@ -61,14 +75,28 @@
}
List internalGetChildListProperty(ChildListPropertyDescriptor property)
- {
- if (property == ELEMENTS_PROPERTY) {
- return this._elements;
- }
- // allow default implementation to flag the error
- return super.internalGetChildListProperty(property);
- }
-
+ {
+ if (property == ELEMENTS_PROPERTY) {
+ return this._elements;
+ }
+ // allow default implementation to flag the error
+ return super.internalGetChildListProperty(property);
+ }
+
+ @Override
+ boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
+ if (property == AFTER_PROPERTY) {
+ if (get) {
+ return isAfter();
+ } else {
+ setAfter(value);
+ return false;
+ }
+ }
+ // allow default implementation to flag the error
+ return super.internalGetSetBooleanProperty(property, get, value);
+ }
+
@Override
void accept0(ASTVisitor visitor) {
boolean visitChildren = visitor.visit(this);
@@ -98,6 +126,7 @@
PrecedenceDeclaration result = new PrecedenceDeclaration(target);
result.setSourceRange(this.getStartPosition(), this.getLength());
result.elements().addAll(ASTNode.copySubtrees(target, elements()));
+ result.setAfter(isAfter());
return result;
}
@@ -115,9 +144,25 @@
return this._elements;
}
+ /**
+ * Mark whether this is a <code>precedence after</code> declaration.
+ */
+ public void setAfter(boolean isAfter) {
+ preValueChange(AFTER_PROPERTY);
+ this.isAfter = isAfter;
+ postValueChange(AFTER_PROPERTY);
+ }
+
+ /**
+ * Answer whether this is a <code>precedence after</code> declaration.
+ */
+ public boolean isAfter() {
+ return this.isAfter;
+ }
+
@Override
int memSize() {
- return BASE_NODE_SIZE;
+ return BASE_NODE_SIZE + 1;
}
@Override
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
index 587384a..952692d 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -2096,7 +2096,27 @@
this.buffer.append("}\n");//$NON-NLS-1$
return false;
}
-//gbr}
+
+ /*
+ * @see ASTVisitor#visit(PrecedenceDeclaration)
+ */
+ @SuppressWarnings("nls")
+ @Override
+ public boolean visit(PrecedenceDeclaration node)
+ {
+ buffer.append("precedence ");
+ if (node.isAfter())
+ buffer.append("after ");
+ for (Iterator iter = node.elements().iterator(); iter.hasNext();) {
+ Name name = (Name) iter.next();
+ name.accept(this);
+ if (iter.hasNext())
+ buffer.append(", ");
+ }
+ buffer.append(";");
+ return false;
+ }
+//gbr+SH}
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
index 20eefea..166a3c2 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
@@ -3869,6 +3869,25 @@
@Override
public boolean visit(PrecedenceDeclaration node) {
+ // 'after' keyword:
+ boolean isAfter = ((Boolean) getOriginalValue(node, PrecedenceDeclaration.AFTER_PROPERTY)).booleanValue();
+ boolean invertAfter = isChanged(node, PrecedenceDeclaration.AFTER_PROPERTY);
+ if (invertAfter) {
+ if (isAfter) {
+ try {
+ getScanner().readToToken(TerminalTokens.TokenNameafter, node.getStartPosition());
+ int start= getScanner().getCurrentStartOffset();
+ int end= getScanner().getCurrentEndOffset();
+ doTextRemove(start, end-start+1, getEditGroup(node, PrecedenceDeclaration.AFTER_PROPERTY));
+ } catch (CoreException e) {
+ // ignore
+ }
+ } else {
+ int pos = node.getStartPosition()+"precedence".length(); //$NON-NLS-1$
+ doTextInsert(pos, " after", getEditGroup(node, PrecedenceDeclaration.AFTER_PROPERTY)); //$NON-NLS-1$
+ }
+ }
+ // elements
RewriteEvent precedencesEvent = getEvent(node, PrecedenceDeclaration.ELEMENTS_PROPERTY);
if ( precedencesEvent == null
|| precedencesEvent.getChangeKind() == RewriteEvent.UNCHANGED)
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
index 1f6d9a0..f6de71c 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
@@ -1741,6 +1741,8 @@
@Override
public boolean visit(PrecedenceDeclaration node) {
this.result.append("precedence ");
+ if (node.isAfter())
+ this.result.append("after ");
String sep = "";
for (Object element: node.elements()) {
this.result.append(sep);
diff --git a/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/text/correction/PrecedenceProposalSubProcessor.java b/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/text/correction/PrecedenceProposalSubProcessor.java
index 6d07e92..673b9cd 100644
--- a/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/text/correction/PrecedenceProposalSubProcessor.java
+++ b/plugins/org.eclipse.objectteams.otdt.jdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/text/correction/PrecedenceProposalSubProcessor.java
@@ -28,6 +28,8 @@
import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IMethodMappingBinding;
+import org.eclipse.jdt.core.dom.Modifier;
+import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.PrecedenceDeclaration;
import org.eclipse.jdt.core.dom.RoleTypeDeclaration;
@@ -181,6 +183,7 @@
Messages.format(CorrectionMessages.OTQuickfix_addbindingprecedence_description,
new String[]{roleType.getName().getIdentifier()}),
callin1, callin2,
+ Modifier.isAfter(mapping1.getCallinModifier()),
name1 != null, name2 != null);
// create new, editable labels (linked to their mentioning within the precedence declaration):
@@ -221,6 +224,7 @@
new String[]{teamType.getName().getIdentifier()}),
Signature.getSimpleName(problemArguments[0])+"."+callin1, //$NON-NLS-1$
Signature.getSimpleName(problemArguments[2])+"."+callin2, //$NON-NLS-1$
+ ModifierKeyword.AFTER_KEYWORD.toString().equals(problemArguments[4]),
false, false /* don't link labels */);
}
@@ -245,6 +249,7 @@
new String[]{teamType.getName().getIdentifier()}),
Signature.getSimpleName(problemArguments[0]),
Signature.getSimpleName(problemArguments[2]),
+ ModifierKeyword.AFTER_KEYWORD.toString().equals(problemArguments[4]),
false, false /* don't link labels */);
}
@@ -268,6 +273,7 @@
String label,
String callin1,
String callin2,
+ boolean isAfter,
boolean linkLabel1,
boolean linkLabel2)
{
@@ -282,6 +288,8 @@
Name element2 = ast.newName(callin2);
newPrecedence.elements().add(element1);
newPrecedence.elements().add(element2);
+ if (isAfter)
+ newPrecedence.setAfter(true);
listRewrite.insertLast(newPrecedence, null);
MyLinkedCorrectionProposal proposal = new MyLinkedCorrectionProposal(
label,