blob: 971a7285d2153e9162c1ac6a0ed66874a3983009 [file] [log] [blame]
package org.checkerframework.common.reflection;
import com.sun.source.tree.Tree;
import java.util.List;
import javax.lang.model.element.AnnotationMirror;
import org.checkerframework.common.basetype.BaseTypeChecker;
import org.checkerframework.common.basetype.BaseTypeValidator;
import org.checkerframework.common.basetype.BaseTypeVisitor;
import org.checkerframework.common.reflection.qual.MethodVal;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType;
import org.checkerframework.javacutil.AnnotationUtils;
public class MethodValVisitor extends BaseTypeVisitor<MethodValAnnotatedTypeFactory> {
public MethodValVisitor(BaseTypeChecker checker) {
super(checker);
}
@Override
protected MethodValAnnotatedTypeFactory createTypeFactory() {
return new MethodValAnnotatedTypeFactory(checker);
}
@Override
protected BaseTypeValidator createTypeValidator() {
return new MethodNameValidator(checker, this, atypeFactory);
}
}
class MethodNameValidator extends BaseTypeValidator {
public MethodNameValidator(
BaseTypeChecker checker, BaseTypeVisitor<?> visitor, AnnotatedTypeFactory atypeFactory) {
super(checker, visitor, atypeFactory);
}
@Override
public Void visitDeclared(AnnotatedDeclaredType type, Tree tree) {
AnnotationMirror methodVal = type.getAnnotation(MethodVal.class);
if (methodVal != null) {
AnnotatedTypeFactory atypeFactory = checker.getTypeFactory();
List<String> classNames =
AnnotationUtils.getElementValueArray(
methodVal, atypeFactory.methodValClassNameElement, String.class);
List<String> methodNames =
AnnotationUtils.getElementValueArray(
methodVal, atypeFactory.methodValMethodNameElement, String.class);
List<Integer> params =
AnnotationUtils.getElementValueArray(
methodVal, atypeFactory.methodValParamsElement, Integer.class);
if (!(classNames.size() == methodNames.size() && classNames.size() == params.size())) {
checker.reportError(tree, "invalid.methodval", methodVal);
}
for (String methodName : methodNames) {
if (!legalMethodName(methodName)) {
checker.reportError(tree, "illegal.methodname", methodName, type);
}
}
}
return super.visitDeclared(type, tree);
}
private boolean legalMethodName(String methodName) {
if (methodName.equals(ReflectionResolver.INIT)) {
return true;
}
if (methodName.length() < 1) {
return false;
}
char[] methodNameChars = methodName.toCharArray();
if (!Character.isJavaIdentifierStart(methodNameChars[0])) {
return false;
}
for (int i = 1; i < methodNameChars.length; i++) {
if (!Character.isJavaIdentifierPart(methodNameChars[i])) {
return false;
}
}
return true;
}
}