diff options
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.java | 40 |
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; } } |