EA-26560 - SOE: GroovyPsiElementImpl.acceptGroovyChildren

This commit is contained in:
Maxim Medvedev
2011-04-18 15:31:29 +04:00
parent 39fb947218
commit 60632b102f
5 changed files with 60 additions and 28 deletions
@@ -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);
}
@@ -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;
}
@@ -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