mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
EA-26560 - SOE: GroovyPsiElementImpl.acceptGroovyChildren
This commit is contained in:
+19
-19
@@ -24,7 +24,7 @@ import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
|
||||
@@ -270,25 +270,25 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
|
||||
|
||||
public void visitThrowStatement(GrThrowStatement throwStatement) {
|
||||
final GrExpression exception = throwStatement.getException();
|
||||
if (exception != null) {
|
||||
exception.accept(this);
|
||||
final InstructionImpl throwInstruction = startNode(throwStatement);
|
||||
flowAbrupted();
|
||||
final PsiType type = exception.getNominalType();
|
||||
if (type != null) {
|
||||
ExceptionInfo info = findCatch(type);
|
||||
if (info != null) {
|
||||
info.myThrowers.add(throwInstruction);
|
||||
}
|
||||
else {
|
||||
addPendingEdge(null, throwInstruction);
|
||||
}
|
||||
if (exception == null) return;
|
||||
|
||||
exception.accept(this);
|
||||
final InstructionImpl throwInstruction = startNode(throwStatement);
|
||||
flowAbrupted();
|
||||
final PsiType type = exception.getNominalType();
|
||||
if (type != null) {
|
||||
ExceptionInfo info = findCatch(type);
|
||||
if (info != null) {
|
||||
info.myThrowers.add(throwInstruction);
|
||||
}
|
||||
else {
|
||||
addPendingEdge(null, throwInstruction);
|
||||
}
|
||||
finishNode(throwInstruction);
|
||||
}
|
||||
else {
|
||||
addPendingEdge(null, throwInstruction);
|
||||
}
|
||||
finishNode(throwInstruction);
|
||||
}
|
||||
|
||||
private void flowAbrupted() {
|
||||
@@ -317,7 +317,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
|
||||
|
||||
public void visitAssignmentExpression(GrAssignmentExpression expression) {
|
||||
GrExpression lValue = expression.getLValue();
|
||||
if (expression.getOperationToken() != GroovyElementTypes.mASSIGN) {
|
||||
if (expression.getOperationToken() != GroovyTokenTypes.mASSIGN) {
|
||||
if (lValue instanceof GrReferenceExpression) {
|
||||
ReadWriteVariableInstructionImpl instruction =
|
||||
new ReadWriteVariableInstructionImpl((GrReferenceExpression)lValue, myInstructionNumber++, false);
|
||||
@@ -343,7 +343,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
|
||||
public void visitUnaryExpression(GrUnaryExpression expression) {
|
||||
final GrExpression operand = expression.getOperand();
|
||||
if (operand != null) {
|
||||
final boolean negation = expression.getOperationTokenType() == GroovyElementTypes.mLNOT;
|
||||
final boolean negation = expression.getOperationTokenType() == GroovyTokenTypes.mLNOT;
|
||||
if (negation) {
|
||||
myNegate = !myNegate;
|
||||
}
|
||||
@@ -505,7 +505,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
|
||||
}
|
||||
|
||||
//add edge when instruction.getElement() is not contained in scopeWhenAdded
|
||||
private void addPendingEdge(GroovyPsiElement scopeWhenAdded, InstructionImpl instruction) {
|
||||
private void addPendingEdge(@Nullable GroovyPsiElement scopeWhenAdded, InstructionImpl instruction) {
|
||||
if (instruction == null) return;
|
||||
|
||||
int i = 0;
|
||||
@@ -662,7 +662,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private InstructionImpl startNode(GroovyPsiElement element) {
|
||||
private InstructionImpl startNode(@Nullable GroovyPsiElement element) {
|
||||
return startNode(element, true);
|
||||
}
|
||||
|
||||
|
||||
+1
-4
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.CallEnvironment;
|
||||
@@ -29,8 +28,6 @@ import java.util.Stack;
|
||||
* @author ven
|
||||
*/
|
||||
public class InstructionImpl implements Instruction, Cloneable {
|
||||
private static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.InstructionImpl");
|
||||
|
||||
ArrayList<InstructionImpl> myPred = new ArrayList<InstructionImpl>();
|
||||
|
||||
ArrayList<InstructionImpl> mySucc = new ArrayList<InstructionImpl>();
|
||||
@@ -43,7 +40,7 @@ public class InstructionImpl implements Instruction, Cloneable {
|
||||
return myPsiElement;
|
||||
}
|
||||
|
||||
public InstructionImpl(PsiElement element, int num) {
|
||||
public InstructionImpl(@Nullable PsiElement element, int num) {
|
||||
myPsiElement = element;
|
||||
myNumber = num;
|
||||
}
|
||||
|
||||
+26
-5
@@ -27,14 +27,17 @@ import com.intellij.util.containers.hash.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrThrowStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter;
|
||||
@@ -63,7 +66,8 @@ public class MethodResolverProcessor extends ResolverProcessor {
|
||||
private final boolean myIsConstructor;
|
||||
|
||||
private boolean myStopExecuting = false;
|
||||
private final Set<GrStatement> myExitPoints = new HashSet<GrStatement>();
|
||||
private Set<GrStatement> myExitPoints;
|
||||
private final boolean canNotBeExitPoint;
|
||||
|
||||
public MethodResolverProcessor(String name, GroovyPsiElement place, boolean isConstructor, PsiType thisType, @Nullable PsiType[] argumentTypes, PsiType[] typeArguments) {
|
||||
this(name, place, isConstructor, thisType, argumentTypes, typeArguments, false);
|
||||
@@ -75,11 +79,16 @@ public class MethodResolverProcessor extends ResolverProcessor {
|
||||
myArgumentTypes = argumentTypes;
|
||||
myTypeArguments = typeArguments;
|
||||
myAllVariants = allVariants;
|
||||
canNotBeExitPoint = !canBexExitPoint(place);
|
||||
}
|
||||
|
||||
final GrMethod method = PsiTreeUtil.getParentOfType(myPlace, GrMethod.class, true, GrClosableBlock.class);
|
||||
if (method != null) {
|
||||
myExitPoints.addAll(ControlFlowUtils.collectReturns(method.getBlock()));
|
||||
private static boolean canBexExitPoint(PsiElement place) {
|
||||
while (place != null) {
|
||||
if (place instanceof GrMethod || place instanceof GrClosableBlock) return true;
|
||||
if (place instanceof GrThrowStatement || place instanceof GrTypeDefinitionBody || place instanceof GroovyFile) return false;
|
||||
place = place.getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean execute(PsiElement element, ResolveState state) {
|
||||
@@ -228,7 +237,7 @@ public class MethodResolverProcessor extends ResolverProcessor {
|
||||
PsiElement call = myPlace.getParent();
|
||||
final PsiElement parent = call.getParent();
|
||||
PsiType rType = null;
|
||||
if (parent instanceof GrReturnStatement || myExitPoints.contains(call)) {
|
||||
if (parent instanceof GrReturnStatement || exitsContains(call)) {
|
||||
final GrMethod method = PsiTreeUtil.getParentOfType(parent, GrMethod.class, true, GrClosableBlock.class);
|
||||
if (method != null) rType = method.getReturnType();
|
||||
}
|
||||
@@ -241,6 +250,18 @@ public class MethodResolverProcessor extends ResolverProcessor {
|
||||
return rType;
|
||||
}
|
||||
|
||||
private boolean exitsContains(PsiElement call) {
|
||||
if (canNotBeExitPoint) return false;
|
||||
if (myExitPoints == null) {
|
||||
final GrMethod method = PsiTreeUtil.getParentOfType(myPlace, GrMethod.class, true, GrClosableBlock.class);
|
||||
myExitPoints = new HashSet<GrStatement>();
|
||||
if (method != null) {
|
||||
myExitPoints.addAll(ControlFlowUtils.collectReturns(method.getBlock()));
|
||||
}
|
||||
}
|
||||
return myExitPoints.contains(call);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public GroovyResolveResult[] getCandidates() {
|
||||
if (!myAllVariants && super.hasCandidates()) {
|
||||
|
||||
@@ -208,4 +208,8 @@ public class TypeInferenceTest extends GroovyResolveTestCase {
|
||||
public void testReturnTypeFromMethodClosure() {
|
||||
assertTypeEquals("java.lang.String","A.groovy");
|
||||
}
|
||||
|
||||
public void testNoSOF() {
|
||||
assertTypeEquals("java.lang.Object", "A.groovy");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
class Abc3 {
|
||||
Abc3 foo(){}
|
||||
def <T, S> getAt(T t) {
|
||||
def ab= foo()
|
||||
throw ab[2]
|
||||
}
|
||||
}
|
||||
|
||||
def aa = new Abc3().getAt()
|
||||
print a<ref>a
|
||||
Reference in New Issue
Block a user