@Nullable
  public static PsiClass getSuperClass(@NotNull PsiClass psiClass) {
    PsiManager manager = psiClass.getManager();
    GlobalSearchScope resolveScope = psiClass.getResolveScope();

    final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
    if (psiClass.isInterface()) {
      return facade.findClass(CommonClassNames.JAVA_LANG_OBJECT, resolveScope);
    }
    if (psiClass.isEnum()) {
      return facade.findClass(CommonClassNames.JAVA_LANG_ENUM, resolveScope);
    }

    if (psiClass instanceof PsiAnonymousClass) {
      PsiClassType baseClassReference = ((PsiAnonymousClass) psiClass).getBaseClassType();
      PsiClass baseClass = baseClassReference.resolve();
      if (baseClass == null || baseClass.isInterface())
        return facade.findClass(CommonClassNames.JAVA_LANG_OBJECT, resolveScope);
      return baseClass;
    }

    if (CommonClassNames.JAVA_LANG_OBJECT.equals(psiClass.getQualifiedName())) return null;

    final PsiClassType[] referenceElements = psiClass.getExtendsListTypes();

    if (referenceElements.length == 0)
      return facade.findClass(CommonClassNames.JAVA_LANG_OBJECT, resolveScope);

    PsiClass psiResoved = referenceElements[0].resolve();
    return psiResoved == null
        ? facade.findClass(CommonClassNames.JAVA_LANG_OBJECT, resolveScope)
        : psiResoved;
  }
  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 testSavedUncommittedDocument() throws IOException {
    VirtualFile dir = getVirtualFile(createTempDirectory());
    PsiTestUtil.addSourceContentToRoots(myModule, dir);

    final VirtualFile vFile = createChildData(dir, "Foo.java");
    VfsUtil.saveText(vFile, "");

    final GlobalSearchScope scope = GlobalSearchScope.allScope(getProject());
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
    assertNull(facade.findClass("Foo", scope));
    WriteCommandAction.runWriteCommandAction(
        null,
        new Runnable() {
          @Override
          public void run() {
            PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(vFile);
            assertNotNull(psiFile);

            long count =
                PsiManager.getInstance(myProject).getModificationTracker().getModificationCount();

            Document document = FileDocumentManager.getInstance().getDocument(vFile);
            document.insertString(0, "class Foo {}");
            FileDocumentManager.getInstance().saveDocument(document);

            assertTrue(
                count
                    == PsiManager.getInstance(myProject)
                        .getModificationTracker()
                        .getModificationCount());
            assertNull(facade.findClass("Foo", scope));

            PsiDocumentManager.getInstance(myProject).commitAllDocuments();
            assertNotNull(facade.findClass("Foo", scope));
            assertNotNull(facade.findClass("Foo", scope).getText());
            // if Foo exists now, mod count should be different
            assertTrue(
                count
                    != PsiManager.getInstance(myProject)
                        .getModificationTracker()
                        .getModificationCount());
          }
        });
  }
  public void testCollectedPsiWithChangedDocument() throws IOException {
    VirtualFile dir = getVirtualFile(createTempDirectory());
    PsiTestUtil.addSourceContentToRoots(myModule, dir);

    final VirtualFile vFile = createChildData(dir, "Foo.java");
    VfsUtil.saveText(vFile, "class Foo {}");

    final GlobalSearchScope scope = GlobalSearchScope.allScope(getProject());
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
    assertNotNull(facade.findClass("Foo", scope));
    WriteCommandAction.runWriteCommandAction(
        null,
        new Runnable() {
          @Override
          public void run() {
            PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(vFile);
            assertNotNull(psiFile);

            Document document = FileDocumentManager.getInstance().getDocument(vFile);
            document.deleteString(0, document.getTextLength());
            assertNotNull(facade.findClass("Foo", scope));

            psiFile = null;
            PlatformTestUtil.tryGcSoftlyReachableObjects();
            assertNull(
                ((PsiManagerEx) PsiManager.getInstance(getProject()))
                    .getFileManager()
                    .getCachedPsiFile(vFile));

            PsiClass foo = facade.findClass("Foo", scope);
            assertNotNull(foo);
            assertTrue(foo.isValid());
            assertEquals("class Foo {}", foo.getText());
            assertTrue(foo.isValid());

            PsiDocumentManager.getInstance(myProject).commitAllDocuments();
            assertNull(facade.findClass("Foo", scope));
          }
        });
  }
Beispiel #6
0
 public static boolean addStaticImport(
     @NotNull String qualifierClass,
     @NonNls @NotNull String memberName,
     @NotNull PsiElement context) {
   if (!nameCanBeStaticallyImported(qualifierClass, memberName, context)) {
     return false;
   }
   final PsiClass containingClass = PsiTreeUtil.getParentOfType(context, PsiClass.class);
   if (InheritanceUtil.isInheritor(containingClass, qualifierClass)) {
     return true;
   }
   final PsiFile psiFile = context.getContainingFile();
   if (!(psiFile instanceof PsiJavaFile)) {
     return false;
   }
   final PsiJavaFile javaFile = (PsiJavaFile) psiFile;
   final PsiImportList importList = javaFile.getImportList();
   if (importList == null) {
     return false;
   }
   final PsiImportStatementBase existingImportStatement =
       importList.findSingleImportStatement(memberName);
   if (existingImportStatement != null) {
     if (existingImportStatement instanceof PsiImportStaticStatement) {
       final PsiImportStaticStatement importStaticStatement =
           (PsiImportStaticStatement) existingImportStatement;
       if (!memberName.equals(importStaticStatement.getReferenceName())) {
         return false;
       }
       final PsiClass targetClass = importStaticStatement.resolveTargetClass();
       return targetClass != null && qualifierClass.equals(targetClass.getQualifiedName());
     }
     return false;
   }
   final PsiImportStaticStatement onDemandImportStatement =
       findOnDemandImportStaticStatement(importList, qualifierClass);
   if (onDemandImportStatement != null
       && !hasOnDemandImportStaticConflict(qualifierClass, memberName, context)) {
     return true;
   }
   final Project project = context.getProject();
   final GlobalSearchScope scope = context.getResolveScope();
   final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
   final PsiClass aClass = psiFacade.findClass(qualifierClass, scope);
   if (aClass == null) {
     return false;
   }
   final String qualifiedName = aClass.getQualifiedName();
   if (qualifiedName == null) {
     return false;
   }
   final List<PsiImportStaticStatement> imports = getMatchingImports(importList, qualifiedName);
   final int onDemandCount =
       JavaCodeStyleSettingsFacade.getInstance(project).getNamesCountToUseImportOnDemand();
   final PsiElementFactory elementFactory = psiFacade.getElementFactory();
   if (imports.size() < onDemandCount) {
     importList.add(elementFactory.createImportStaticStatement(aClass, memberName));
   } else {
     for (PsiImportStaticStatement importStatement : imports) {
       importStatement.delete();
     }
     importList.add(elementFactory.createImportStaticStatement(aClass, "*"));
   }
   return true;
 }
Beispiel #7
0
  /**
   * Adds import if it is needed.
   *
   * @return false when the FQ-name have to be used in code (e.g. when conflicting imports already
   *     exist)
   */
  public boolean addImport(@NotNull PsiJavaFile file, @NotNull PsiClass refClass) {
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(file.getProject());
    PsiElementFactory factory = facade.getElementFactory();
    PsiResolveHelper helper = facade.getResolveHelper();

    String className = refClass.getQualifiedName();
    if (className == null) return true;
    String packageName = getPackageOrClassName(className);
    String shortName = PsiNameHelper.getShortClassName(className);

    PsiClass conflictSingleRef = findSingleImportByShortName(file, shortName);
    if (conflictSingleRef != null) {
      return className.equals(conflictSingleRef.getQualifiedName());
    }

    PsiClass curRefClass = helper.resolveReferencedClass(shortName, file);
    if (file.getManager().areElementsEquivalent(refClass, curRefClass)) {
      return true;
    }

    boolean useOnDemand = true;
    if (packageName.length() == 0) {
      useOnDemand = false;
    }

    PsiElement conflictPackageRef = findImportOnDemand(file, packageName);
    if (conflictPackageRef != null) {
      useOnDemand = false;
    }

    List<PsiElement> classesToReimport = new ArrayList<PsiElement>();

    List<PsiJavaCodeReferenceElement> importRefs = getImportsFromPackage(file, packageName);
    if (useOnDemand) {
      if (mySettings.USE_SINGLE_CLASS_IMPORTS
          && importRefs.size() + 1 < mySettings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND
          && !mySettings.PACKAGES_TO_USE_IMPORT_ON_DEMAND.contains(packageName)) {
        useOnDemand = false;
      }
      // name of class we try to import is the same as of the class defined in this file
      if (curRefClass != null) {
        useOnDemand = true;
      }
      // check conflicts
      if (useOnDemand) {
        PsiElement[] onDemandRefs = file.getOnDemandImports(false, true);
        if (onDemandRefs.length > 0) {
          PsiPackage aPackage = facade.findPackage(packageName);
          if (aPackage != null) {
            PsiDirectory[] dirs = aPackage.getDirectories();
            for (PsiDirectory dir : dirs) {
              PsiFile[] files = dir.getFiles(); // do not iterate classes - too slow when not loaded
              for (PsiFile aFile : files) {
                if (aFile instanceof PsiJavaFile) {
                  String name = aFile.getVirtualFile().getNameWithoutExtension();
                  for (PsiElement ref : onDemandRefs) {
                    String refName =
                        ref instanceof PsiClass
                            ? ((PsiClass) ref).getQualifiedName()
                            : ((PsiPackage) ref).getQualifiedName();
                    String conflictClassName = refName + "." + name;
                    GlobalSearchScope resolveScope = file.getResolveScope();
                    PsiClass conflictClass = facade.findClass(conflictClassName, resolveScope);
                    if (conflictClass != null && helper.isAccessible(conflictClass, file, null)) {
                      String conflictClassName2 = aPackage.getQualifiedName() + "." + name;
                      PsiClass conflictClass2 = facade.findClass(conflictClassName2, resolveScope);
                      if (conflictClass2 != null
                          && helper.isAccessible(conflictClass2, file, null)) {
                        if (ReferencesSearch.search(
                                    conflictClass, new LocalSearchScope(file), false)
                                .findFirst()
                            != null) {
                          classesToReimport.add(conflictClass);
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }

    try {
      PsiImportList importList = file.getImportList();
      PsiImportStatement statement;
      if (useOnDemand) {
        statement = factory.createImportStatementOnDemand(packageName);
      } else {
        statement = factory.createImportStatement(refClass);
      }
      importList.add(statement);
      if (useOnDemand) {
        for (PsiJavaCodeReferenceElement ref : importRefs) {
          LOG.assertTrue(ref.getParent() instanceof PsiImportStatement);
          if (!ref.isValid()) continue; // todo[dsl] Q?
          classesToReimport.add(ref.resolve());
          PsiImportStatement importStatement = (PsiImportStatement) ref.getParent();
          importStatement.delete();
        }
      }

      for (PsiElement aClassesToReimport : classesToReimport) {
        PsiClass aClass = (PsiClass) aClassesToReimport;
        if (aClass != null) {
          addImport(file, aClass);
        }
      }
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
    return true;
  }