private static boolean methodCallExpressionsAreEquivalent(
     @NotNull GrMethodCall methodExp1, @NotNull GrMethodCall methodExp2) {
   final GrExpression methodExpression1 = methodExp1.getInvokedExpression();
   final GrExpression methodExpression2 = methodExp2.getInvokedExpression();
   if (!expressionsAreEquivalent(methodExpression1, methodExpression2)) {
     return false;
   }
   final GrArgumentList argumentList1 = methodExp1.getArgumentList();
   if (argumentList1 == null) {
     return false;
   }
   final GrArgumentList argumentList2 = methodExp2.getArgumentList();
   if (argumentList2 == null) {
     return false;
   }
   final GrExpression[] args1 = argumentList1.getExpressionArguments();
   final GrExpression[] args2 = argumentList2.getExpressionArguments();
   if (!expressionListsAreEquivalent(args1, args2)) {
     return false;
   }
   final GrNamedArgument[] namedArgs1 = argumentList1.getNamedArguments();
   final GrNamedArgument[] namedArgs2 = argumentList2.getNamedArguments();
   if (!namedArgumentListsAreEquivalent(namedArgs1, namedArgs2)) {
     return false;
   }
   final GrClosableBlock[] closures1 = methodExp1.getClosureArguments();
   final GrClosableBlock[] closures2 = methodExp2.getClosureArguments();
   return expressionListsAreEquivalent(closures1, closures2);
 }
  private static boolean applicationStatementsAreEquivalent(
      GrApplicationStatement statement1, GrApplicationStatement statement2) {
    final GrExpression funExpression1 = statement1.getInvokedExpression();
    final GrExpression funExpression2 = statement2.getInvokedExpression();
    if (!expressionsAreEquivalent(funExpression1, funExpression2)) {
      return false;
    }

    final GrArgumentList argumentList1 = statement1.getArgumentList();
    if (argumentList1 == null) {
      return false;
    }
    final GrArgumentList argumentList2 = statement2.getArgumentList();
    if (argumentList2 == null) {
      return false;
    }
    final GrExpression[] args1 = argumentList1.getExpressionArguments();
    final GrExpression[] args2 = argumentList2.getExpressionArguments();
    if (!expressionListsAreEquivalent(args1, args2)) {
      return false;
    }
    final GrNamedArgument[] namedArgs1 = argumentList1.getNamedArguments();
    final GrNamedArgument[] namedArgs2 = argumentList2.getNamedArguments();
    if (!namedArgumentListsAreEquivalent(namedArgs1, namedArgs2)) {
      return false;
    }
    return true;
  }
    @Override
    public void visitMethodCallExpression(GrMethodCallExpression grMethodCallExpression) {
      super.visitMethodCallExpression(grMethodCallExpression);
      final GrArgumentList args = grMethodCallExpression.getArgumentList();
      if (args.getExpressionArguments().length != 1) {
        return;
      }
      if (PsiImplUtil.hasNamedArguments(args)) {
        return;
      }
      final GrExpression methodExpression = grMethodCallExpression.getInvokedExpression();
      if (!(methodExpression instanceof GrReferenceExpression)) {
        return;
      }
      final GrReferenceExpression referenceExpression = (GrReferenceExpression) methodExpression;
      final String name = referenceExpression.getReferenceName();
      if (!"get".equals(name)) {
        return;
      }
      final GrExpression qualifier = referenceExpression.getQualifierExpression();

      if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
        return;
      }

      if (referenceExpression.getDotTokenType() == GroovyTokenTypes.mOPTIONAL_DOT) return;
      final PsiType type = qualifier.getType();
      if (!InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) {
        return;
      }
      registerMethodCallError(grMethodCallExpression);
    }
 private static boolean newExpressionsAreEquivalent(
     @NotNull GrNewExpression newExp1, @NotNull GrNewExpression newExp2) {
   final PsiMethod constructor1 = newExp1.resolveMethod();
   final PsiMethod constructor2 = newExp2.resolveMethod();
   if (constructor1 == null || constructor2 == null || constructor1.equals(constructor2)) {
     return false;
   }
   final GrArgumentList argumentList1 = newExp1.getArgumentList();
   if (argumentList1 == null) {
     return false;
   }
   final GrExpression[] args1 = argumentList1.getExpressionArguments();
   final GrArgumentList argumentList2 = newExp2.getArgumentList();
   if (argumentList2 == null) {
     return false;
   }
   final GrExpression[] args2 = argumentList2.getExpressionArguments();
   return expressionListsAreEquivalent(args1, args2);
 }
 @Override
 public void doFix(Project project, ProblemDescriptor descriptor)
     throws IncorrectOperationException {
   final PsiElement referenceName = descriptor.getPsiElement();
   final GrReferenceExpression invokedExpression =
       (GrReferenceExpression) referenceName.getParent();
   final GrMethodCallExpression callExpression =
       (GrMethodCallExpression) invokedExpression.getParent();
   final GrArgumentList args = callExpression.getArgumentList();
   final GrExpression arg = args.getExpressionArguments()[0];
   replaceExpression(
       callExpression,
       invokedExpression.getQualifierExpression().getText() + '[' + arg.getText() + ']');
 }
 public void visitArgumentList(GrArgumentList list) {
   List<TypeConstraint> constraints = new ArrayList<TypeConstraint>();
   for (GroovyResolveResult variant : ResolveUtil.getCallVariants(list)) {
     final Map<GrExpression, Pair<PsiParameter, PsiType>> map =
         GrClosureSignatureUtil.mapArgumentsToParameters(
             variant,
             list,
             true,
             true,
             list.getNamedArguments(),
             list.getExpressionArguments(),
             GrClosableBlock.EMPTY_ARRAY);
     addConstraintsFromMap(constraints, map);
   }
   if (!constraints.isEmpty()) {
     myResult = constraints.toArray(new TypeConstraint[constraints.size()]);
   }
 }
  private static boolean isSetterInvocation(GrMethodCall call) {
    GrExpression expr = call.getInvokedExpression();

    if (!(expr instanceof GrReferenceExpression)) return false;
    GrReferenceExpression refExpr = (GrReferenceExpression) expr;

    PsiMethod method;
    if (call instanceof GrApplicationStatement) {
      PsiElement element = refExpr.resolve();
      if (!(element instanceof PsiMethod)
          || !GroovyPropertyUtils.isSimplePropertySetter(((PsiMethod) element))) return false;
      method = (PsiMethod) element;
    } else {
      method = call.resolveMethod();
      if (!GroovyPropertyUtils.isSimplePropertySetter(method)) return false;
      LOG.assertTrue(method != null);
    }

    if (!GroovyNamesUtil.isValidReference(
        GroovyPropertyUtils.getPropertyNameBySetterName(method.getName()),
        ((GrReferenceExpression) expr).getQualifier() != null,
        call.getProject())) {
      return false;
    }

    GrArgumentList args = call.getArgumentList();
    if (args == null
        || args.getExpressionArguments().length != 1
        || PsiImplUtil.hasNamedArguments(args)) {
      return false;
    }

    GrAssignmentExpression assignment = genRefForSetter(call, refExpr.getReferenceName());
    if (assignment != null) {
      GrExpression value = assignment.getLValue();
      if (value instanceof GrReferenceExpression
          && call.getManager()
              .areElementsEquivalent(((GrReferenceExpression) value).resolve(), method)) {
        return true;
      }
    }

    return false;
  }
  @Override
  public void getNamedArguments(
      @NotNull GrCall call,
      @Nullable PsiElement resolve,
      @Nullable String argumentName,
      boolean forCompletion,
      Map<String, ArgumentDescriptor> result) {
    if (!(call instanceof GrNewExpression)) return;

    if (resolve != null) {
      if (!(resolve instanceof PsiMethod)) return;
      PsiMethod method = (PsiMethod) resolve;
      if (!method.isConstructor()) return;
    }

    GrNewExpression newCall = (GrNewExpression) call;

    GrArgumentList argumentList = newCall.getArgumentList();
    if (argumentList == null) return;

    GrExpression[] expressionArguments = argumentList.getExpressionArguments();
    if (expressionArguments.length > 1
        || (expressionArguments.length == 1
            && !(expressionArguments[0] instanceof GrReferenceExpression))) {
      return;
    }

    for (GroovyResolveResult resolveResult : newCall.multiResolveClass()) {
      PsiElement element = resolveResult.getElement();
      if (!(element instanceof PsiClass)) continue;

      PsiClass aClass = (PsiClass) element;

      if (!isClassHasConstructorWithMap(aClass)) continue;

      PsiClassType classType =
          JavaPsiFacade.getElementFactory(aClass.getProject()).createType(aClass);

      processClass(call, classType, argumentName, result);
    }
  }
    public void visitMethodCallExpression(GrMethodCallExpression methodCall) {
      final GrExpression invokedExpression = methodCall.getInvokedExpression();
      if (myExpression.equals(invokedExpression)) {
        myResult =
            new TypeConstraint[] {
              SubtypeConstraint.create(GroovyCommonClassNames.GROOVY_LANG_CLOSURE, methodCall)
            };
        return;
      }

      final GrClosableBlock[] closureArgs = methodCall.getClosureArguments();
      //noinspection SuspiciousMethodCalls
      final int closureIndex = Arrays.asList(closureArgs).indexOf(myExpression);
      if (closureIndex >= 0) {
        List<TypeConstraint> constraints = new ArrayList<TypeConstraint>();
        for (GroovyResolveResult variant : ResolveUtil.getCallVariants(myExpression)) {
          final GrArgumentList argumentList = methodCall.getArgumentList();
          final GrNamedArgument[] namedArgs =
              argumentList == null ? GrNamedArgument.EMPTY_ARRAY : argumentList.getNamedArguments();
          final GrExpression[] expressionArgs =
              argumentList == null
                  ? GrExpression.EMPTY_ARRAY
                  : argumentList.getExpressionArguments();
          try {
            final Map<GrExpression, Pair<PsiParameter, PsiType>> map =
                GrClosureSignatureUtil.mapArgumentsToParameters(
                    variant, methodCall, true, true, namedArgs, expressionArgs, closureArgs);
            addConstraintsFromMap(constraints, map);
          } catch (RuntimeException e) {
            LOG.error(
                "call: " + methodCall.getText() + "\nsymbol: " + variant.getElement().getText(), e);
          }
        }
        if (!constraints.isEmpty()) {
          myResult = constraints.toArray(new TypeConstraint[constraints.size()]);
        }
      }
    }
        @Override
        public PsiType fun(GrIndexPropertyImpl index) {
          GrExpression selected = index.getInvokedExpression();
          PsiType thisType = selected.getType();

          if (thisType == null) return null;

          GrArgumentList argList = index.getArgumentList();

          PsiType[] argTypes = PsiUtil.getArgumentTypes(argList);
          if (argTypes == null) return null;

          final PsiManager manager = index.getManager();
          final GlobalSearchScope resolveScope = index.getResolveScope();

          if (argTypes.length == 0) {
            PsiType arrType = null;
            if (selected instanceof GrBuiltinTypeClassExpression) {
              arrType = ((GrBuiltinTypeClassExpression) selected).getPrimitiveType();
            }

            if (selected instanceof GrReferenceExpression) {
              final PsiElement resolved = ((GrReferenceExpression) selected).resolve();
              if (resolved instanceof PsiClass) {
                String qname = ((PsiClass) resolved).getQualifiedName();
                if (qname != null) {
                  arrType = TypesUtil.createTypeByFQClassName(qname, index);
                }
              }
            }

            if (arrType != null) {
              final PsiArrayType param = arrType.createArrayType();
              return TypesUtil.createJavaLangClassType(param, index.getProject(), resolveScope);
            }
          }

          if (PsiImplUtil.isSimpleArrayAccess(
              thisType, argTypes, manager, resolveScope, PsiUtil.isLValue(index))) {
            return TypesUtil.boxPrimitiveType(
                ((PsiArrayType) thisType).getComponentType(), manager, resolveScope);
          }

          final GroovyResolveResult[] candidates = index.multiResolve(false);

          PsiType[] args =
              PsiUtil.getArgumentTypes(
                  argList.getNamedArguments(),
                  argList.getExpressionArguments(),
                  GrClosableBlock.EMPTY_ARRAY,
                  true,
                  null,
                  false);
          final GroovyResolveResult candidate = PsiImplUtil.extractUniqueResult(candidates);
          final PsiElement element = candidate.getElement();
          if (element instanceof PsiNamedElement) {
            final String name = ((PsiNamedElement) element).getName();
            if ("putAt".equals(name) && args != null) {
              args =
                  ArrayUtil.append(
                      args, TypeInferenceHelper.getInitializerFor(index), PsiType.class);
            }
          }
          PsiType overloadedOperatorType =
              ResolveUtil.extractReturnTypeFromCandidate(candidate, index, args);

          PsiType componentType = extractMapValueType(thisType, args, manager, resolveScope);

          if (overloadedOperatorType != null
              && (componentType == null
                  || !TypesUtil.isAssignable(
                      overloadedOperatorType, componentType, manager, resolveScope))) {
            return TypesUtil.boxPrimitiveType(overloadedOperatorType, manager, resolveScope);
          }
          return componentType;
        }
 @NotNull
 @Override
 public GrExpression[] getExpressionArguments() {
   GrArgumentList list = getArgumentList();
   return list.getExpressionArguments();
 }
  private GroovyResolveResult[] resolveImpl(
      boolean incompleteCode, @Nullable GrExpression upToArgument) {
    GrExpression invoked = getInvokedExpression();
    PsiType thisType = invoked.getType();

    if (thisType == null) return GroovyResolveResult.EMPTY_ARRAY;

    GrArgumentList argList = getArgumentList();

    PsiType[] argTypes =
        PsiUtil.getArgumentTypes(
            argList.getNamedArguments(),
            argList.getExpressionArguments(),
            GrClosableBlock.EMPTY_ARRAY,
            true,
            upToArgument,
            false);
    if (argTypes == null) return GroovyResolveResult.EMPTY_ARRAY;

    final PsiManager manager = getManager();
    final GlobalSearchScope resolveScope = getResolveScope();

    if (argTypes.length == 0) {
      PsiType arrType = null;
      if (invoked instanceof GrBuiltinTypeClassExpression) {
        arrType = ((GrBuiltinTypeClassExpression) invoked).getPrimitiveType();
      }

      if (invoked instanceof GrReferenceExpression) {
        final PsiElement resolved = ((GrReferenceExpression) invoked).resolve();
        if (resolved instanceof PsiClass) {
          String qname = ((PsiClass) resolved).getQualifiedName();
          if (qname != null) {
            arrType = TypesUtil.createTypeByFQClassName(qname, this);
          }
        }
      }

      if (arrType != null) {
        return GroovyResolveResult.EMPTY_ARRAY;
      }
    }

    GroovyResolveResult[] candidates;
    final String name;
    if (PsiUtil.isLValue(this)) {
      name = "putAt";
      if (!incompleteCode) {
        argTypes =
            ArrayUtil.append(argTypes, TypeInferenceHelper.getInitializerFor(this), PsiType.class);
      }
    } else {
      name = "getAt";
    }

    if (PsiImplUtil.isSimpleArrayAccess(
        thisType, argTypes, manager, resolveScope, PsiUtil.isLValue(this))) {
      return GroovyResolveResult.EMPTY_ARRAY;
    }

    candidates =
        ResolveUtil.getMethodCandidates(
            thisType, name, this, true, incompleteCode, false, argTypes);

    // hack for remove DefaultGroovyMethods.getAt(Object, ...)
    if (candidates.length == 2) {
      for (int i = 0; i < candidates.length; i++) {
        GroovyResolveResult candidate = candidates[i];
        final PsiElement element = candidate.getElement();
        if (element instanceof GrGdkMethod) {
          final PsiMethod staticMethod = ((GrGdkMethod) element).getStaticMethod();
          final PsiParameter param = staticMethod.getParameterList().getParameters()[0];
          if (param.getType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
            return new GroovyResolveResult[] {candidates[1 - i]};
          }
        }
      }
    }

    if (candidates.length != 1) {
      final GrTupleType tupleType =
          new GrTupleType(argTypes, JavaPsiFacade.getInstance(getProject()), resolveScope);
      candidates = ResolveUtil.getMethodCandidates(thisType, name, this, tupleType);
    }
    return candidates;
  }