-
-
Notifications
You must be signed in to change notification settings - Fork 351
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: add filter helpers (FieldReferenceFunction, FieldScopeFuncti…
…on, SubtypeFilter) (#1141) * feature FieldReferenceFunction, FieldScopeFunction, SubtypeFilter * FieldReferenceFunction uses CtQuery#select * test FieldReferenceFunction * test FieldReferenceFunction in other classes and packages * fix comment
- Loading branch information
1 parent
439f251
commit 6bef9fd
Showing
8 changed files
with
543 additions
and
4 deletions.
There are no files selected for viewing
49 changes: 49 additions & 0 deletions
49
src/main/java/spoon/reflect/visitor/filter/FieldReferenceFunction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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.declaration.CtField; | ||
import spoon.reflect.reference.CtFieldReference; | ||
import spoon.reflect.visitor.chain.CtConsumableFunction; | ||
import spoon.reflect.visitor.chain.CtConsumer; | ||
|
||
/** | ||
* This Query expects a {@link CtField} as input | ||
* and returns all {@link CtFieldReference}s, which refers this input. | ||
* <br> | ||
* Usage:<br> | ||
* <pre> {@code | ||
* CtField param = ...; | ||
* param | ||
* .map(new FieldReferenceFunction()) | ||
* .forEach((CtFieldReference ref)->...process references...); | ||
* } | ||
* </pre> | ||
*/ | ||
public class FieldReferenceFunction implements CtConsumableFunction<CtField<?>> { | ||
|
||
public FieldReferenceFunction() { | ||
} | ||
|
||
@Override | ||
public void apply(CtField<?> field, CtConsumer<Object> outputConsumer) { | ||
field | ||
.map(new FieldScopeFunction()) | ||
.select(new DirectReferenceFilter<CtFieldReference<?>>(field.getReference())) | ||
.forEach(outputConsumer); | ||
} | ||
} |
87 changes: 87 additions & 0 deletions
87
src/main/java/spoon/reflect/visitor/filter/FieldScopeFunction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/** | ||
* 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.declaration.CtField; | ||
import spoon.reflect.declaration.ModifierKind; | ||
import spoon.reflect.visitor.chain.CtConsumableFunction; | ||
import spoon.reflect.visitor.chain.CtConsumer; | ||
|
||
/** | ||
* This Query expects a {@link CtField} as input | ||
* and returns all CtElements, | ||
* which are in visibility scope of that field. | ||
* In other words, it returns all elements, | ||
* which might be reference to that field. | ||
* <br> | ||
* It can be used to search for variable declarations or | ||
* variable references which might be in name conflict with input field. | ||
* <br> | ||
* Usage:<br> | ||
* <pre> {@code | ||
* CtField param = ...; | ||
* param.map(new FieldScopeFunction()).forEach(...process result...); | ||
* } | ||
* </pre> | ||
*/ | ||
public class FieldScopeFunction implements CtConsumableFunction<CtField<?>> { | ||
|
||
public FieldScopeFunction() { | ||
} | ||
|
||
@Override | ||
public void apply(CtField<?> field, CtConsumer<Object> outputConsumer) { | ||
if (field.hasModifier(ModifierKind.PRIVATE)) { | ||
searchForPrivateField(field, outputConsumer); | ||
} else if (field.hasModifier(ModifierKind.PUBLIC)) { | ||
searchForPublicField(field, outputConsumer); | ||
} else if (field.hasModifier(ModifierKind.PROTECTED)) { | ||
searchForProtectedField(field, outputConsumer); | ||
} else { | ||
searchForPackageProtectedField(field, outputConsumer); | ||
} | ||
} | ||
protected void searchForPrivateField(CtField<?> field, CtConsumer<Object> outputConsumer) { | ||
//private field can be referred from the scope of current top level type only and children | ||
field.getTopLevelType() | ||
.filterChildren(null) | ||
.forEach(outputConsumer); | ||
} | ||
protected void searchForProtectedField(CtField<?> field, CtConsumer<Object> outputConsumer) { | ||
//protected field can be referred from the scope of current top level type only and children | ||
field.getFactory().getModel().getRootPackage() | ||
//search for all types which inherits from declaring type of this field | ||
.filterChildren(new SubtypeFilter(field.getDeclaringType().getReference())) | ||
//visit all elements in scope of these inherited types | ||
.filterChildren(null) | ||
.forEach(outputConsumer); | ||
} | ||
protected void searchForPublicField(CtField<?> field, CtConsumer<Object> outputConsumer) { | ||
//public field is visible everywhere | ||
field.getFactory().getModel().getRootPackage() | ||
//visit all children of root package | ||
.filterChildren(null) | ||
.forEach(outputConsumer); | ||
} | ||
protected void searchForPackageProtectedField(CtField<?> field, CtConsumer<Object> outputConsumer) { | ||
//package protected fields are visible in scope of the package of the top level type of the `field` | ||
field.getTopLevelType().getPackage() | ||
//visit all children of package, where top level type of the field is declared | ||
.filterChildren(null) | ||
.forEach(outputConsumer); | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
src/main/java/spoon/reflect/visitor/filter/SubtypeFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/** | ||
* 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.declaration.CtType; | ||
import spoon.reflect.reference.CtTypeReference; | ||
import spoon.reflect.visitor.Filter; | ||
|
||
/** | ||
* Matches all CtType elements, which are sub type of {@link #superType} | ||
* Matches the input `superType` too. | ||
* Call {@link #includingSelf(boolean)} with value false, if instance of {@link #superType} should no match this {@link Filter} | ||
*/ | ||
public class SubtypeFilter extends AbstractFilter<CtType<?>> { | ||
|
||
private CtTypeReference<?> superType; | ||
private String superTypeQualifiedName; | ||
|
||
public SubtypeFilter(CtTypeReference<?> superType) { | ||
this.superType = superType; | ||
} | ||
|
||
/** | ||
* @param includingSelf if false then element which is equal to to #superType is not matching | ||
*/ | ||
public SubtypeFilter includingSelf(boolean includingSelf) { | ||
if (includingSelf) { | ||
superTypeQualifiedName = null; | ||
} else { | ||
superTypeQualifiedName = superType.getQualifiedName(); | ||
} | ||
return this; | ||
} | ||
|
||
@Override | ||
public boolean matches(CtType<?> mayBeSubType) { | ||
if (superTypeQualifiedName != null && superTypeQualifiedName.equals(mayBeSubType.getQualifiedName())) { | ||
//we should not accept superType | ||
return false; | ||
} | ||
return mayBeSubType.isSubtypeOf(superType); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
src/test/java/spoon/test/query_function/testclasses/ClassC.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package spoon.test.query_function.testclasses; | ||
|
||
import static org.junit.Assert.assertTrue; | ||
|
||
public class ClassC { | ||
|
||
//package protected field | ||
int field = 300; | ||
int packageProtectedField = 301; | ||
private int privateField = 302; | ||
protected int protectedField = 303; | ||
public int publicField = 304; | ||
|
||
public ClassC() { | ||
assertTrue(field == 300); | ||
assertTrue(packageProtectedField == 301); | ||
assertTrue(privateField == 302); | ||
assertTrue(protectedField == 303); | ||
assertTrue(publicField == 304); | ||
} | ||
|
||
} |
Oops, something went wrong.