summaryrefslogtreecommitdiff
path: root/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GrReassignedInClosureLocalVarInspection.java
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GrReassignedInClosureLocalVarInspection.java')
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GrReassignedInClosureLocalVarInspection.java40
1 files changed, 32 insertions, 8 deletions
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GrReassignedInClosureLocalVarInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GrReassignedInClosureLocalVarInspection.java
index 82a688f9bd89..400c0a366970 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GrReassignedInClosureLocalVarInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GrReassignedInClosureLocalVarInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,12 +21,16 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.codeInsight.GrReassignedLocalVarsChecker;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
+import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
import org.jetbrains.plugins.groovy.lang.psi.GrNamedElement;
-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.expressions.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
@@ -66,18 +70,38 @@ public class GrReassignedInClosureLocalVarInspection extends BaseInspection {
final PsiElement resolved = referenceExpression.resolve();
if (!GroovyRefactoringUtil.isLocalVariable(resolved)) return;
- if (isOtherTypeOrDifferent(referenceExpression, (GrVariable)resolved) ) {
- final String message = message("local.var.0.is.reassigned", ((GrNamedElement)resolved).getName());
+ final PsiType checked = GrReassignedLocalVarsChecker.getReassignedVarType(referenceExpression, false);
+ if (checked == null) return;
+
+ final GrControlFlowOwner varFlowOwner = ControlFlowUtils.findControlFlowOwner(resolved);
+ final GrControlFlowOwner refFlorOwner = ControlFlowUtils.findControlFlowOwner(referenceExpression);
+ if (isOtherScopeAndType(referenceExpression, checked, varFlowOwner, refFlorOwner)) {
+ String flowDescription = getFlowDescription(refFlorOwner);
+ final String message = message("local.var.0.is.reassigned", ((GrNamedElement)resolved).getName(), flowDescription);
registerError(referenceExpression, message, LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
}
};
}
- private static boolean isOtherTypeOrDifferent(@NotNull GrReferenceExpression referenceExpression, GrVariable resolved) {
- if (ControlFlowUtils.findControlFlowOwner(referenceExpression) != ControlFlowUtils.findControlFlowOwner(resolved)) return true;
+ private static boolean isOtherScopeAndType(GrReferenceExpression referenceExpression,
+ PsiType checked,
+ GrControlFlowOwner varFlowOwner,
+ GrControlFlowOwner refFlorOwner) {
+ return varFlowOwner != refFlorOwner && !TypesUtil.isAssignable(referenceExpression.getType(), checked, referenceExpression);
+ }
- final PsiType currentType = referenceExpression.getType();
- return currentType != null && currentType != PsiType.NULL && !ControlFlowUtils.findAccess(resolved, referenceExpression, false, true).isEmpty();
+ private static String getFlowDescription(GrControlFlowOwner refFlorOwner) {
+ String flowDescription;
+ if (refFlorOwner instanceof GrClosableBlock) {
+ flowDescription = message("closure");
+ }
+ else if (refFlorOwner instanceof GrAnonymousClassDefinition) {
+ flowDescription = message("anonymous.class");
+ }
+ else {
+ flowDescription = message("other.scope");
+ }
+ return flowDescription;
}
}