private static Optional<String> lookupMatchingStandardInterface(MethodSymbol functionalMethod) { MethodTree declaration = functionalMethod.declaration(); if (!functionalMethod.thrownTypes().isEmpty() || (declaration != null && !declaration.typeParameters().isEmpty())) { return Optional.empty(); } Type returnType = declaration != null ? declaration.returnType().symbolType() : functionalMethod.returnType().type(); return STD_INTERFACE_BY_PARAMETER_COUNT.getOrDefault(functionalMethod.parameterTypes().size(), Collections.emptyList()).stream() .map(standardInterface -> standardInterface.matchingSpecialization(functionalMethod, returnType)) .filter(Objects::nonNull) .findFirst(); }
private static Optional<String> isSetterLike(Symbol.MethodSymbol methodSymbol) { if (methodSymbol.parameterTypes().size() != 1 || isPrivateStaticOrAbstract(methodSymbol)) { return Optional.empty(); } String methodName = methodSymbol.name(); if (methodName.length() > 3 && methodName.startsWith("set") && methodSymbol.returnType().type().isVoid()) { return Optional.of(lowerCaseFirstLetter(methodName.substring(3))); } return Optional.empty(); }
private boolean isInherited(Symbol symbol) { Type methodOwnerType = symbol.owner().type().erasure(); Type innerType = classSymbol.type().erasure(); return !symbol.isStatic() && innerType.isSubtypeOf(methodOwnerType) && !classSymbol.owner().type().equals(methodOwnerType) && !innerType.equals(methodOwnerType); }
@CheckForNull private static Type getCallSiteType(MethodInvocationTree mit) { ExpressionTree methodSelect = mit.methodSelect(); // methodSelect can only be Tree.Kind.IDENTIFIER or Tree.Kind.MEMBER_SELECT if (methodSelect.is(Tree.Kind.IDENTIFIER)) { Symbol.TypeSymbol enclosingClassSymbol = ((IdentifierTree) methodSelect).symbol().enclosingClass(); return enclosingClassSymbol != null ? enclosingClassSymbol.type() : null; } else { return ((MemberSelectExpressionTree) methodSelect).expression().symbolType(); } }
@Override public void visitNode(Tree tree) { if (hasSemantic()) { Symbol.TypeSymbol classSymbol = ((ClassTree) tree).symbol(); Type superclass = classSymbol.superClass(); if (isSerializable(classSymbol.type()) && isNotSerializableMissingNoArgConstructor(superclass)) { reportIssue(tree, "Add a no-arg constructor to \"" + superclass + "\"."); } } }
private static boolean isExtended(ClassTree classTree) { IsExtendedVisitor isExtendedVisitor = new IsExtendedVisitor(classTree.symbol().type().erasure()); classTree.accept(isExtendedVisitor); return isExtendedVisitor.isExtended; }
private void checkReturnType(MethodTree methodTree, String requiredReturnType) { Symbol.MethodSymbol methodSymbol = methodTree.symbol(); if (!methodSymbol.returnType().type().is(requiredReturnType)) { reportIssue(methodTree.simpleName(), "\"" + methodSymbol.name() + "\" should return \"" + requiredReturnType + "\"."); } }
@Override public void visitClass(ClassTree tree) { if (tree.symbol().type().isSubtypeOf("org.eclipse.osgi.util.NLS")) { excludeLines(tree, FILTERED_RULES); } else { acceptLines(tree, FILTERED_RULES); } super.visitClass(tree); } }
private static boolean isNotSerializable(Symbol.TypeSymbol symbol) { for (Type superType : ((TypeJavaSymbol) symbol).superTypes()) { if (superType.isUnknown()) { return false; } } return !symbol.type().isSubtypeOf("java.io.Serializable"); }
private static boolean isUnitTest(MethodTree methodTree) { Symbol.MethodSymbol symbol = methodTree.symbol(); while (symbol != null) { if (symbol.metadata().isAnnotatedWith("org.junit.Test")) { return true; } symbol = symbol.overriddenSymbol(); } Symbol.TypeSymbol enclosingClass = methodTree.symbol().enclosingClass(); return enclosingClass != null && enclosingClass.type().isSubtypeOf("junit.framework.TestCase") && methodTree.simpleName().name().startsWith("test"); }
private static boolean isJavaSecurityMessageDigestSubClass(ClassTree tree) { Symbol.TypeSymbol classSymbol = tree.symbol(); // Corner case: A type is a subtype of itself return classSymbol != null && !classSymbol.type().is(MESSAGE_DIGEST_QUALIFIED_NAME) && classSymbol.type().isSubtypeOf(MESSAGE_DIGEST_QUALIFIED_NAME); } }
@Override public void visitClass(ClassTree tree) { for (Tree member : tree.members()) { if (!tree.symbol().type().isSubtypeOf(JAVA_UTIL_COLLECTION) || !member.is(Tree.Kind.METHOD)) { scan(member); } } }
@Override public void visitNode(Tree tree) { if (hasSemantic()) { ClassTree classTree = (ClassTree) tree; Symbol.TypeSymbol symbol = classTree.symbol(); Type type = symbol.type(); IdentifierTree simpleName = classTree.simpleName(); if (simpleName != null && type.isSubtypeOf("java.util.Comparator") && !type.isSubtypeOf("java.io.Serializable") && !symbol.isAbstract()) { reportIssue(simpleName, "Make this class \"Serializable\"."); } } }
private void checkExtensions(ClassTree tree) { if (tree.symbol().type().isSubtypeOf(JAVAX_NET_SOCKET_FACTORY) || (tree.symbol().type().isSubtypeOf("io.netty.channel.ChannelInitializer"))) { TypeTree superClass = tree.superClass(); if (superClass != null) { // Anonymous class creation will raise issue in `onConstructorFound` method reportIssue(superClass, MESSAGE); } } }
private static boolean isIntermediateOperation(MethodInvocationTree mit) { if (BASE_STREAM_INTERMEDIATE_OPERATIONS.anyMatch(mit)) { return true; } Symbol method = mit.symbol(); return method.isMethodSymbol() && !method.isStatic() && STREAM_TYPES.contains(method.owner().type().fullyQualifiedName()) && STREAM_TYPES.contains(((Symbol.MethodSymbol) method).returnType().type().fullyQualifiedName()); }
public boolean matches(MethodTree methodTree) { MethodSymbol symbol = methodTree.symbol(); Symbol.TypeSymbol enclosingClass = symbol.enclosingClass(); return enclosingClass != null && matches(symbol, enclosingClass.type()); }
private static boolean isSerializable(Tree tree) { if (tree.is(Tree.Kind.ENUM, Tree.Kind.PRIMITIVE_TYPE)) { return true; } else if (tree.is(Tree.Kind.CLASS)) { Symbol.TypeSymbol symbol = ((ClassTree) tree).symbol(); return implementsSerializable(symbol.type()); } else if (tree.is(Tree.Kind.EXTENDS_WILDCARD, Tree.Kind.SUPER_WILDCARD, Tree.Kind.UNBOUNDED_WILDCARD)) { TypeTree bound = ((WildcardTree) tree).bound(); return bound != null && implementsSerializable(bound.symbolType()); } return implementsSerializable(((TypeTree) tree).symbolType()); }
private void checkIdentifier(IdentifierTree identifier) { Symbol.TypeSymbol enclosingClass = identifier.symbol().enclosingClass(); if (enclosingClass != null && enclosingClass.type().is("java.lang.System") && identifier.symbolType().is("java.io.InputStream") && identifier.name().equals("in") && !isClosingStream(identifier.parent())) { reportIssue(identifier); } }
private static boolean isExclusion(Symbol.TypeSymbol symbol) { return symbol.isAbstract() || symbol.type().isSubtypeOf("java.lang.Throwable") || isGuiClass((TypeJavaSymbol) symbol) || hasSuppressWarningAnnotation((TypeJavaSymbol) symbol); }
private static boolean useThisInstance(ClassTree body) { UsesThisInstanceVisitor visitor = new UsesThisInstanceVisitor(body.symbol().type()); body.accept(visitor); return visitor.usesThisInstance; }