From 21616a41f7a5354e0652daaa3289e88ecd2a6c54 Mon Sep 17 00:00:00 2001 From: Pavel Vojtechovsky Date: Mon, 30 Jan 2017 10:50:30 +0100 Subject: [PATCH] feature: add filtering helpers (CatchVariableReferenceFunction, CatchVariableScopeFunction) (#1145) * feature: add CatchVariableReferenceFunction, CatchVariableScopeFunction * test - common code shared by all variable based reference functions * test CatchVariableReferenceFunction --- .../CatchVariableReferenceFunction.java | 49 ++++++++++++++++++ .../filter/CatchVariableScopeFunction.java | 50 +++++++++++++++++++ .../spoon/test/query_function/QueryTest.java | 19 ++++++- 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 src/main/java/spoon/reflect/visitor/filter/CatchVariableReferenceFunction.java create mode 100644 src/main/java/spoon/reflect/visitor/filter/CatchVariableScopeFunction.java 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 {