private static boolean hasSingleAbstractMethodInHierarchy(Set<ClassJavaType> superTypes) { return superTypes.stream() .filter(type -> !type.is(JAVA_LANG_OBJECT)) .map(ClassJavaType::getSymbol) // collect all the methods declared in hierarchy .flatMap(superType -> superType.memberSymbols().stream().filter(Symbol::isMethodSymbol).filter(Symbol::isAbstract)) .map(JavaSymbol.MethodJavaSymbol.class::cast) // remove objects methods redefined in interfaces .filter(symbol -> !isObjectMethod(symbol)) // always take same symbol if method is redeclared over and over in hierarchy .map(symbol -> symbol.overriddenSymbol() != null ? symbol.overriddenSymbol() : symbol) .collect(Collectors.toSet()) .size() == 1; }
private static boolean hasSingleAbstractMethodInHierarchy(Set<ClassJavaType> superTypes) { return superTypes.stream() .filter(type -> !type.is(JAVA_LANG_OBJECT)) .map(ClassJavaType::getSymbol) // collect all the methods declared in hierarchy .flatMap(superType -> superType.memberSymbols().stream().filter(Symbol::isMethodSymbol).filter(Symbol::isAbstract)) .map(JavaSymbol.MethodJavaSymbol.class::cast) // remove objects methods redefined in interfaces .filter(symbol -> !isObjectMethod(symbol)) // always take same symbol if method is redeclared over and over in hierarchy .map(symbol -> symbol.overriddenSymbol() != null ? symbol.overriddenSymbol() : symbol) .collect(Collectors.toSet()) .size() == 1; }
public Optional<JavaSymbol.MethodJavaSymbol> getSamMethod(JavaType lambdaType) { List<JavaSymbol.MethodJavaSymbol> methodSymbols = abstractMethodsOfType(lambdaType); if (methodSymbols.size() > 1) { return Optional.empty(); } if (methodSymbols.size() == 1) { JavaSymbol.MethodJavaSymbol override = methodSymbols.get(0).overriddenSymbol(); Optional<JavaSymbol.MethodJavaSymbol> otherAbstractMethod = lambdaType.symbol.superTypes() .stream() .filter(t -> t.symbol().isInterface()) .flatMap(t -> abstractMethodsOfType(t).stream()) .filter(m -> override == null || !override.equals(m)) .findFirst(); if (otherAbstractMethod.isPresent()) { return Optional.empty(); } else { return Optional.of(methodSymbols.get(0)); } } else { // FIXME if list of supertypes define multiple abstract methods we might end up with a wrong samMethod from a non-functional interface return lambdaType.symbol.superTypes() .stream() .flatMap(t -> abstractMethodsOfType(t).stream()) .findFirst(); } }
public Optional<JavaSymbol.MethodJavaSymbol> getSamMethod(JavaType lambdaType) { List<JavaSymbol.MethodJavaSymbol> methodSymbols = abstractMethodsOfType(lambdaType); if (methodSymbols.size() > 1) { return Optional.empty(); } if (methodSymbols.size() == 1) { JavaSymbol.MethodJavaSymbol override = methodSymbols.get(0).overriddenSymbol(); Optional<JavaSymbol.MethodJavaSymbol> otherAbstractMethod = lambdaType.symbol.superTypes() .stream() .filter(t -> t.symbol().isInterface()) .flatMap(t -> abstractMethodsOfType(t).stream()) .filter(m -> override == null || !override.equals(m)) .findFirst(); if (otherAbstractMethod.isPresent()) { return Optional.empty(); } else { return Optional.of(methodSymbols.get(0)); } } else { // FIXME if list of supertypes define multiple abstract methods we might end up with a wrong samMethod from a non-functional interface return lambdaType.symbol.superTypes() .stream() .flatMap(t -> abstractMethodsOfType(t).stream()) .findFirst(); } }
/** * Check if a methodTree is overriden. * * @return true if overriden, null if it cannot be decided (method symbol not resolved or lack of bytecode for super types). */ @CheckForNull public Boolean isOverriding() { if (isStatic() || isPrivate()) { return false; } if (isAnnotatedOverride()) { return true; } if (symbol == null) { return null; } JavaSymbol.MethodJavaSymbol methodJavaSymbol = symbol.overriddenSymbol(); if (methodJavaSymbol != null) { return methodJavaSymbol.isUnknown() ? null : true; } return false; }
@Override @Nullable public Boolean isOverriding() { if (isStatic() || isPrivate()) { return false; } if (isAnnotatedOverride()) { return true; } if (symbol == null) { return null; } Symbol.MethodSymbol methodSymbol = symbol.overriddenSymbol(); if (methodSymbol != null) { return methodSymbol.isUnknown() ? null : true; } return false; }
@Override @Nullable public Boolean isOverriding() { if (isStatic() || isPrivate()) { return false; } if (isAnnotatedOverride()) { return true; } if (symbol == null) { return null; } Symbol.MethodSymbol methodSymbol = symbol.overriddenSymbol(); if (methodSymbol != null) { return methodSymbol.isUnknown() ? null : true; } return false; }
private static boolean isObjectMethod(JavaSymbol.MethodJavaSymbol methodSymbol) { Symbol overridenSymbol = methodSymbol.overriddenSymbol(); return overridenSymbol != null && overridenSymbol.owner().type().is(JAVA_LANG_OBJECT); }
private static boolean isSingleAbstractMethodOverride(MethodJavaSymbol childMethod, Type parentType) { MethodJavaSymbol overriddenSymbol = childMethod.overriddenSymbol(); return !childMethod.isDefault() && overriddenSymbol != null && getMethodSymbolsOf(parentType).filter(NON_DEFAULT_METHOD_PREDICATE).anyMatch(overriddenSymbol::equals); }
private void checkMethod(JavaSymbol.MethodJavaSymbol method) { JavaSymbol.MethodJavaSymbol overridee = method.overriddenSymbol(); if (overridee != null && overridee.owner().isInterface() && !differentContract(method, overridee)) { reportIssue(method.declaration(), "\"" + method.name() + "\" is defined in the \"" + overridee.owner().name() + "\" interface and can be removed from this class."); } }
private void checkMethod(JavaSymbol.MethodJavaSymbol method) { JavaSymbol.MethodJavaSymbol overridee = method.overriddenSymbol(); if (overridee != null && overridee.owner().isInterface() && !differentContract(method, overridee)) { reportIssue(method.declaration(), "\"" + method.name() + "\" is defined in the \"" + overridee.owner().name() + "\" interface and can be removed from this class."); } }
private static boolean isObjectMethod(JavaSymbol.MethodJavaSymbol methodSymbol) { Symbol overridenSymbol = methodSymbol.overriddenSymbol(); return overridenSymbol != null && overridenSymbol.owner().type().is(JAVA_LANG_OBJECT); }
private boolean isObjectMethod(JavaSymbol.MethodJavaSymbol methodJavaSymbol) { JavaSymbol.MethodJavaSymbol overriddenSymbol = methodJavaSymbol.overriddenSymbol(); boolean isObjectMethod = false; while (overriddenSymbol != null && !isObjectMethod) { isObjectMethod = overriddenSymbol.owner.type == symbols.objectType; overriddenSymbol = overriddenSymbol.overriddenSymbol(); } return isObjectMethod; }
private static boolean isSingleAbstractMethodOverride(MethodJavaSymbol childMethod, Type parentType) { MethodJavaSymbol overriddenSymbol = childMethod.overriddenSymbol(); return !childMethod.isDefault() && overriddenSymbol != null && getMethodSymbolsOf(parentType).filter(NON_DEFAULT_METHOD_PREDICATE).anyMatch(overriddenSymbol::equals); }
private boolean isObjectMethod(JavaSymbol.MethodJavaSymbol methodJavaSymbol) { JavaSymbol.MethodJavaSymbol overriddenSymbol = methodJavaSymbol.overriddenSymbol(); boolean isObjectMethod = false; while (overriddenSymbol != null && !isObjectMethod) { isObjectMethod = overriddenSymbol.owner.type == symbols.objectType; overriddenSymbol = overriddenSymbol.overriddenSymbol(); } return isObjectMethod; }