report 'Missing return' for closure if there is explicit generic in expected type

This commit is contained in:
Maxim.Medvedev
2012-03-28 16:14:41 +04:00
parent c5f76ad3c4
commit 1695bb3fec
3 changed files with 25 additions and 3 deletions
@@ -18,9 +18,7 @@ package org.jetbrains.plugins.groovy.codeInspection.noReturnMethod;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiType;
import com.intellij.psi.*;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -71,6 +69,10 @@ public class MissingReturnInspection extends GroovySuppressableInspectionTool {
public static ReturnStatus getReturnStatus(PsiElement subject) {
if (subject instanceof GrClosableBlock) {
final PsiType inferredReturnType = GroovyExpectedTypesProvider.getExpectedClosureReturnType((GrClosableBlock)subject);
if (inferredReturnType instanceof PsiClassType) {
PsiClass resolved = ((PsiClassType)inferredReturnType).resolve();
if (resolved != null && !(resolved instanceof PsiTypeParameter)) return mustReturnValue;
}
return inferredReturnType != null && inferredReturnType != PsiType.VOID ? shouldReturnValue : shouldNotReturnValue;
}
else if (subject instanceof GrMethod) {
@@ -41,6 +41,7 @@ public class MissingReturnTest extends LightCodeInsightFixtureTestCase {
public void testImplicitReturnNull() throws Throwable {doTest();}
public void testMissingReturnInClosure() {doTest();}
public void testFinally() {doTest();}
public void testClosureWithExplicitExpectedType() {doTest()}
private void doTest() {
myFixture.enableInspections(new MissingReturnInspection());
@@ -0,0 +1,19 @@
def foo(Closure<String> c) {
return c().substring(1)
}
foo {
print 2
<warning descr="Not all execution paths return a value">}</warning>
foo {
's'
}
foo {
if (a) 's'
<warning descr="Not all execution paths return a value">}</warning>
foo {
if (a) 'a' else 'b'
}