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; } }