use of org.checkerframework.checker.nullness.qual.Nullable in project checker-framework by typetools.
the class SourceChecker method unwrapIntelliJ.
/**
* Tries to unwrap ProcessingEnvironment from proxy in IntelliJ 2020.3 or later.
*
* @param env possibly a dynamic proxy wrapping processing environment
* @return unwrapped processing environment, null if not successful
*/
@Nullable
private static ProcessingEnvironment unwrapIntelliJ(ProcessingEnvironment env) {
if (!Proxy.isProxyClass(env.getClass())) {
return null;
}
InvocationHandler handler = Proxy.getInvocationHandler(env);
try {
Field field = handler.getClass().getDeclaredField("val$delegateTo");
field.setAccessible(true);
Object o = field.get(handler);
if (o instanceof ProcessingEnvironment) {
return (ProcessingEnvironment) o;
}
return null;
} catch (NoSuchFieldException | IllegalAccessException e) {
return null;
}
}
use of org.checkerframework.checker.nullness.qual.Nullable in project checker-framework by typetools.
the class SourceChecker method shouldSuppressWarnings.
/**
* Determines whether all the warnings pertaining to a given tree should be suppressed. Returns
* true if the tree is within the scope of a @SuppressWarnings annotation, one of whose values
* suppresses the checker's warnings. Also, returns true if the {@code errKey} matches a string in
* {@code -AsuppressWarnings}.
*
* @param tree the tree that might be a source of a warning
* @param errKey the error key the checker is emitting
* @return true if no warning should be emitted for the given tree because it is contained by a
* declaration with an appropriately-valued {@literal @}SuppressWarnings annotation; false
* otherwise
*/
public boolean shouldSuppressWarnings(Tree tree, String errKey) {
Collection<String> prefixes = getSuppressWarningsPrefixes();
if (prefixes.isEmpty() || (prefixes.contains(SUPPRESS_ALL_PREFIX) && prefixes.size() == 1)) {
throw new BugInCF("Checker must provide a SuppressWarnings prefix." + " SourceChecker#getSuppressWarningsPrefixes was not overridden correctly.");
}
if (shouldSuppress(getSuppressWarningsStringsFromOption(), errKey)) {
return true;
}
if (shouldSuppress(getSuppressWarningsStringsFromOption(), errKey)) {
// the warning.
return true;
}
// trees.getPath might be slow, but this is only used in error reporting
@Nullable TreePath path = trees.getPath(this.currentRoot, tree);
@Nullable VariableTree var = TreePathUtil.enclosingVariable(path);
if (var != null && shouldSuppressWarnings(TreeUtils.elementFromTree(var), errKey)) {
return true;
}
@Nullable MethodTree method = TreePathUtil.enclosingMethod(path);
if (method != null) {
@Nullable Element elt = TreeUtils.elementFromTree(method);
if (shouldSuppressWarnings(elt, errKey)) {
return true;
}
if (isAnnotatedForThisCheckerOrUpstreamChecker(elt)) {
// because they may not have an @AnnotatedFor.
return false;
}
}
@Nullable ClassTree cls = TreePathUtil.enclosingClass(path);
if (cls != null) {
@Nullable Element elt = TreeUtils.elementFromTree(cls);
if (shouldSuppressWarnings(elt, errKey)) {
return true;
}
if (isAnnotatedForThisCheckerOrUpstreamChecker(elt)) {
// because they may not have an @AnnotatedFor.
return false;
}
}
if (useConservativeDefault("source")) {
// false, we DO suppress the warning.
return true;
}
return false;
}
use of org.checkerframework.checker.nullness.qual.Nullable in project checker-framework by typetools.
the class SourceChecker method unwrapGradle.
/**
* Tries to unwrap processing environment in Gradle incremental processing. Inspired by project
* Lombok.
*
* @param delegateClass a class in which to find a {@code delegate} field
* @param env a processing environment wrapper
* @return unwrapped processing environment, null if not successful
*/
@Nullable
private static ProcessingEnvironment unwrapGradle(Class<?> delegateClass, ProcessingEnvironment env) {
try {
Field field = delegateClass.getDeclaredField("delegate");
field.setAccessible(true);
Object o = field.get(env);
if (o instanceof ProcessingEnvironment) {
return (ProcessingEnvironment) o;
}
return null;
} catch (NoSuchFieldException | IllegalAccessException e) {
return null;
}
}
use of org.checkerframework.checker.nullness.qual.Nullable in project checker-framework by typetools.
the class AnnotationFileParser method findElement.
/**
* Looks for the nested type element in the typeElt and returns it if the element has the same
* name as provided class or interface declaration. In case nested element is not found it returns
* null.
*
* @param typeElt an element where nested type element should be looked for
* @param ciDecl class or interface declaration which name should be found among nested elements
* of the typeElt
* @return nested in typeElt element with the name of the class or interface or null if nested
* element is not found
*/
@Nullable
private Element findElement(TypeElement typeElt, ClassOrInterfaceDeclaration ciDecl) {
final String wantedClassOrInterfaceName = ciDecl.getNameAsString();
for (TypeElement typeElement : ElementUtils.getAllTypeElementsIn(typeElt)) {
if (wantedClassOrInterfaceName.equals(typeElement.getSimpleName().toString())) {
return typeElement;
}
}
stubWarnNotFound(ciDecl, "Class/interface " + wantedClassOrInterfaceName + " not found in type " + typeElt);
if (debugAnnotationFileParser) {
stubDebug(String.format(" Here are the type declarations of %s:", typeElt));
for (TypeElement method : ElementFilter.typesIn(typeElt.getEnclosedElements())) {
stubDebug(String.format(" %s", method));
}
}
return null;
}
use of org.checkerframework.checker.nullness.qual.Nullable in project checker-framework by typetools.
the class AnnotationFileParser method findVariableElement.
/**
* Returns the VariableElement for the given field access.
*
* @param faexpr a field access expression
* @return the VariableElement for the given field access
*/
// string manipulation
@SuppressWarnings("signature:argument")
@Nullable
private VariableElement findVariableElement(FieldAccessExpr faexpr) {
if (findVariableElementFieldCache.containsKey(faexpr)) {
return findVariableElementFieldCache.get(faexpr);
}
TypeElement rcvElt = elements.getTypeElement(faexpr.getScope().toString());
if (rcvElt == null) {
// Search importedConstants for full annotation name.
for (String imp : importedConstants) {
// TODO: should this use AnnotationFileUtil.partitionQualifiedName?
String[] importDelimited = imp.split("\\.");
if (importDelimited[importDelimited.length - 1].equals(faexpr.getScope().toString())) {
StringBuilder fullAnnotation = new StringBuilder();
for (int i = 0; i < importDelimited.length - 1; i++) {
fullAnnotation.append(importDelimited[i]);
fullAnnotation.append('.');
}
fullAnnotation.append(faexpr.getScope().toString());
rcvElt = elements.getTypeElement(fullAnnotation);
break;
}
}
if (rcvElt == null) {
stubWarnNotFound(faexpr, "Type " + faexpr.getScope() + " not found");
return null;
}
}
VariableElement res = findFieldElement(rcvElt, faexpr.getNameAsString(), faexpr);
findVariableElementFieldCache.put(faexpr, res);
return res;
}
Aggregations