Source:
protected MethodUsage toMethodUsage(MethodReferenceExpr methodReferenceExpr, List<ResolvedType> paramTypes) { Expression scope = methodReferenceExpr.getScope(); ResolvedType typeOfScope = getType(methodReferenceExpr.getScope()); if (!typeOfScope.isReferenceType()) { throw new UnsupportedOperationException(typeOfScope.getClass().getCanonicalName()); } Optional<MethodUsage> result; Set<MethodUsage> allMethods = typeOfScope.asReferenceType().getTypeDeclaration().getAllMethods(); if (scope instanceof TypeExpr) { List<MethodUsage> staticMethodUsages = allMethods.stream() .filter(it -> it.getDeclaration().isStatic()) .collect(Collectors.toList()); result = MethodResolutionLogic.findMostApplicableUsage(staticMethodUsages, methodReferenceExpr.getIdentifier(), paramTypes, typeSolver); if (!paramTypes.isEmpty()) { List<MethodUsage> instanceMethodUsages = allMethods.stream() .filter(it -> !it.getDeclaration().isStatic()) .collect(Collectors.toList()); List<ResolvedType> instanceMethodParamTypes = new ArrayList<>(paramTypes); instanceMethodParamTypes.remove(0); Optional<MethodUsage> instanceResult = MethodResolutionLogic.findMostApplicableUsage( instanceMethodUsages, methodReferenceExpr.getIdentifier(), instanceMethodParamTypes, typeSolver); if (result.isPresent() && instanceResult.isPresent()) { throw new MethodAmbiguityException("Ambiguous method call: cannot find a most applicable method for " + methodReferenceExpr.getIdentifier()); } if (instanceResult.isPresent()) { result = instanceResult; } } } else { result = MethodResolutionLogic.findMostApplicableUsage(new ArrayList<>(allMethods), methodReferenceExpr.getIdentifier(), paramTypes, typeSolver); if (result.isPresent() && result.get().getDeclaration().isStatic()) { throw new RuntimeException("Invalid static method reference " + methodReferenceExpr.getIdentifier()); } } if (!result.isPresent()) { throw new UnsupportedOperationException(); } return result.get(); }

Target:
protected MethodUsage toMethodUsage(MethodReferenceExpr methodReferenceExpr, List<ResolvedType> paramTypes) { Expression scope = methodReferenceExpr.getScope(); ResolvedType typeOfScope = getType(methodReferenceExpr.getScope()); if (!typeOfScope.isReferenceType()) { throw new UnsupportedOperationException(typeOfScope.getClass().getCanonicalName()); } Optional<MethodUsage> result; Set<MethodUsage> allMethods = typeOfScope.asReferenceType().getTypeDeclaration() .orElseThrow(() -> new RuntimeException("TypeDeclaration unexpectedly empty.")) .getAllMethods(); if (scope instanceof TypeExpr) { List<MethodUsage> staticMethodUsages = allMethods.stream() .filter(it -> it.getDeclaration().isStatic()) .collect(Collectors.toList()); result = MethodResolutionLogic.findMostApplicableUsage(staticMethodUsages, methodReferenceExpr.getIdentifier(), paramTypes, typeSolver); if (!paramTypes.isEmpty()) { List<MethodUsage> instanceMethodUsages = allMethods.stream() .filter(it -> !it.getDeclaration().isStatic()) .collect(Collectors.toList()); List<ResolvedType> instanceMethodParamTypes = new ArrayList<>(paramTypes); instanceMethodParamTypes.remove(0); Optional<MethodUsage> instanceResult = MethodResolutionLogic.findMostApplicableUsage( instanceMethodUsages, methodReferenceExpr.getIdentifier(), instanceMethodParamTypes, typeSolver); if (result.isPresent() && instanceResult.isPresent()) { throw new MethodAmbiguityException("Ambiguous method call: cannot find a most applicable method for " + methodReferenceExpr.getIdentifier()); } if (instanceResult.isPresent()) { result = instanceResult; } } } else { result = MethodResolutionLogic.findMostApplicableUsage(new ArrayList<>(allMethods), methodReferenceExpr.getIdentifier(), paramTypes, typeSolver); if (result.isPresent() && result.get().getDeclaration().isStatic()) { throw new RuntimeException("Invalid static method reference " + methodReferenceExpr.getIdentifier()); } } if (!result.isPresent()) { throw new UnsupportedOperationException(); } return result.get(); }