mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
missing return expression for 'x in Y'
This commit is contained in:
+25
-2
@@ -164,7 +164,10 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
|
||||
return st == ArrayUtil.getLastElement(((GroovyFileBase)parent).getStatements());
|
||||
}
|
||||
|
||||
else if (parent instanceof GrControlStatement ||
|
||||
else if (parent instanceof GrForStatement ||
|
||||
parent instanceof GrIfStatement && st != ((GrIfStatement)parent).getCondition() ||
|
||||
parent instanceof GrSynchronizedStatement && st != ((GrSynchronizedStatement)parent).getMonitor() ||
|
||||
parent instanceof GrWhileStatement && st != ((GrWhileStatement)parent).getCondition() ||
|
||||
parent instanceof GrConditionalExpression && st != ((GrConditionalExpression)parent).getCondition() ||
|
||||
parent instanceof GrElvisExpression) {
|
||||
return isCertainlyReturnStatement((GrStatement)parent);
|
||||
@@ -208,6 +211,23 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
|
||||
private void handlePossibleReturn(@NotNull GrStatement possibleReturn) {
|
||||
if (possibleReturn instanceof GrExpression && isCertainlyReturnStatement(possibleReturn)) {
|
||||
addNodeAndCheckPending(new MaybeReturnInstruction((GrExpression)possibleReturn));
|
||||
/*
|
||||
|
||||
//all pending edges from the same psi element may be return too
|
||||
InstructionImpl head = myHead;
|
||||
for (ListIterator<Pair<InstructionImpl, GroovyPsiElement>> iterator = myPending.listIterator(); iterator.hasNext(); ) {
|
||||
Pair<InstructionImpl, GroovyPsiElement> pair = iterator.next();
|
||||
final InstructionImpl instruction = pair.getFirst();
|
||||
if (instruction.getElement() == possibleReturn) {
|
||||
myHead = instruction;
|
||||
MaybeReturnInstruction newPending = addNode(new MaybeReturnInstruction((GrExpression)possibleReturn));
|
||||
iterator.set(new Pair<InstructionImpl, GroovyPsiElement>(newPending, pair.getSecond()));
|
||||
}
|
||||
}
|
||||
|
||||
myHead = head;
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,6 +417,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiType getNominalTypeNoRecursion(final GrExpression exception) {
|
||||
return RecursionManager.doPreventingRecursion(exception, true, new NullableComputable<PsiType>() {
|
||||
@Override
|
||||
@@ -640,10 +661,12 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
|
||||
addNode(new InstanceOfInstruction(expression, cond));
|
||||
NegatingGotoInstruction negation = new NegatingGotoInstruction(expression, cond);
|
||||
addNode(negation);
|
||||
handlePossibleReturn(expression);
|
||||
addPendingEdge(expression, negation);
|
||||
|
||||
myHead = cond;
|
||||
addNode(new InstanceOfInstruction(expression, cond));
|
||||
handlePossibleReturn(expression);
|
||||
myConditions.removeFirstOccurrence(cond);
|
||||
}
|
||||
|
||||
@@ -1093,7 +1116,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
|
||||
return startNode(element, true);
|
||||
}
|
||||
|
||||
private InstructionImpl startNode(GroovyPsiElement element, boolean checkPending) {
|
||||
private InstructionImpl startNode(@Nullable GroovyPsiElement element, boolean checkPending) {
|
||||
final InstructionImpl instruction = new InstructionImpl(element);
|
||||
addNode(instruction);
|
||||
if (checkPending) checkPending(instruction);
|
||||
|
||||
+21
-26
@@ -1,27 +1,21 @@
|
||||
package org.jetbrains.plugins.groovy.lang.controlFlow;
|
||||
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ControlFlowBuilder;
|
||||
import org.jetbrains.plugins.groovy.util.TestUtils;
|
||||
|
||||
import java.util.List;
|
||||
package org.jetbrains.plugins.groovy.lang.controlFlow
|
||||
|
||||
import com.intellij.openapi.editor.SelectionModel
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType
|
||||
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ControlFlowBuilder
|
||||
import org.jetbrains.plugins.groovy.util.TestUtils
|
||||
/**
|
||||
* @author ven
|
||||
*/
|
||||
public class ControlFlowTest extends LightCodeInsightFixtureTestCase {
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return TestUtils.getTestDataPath() + "groovy/controlFlow/";
|
||||
}
|
||||
final String basePath = TestUtils.testDataPath + "groovy/controlFlow/"
|
||||
|
||||
public void testAssignment() throws Throwable { doTest(); }
|
||||
public void testClosure1() throws Throwable { doTest(); }
|
||||
@@ -61,18 +55,19 @@ public class ControlFlowTest extends LightCodeInsightFixtureTestCase {
|
||||
public void testSomeCatches() {doTest();}
|
||||
public void testOrInReturn() {doTest();}
|
||||
public void testVarInString() {doTest();}
|
||||
public void testMayBeStaticWithCondition() {doTest()}
|
||||
|
||||
public void doTest() {
|
||||
final List<String> input = TestUtils.readInput(getTestDataPath() + getTestName(true) + ".test");
|
||||
final List<String> input = TestUtils.readInput(testDataPath + getTestName(true) + ".test");
|
||||
|
||||
myFixture.configureByText(GroovyFileType.GROOVY_FILE_TYPE, input.get(0));
|
||||
|
||||
final GroovyFile file = (GroovyFile)myFixture.getFile();
|
||||
final SelectionModel model = myFixture.getEditor().getSelectionModel();
|
||||
final PsiElement start = file.findElementAt(model.hasSelection() ? model.getSelectionStart() : 0);
|
||||
final PsiElement end = file.findElementAt(model.hasSelection() ? model.getSelectionEnd() - 1 : file.getTextLength() - 1);
|
||||
final GrControlFlowOwner owner = PsiTreeUtil.getParentOfType(PsiTreeUtil.findCommonParent(start, end), GrControlFlowOwner.class, false);
|
||||
final Instruction[] instructions = new ControlFlowBuilder(getProject()).buildControlFlow(owner);
|
||||
final GroovyFile file = (GroovyFile)myFixture.file;
|
||||
final SelectionModel model = myFixture.editor.selectionModel;
|
||||
final PsiElement start = file.findElementAt(model.hasSelection() ? model.selectionStart : 0);
|
||||
final PsiElement end = file.findElementAt(model.hasSelection() ? model.selectionEnd - 1 : file.textLength - 1);
|
||||
final GrControlFlowOwner owner = PsiTreeUtil.getParentOfType(PsiTreeUtil.findCommonParent(start, end), GrControlFlowOwner, false);
|
||||
final Instruction[] instructions = new ControlFlowBuilder(project).buildControlFlow(owner);
|
||||
final String cf = ControlFlowUtils.dumpControlFlow(instructions);
|
||||
assertEquals(input.get(1).trim(), cf.trim());
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
a instanceof String
|
||||
-----
|
||||
0(1) element: null
|
||||
1(2) READ a
|
||||
2(3,6) Condition Instanceof expression
|
||||
3(4) instanceof: a instanceof String
|
||||
4(5,9) Negating goto instruction, condition=2Instanceof expression
|
||||
5() element: Instanceof expression MAYBE_RETURN
|
||||
6(7) instanceof: a instanceof String
|
||||
7(8) element: Instanceof expression MAYBE_RETURN
|
||||
8(9) element: Instanceof expression MAYBE_RETURN
|
||||
9() element: null
|
||||
Reference in New Issue
Block a user