| package org.checkerframework.common.value; |
| |
| import com.sun.source.tree.Tree; |
| import java.util.List; |
| import javax.annotation.processing.ProcessingEnvironment; |
| import javax.lang.model.element.ExecutableElement; |
| import org.checkerframework.javacutil.TreeUtils; |
| |
| /** Stores methods that have special handling in the value checker. */ |
| class ValueMethodIdentifier { |
| |
| /** String.length() method. */ |
| private final ExecutableElement lengthMethod; |
| /** Array.getLength() method. */ |
| private final ExecutableElement getLengthMethod; |
| /** String.startsWith(String) method. */ |
| private final ExecutableElement startsWithMethod; |
| /** String.endsWith(String) method. */ |
| private final ExecutableElement endsWithMethod; |
| /** The {@code java.lang.Math#min()} methods. */ |
| private final List<ExecutableElement> mathMinMethods; |
| /** The {@code java.lang.Math#max()} methods. */ |
| private final List<ExecutableElement> mathMaxMethods; |
| /** Arrays.copyOf() methods. */ |
| private final List<ExecutableElement> copyOfMethods; |
| |
| /** |
| * Initialize elements with methods that have special handling in the value checker. |
| * |
| * @param processingEnv the processing environment |
| */ |
| public ValueMethodIdentifier(ProcessingEnvironment processingEnv) { |
| lengthMethod = TreeUtils.getMethod("java.lang.String", "length", 0, processingEnv); |
| getLengthMethod = TreeUtils.getMethod("java.lang.reflect.Array", "getLength", 1, processingEnv); |
| startsWithMethod = TreeUtils.getMethod("java.lang.String", "startsWith", 1, processingEnv); |
| endsWithMethod = TreeUtils.getMethod("java.lang.String", "endsWith", 1, processingEnv); |
| mathMinMethods = TreeUtils.getMethods("java.lang.Math", "min", 2, processingEnv); |
| mathMaxMethods = TreeUtils.getMethods("java.lang.Math", "max", 2, processingEnv); |
| copyOfMethods = TreeUtils.getMethods("java.util.Arrays", "copyOf", 2, processingEnv); |
| copyOfMethods.add(TreeUtils.getMethod("java.util.Arrays", "copyOf", 3, processingEnv)); |
| } |
| |
| /** |
| * Returns true iff the argument is an invocation of Math.min. |
| * |
| * @param methodTree a tree |
| * @param processingEnv the processing environment |
| * @return true iff the argument is an invocation of Math.min |
| */ |
| public boolean isMathMin(Tree methodTree, ProcessingEnvironment processingEnv) { |
| return TreeUtils.isMethodInvocation(methodTree, mathMinMethods, processingEnv); |
| } |
| |
| /** |
| * Returns true iff the argument is an invocation of Math.max. |
| * |
| * @param methodTree a tree |
| * @param processingEnv the processing environment |
| * @return true iff the argument is an invocation of Math.max |
| */ |
| public boolean isMathMax(Tree methodTree, ProcessingEnvironment processingEnv) { |
| return TreeUtils.isMethodInvocation(methodTree, mathMaxMethods, processingEnv); |
| } |
| |
| /** Determines whether a tree is an invocation of the {@code String.length()} method. */ |
| public boolean isStringLengthInvocation(Tree tree, ProcessingEnvironment processingEnv) { |
| return TreeUtils.isMethodInvocation(tree, lengthMethod, processingEnv); |
| } |
| |
| /** |
| * Determines whether a tree is an invocation of the {@code Array.getLength()} method. |
| * |
| * @param tree tree to check |
| * @param processingEnv the processing environment |
| * @return true iff the argument is an invocation of {@code Array.getLength()} method |
| */ |
| public boolean isArrayGetLengthInvocation(Tree tree, ProcessingEnvironment processingEnv) { |
| return TreeUtils.isMethodInvocation(tree, getLengthMethod, processingEnv); |
| } |
| |
| /** |
| * Determines whether a method is the {@code String.length()} method. |
| * |
| * @param method the element to check |
| * @return true iff the argument methid is {@code String.length()} method |
| */ |
| public boolean isStringLengthMethod(ExecutableElement method) { |
| // equals (rather than ElementUtils.ismethod) because String.length cannot be overridden |
| return method.equals(lengthMethod); |
| } |
| |
| /** |
| * Determines whether a method is the {@code Array.getLength()} method. |
| * |
| * @param method the element to check |
| * @return true iff the argument method is {@code Array.getLength()} method |
| */ |
| public boolean isArrayGetLengthMethod(ExecutableElement method) { |
| // equals (rather than ElementUtils.ismethod) because String.length cannot be overridden |
| return method.equals(getLengthMethod); |
| } |
| |
| /** |
| * Determines whether a method is the {@code String.startsWith(String)} method. |
| * |
| * @param method the element to check |
| * @return true iff the argument method is {@code String.startsWith(String)} method |
| */ |
| public boolean isStartsWithMethod(ExecutableElement method) { |
| // equals (rather than ElementUtils.ismethod) because String.length cannot be overridden |
| return method.equals(startsWithMethod); |
| } |
| /** Determines whether a method is the {@code String.endsWith(String)} method. */ |
| public boolean isEndsWithMethod(ExecutableElement method) { |
| // equals (rather than ElementUtils.ismethod) because String.length cannot be overridden |
| return method.equals(endsWithMethod); |
| } |
| |
| /** |
| * Determines whether a tree is an invocation of the {@code Arrays.copyOf()} method. |
| * |
| * @param tree tree to check |
| * @param processingEnv the processing environment |
| * @return true iff the argument is an invocation of {@code Arrays.copyOf()} method |
| */ |
| public boolean isArraysCopyOfInvocation(Tree tree, ProcessingEnvironment processingEnv) { |
| return TreeUtils.isMethodInvocation(tree, copyOfMethods, processingEnv); |
| } |
| } |