#1353 False positive "Only One Return" with lambda

This commit is contained in:
Andreas Dangel
2015-05-13 21:33:30 +02:00
parent b5e7cbbaf3
commit cae16d39d7
3 changed files with 47 additions and 1 deletions

View File

@ -9,6 +9,7 @@ import java.util.List;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
@ -31,9 +32,11 @@ public class OnlyOneReturnRule extends AbstractJavaRule {
List<ASTReturnStatement> returnNodes = new ArrayList<ASTReturnStatement>();
node.findDescendantsOfType(ASTReturnStatement.class, returnNodes, false);
returnNodes = filterLambdaExpressions(returnNodes);
if (returnNodes.size() > 1) {
for (Iterator<ASTReturnStatement> i = returnNodes.iterator(); i.hasNext();) {
Node problem = i.next();
Node problem = i.next();
// skip the last one, it's OK
if (!i.hasNext()) {
continue;
@ -44,4 +47,21 @@ public class OnlyOneReturnRule extends AbstractJavaRule {
return data;
}
/**
* Checks whether the return statement is inside a lambda expression, and if
* so, this return statement is removed.
*
* @param returnNodes
* all the return statements inside the method
* @return all return statements, that are NOT within a lambda expression.
*/
private List<ASTReturnStatement> filterLambdaExpressions(List<ASTReturnStatement> returnNodes) {
List<ASTReturnStatement> filtered = new ArrayList<ASTReturnStatement>();
for (ASTReturnStatement ret : returnNodes) {
if (ret.getFirstParentOfType(ASTLambdaExpression.class) == null) {
filtered.add(ret);
}
}
return filtered;
}
}

View File

@ -94,4 +94,29 @@ public class Foo {
}
]]></code>
</test-code>
<test-code>
<description>#1353 False positive "Only One Return" with lambda</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class OnlyOneReturn {
public Try<SearchHit[]> search(final String indexName, final SearchRequest searchRequest) {
final SearchHit[] empty = new SearchHit[0];
final Optional<SearchDefinition> searchDefinition = settingsService.getSearchDefinition(indexName);
return searchDefinition.<Try<SearchHit[]>>map(
i -> {
final List<Try<ProviderSearchHit[]>> res = i.getSearchMapping().stream()
.peek(m -> LOGGER.debug("Treating backend \"{}\"", m.getProviderRef()))
.map(m -> invokeAdapter(getProviderSearchService(m.getProviderRef()), m, searchRequest))
.collect(Collectors.toList());
return TryCollections.pull(res).map(l -> sortReturning(l.stream().collect(ArrayCollectors.arrayMerging(
SearchServiceImpl::toSearchHit,
SearchHit::getInternalId,
Function.identity(),
SearchServiceImpl::merge)).orElse(Collections.emptyList()), SearchServiceImpl.searchHitComparator()))
.map(list -> list.toArray(empty));
}).orElse(Try.success(empty));
}
}
]]></code>
</test-code>
</test-data>