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.source.Result;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
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 boolean isValid(AnnotatedTypeMirror type, Tree tree) {
AnnotationMirror methodVal = type.getAnnotation(MethodVal.class);
if (methodVal != null) {
List<String> classNames =
AnnotationUtils.getElementValueArray(
methodVal, "className", String.class, true);
List<Integer> params =
AnnotationUtils.getElementValueArray(methodVal, "params", Integer.class, true);
List<String> methodNames =
AnnotationUtils.getElementValueArray(
methodVal, "methodName", String.class, true);
if (!(params.size() == methodNames.size() && params.size() == classNames.size())) {
checker.report(Result.failure("invalid.methodval", methodVal), tree);
}
for (String methodName : methodNames) {
if (!legalMethodName(methodName)) {
checker.report(Result.failure("illegal.methodname", methodName, type), tree);
}
}
}
return super.isValid(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;
}
}