@Override
 public void visitReferenceExpression(GrReferenceExpression expression) {
   super.visitReferenceExpression(expression);
   if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isSuperReference(expression)) {
     final GrExpression qualifier = expression.getQualifier();
     if (qualifier instanceof GrReferenceExpression
         && ((GrReferenceExpression) qualifier).isReferenceTo(mySourceClass)) {
       try {
         expression.putCopyableUserData(SUPER_REF, Boolean.TRUE);
       } catch (IncorrectOperationException e) {
         LOG.error(e);
       }
     }
   } else if (org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isThisReference(expression)) {
     final GrExpression qualifier = expression.getQualifier();
     if (qualifier instanceof GrReferenceExpression
         && ((GrReferenceExpression) qualifier).isReferenceTo(mySourceClass)) {
       try {
         expression.putCopyableUserData(THIS_REF, Boolean.TRUE);
       } catch (IncorrectOperationException e) {
         LOG.error(e);
       }
     }
   }
 }
 @Override
 public void visitReferenceExpression(GrReferenceExpression expression) {
   super.visitReferenceExpression(expression);
   if (expression.getCopyableUserData(SUPER_REF) != null) {
     expression.putCopyableUserData(SUPER_REF, null);
     final GrExpression qualifier = expression.getQualifier();
     if (qualifier instanceof GrReferenceExpression
         && ((GrReferenceExpression) qualifier).isReferenceTo(mySourceClass)) {
       try {
         GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
         GrExpression newExpr =
             factory.createExpressionFromText(myTargetSuperClass.getName() + ".this", null);
         expression.replace(newExpr);
       } catch (IncorrectOperationException e) {
         LOG.error(e);
       }
     }
   } else if (expression.getCopyableUserData(THIS_REF) != null) {
     expression.putCopyableUserData(THIS_REF, null);
     final GrExpression qualifier = expression.getQualifier();
     if (qualifier instanceof GrReferenceExpression
         && ((GrReferenceExpression) qualifier).isReferenceTo(mySourceClass)) {
       try {
         ((GrReferenceExpression) qualifier).bindToElement(myTargetSuperClass);
         GroovyChangeContextUtil.clearContextInfo(qualifier);
       } catch (IncorrectOperationException e) {
         LOG.error(e);
       }
     }
   }
 }
  public FieldConflictsResolver(String name, GrCodeBlock scope) {
    myScope = scope;
    if (myScope == null) return;

    final GroovyPsiElement resolved = ResolveUtil.resolveProperty(myScope, name);
    if (resolved instanceof GrReferenceExpression || resolved == null) return;

    assert resolved instanceof PsiVariable;
    final PsiVariable oldVariable = (PsiVariable) resolved;
    myField = oldVariable instanceof PsiField ? (PsiField) oldVariable : null;
    if (!(oldVariable instanceof PsiField)) return;

    myReferenceExpressions = new ArrayList<>();
    for (PsiReference reference :
        ReferencesSearch.search(myField, new LocalSearchScope(myScope), false)) {
      final PsiElement element = reference.getElement();
      if (element instanceof GrReferenceExpression) {
        final GrReferenceExpression referenceExpression = (GrReferenceExpression) element;
        if (referenceExpression.getQualifier() == null) {
          myReferenceExpressions.add(referenceExpression);
        }
      }
    }
    if (myField.hasModifierProperty(PsiModifier.STATIC)) {
      myQualifyingClass = myField.getContainingClass();
    }
  }
 public static boolean isClassReference(GrReferenceExpression ref) {
   GrExpression qualifier = ref.getQualifier();
   return "class".equals(ref.getReferenceName())
       && qualifier instanceof GrReferenceExpression
       && ((GrReferenceExpression) qualifier).resolve() instanceof PsiClass
       && !PsiUtil.isThisReference(qualifier);
 }
  private static boolean isQualifiedStaticMethodWithUnnecessaryQualifier(
      GrReferenceExpression ref) {
    if (ref.getQualifier() == null) return false;

    final PsiElement resolved = ref.resolve();
    if (!(resolved instanceof PsiMember)) return false;
    if (!((PsiMember) resolved).hasModifierProperty(PsiModifier.STATIC)) return false;

    PsiElement copyResolved;
    final PsiElement parent = ref.getParent();
    if (parent instanceof GrMethodCall) {
      final GrMethodCall copy = (GrMethodCall) parent.copy();
      GrReferenceExpression invoked = (GrReferenceExpression) copy.getInvokedExpression();
      assert invoked != null;

      invoked.setQualifier(null);

      copyResolved = ((GrReferenceExpression) copy.getInvokedExpression()).resolve();
    } else {
      final GrReferenceExpression copy = (GrReferenceExpression) ref.copy();
      copy.setQualifier(null);
      copyResolved = copy.resolve();
    }
    return ref.getManager().areElementsEquivalent(copyResolved, resolved);
  }
 private static boolean isPropertyAccessInStaticMethod(GrReferenceExpression referenceExpression) {
   if (referenceExpression.getParent() instanceof GrMethodCall
       || referenceExpression.getQualifier() != null) return false;
   GrMember context =
       PsiTreeUtil.getParentOfType(
           referenceExpression, GrMember.class, true, GrClosableBlock.class);
   return (context instanceof GrMethod || context instanceof GrClassInitializer)
       && context.hasModifierProperty(STATIC);
 }
    private static PsiType doFun(GrReferenceExpression refExpr) {
      if (ResolveUtil.isClassReference(refExpr)) {
        GrExpression qualifier = refExpr.getQualifier();
        LOG.assertTrue(qualifier != null);
        return TypesUtil.createJavaLangClassType(
            qualifier.getType(), refExpr.getProject(), refExpr.getResolveScope());
      }

      if (PsiUtil.isCompileStatic(refExpr)) {
        final GroovyResolveResult resolveResult = refExpr.advancedResolve();
        final PsiElement resolvedF = resolveResult.getElement();
        final PsiType type;
        if (resolvedF instanceof GrField) {
          type = ((GrField) resolvedF).getType();
        } else if (resolvedF instanceof GrAccessorMethod) {
          type = ((GrAccessorMethod) resolvedF).getProperty().getType();
        } else {
          type = null;
        }
        if (type != null) {
          return resolveResult.getSubstitutor().substitute(type);
        }
      }

      final PsiElement resolved = refExpr.resolve();
      final PsiType nominal = refExpr.getNominalType();

      Boolean reassigned = GrReassignedLocalVarsChecker.isReassignedVar(refExpr);
      if (reassigned != null && reassigned.booleanValue()) {
        return GrReassignedLocalVarsChecker.getReassignedVarType(refExpr, true);
      }

      final PsiType inferred = getInferredTypes(refExpr, resolved);
      if (inferred == null) {
        if (nominal == null) {
          // inside nested closure we could still try to infer from variable initializer. Not sound,
          // but makes sense
          if (resolved instanceof GrVariable) {
            LOG.assertTrue(resolved.isValid());
            return ((GrVariable) resolved).getTypeGroovy();
          }
        }

        return nominal;
      }

      if (nominal == null) return inferred;
      if (!TypeConversionUtil.isAssignable(TypeConversionUtil.erasure(nominal), inferred, false)) {
        if (resolved instanceof GrVariable
            && ((GrVariable) resolved).getTypeElementGroovy() != null) {
          return nominal;
        }
      }
      return inferred;
    }
  private static void registerStaticImportFix(
      @NotNull GrReferenceExpression referenceExpression,
      @Nullable HighlightInfo info,
      @Nullable final HighlightDisplayKey key) {
    final String referenceName = referenceExpression.getReferenceName();
    if (StringUtil.isEmpty(referenceName)) return;
    if (referenceExpression.getQualifier() != null) return;

    QuickFixAction.registerQuickFixAction(
        info, new GroovyStaticImportMethodFix((GrMethodCall) referenceExpression.getParent()), key);
  }
    @Override
    public void visitReferenceExpression(GrReferenceExpression ref) {
      super.visitReferenceExpression(ref);
      final GrExpression qualifier = ref.getQualifier();
      if (!PsiUtil.isThisReference(qualifier)) return;

      final PsiElement resolved = ref.resolve();
      if (!(resolved instanceof PsiField)) return;
      final PsiMethod getter = GroovyPropertyUtils.findGetterForField((PsiField) resolved);
      if (getter != null) {
        result.add((PsiField) resolved);
      }
    }
  @Nullable
  public static PsiType checkReassignedVar(
      GrReferenceExpression refExpr, boolean honorCompileStatic) {
    if (honorCompileStatic && !PsiUtil.isCompileStatic(refExpr) || refExpr.getQualifier() != null) {
      return null;
    }

    final PsiElement resolved = refExpr.resolve();
    if (!GroovyRefactoringUtil.isLocalVariable(resolved)) {
      return null;
    }

    assert resolved != null;
    return getLeastUpperBoundByVar((GrVariable) resolved);
  }
  @Nullable
  private static GrAssignmentExpression genRefForSetter(GrMethodCall call, String accessorName) {
    String name = GroovyPropertyUtils.getPropertyNameBySetterName(accessorName);
    if (name == null) return null;
    GrExpression value = call.getExpressionArguments()[0];
    GrReferenceExpression refExpr = (GrReferenceExpression) call.getInvokedExpression();

    final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(call.getProject());
    final GrAssignmentExpression assignment =
        (GrAssignmentExpression) factory.createStatementFromText("yyy = xxx", call);

    GrReferenceExpression lvalueRef = (GrReferenceExpression) assignment.getLValue();
    lvalueRef.setQualifier(refExpr.getQualifier());
    lvalueRef.handleElementRenameSimple(name);
    assignment.getRValue().replaceWithExpression(value, true);

    return assignment;
  }
 @Nullable
 private static PsiType getInferredTypes(
     @NotNull GrReferenceExpression refExpr, @Nullable PsiElement resolved) {
   final GrExpression qualifier = refExpr.getQualifier();
   if (!(resolved instanceof PsiClass) && !(resolved instanceof PsiPackage)) {
     if (qualifier == null) {
       return TypeInferenceHelper.getCurrentContext().getVariableType(refExpr);
     } else {
       // map access
       PsiType qType = qualifier.getType();
       if (qType instanceof PsiClassType && !(qType instanceof GrMapType)) {
         final PsiType mapValueType = getTypeFromMapAccess(refExpr);
         if (mapValueType != null) {
           return mapValueType;
         }
       }
     }
   }
   return null;
 }
 public static GrReferenceExpression qualifyReference(
     GrReferenceExpression referenceExpression,
     final PsiMember member,
     @Nullable final PsiClass qualifyingClass)
     throws IncorrectOperationException {
   PsiManager manager = referenceExpression.getManager();
   GrReferenceExpression expressionFromText;
   final GroovyPsiElementFactory factory =
       GroovyPsiElementFactory.getInstance(referenceExpression.getProject());
   if (qualifyingClass == null) {
     PsiClass parentClass = PsiTreeUtil.getParentOfType(referenceExpression, PsiClass.class);
     final PsiClass containingClass = member.getContainingClass();
     if (parentClass != null
         && !InheritanceUtil.isInheritorOrSelf(parentClass, containingClass, true)) {
       while (parentClass != null
           && !InheritanceUtil.isInheritorOrSelf(parentClass, containingClass, true)) {
         parentClass = PsiTreeUtil.getParentOfType(parentClass, PsiClass.class, true);
       }
       LOG.assertTrue(parentClass != null);
       expressionFromText =
           factory.createReferenceExpressionFromText("A.this." + member.getName());
       //noinspection ConstantConditions
       ((GrReferenceExpression) expressionFromText.getQualifier())
           .getQualifier()
           .replace(factory.createReferenceElementForClass(parentClass));
     } else {
       expressionFromText =
           (GrReferenceExpression) factory.createExpressionFromText("this." + member.getName());
     }
   } else {
     expressionFromText =
         (GrReferenceExpression) factory.createExpressionFromText("A." + member.getName());
     expressionFromText.setQualifier(factory.createReferenceElementForClass(qualifyingClass));
   }
   CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject());
   expressionFromText = (GrReferenceExpression) codeStyleManager.reformat(expressionFromText);
   return (GrReferenceExpression) referenceExpression.replace(expressionFromText);
 }
  private static boolean shouldHighlightAsUnresolved(
      @NotNull GrReferenceExpression referenceExpression) {
    if (GrHighlightUtil.isDeclarationAssignment(referenceExpression)) return false;

    GrExpression qualifier = referenceExpression.getQualifier();
    if (qualifier != null && qualifier.getType() == null && !isRefToPackage(qualifier))
      return false;

    if (qualifier != null
        && referenceExpression.getDotTokenType() == GroovyTokenTypes.mMEMBER_POINTER
        && referenceExpression.multiResolve(false).length > 0) {
      return false;
    }

    if (!GroovyUnresolvedHighlightFilter.shouldHighlight(referenceExpression)) return false;

    CollectConsumer<PomTarget> consumer = new CollectConsumer<PomTarget>();
    for (PomDeclarationSearcher searcher : PomDeclarationSearcher.EP_NAME.getExtensions()) {
      searcher.findDeclarationsAt(referenceExpression, 0, consumer);
      if (!consumer.getResult().isEmpty()) return false;
    }

    return true;
  }