@NotNull
 private static List<PsiMethod> findMethodsBySignature(
     @NotNull PsiClass aClass,
     @NotNull PsiMethod patternMethod,
     boolean checkBases,
     boolean stopOnFirst) {
   final PsiMethod[] methodsByName = aClass.findMethodsByName(patternMethod.getName(), checkBases);
   if (methodsByName.length == 0) return Collections.emptyList();
   final List<PsiMethod> methods = new SmartList<PsiMethod>();
   final MethodSignature patternSignature = patternMethod.getSignature(PsiSubstitutor.EMPTY);
   for (final PsiMethod method : methodsByName) {
     final PsiClass superClass = method.getContainingClass();
     final PsiSubstitutor substitutor;
     if (checkBases && !aClass.equals(superClass)) {
       substitutor =
           TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY);
     } else {
       substitutor = PsiSubstitutor.EMPTY;
     }
     final MethodSignature signature = method.getSignature(substitutor);
     if (signature.equals(patternSignature)) {
       methods.add(method);
       if (stopOnFirst) {
         break;
       }
     }
   }
   return methods;
 }
  @NotNull
  private static List<PsiMember> findByMap(
      @NotNull PsiClass aClass, String name, boolean checkBases, @NotNull MemberType type) {
    if (name == null) return Collections.emptyList();

    if (checkBases) {
      Map<String, List<Pair<PsiMember, PsiSubstitutor>>> allMethodsMap = getMap(aClass, type);
      List<Pair<PsiMember, PsiSubstitutor>> list = allMethodsMap.get(name);
      if (list == null) return Collections.emptyList();
      List<PsiMember> ret = new ArrayList<PsiMember>(list.size());
      for (final Pair<PsiMember, PsiSubstitutor> info : list) {
        ret.add(info.getFirst());
      }

      return ret;
    } else {
      PsiMember[] members = null;
      switch (type) {
        case METHOD:
          members = aClass.getMethods();
          break;
        case CLASS:
          members = aClass.getInnerClasses();
          break;
        case FIELD:
          members = aClass.getFields();
          break;
      }

      List<PsiMember> list = new ArrayList<PsiMember>();
      for (PsiMember member : members) {
        if (name.equals(member.getName())) {
          list.add(member);
        }
      }
      return list;
    }
  }
Пример #3
0
 private static Collection<String> extractAnnotationValuesFromJavaDoc(
     PsiDocTag tag, String parameter) {
   if (tag == null) return Collections.emptyList();
   Collection<String> results = new ArrayList<>();
   Matcher matcher =
       Pattern.compile("\\@testng.test(?:.*)" + parameter + "\\s*=\\s*\"(.*?)\".*")
           .matcher(tag.getText());
   if (matcher.matches()) {
     String[] groups = matcher.group(1).split("[,\\s]");
     for (String group : groups) {
       final String trimmed = group.trim();
       if (trimmed.length() > 0) {
         results.add(trimmed);
       }
     }
   }
   return results;
 }
 @NotNull
 public static List<Pair<PsiMethod, PsiSubstitutor>> findMethodsAndTheirSubstitutorsByName(
     @NotNull PsiClass psiClass, String name, boolean checkBases) {
   if (!checkBases) {
     final PsiMethod[] methodsByName = psiClass.findMethodsByName(name, false);
     final List<Pair<PsiMethod, PsiSubstitutor>> ret =
         new ArrayList<Pair<PsiMethod, PsiSubstitutor>>(methodsByName.length);
     for (final PsiMethod method : methodsByName) {
       ret.add(new Pair<PsiMethod, PsiSubstitutor>(method, PsiSubstitutor.EMPTY));
     }
     return ret;
   }
   Map<String, List<Pair<PsiMember, PsiSubstitutor>>> map = getMap(psiClass, MemberType.METHOD);
   @SuppressWarnings("unchecked")
   List<Pair<PsiMethod, PsiSubstitutor>> list = (List) map.get(name);
   return list == null
       ? Collections.<Pair<PsiMethod, PsiSubstitutor>>emptyList()
       : Collections.unmodifiableList(list);
 }
/** @author max Date: Oct 21, 2001 */
public class RefMethodImpl extends RefJavaElementImpl implements RefMethod {
  private static final List<RefMethod> EMPTY_METHOD_LIST = Collections.emptyList();
  private static final RefParameter[] EMPTY_PARAMS_ARRAY = new RefParameter[0];

  private static final int IS_APPMAIN_MASK = 0x10000;
  private static final int IS_LIBRARY_OVERRIDE_MASK = 0x20000;
  private static final int IS_CONSTRUCTOR_MASK = 0x40000;
  private static final int IS_ABSTRACT_MASK = 0x80000;
  private static final int IS_BODY_EMPTY_MASK = 0x100000;
  private static final int IS_ONLY_CALLS_SUPER_MASK = 0x200000;
  private static final int IS_RETURN_VALUE_USED_MASK = 0x400000;

  private static final int IS_TEST_METHOD_MASK = 0x4000000;
  private static final int IS_CALLED_ON_SUBCLASS_MASK = 0x8000000;

  private static final String RETURN_VALUE_UNDEFINED = "#";

  private List<RefMethod> mySuperMethods;
  private List<RefMethod> myDerivedMethods;
  private List<String> myUnThrownExceptions;

  private RefParameter[] myParameters;
  private String myReturnValueTemplate;
  protected final RefClass myOwnerClass;

  RefMethodImpl(@NotNull RefClass ownerClass, PsiMethod method, RefManager manager) {
    super(method, manager);

    ((RefClassImpl) ownerClass).add(this);

    myOwnerClass = ownerClass;
  }

  // To be used only from RefImplicitConstructor.
  protected RefMethodImpl(@NotNull String name, @NotNull RefClass ownerClass) {
    super(name, ownerClass);
    myOwnerClass = ownerClass;
    ((RefClassImpl) ownerClass).add(this);

    addOutReference(getOwnerClass());
    ((RefClassImpl) getOwnerClass()).addInReference(this);

    setConstructor(true);
  }

  @Override
  public void add(@NotNull RefEntity child) {
    if (child instanceof RefParameter) {
      return;
    }
    super.add(child);
  }

  @Override
  public List<RefEntity> getChildren() {
    List<RefEntity> superChildren = super.getChildren();
    if (myParameters == null) return superChildren;
    if (superChildren == null || superChildren.isEmpty())
      return Arrays.<RefEntity>asList(myParameters);

    List<RefEntity> allChildren =
        new ArrayList<RefEntity>(superChildren.size() + myParameters.length);
    allChildren.addAll(superChildren);
    Collections.addAll(allChildren, myParameters);
    return allChildren;
  }

  @Override
  protected void initialize() {
    final PsiMethod method = (PsiMethod) getElement();
    LOG.assertTrue(method != null);
    setConstructor(method.isConstructor());
    final PsiType returnType = method.getReturnType();
    setFlag(
        returnType == null
            || PsiType.VOID.equals(returnType)
            || returnType.equalsToText(CommonClassNames.JAVA_LANG_VOID),
        IS_RETURN_VALUE_USED_MASK);

    if (!isReturnValueUsed()) {
      myReturnValueTemplate = RETURN_VALUE_UNDEFINED;
    }

    if (isConstructor()) {
      addReference(getOwnerClass(), getOwnerClass().getElement(), method, false, true, null);
    }

    if (getOwnerClass().isInterface()) {
      setAbstract(false);
    } else {
      setAbstract(method.hasModifierProperty(PsiModifier.ABSTRACT));
    }

    setAppMain(isAppMain(method, this));
    setLibraryOverride(method.hasModifierProperty(PsiModifier.NATIVE));

    initializeSuperMethods(method);
    if (isExternalOverride()) {
      ((RefClassImpl) getOwnerClass()).addLibraryOverrideMethod(this);
    }

    @NonNls final String name = method.getName();
    if (getOwnerClass().isTestCase() && name.startsWith("test")) {
      setTestMethod(true);
    }

    PsiParameter[] paramList = method.getParameterList().getParameters();
    if (paramList.length > 0) {
      myParameters = new RefParameterImpl[paramList.length];
      for (int i = 0; i < paramList.length; i++) {
        PsiParameter parameter = paramList[i];
        myParameters[i] = getRefJavaManager().getParameterReference(parameter, i);
      }
    }

    if (method.hasModifierProperty(PsiModifier.NATIVE)) {
      updateReturnValueTemplate(null);
      updateThrowsList(null);
    }
    collectUncaughtExceptions(method);
  }

  private static boolean isAppMain(PsiMethod psiMethod, RefMethod refMethod) {
    if (!refMethod.isStatic()) return false;
    if (!PsiType.VOID.equals(psiMethod.getReturnType())) return false;

    PsiMethod appMainPattern = ((RefMethodImpl) refMethod).getRefJavaManager().getAppMainPattern();
    if (MethodSignatureUtil.areSignaturesEqual(psiMethod, appMainPattern)) return true;

    PsiMethod appPremainPattern =
        ((RefMethodImpl) refMethod).getRefJavaManager().getAppPremainPattern();
    if (MethodSignatureUtil.areSignaturesEqual(psiMethod, appPremainPattern)) return true;

    PsiMethod appAgentmainPattern =
        ((RefMethodImpl) refMethod).getRefJavaManager().getAppAgentmainPattern();
    return MethodSignatureUtil.areSignaturesEqual(psiMethod, appAgentmainPattern);
  }

  private void checkForSuperCall(PsiMethod method) {
    if (isConstructor()) {
      PsiCodeBlock body = method.getBody();
      if (body == null) return;
      PsiStatement[] statements = body.getStatements();
      boolean isBaseExplicitlyCalled = false;
      if (statements.length > 0) {
        PsiStatement first = statements[0];
        if (first instanceof PsiExpressionStatement) {
          PsiExpression firstExpression = ((PsiExpressionStatement) first).getExpression();
          if (firstExpression instanceof PsiMethodCallExpression) {
            PsiExpression qualifierExpression =
                ((PsiMethodCallExpression) firstExpression)
                    .getMethodExpression()
                    .getQualifierExpression();
            if (qualifierExpression instanceof PsiReferenceExpression) {
              @NonNls String text = qualifierExpression.getText();
              if ("super".equals(text) || text.equals("this")) {
                isBaseExplicitlyCalled = true;
              }
            }
          }
        }
      }

      if (!isBaseExplicitlyCalled) {
        for (RefClass superClass : getOwnerClass().getBaseClasses()) {
          RefMethodImpl superDefaultConstructor =
              (RefMethodImpl) superClass.getDefaultConstructor();

          if (superDefaultConstructor != null) {
            superDefaultConstructor.addInReference(this);
            addOutReference(superDefaultConstructor);
          }
        }
      }
    }
  }

  @Override
  @NotNull
  public Collection<RefMethod> getSuperMethods() {
    if (mySuperMethods == null) return EMPTY_METHOD_LIST;
    if (mySuperMethods.size() > 10) {
      LOG.info("method: " + getName() + " owner:" + getOwnerClass().getQualifiedName());
    }
    if (getRefManager().isOfflineView()) {
      LOG.debug("Should not traverse graph offline");
    }
    return mySuperMethods;
  }

  @Override
  @NotNull
  public Collection<RefMethod> getDerivedMethods() {
    if (myDerivedMethods == null) return EMPTY_METHOD_LIST;
    return myDerivedMethods;
  }

  @Override
  public boolean isBodyEmpty() {
    return checkFlag(IS_BODY_EMPTY_MASK);
  }

  @Override
  public boolean isOnlyCallsSuper() {
    return checkFlag(IS_ONLY_CALLS_SUPER_MASK);
  }

  @Override
  public boolean hasBody() {
    return !isAbstract() && !getOwnerClass().isInterface() || !isBodyEmpty();
  }

  private void initializeSuperMethods(PsiMethod method) {
    if (getRefManager().isOfflineView()) return;
    for (PsiMethod psiSuperMethod : method.findSuperMethods()) {
      if (getRefManager().belongsToScope(psiSuperMethod)) {
        RefMethodImpl refSuperMethod = (RefMethodImpl) getRefManager().getReference(psiSuperMethod);
        if (refSuperMethod != null) {
          addSuperMethod(refSuperMethod);
          refSuperMethod.markExtended(this);
        }
      } else {
        setLibraryOverride(true);
      }
    }
  }

  public void addSuperMethod(RefMethodImpl refSuperMethod) {
    if (!getSuperMethods().contains(refSuperMethod)
        && !refSuperMethod.getSuperMethods().contains(this)) {
      if (mySuperMethods == null) {
        mySuperMethods = new ArrayList<RefMethod>(1);
      }
      mySuperMethods.add(refSuperMethod);
    }
  }

  public void markExtended(RefMethodImpl method) {
    if (!getDerivedMethods().contains(method) && !method.getDerivedMethods().contains(this)) {
      if (myDerivedMethods == null) {
        myDerivedMethods = new ArrayList<RefMethod>(1);
      }
      myDerivedMethods.add(method);
    }
  }

  @Override
  @NotNull
  public RefParameter[] getParameters() {
    if (myParameters == null) return EMPTY_PARAMS_ARRAY;
    return myParameters;
  }

  @Override
  public void buildReferences() {
    // Work on code block to find what we're referencing...
    PsiMethod method = (PsiMethod) getElement();
    if (method == null) return;
    PsiCodeBlock body = method.getBody();
    final RefJavaUtil refUtil = RefJavaUtil.getInstance();
    refUtil.addReferences(method, this, body);
    refUtil.addReferences(method, this, method.getModifierList());
    checkForSuperCall(method);
    setOnlyCallsSuper(refUtil.isMethodOnlyCallsSuper(method));

    setBodyEmpty(
        isOnlyCallsSuper()
            || !isExternalOverride() && (body == null || body.getStatements().length == 0));

    refUtil.addTypeReference(method, method.getReturnType(), getRefManager(), this);

    for (RefParameter parameter : getParameters()) {
      refUtil.setIsFinal(parameter, parameter.getElement().hasModifierProperty(PsiModifier.FINAL));
    }

    getRefManager().fireBuildReferences(this);
  }

  private void collectUncaughtExceptions(@NotNull PsiMethod method) {
    if (isExternalOverride()) return;
    if (getRefManager().isOfflineView()) return;
    @NonNls final String name = method.getName();
    if (getOwnerClass().isTestCase() && name.startsWith("test")) return;

    if (getSuperMethods().isEmpty()) {
      PsiClassType[] throwsList = method.getThrowsList().getReferencedTypes();
      if (throwsList.length > 0) {
        myUnThrownExceptions =
            throwsList.length == 1
                ? new SmartList<String>()
                : new ArrayList<String>(throwsList.length);
        for (final PsiClassType type : throwsList) {
          PsiClass aClass = type.resolve();
          String fqn = aClass == null ? null : aClass.getQualifiedName();
          if (fqn != null) {
            myUnThrownExceptions.add(fqn);
          }
        }
      }
    }

    final PsiCodeBlock body = method.getBody();
    if (body == null) return;

    final Collection<PsiClassType> exceptionTypes =
        ExceptionUtil.collectUnhandledExceptions(body, method, false);
    for (final PsiClassType exceptionType : exceptionTypes) {
      updateThrowsList(exceptionType);
    }
  }

  public void removeUnThrownExceptions(PsiClass unThrownException) {
    if (myUnThrownExceptions != null) {
      myUnThrownExceptions.remove(unThrownException.getQualifiedName());
    }
  }

  @Override
  public void accept(@NotNull final RefVisitor visitor) {
    if (visitor instanceof RefJavaVisitor) {
      ApplicationManager.getApplication()
          .runReadAction(
              new Runnable() {
                @Override
                public void run() {
                  ((RefJavaVisitor) visitor).visitMethod(RefMethodImpl.this);
                }
              });
    } else {
      super.accept(visitor);
    }
  }

  @Override
  public boolean isExternalOverride() {
    return isLibraryOverride(new HashSet<RefMethod>());
  }

  private boolean isLibraryOverride(@NotNull Collection<RefMethod> processed) {
    if (!processed.add(this)) return false;

    if (checkFlag(IS_LIBRARY_OVERRIDE_MASK)) return true;
    for (RefMethod superMethod : getSuperMethods()) {
      if (((RefMethodImpl) superMethod).isLibraryOverride(processed)) {
        setFlag(true, IS_LIBRARY_OVERRIDE_MASK);
        return true;
      }
    }

    return false;
  }

  @Override
  public boolean isAppMain() {
    return checkFlag(IS_APPMAIN_MASK);
  }

  @Override
  public boolean isAbstract() {
    return checkFlag(IS_ABSTRACT_MASK);
  }

  @Override
  public boolean hasSuperMethods() {
    return !getSuperMethods().isEmpty() || isExternalOverride();
  }

  @Override
  public boolean isReferenced() {
    // Directly called from somewhere..
    for (RefElement refCaller : getInReferences()) {
      if (!getDerivedMethods().contains(refCaller)) return true;
    }

    // Library override probably called from library code.
    return isExternalOverride();
  }

  @Override
  public boolean hasSuspiciousCallers() {
    // Directly called from somewhere..
    for (RefElement refCaller : getInReferences()) {
      if (((RefElementImpl) refCaller).isSuspicious() && !getDerivedMethods().contains(refCaller))
        return true;
    }

    // Library override probably called from library code.
    if (isExternalOverride()) return true;

    // Class isn't instantiated. Most probably we have problem with class, not method.
    if (!isStatic() && !isConstructor()) {
      if (((RefClassImpl) getOwnerClass()).isSuspicious()) return true;

      // Is an override. Probably called via reference to base class.
      for (RefMethod refSuper : getSuperMethods()) {
        if (((RefMethodImpl) refSuper).isSuspicious()) return true;
      }
    }

    return false;
  }

  @Override
  public boolean isConstructor() {
    return checkFlag(IS_CONSTRUCTOR_MASK);
  }

  @Override
  public RefClass getOwnerClass() {
    return (RefClass) getOwner();
  }

  @NotNull
  @Override
  public String getName() {
    if (isValid()) {
      final String[] result = new String[1];
      final Runnable runnable =
          new Runnable() {
            @Override
            public void run() {
              PsiMethod psiMethod = (PsiMethod) getElement();
              if (psiMethod instanceof SyntheticElement) {
                result[0] = psiMethod.getName();
              } else {
                result[0] =
                    PsiFormatUtil.formatMethod(
                        psiMethod,
                        PsiSubstitutor.EMPTY,
                        PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS,
                        PsiFormatUtilBase.SHOW_TYPE);
              }
            }
          };

      ApplicationManager.getApplication().runReadAction(runnable);

      return result[0];
    } else {
      return super.getName();
    }
  }

  @Override
  public String getExternalName() {
    final String[] result = new String[1];
    final Runnable runnable =
        new Runnable() {
          @Override
          public void run() {
            final PsiMethod psiMethod = (PsiMethod) getElement();
            LOG.assertTrue(psiMethod != null);
            result[0] = PsiFormatUtil.getExternalName(psiMethod, true, Integer.MAX_VALUE);
          }
        };

    ApplicationManager.getApplication().runReadAction(runnable);

    return result[0];
  }

  @Nullable
  public static RefMethod methodFromExternalName(RefManager manager, String externalName) {
    return (RefMethod)
        manager.getReference(
            findPsiMethod(PsiManager.getInstance(manager.getProject()), externalName));
  }

  @Nullable
  public static PsiMethod findPsiMethod(PsiManager manager, String externalName) {
    final int spaceIdx = externalName.indexOf(' ');
    final String className = externalName.substring(0, spaceIdx);
    final PsiClass psiClass = ClassUtil.findPsiClass(manager, className);
    if (psiClass == null) return null;
    try {
      PsiElementFactory factory =
          JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory();
      String methodSignature = externalName.substring(spaceIdx + 1);
      PsiMethod patternMethod = factory.createMethodFromText(methodSignature, psiClass);
      return psiClass.findMethodBySignature(patternMethod, false);
    } catch (IncorrectOperationException e) {
      // Do nothing. Returning null is acceptable in this case.
      return null;
    }
  }

  @Override
  public void referenceRemoved() {
    if (getOwnerClass() != null) {
      ((RefClassImpl) getOwnerClass()).methodRemoved(this);
    }

    super.referenceRemoved();

    for (RefMethod superMethod : getSuperMethods()) {
      superMethod.getDerivedMethods().remove(this);
    }

    for (RefMethod subMethod : getDerivedMethods()) {
      subMethod.getSuperMethods().remove(this);
    }

    ArrayList<RefElement> deletedRefs = new ArrayList<RefElement>();
    for (RefParameter parameter : getParameters()) {
      getRefManager().removeRefElement(parameter, deletedRefs);
    }
  }

  @Override
  public boolean isSuspicious() {
    if (isConstructor()
        && PsiModifier.PRIVATE.equals(getAccessModifier())
        && getParameters().length == 0
        && getOwnerClass().getConstructors().size() == 1) return false;
    return super.isSuspicious();
  }

  public void setReturnValueUsed(boolean value) {
    if (checkFlag(IS_RETURN_VALUE_USED_MASK) == value) return;
    setFlag(value, IS_RETURN_VALUE_USED_MASK);
    for (RefMethod refSuper : getSuperMethods()) {
      ((RefMethodImpl) refSuper).setReturnValueUsed(value);
    }
  }

  @Override
  public boolean isReturnValueUsed() {
    return checkFlag(IS_RETURN_VALUE_USED_MASK);
  }

  public void updateReturnValueTemplate(PsiExpression expression) {
    if (myReturnValueTemplate == null) return;

    if (!getSuperMethods().isEmpty()) {
      for (final RefMethod refMethod : getSuperMethods()) {
        RefMethodImpl refSuper = (RefMethodImpl) refMethod;
        refSuper.updateReturnValueTemplate(expression);
      }
    } else {
      String newTemplate = null;
      final RefJavaUtil refUtil = RefJavaUtil.getInstance();
      if (expression instanceof PsiLiteralExpression) {
        PsiLiteralExpression psiLiteralExpression = (PsiLiteralExpression) expression;
        newTemplate = psiLiteralExpression.getText();
      } else if (expression instanceof PsiReferenceExpression) {
        PsiReferenceExpression referenceExpression = (PsiReferenceExpression) expression;
        PsiElement resolved = referenceExpression.resolve();
        if (resolved instanceof PsiField) {
          PsiField psiField = (PsiField) resolved;
          if (psiField.hasModifierProperty(PsiModifier.STATIC)
              && psiField.hasModifierProperty(PsiModifier.FINAL)
              && refUtil.compareAccess(refUtil.getAccessModifier(psiField), getAccessModifier())
                  >= 0) {
            newTemplate =
                PsiFormatUtil.formatVariable(
                    psiField,
                    PsiFormatUtilBase.SHOW_NAME
                        | PsiFormatUtilBase.SHOW_CONTAINING_CLASS
                        | PsiFormatUtilBase.SHOW_FQ_NAME,
                    PsiSubstitutor.EMPTY);
          }
        }
      } else if (refUtil.isCallToSuperMethod(expression, (PsiMethod) getElement())) return;

      //noinspection StringEquality
      if (myReturnValueTemplate == RETURN_VALUE_UNDEFINED) {
        myReturnValueTemplate = newTemplate;
      } else if (!Comparing.equal(myReturnValueTemplate, newTemplate)) {
        myReturnValueTemplate = null;
      }
    }
  }

  public void updateParameterValues(PsiExpression[] args) {
    if (isExternalOverride()) return;

    if (!getSuperMethods().isEmpty()) {
      for (RefMethod refSuper : getSuperMethods()) {
        ((RefMethodImpl) refSuper).updateParameterValues(args);
      }
    } else {
      final RefParameter[] params = getParameters();
      if (params.length <= args.length && params.length > 0) {
        for (int i = 0; i < args.length; i++) {
          RefParameter refParameter;
          if (params.length <= i) {
            refParameter = params[params.length - 1];
          } else {
            refParameter = params[i];
          }
          ((RefParameterImpl) refParameter).updateTemplateValue(args[i]);
        }
      }
    }
  }

  @Override
  public String getReturnValueIfSame() {
    //noinspection StringEquality
    if (myReturnValueTemplate == RETURN_VALUE_UNDEFINED) return null;
    return myReturnValueTemplate;
  }

  public void updateThrowsList(PsiClassType exceptionType) {
    if (!getSuperMethods().isEmpty()) {
      for (RefMethod refSuper : getSuperMethods()) {
        ((RefMethodImpl) refSuper).updateThrowsList(exceptionType);
      }
    } else if (myUnThrownExceptions != null) {
      if (exceptionType == null) {
        myUnThrownExceptions = null;
        return;
      }
      PsiClass exceptionClass = exceptionType.resolve();
      JavaPsiFacade facade = JavaPsiFacade.getInstance(myManager.getProject());
      for (int i = myUnThrownExceptions.size() - 1; i >= 0; i--) {
        String exceptionFqn = myUnThrownExceptions.get(i);
        PsiClass classType =
            facade.findClass(
                exceptionFqn, GlobalSearchScope.allScope(getRefManager().getProject()));
        if (InheritanceUtil.isInheritorOrSelf(exceptionClass, classType, true)
            || InheritanceUtil.isInheritorOrSelf(classType, exceptionClass, true)) {
          myUnThrownExceptions.remove(i);
        }
      }

      if (myUnThrownExceptions.isEmpty()) myUnThrownExceptions = null;
    }
  }

  @Override
  @Nullable
  public PsiClass[] getUnThrownExceptions() {
    if (getRefManager().isOfflineView()) {
      LOG.debug("Should not traverse graph offline");
    }
    if (myUnThrownExceptions == null) return null;
    JavaPsiFacade facade = JavaPsiFacade.getInstance(myManager.getProject());
    List<PsiClass> result = new ArrayList<PsiClass>(myUnThrownExceptions.size());
    for (String exception : myUnThrownExceptions) {
      PsiClass element =
          facade.findClass(exception, GlobalSearchScope.allScope(myManager.getProject()));
      if (element != null) result.add(element);
    }
    return result.toArray(new PsiClass[result.size()]);
  }

  public void setLibraryOverride(boolean libraryOverride) {
    setFlag(libraryOverride, IS_LIBRARY_OVERRIDE_MASK);
  }

  private void setAppMain(boolean appMain) {
    setFlag(appMain, IS_APPMAIN_MASK);
  }

  private void setAbstract(boolean anAbstract) {
    setFlag(anAbstract, IS_ABSTRACT_MASK);
  }

  public void setBodyEmpty(boolean bodyEmpty) {
    setFlag(bodyEmpty, IS_BODY_EMPTY_MASK);
  }

  private void setOnlyCallsSuper(boolean onlyCallsSuper) {
    setFlag(onlyCallsSuper, IS_ONLY_CALLS_SUPER_MASK);
  }

  private void setConstructor(boolean constructor) {
    setFlag(constructor, IS_CONSTRUCTOR_MASK);
  }

  @Override
  public boolean isTestMethod() {
    return checkFlag(IS_TEST_METHOD_MASK);
  }

  private void setTestMethod(boolean testMethod) {
    setFlag(testMethod, IS_TEST_METHOD_MASK);
  }

  @Override
  public PsiModifierListOwner getElement() {
    return (PsiModifierListOwner) super.getElement();
  }

  @Override
  public boolean isCalledOnSubClass() {
    return checkFlag(IS_CALLED_ON_SUBCLASS_MASK);
  }

  public void setCalledOnSubClass(boolean isCalledOnSubClass) {
    setFlag(isCalledOnSubClass, IS_CALLED_ON_SUBCLASS_MASK);
  }
}
 @NotNull
 public static List<MethodSignatureBackedByPsiMethod> findSuperMethodSignaturesIncludingStatic(
     PsiMethod method, boolean checkAccess) {
   if (!canHaveSuperMethod(method, checkAccess, true)) return Collections.emptyList();
   return findSuperMethodSignatures(method, null, true);
 }