From 6d712aeabdd85b0ca25b372fe4823e33aff6da1c Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Mon, 1 Jul 2013 19:33:31 +0400 Subject: [PATCH] Groovy: full support for resolverPolicy in control flow builder --- .../controlFlow/impl/ControlFlowBuilder.java | 47 ++++++++++--------- .../controlFlow/impl/GrResolverPolicy.java | 3 +- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ControlFlowBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ControlFlowBuilder.java index ebb06e5782b2..f04225337502 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ControlFlowBuilder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ControlFlowBuilder.java @@ -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 names = new HashSet(); - 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 vars = collectUsedVariableWithoutInitialization(typeDefinition); + final Set 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 collectUsedVariableWithoutInitialization(GrTypeDefinition typeDefinition) { - final Set vars = new HashSet(); + private static Set collectUsedVariableWithoutInitialization(GrTypeDefinition typeDefinition) { + final Set 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 diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/GrResolverPolicy.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/GrResolverPolicy.java index 77b1f302a333..52c875bd6bf0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/GrResolverPolicy.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/GrResolverPolicy.java @@ -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) {