CallMatcher: exact instance call

This commit is contained in:
Tagir Valeev
2018-05-28 11:34:24 +07:00
parent 9ebf6e1766
commit d93171cada
@@ -122,7 +122,18 @@ public interface CallMatcher extends Predicate<PsiMethodCallExpression> {
* @return a new matcher
*/
static Simple instanceCall(@NotNull String className, String... methodNames) {
return new Simple(className, ContainerUtil.newTroveSet(methodNames), null, false);
return new Simple(className, ContainerUtil.newTroveSet(methodNames), null, CallType.INSTANCE);
}
/**
* Creates a matcher which matches an instance method having one of supplied names which class is exactly a className
*
* @param className fully-qualified class name
* @param methodNames names of the methods
* @return a new matcher
*/
static Simple exactInstanceCall(@NotNull String className, String... methodNames) {
return new Simple(className, ContainerUtil.newTroveSet(methodNames), null, CallType.EXACT_INSTANCE);
}
/**
@@ -133,20 +144,20 @@ public interface CallMatcher extends Predicate<PsiMethodCallExpression> {
* @return a new matcher
*/
static Simple staticCall(@NotNull String className, String... methodNames) {
return new Simple(className, ContainerUtil.newTroveSet(methodNames), null, true);
return new Simple(className, ContainerUtil.newTroveSet(methodNames), null, CallType.STATIC);
}
class Simple implements CallMatcher {
private final @NotNull String myClassName;
private final @NotNull Set<String> myNames;
private final @Nullable String[] myParameters;
private final boolean myStatic;
private final CallType myCallType;
private Simple(@NotNull String className, @NotNull Set<String> names, @Nullable String[] parameters, boolean aStatic) {
private Simple(@NotNull String className, @NotNull Set<String> names, @Nullable String[] parameters, CallType callType) {
myClassName = className;
myNames = names;
myParameters = parameters;
myStatic = aStatic;
myCallType = callType;
}
@Override
@@ -165,7 +176,7 @@ public interface CallMatcher extends Predicate<PsiMethodCallExpression> {
if (myParameters != null) {
throw new IllegalStateException("Parameter count is already set to " + count);
}
return new Simple(myClassName, myNames, count == 0 ? ArrayUtil.EMPTY_STRING_ARRAY : new String[count], myStatic);
return new Simple(myClassName, myNames, count == 0 ? ArrayUtil.EMPTY_STRING_ARRAY : new String[count], myCallType);
}
/**
@@ -180,7 +191,7 @@ public interface CallMatcher extends Predicate<PsiMethodCallExpression> {
if (myParameters != null) {
throw new IllegalStateException("Parameters are already registered");
}
return new Simple(myClassName, myNames, types.length == 0 ? ArrayUtil.EMPTY_STRING_ARRAY : types.clone(), myStatic);
return new Simple(myClassName, myNames, types.length == 0 ? ArrayUtil.EMPTY_STRING_ARRAY : types.clone(), myCallType);
}
private static boolean parameterTypeMatches(String type, PsiParameter parameter) {
@@ -232,12 +243,8 @@ public interface CallMatcher extends Predicate<PsiMethodCallExpression> {
if (method == null) return false;
PsiClass aClass = method.getContainingClass();
if (aClass == null) return false;
if (myStatic != method.getModifierList().hasExplicitModifier(PsiModifier.STATIC) ||
(myStatic && !myClassName.equals(aClass.getQualifiedName())) ||
(!myStatic && !InheritanceUtil.isInheritor(aClass, myClassName))) {
return false;
}
return parametersMatch(method.getParameterList());
return myCallType.matches(aClass, myClassName, method.hasModifierProperty(PsiModifier.STATIC)) &&
parametersMatch(method.getParameterList());
}
@Override
@@ -245,4 +252,27 @@ public interface CallMatcher extends Predicate<PsiMethodCallExpression> {
return myClassName + "." + String.join("|", myNames);
}
}
enum CallType {
STATIC {
@Override
boolean matches(PsiClass aClass, String className, boolean isStatic) {
return isStatic && className.equals(aClass.getQualifiedName());
}
},
INSTANCE {
@Override
boolean matches(PsiClass aClass, String className, boolean isStatic) {
return !isStatic && InheritanceUtil.isInheritor(aClass, className);
}
},
EXACT_INSTANCE {
@Override
boolean matches(PsiClass aClass, String className, boolean isStatic) {
return !isStatic && className.equals(aClass.getQualifiedName());
}
};
abstract boolean matches(PsiClass aClass, String className, boolean isStatic);
}
}