diff --git a/src/main/java/spoon/reflect/visitor/filter/CatchVariableReferenceFunction.java b/src/main/java/spoon/reflect/visitor/filter/CatchVariableReferenceFunction.java
new file mode 100644
index 00000000000..6588be65b04
--- /dev/null
+++ b/src/main/java/spoon/reflect/visitor/filter/CatchVariableReferenceFunction.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2006-2017 INRIA and contributors
+ * Spoon - http://spoon.gforge.inria.fr/
+ *
+ * This software is governed by the CeCILL-C License under French law and
+ * abiding by the rules of distribution of free software. You can use, modify
+ * and/or redistribute the software under the terms of the CeCILL-C license as
+ * circulated by CEA, CNRS and INRIA at http://www.cecill.info.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-C license and that you accept its terms.
+ */
+package spoon.reflect.visitor.filter;
+
+import spoon.reflect.code.CtCatchVariable;
+import spoon.reflect.reference.CtCatchVariableReference;
+import spoon.reflect.visitor.chain.CtConsumableFunction;
+import spoon.reflect.visitor.chain.CtConsumer;
+
+/**
+ * This Query expects a {@link CtCatchVariable} as input
+ * and returns all {@link CtCatchVariableReference}s, which refers this input.
+ *
+ * Usage:
+ *
{@code
+ * CtCatchVariable var = ...;
+ * var
+ * .map(new CatchVariableReferenceFunction())
+ * .forEach((CtCatchVariableReference ref)->...process references...);
+ * }
+ *
+ */
+public class CatchVariableReferenceFunction implements CtConsumableFunction> {
+
+ public CatchVariableReferenceFunction() {
+ }
+
+ @Override
+ public void apply(CtCatchVariable> localVariable, CtConsumer outputConsumer) {
+ localVariable
+ .map(new CatchVariableScopeFunction())
+ .select(new DirectReferenceFilter>(localVariable.getReference()))
+ .forEach(outputConsumer);
+ }
+}
diff --git a/src/main/java/spoon/reflect/visitor/filter/CatchVariableScopeFunction.java b/src/main/java/spoon/reflect/visitor/filter/CatchVariableScopeFunction.java
new file mode 100644
index 00000000000..b685d1dfcb1
--- /dev/null
+++ b/src/main/java/spoon/reflect/visitor/filter/CatchVariableScopeFunction.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (C) 2006-2017 INRIA and contributors
+ * Spoon - http://spoon.gforge.inria.fr/
+ *
+ * This software is governed by the CeCILL-C License under French law and
+ * abiding by the rules of distribution of free software. You can use, modify
+ * and/or redistribute the software under the terms of the CeCILL-C license as
+ * circulated by CEA, CNRS and INRIA at http://www.cecill.info.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-C license and that you accept its terms.
+ */
+package spoon.reflect.visitor.filter;
+
+import spoon.reflect.code.CtCatch;
+import spoon.reflect.code.CtCatchVariable;
+import spoon.reflect.visitor.chain.CtConsumableFunction;
+import spoon.reflect.visitor.chain.CtConsumer;
+
+/**
+ * This Query expects a {@link CtCatchVariable} as input
+ * and returns all CtElements,
+ * which are in visibility scope of that catch variable.
+ * In other words, it returns all elements,
+ * which might be reference to that catch variable.
+ *
+ * It can be used to search for variable declarations or
+ * variable references which might be in name conflict with input catch variable.
+ *
+ * Usage:
+ * {@code
+ * CtCatchVariable var = ...;
+ * var.map(new CatchVariableScopeFunction()).forEach(...process result...);
+ * }
+ *
+ */
+public class CatchVariableScopeFunction implements CtConsumableFunction> {
+
+ public CatchVariableScopeFunction() {
+ }
+
+ @Override
+ public void apply(CtCatchVariable> catchVariable, CtConsumer outputConsumer) {
+ catchVariable.getParent(CtCatch.class).getBody().filterChildren(null).forEach(outputConsumer);
+ }
+}
diff --git a/src/test/java/spoon/test/query_function/QueryTest.java b/src/test/java/spoon/test/query_function/QueryTest.java
index 7ab07ba1ac3..7c13b8cb86d 100644
--- a/src/test/java/spoon/test/query_function/QueryTest.java
+++ b/src/test/java/spoon/test/query_function/QueryTest.java
@@ -22,6 +22,7 @@
import spoon.reflect.reference.CtExecutableReference;
import spoon.reflect.reference.CtVariableReference;
import spoon.reflect.visitor.chain.CtConsumableFunction;
+import spoon.reflect.visitor.filter.CatchVariableReferenceFunction;
import spoon.reflect.visitor.filter.ParameterReferenceFunction;
import spoon.test.query_function.testclasses.packageA.ClassA;
@@ -95,7 +96,7 @@ class Context {
assertEquals(countOfModelClasses, context.classCount);
}
- @Test
+ @Test
public void testParameterReferenceFunction() throws Exception {
//visits all the CtParameter elements whose name is "field" and search for all their references
//The test detects whether found references are correct by these two checks:
@@ -110,6 +111,22 @@ public void testParameterReferenceFunction() throws Exception {
return false;
}).list();
}
+
+ @Test
+ public void testCatchVariableReferenceFunction() throws Exception {
+ //visits all the CtCatchVariable elements whose name is "field" and search for all their references
+ //The test detects whether found references are correct by these two checks:
+ //1) the each found reference is on the left side of binary operator and on the right side there is unique reference identification number. Like: (field == 7)
+ //2) the model is searched for all variable references which has same identification number and counts them
+ //Then it checks that counted number of references and found number of references is same
+ factory.Package().getRootPackage().filterChildren((CtCatchVariable> var)->{
+ if(var.getSimpleName().equals("field")) {
+ int value = getLiteralValue(var);
+ checkVariableAccess(var, value, new CatchVariableReferenceFunction());
+ }
+ return false;
+ }).list();
+ }
private void checkVariableAccess(CtVariable> var, int value, CtConsumableFunction> query) {
class Context {