@NotNull
 public GroovyResolveResult[] multiResolve(
     boolean incomplete) { // incomplete means we do not take arguments into consideration
   final ResolveResult[] results =
       TypeInferenceHelper.getCurrentContext().multiResolve(this, incomplete, POLY_RESOLVER);
   return results.length == 0 ? GroovyResolveResult.EMPTY_ARRAY : (GroovyResolveResult[]) results;
 }
  @Override
  public PsiType getTypeGroovy() {
    PsiType type =
        TypeInferenceHelper.getCurrentContext()
            .getExpressionType(
                this,
                new Function<GrFieldImpl, PsiType>() {
                  @Override
                  public PsiType fun(GrFieldImpl field) {
                    if (getDeclaredType() == null && getInitializerGroovy() == null) {
                      final PsiType type = GrVariableEnhancer.getEnhancedType(field);
                      if (type != null) {
                        return type;
                      }
                    }
                    return null;
                  }
                });

    if (type != null) {
      return type;
    }

    return super.getTypeGroovy();
  }
 public GroovyResolveResult advancedResolve() {
   ResolveResult[] results =
       TypeInferenceHelper.getCurrentContext().multiResolve(this, false, POLY_RESOLVER);
   return results.length == 1
       ? (GroovyResolveResult) results[0]
       : GroovyResolveResult.EMPTY_RESULT;
 }
 @Nullable
 private static PsiType getInferredTypes(
     GrReferenceExpressionImpl refExpr, @Nullable PsiElement resolved) {
   final GrExpression qualifier = refExpr.getQualifier();
   if (qualifier == null && !(resolved instanceof PsiClass)) {
     return TypeInferenceHelper.getCurrentContext().getVariableType(refExpr);
   } else if (qualifier != null) {
     // map access
     PsiType qType = qualifier.getType();
     if (qType instanceof PsiClassType && !(qType instanceof GrMapType)) {
       PsiClassType.ClassResolveResult qResult = ((PsiClassType) qType).resolveGenerics();
       PsiClass clazz = qResult.getElement();
       if (clazz != null) {
         PsiClass mapClass =
             JavaPsiFacade.getInstance(refExpr.getProject())
                 .findClass(CommonClassNames.JAVA_UTIL_MAP, refExpr.getResolveScope());
         if (mapClass != null && mapClass.getTypeParameters().length == 2) {
           PsiSubstitutor substitutor =
               TypeConversionUtil.getClassSubstitutor(mapClass, clazz, qResult.getSubstitutor());
           if (substitutor != null) {
             return TypeConversionUtil.erasure(
                 substitutor.substitute(mapClass.getTypeParameters()[1]));
           }
         }
       }
     }
   }
   return null;
 }
  public static TypeConstraint[] calculateTypeConstraints(@NotNull final GrExpression expression) {
    return TypeInferenceHelper.getCurrentContext()
        .getCachedValue(
            expression,
            new Computable<TypeConstraint[]>() {
              @Override
              public TypeConstraint[] compute() {
                MyCalculator calculator = new MyCalculator(expression);
                final PsiElement parent = expression.getParent();
                if (parent instanceof GroovyPsiElement) {
                  ((GroovyPsiElement) parent).accept(calculator);
                } else {
                  parent.accept(new GroovyPsiElementVisitor(calculator));
                }
                final TypeConstraint[] result = calculator.getResult();

                List<TypeConstraint> custom = new ArrayList<TypeConstraint>();
                for (GroovyExpectedTypesContributor contributor :
                    GroovyExpectedTypesContributor.EP_NAME.getExtensions()) {
                  custom.addAll(contributor.calculateTypeConstraints(expression));
                }

                if (!custom.isEmpty()) {
                  custom.addAll(0, Arrays.asList(result));
                  return custom.toArray(new TypeConstraint[custom.size()]);
                }

                return result;
              }
            });
  }
  @Override
  public PsiType getInferredReturnType() {
    if (isConstructor()) {
      return null;
    }

    if (!ApplicationManager.getApplication().isUnitTestMode()) {
      // todo uncomment when EAP is on
      // LOG.assertTrue(!ApplicationManager.getApplication().isDispatchThread()); //this is a
      // potentially long action
    }
    return TypeInferenceHelper.getCurrentContext().getExpressionType(this, ourTypesCalculator);
  }
 @Override
 @Nullable
 public PsiType fun(final GrReferenceExpressionImpl refExpr) {
   final Pair key = Pair.create(TypeInferenceHelper.getCurrentContext(), refExpr);
   return RecursionManager.doPreventingRecursion(
       key,
       true,
       new Computable<PsiType>() {
         @Override
         public PsiType compute() {
           return doFun(refExpr);
         }
       });
 }
  private Pair<Boolean, GroovyResolveResult[]> resolveByShape(
      boolean allVariants, @Nullable GrExpression upToArgument) {
    if (allVariants) {
      return doResolveByShape(allVariants, upToArgument);
    }

    LOG.assertTrue(upToArgument == null);

    return TypeInferenceHelper.getCurrentContext()
        .getCachedValue(
            this,
            new NullableComputable<Pair<Boolean, GroovyResolveResult[]>>() {
              @Override
              public Pair<Boolean, GroovyResolveResult[]> compute() {
                return doResolveByShape(false, null);
              }
            });
  }
 @NotNull
 private GroovyResolveResult[] doPolyResolveWithCaching(
     final boolean incompleteCode, final boolean genericsMatter) {
   final InferenceContext context = TypeInferenceHelper.getCurrentContext();
   final Trinity<?, ?, ?> key =
       Trinity.create(this, context, Pair.create(incompleteCode, genericsMatter));
   final GroovyResolveResult[] value =
       RecursionManager.doPreventingRecursion(
           key,
           true,
           new Computable<GroovyResolveResult[]>() {
             @Override
             public GroovyResolveResult[] compute() {
               return doPolyResolve(incompleteCode, genericsMatter);
             }
           });
   return value == null ? GroovyResolveResult.EMPTY_ARRAY : value;
 }
 @NotNull
 private Pair<Boolean, GroovyResolveResult[]> resolveByShape(
     final boolean allVariants, @Nullable final GrExpression upToArgument) {
   LOG.assertTrue(allVariants || upToArgument == null);
   final Trinity key =
       Trinity.create(
           TypeInferenceHelper.getCurrentContext(), this, Pair.create(allVariants, upToArgument));
   final Pair<Boolean, GroovyResolveResult[]> result =
       RecursionManager.doPreventingRecursion(
           key,
           true,
           new Computable<Pair<Boolean, GroovyResolveResult[]>>() {
             @Override
             public Pair<Boolean, GroovyResolveResult[]> compute() {
               return doResolveByShape(allVariants, upToArgument);
             }
           });
   return result == null ? Pair.create(false, GroovyResolveResult.EMPTY_ARRAY) : result;
 }
 @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;
 }
 @Override
 public GroovyResolveResult[] resolveByShape() {
   final InferenceContext context = TypeInferenceHelper.getCurrentContext();
   return context.getCachedValue(
       this,
       new Computable<GroovyResolveResult[]>() {
         @Override
         public GroovyResolveResult[] compute() {
           Pair<GrReferenceExpressionImpl, InferenceContext> key =
               Pair.create(GrReferenceExpressionImpl.this, context);
           GroovyResolveResult[] value =
               RecursionManager.doPreventingRecursion(
                   key,
                   true,
                   new Computable<GroovyResolveResult[]>() {
                     @Override
                     public GroovyResolveResult[] compute() {
                       return doPolyResolve(false, false);
                     }
                   });
           return value == null ? GroovyResolveResult.EMPTY_ARRAY : value;
         }
       });
 }
 public PsiType getType() {
   return TypeInferenceHelper.getCurrentContext().getExpressionType(this, TYPES_CALCULATOR);
 }
 @NotNull
 @Override
 public GroovyResolveResult[] multiResolve(boolean incompleteCode) {
   return TypeInferenceHelper.getCurrentContext().multiResolve(this, incompleteCode, OUR_RESOLVER);
 }