Groovy: full support for resolverPolicy in control flow builder

This commit is contained in:
Max Medvedev
2013-07-02 12:42:46 +04:00
parent 21a88f47b6
commit 6d712aeabd
2 changed files with 27 additions and 23 deletions
@@ -24,7 +24,6 @@ import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.containers.ContainerUtil;
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;
@@ -111,7 +110,9 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
final PsiElement lbrace = block.getLBrace();
if (lbrace != null && parent instanceof GrMethod) {
for (GrParameter parameter : ((GrMethod)parent).getParameters()) {
addNode(new ReadWriteVariableInstruction(parameter.getName(), parameter, WRITE));
if (myPolicy.isVariableInitialized(parameter)) {
addNode(new ReadWriteVariableInstruction(parameter.getName(), parameter, WRITE));
}
}
}
super.visitOpenBlock(block);
@@ -179,7 +180,9 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
private void buildFlowForClosure(final GrClosableBlock closure) {
for (GrParameter parameter : closure.getAllParameters()) {
addNode(new ReadWriteVariableInstruction(parameter.getName(), parameter, WRITE));
if (myPolicy.isVariableInitialized(parameter)) {
addNode(new ReadWriteVariableInstruction(parameter.getName(), parameter, WRITE));
}
}
addNode(new ReadWriteVariableInstruction("owner", closure.getLBrace(), WRITE));
@@ -227,7 +230,9 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
//do not go inside closures except gstring injections
if (closure.getParent() instanceof GrStringInjection) {
for (GrParameter parameter : closure.getAllParameters()) {
addNode(new ReadWriteVariableInstruction(parameter.getName(), parameter, WRITE));
if (myPolicy.isVariableInitialized(parameter)) {
addNode(new ReadWriteVariableInstruction(parameter.getName(), parameter, WRITE));
}
}
addNode(new ReadWriteVariableInstruction("owner", closure.getLBrace(), WRITE));
@@ -235,15 +240,12 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
return;
}
Set<String> names = new HashSet<String>();
ReadWriteVariableInstruction[] reads = ControlFlowBuilderUtil.getReadsWithoutPriorWrites(closure.getControlFlow(), false);
for (ReadWriteVariableInstruction read : reads) {
names.add(read.getVariableName());
}
for (String name : names) {
addNodeAndCheckPending(new ReadWriteVariableInstruction(name, closure, READ));
PsiElement element = read.getElement();
if (!(element instanceof GrReferenceExpression) || myPolicy.isReferenceAccepted((GrReferenceExpression)element)) {
addNodeAndCheckPending(new ReadWriteVariableInstruction(read.getVariableName(), closure, READ));
}
}
addNodeAndCheckPending(new InstructionImpl(closure));
@@ -398,7 +400,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
public void visitAssignmentExpression(GrAssignmentExpression expression) {
GrExpression lValue = expression.getLValue();
if (expression.getOperationTokenType() != mASSIGN) {
if (lValue instanceof GrReferenceExpression) {
if (lValue instanceof GrReferenceExpression && myPolicy.isReferenceAccepted((GrReferenceExpression)lValue)) {
String referenceName = ((GrReferenceExpression)lValue).getReferenceName();
if (referenceName != null) {
addNodeAndCheckPending(new ReadWriteVariableInstruction(referenceName, lValue, READ));
@@ -768,7 +770,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
private void flushForeachLoopVariable(@Nullable GrForClause clause) {
if (clause instanceof GrForInClause) {
GrVariable variable = clause.getDeclaredVariable();
if (variable != null) {
if (variable != null && myPolicy.isVariableInitialized(variable)) {
addNodeAndCheckPending(new ReadWriteVariableInstruction(variable.getName(), variable, WRITE));
}
}
@@ -1019,7 +1021,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
}
final GrParameter parameter = catchClauses[i].getParameter();
if (parameter != null) {
if (parameter != null && myPolicy.isVariableInitialized(parameter)) {
addNode(new ReadWriteVariableInstruction(parameter.getName(), parameter, WRITE));
}
catchClauses[i].accept(this);
@@ -1145,22 +1147,23 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
public void visitTypeDefinition(final GrTypeDefinition typeDefinition) {
if (!(typeDefinition instanceof GrAnonymousClassDefinition)) return;
final Set<String> vars = collectUsedVariableWithoutInitialization(typeDefinition);
final Set<ReadWriteVariableInstruction> vars = collectUsedVariableWithoutInitialization(typeDefinition);
for (String var : vars) {
addNodeAndCheckPending(new ReadWriteVariableInstruction(var, typeDefinition, READ));
for (ReadWriteVariableInstruction var : vars) {
PsiElement element = var.getElement();
if (!(element instanceof GrReferenceExpression) || myPolicy.isReferenceAccepted((GrReferenceExpression)element)) {
addNodeAndCheckPending(new ReadWriteVariableInstruction(var.getVariableName(), typeDefinition, READ));
}
}
addNodeAndCheckPending(new InstructionImpl(typeDefinition));
}
private static Set<String> collectUsedVariableWithoutInitialization(GrTypeDefinition typeDefinition) {
final Set<String> vars = new HashSet<String>();
private static Set<ReadWriteVariableInstruction> collectUsedVariableWithoutInitialization(GrTypeDefinition typeDefinition) {
final Set<ReadWriteVariableInstruction> vars = ContainerUtil.newLinkedHashSet();
typeDefinition.acceptChildren(new GroovyRecursiveElementVisitor() {
private void collectVars(Instruction[] flow) {
ReadWriteVariableInstruction[] reads = ControlFlowBuilderUtil.getReadsWithoutPriorWrites(flow, false);
for (ReadWriteVariableInstruction instruction : reads) {
vars.add(instruction.getVariableName());
}
Collections.addAll(vars, reads);
}
@Override
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
/**
* @author Max Medvedev
@@ -32,7 +33,7 @@ public class GrResolverPolicy implements GrControlFlowPolicy {
@Override
public boolean isVariableInitialized(@NotNull GrVariable variable) {
return variable.getInitializerGroovy() != null || hasTupleInitializer(variable);
return variable.getInitializerGroovy() != null || hasTupleInitializer(variable) || variable instanceof GrParameter;
}
private static boolean hasTupleInitializer(@NotNull GrVariable variable) {