@Nullable
 public static PsiClass getBaseClass(GrTypeDefinition grType) {
   if (grType.isEnum()) {
     return JavaPsiFacade.getInstance(grType.getProject())
         .findClass(CommonClassNames.JAVA_LANG_ENUM, grType.getResolveScope());
   } else {
     return JavaPsiFacade.getInstance(grType.getProject())
         .findClass(CommonClassNames.JAVA_LANG_OBJECT, grType.getResolveScope());
   }
 }
  @NotNull
  public static PsiClassType[] getExtendsListTypes(GrTypeDefinition grType) {
    final PsiClassType[] extendsTypes = getReferenceListTypes(grType.getExtendsClause());
    if (grType.isInterface()) {
      return extendsTypes;
    }

    for (PsiClassType type : extendsTypes) {
      final PsiClass superClass = type.resolve();
      if (superClass instanceof GrTypeDefinition && !superClass.isInterface()
          || superClass != null
              && GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT.equals(
                  superClass.getQualifiedName())) {
        return extendsTypes;
      }
    }

    PsiClass grObSupport =
        GroovyPsiManager.getInstance(grType.getProject())
            .findClassWithCache(
                GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT, grType.getResolveScope());
    if (grObSupport != null) {
      final PsiClassType type =
          JavaPsiFacade.getInstance(grType.getProject())
              .getElementFactory()
              .createType(grObSupport);
      return ArrayUtil.append(extendsTypes, type, PsiClassType.ARRAY_FACTORY);
    }
    return extendsTypes;
  }
  public static boolean processDeclarations(
      @NotNull GrTypeDefinition grType,
      @NotNull PsiScopeProcessor processor,
      @NotNull ResolveState state,
      @Nullable PsiElement lastParent,
      @NotNull PsiElement place) {
    if (place instanceof GrCodeReferenceElement && lastParent instanceof GrModifierList) {
      final PsiElement possibleAnnotation =
          PsiTreeUtil.skipParentsOfType(place, GrCodeReferenceElement.class);
      if (possibleAnnotation instanceof GrAnnotation
          && possibleAnnotation.getParent() == lastParent) {
        return true; // don't process class members while resolving annotation which annotates
                     // current class
      }
    }

    for (final PsiTypeParameter typeParameter : grType.getTypeParameters()) {
      if (!processElement(processor, typeParameter, state)) return false;
    }

    NameHint nameHint = processor.getHint(NameHint.KEY);
    String name = nameHint == null ? null : nameHint.getName(state);
    ClassHint classHint = processor.getHint(ClassHint.KEY);
    final PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY);
    final PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getProject());

    boolean processInstanceMethods =
        (shouldProcessMethods(classHint) || shouldProcessProperties(classHint))
            && shouldProcessInstanceMembers(grType, lastParent);

    LanguageLevel level = PsiUtil.getLanguageLevel(place);
    if (shouldProcessProperties(classHint)) {
      Map<String, CandidateInfo> fieldsMap = CollectClassMembersUtil.getAllFields(grType);
      if (name != null) {
        CandidateInfo fieldInfo = fieldsMap.get(name);
        if (fieldInfo != null) {
          if (!processField(
              grType,
              processor,
              state,
              place,
              processInstanceMethods,
              substitutor,
              factory,
              level,
              fieldInfo)) {
            return false;
          }
        } else if (grType.isTrait() && lastParent != null) {
          PsiField field = findFieldByName(grType, name, false, true);
          if (field != null && field.hasModifierProperty(PsiModifier.PUBLIC)) {
            if (!processField(
                grType,
                processor,
                state,
                place,
                processInstanceMethods,
                substitutor,
                factory,
                level,
                new CandidateInfo(field, PsiSubstitutor.EMPTY))) {
              return false;
            }
          }
        }
      } else {
        for (CandidateInfo info : fieldsMap.values()) {
          if (!processField(
              grType,
              processor,
              state,
              place,
              processInstanceMethods,
              substitutor,
              factory,
              level,
              info)) {
            return false;
          }
        }
        if (grType.isTrait() && lastParent != null) {
          for (PsiField field : CollectClassMembersUtil.getFields(grType, true)) {
            if (field.hasModifierProperty(PsiModifier.PUBLIC)) {
              if (!processField(
                  grType,
                  processor,
                  state,
                  place,
                  processInstanceMethods,
                  substitutor,
                  factory,
                  level,
                  new CandidateInfo(field, PsiSubstitutor.EMPTY))) {
                return false;
              }
            }
          }
        }
      }
    }

    if (shouldProcessMethods(classHint)) {
      Map<String, List<CandidateInfo>> methodsMap =
          CollectClassMembersUtil.getAllMethods(grType, true);
      boolean isPlaceGroovy = place.getLanguage() == GroovyFileType.GROOVY_LANGUAGE;
      if (name == null) {
        for (List<CandidateInfo> list : methodsMap.values()) {
          for (CandidateInfo info : list) {
            if (!processMethod(
                grType,
                processor,
                state,
                place,
                processInstanceMethods,
                substitutor,
                factory,
                level,
                isPlaceGroovy,
                info)) {
              return false;
            }
          }
        }
      } else {
        List<CandidateInfo> byName = methodsMap.get(name);
        if (byName != null) {
          for (CandidateInfo info : byName) {
            if (!processMethod(
                grType,
                processor,
                state,
                place,
                processInstanceMethods,
                substitutor,
                factory,
                level,
                isPlaceGroovy,
                info)) {
              return false;
            }
          }
        }
      }
    }

    final GrTypeDefinitionBody body = grType.getBody();
    if (body != null) {
      if (shouldProcessClasses(classHint)) {
        for (PsiClass innerClass : getInnerClassesForResolve(grType, lastParent, place)) {
          final String innerClassName = innerClass.getName();
          if (nameHint != null && !innerClassName.equals(nameHint.getName(state))) {
            continue;
          }

          if (!processor.execute(innerClass, state)) {
            return false;
          }
        }
      }
    }

    return true;
  }