[461316] Find variables declared by preceding siblings operations
Bug: 461316
Change-Id: I4bc2ea0f10d7d5d7441e10e48141d4d40ae177b2
Signed-off-by: Cedric Brun <cedric.brun@obeo.fr>
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java
index 3f0aaa5..bc1bfb2 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java
@@ -16,6 +16,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
@@ -294,13 +295,14 @@
*/
private void collectContextualVariableDefinitions(Map<String, String> vars, EObject top, EObject bottom) {
// A map with multiple values is not strictly required as we only use
- // one value, but it is useful when debugging to have all the information.
+ // one value, but it is useful when debugging to have all the
+ // information.
Map<String, Collection<String>> definitions = Maps.newHashMap();
// Walk up from bottom to top and gather every definition in the scope.
EObject context = bottom;
do {
appendAllLocalVariableDefinitions(definitions, context);
- context = context.eContainer();
+ context = precedingSiblingOrContainer(context);
} while (context != null && context != top.eContainer());
// Merge all the definitions, by taking the one closest to
// <code>bottom</code> when there are multiple ones.
@@ -309,6 +311,33 @@
}
}
+ private EObject precedingSiblingOrContainer(EObject context) {
+ EObject container = context.eContainer();
+ EStructuralFeature containingFeature = context.eContainingFeature();
+ if (container != null && containingFeature != null) {
+ Object val = container.eGet(containingFeature);
+ /*
+ * if val is not a collection then we have no siblings.
+ */
+ if (val instanceof EList<?>) {
+ EList<?> childs = (EList<?>) val;
+ int contextPositionInContainingList = childs.indexOf(context);
+ if (contextPositionInContainingList > 0) {
+ /*
+ * we have at least one sibling, we return the closest one
+ * to our position going upward.
+ */
+ Object sibling = childs.get(contextPositionInContainingList - 1);
+ if (sibling instanceof EObject) {
+ return (EObject)sibling;
+ }
+ }
+ }
+ }
+
+ return container;
+ }
+
/**
* Returns the name of the type of the given variable, as defined in the
* meta-model annotations.