private static boolean canBePrivate(
      PsiMethod method,
      Collection<PsiReference> references,
      Collection<? extends PsiElement> deleted,
      final PsiElement[] allElementsToDelete) {
    final PsiClass containingClass = method.getContainingClass();
    if (containingClass == null) {
      return false;
    }

    PsiManager manager = method.getManager();
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
    final PsiElementFactory factory = facade.getElementFactory();
    final PsiModifierList privateModifierList;
    try {
      final PsiMethod newMethod = factory.createMethod("x3", PsiType.VOID);
      privateModifierList = newMethod.getModifierList();
      privateModifierList.setModifierProperty(PsiModifier.PRIVATE, true);
    } catch (IncorrectOperationException e) {
      LOG.assertTrue(false);
      return false;
    }
    for (PsiReference reference : references) {
      final PsiElement element = reference.getElement();
      if (!isInside(element, allElementsToDelete)
          && !isInside(element, deleted)
          && !facade
              .getResolveHelper()
              .isAccessible(method, privateModifierList, element, null, null)) {
        return false;
      }
    }
    return true;
  }
Beispiel #2
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;
  }
  public static Processor<PsiClass> createInheritorsProcessor(
      final PsiElement context,
      final PsiClassType baseType,
      final int arrayDim,
      final boolean getRawSubtypes,
      final Consumer<PsiType> result,
      @NotNull final PsiClass baseClass,
      final PsiSubstitutor baseSubstitutor) {
    final PsiManager manager = context.getManager();
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
    final PsiResolveHelper resolveHelper = facade.getResolveHelper();

    return new Processor<PsiClass>() {
      @Override
      public boolean process(final PsiClass inheritor) {
        ProgressManager.checkCanceled();

        return ApplicationManager.getApplication()
            .runReadAction(
                new Computable<Boolean>() {
                  @Override
                  public Boolean compute() {
                    if (!context.isValid()
                        || !inheritor.isValid()
                        || !facade.getResolveHelper().isAccessible(inheritor, context, null))
                      return true;

                    if (inheritor.getQualifiedName() == null
                        && !manager.areElementsEquivalent(
                            inheritor.getContainingFile(),
                            context.getContainingFile().getOriginalFile())) {
                      return true;
                    }

                    if (JavaCompletionUtil.isInExcludedPackage(inheritor, false)) return true;

                    PsiSubstitutor superSubstitutor =
                        TypeConversionUtil.getClassSubstitutor(
                            baseClass, inheritor, PsiSubstitutor.EMPTY);
                    if (superSubstitutor == null) return true;
                    if (getRawSubtypes) {
                      result.consume(
                          createType(
                              inheritor,
                              facade.getElementFactory().createRawSubstitutor(inheritor),
                              arrayDim));
                      return true;
                    }

                    PsiSubstitutor inheritorSubstitutor = PsiSubstitutor.EMPTY;
                    for (PsiTypeParameter inheritorParameter :
                        PsiUtil.typeParametersIterable(inheritor)) {
                      for (PsiTypeParameter baseParameter :
                          PsiUtil.typeParametersIterable(baseClass)) {
                        final PsiType substituted = superSubstitutor.substitute(baseParameter);
                        PsiType arg = baseSubstitutor.substitute(baseParameter);
                        if (arg instanceof PsiWildcardType) {
                          PsiType bound = ((PsiWildcardType) arg).getBound();
                          arg = bound != null ? bound : ((PsiWildcardType) arg).getExtendsBound();
                        }
                        PsiType substitution =
                            resolveHelper.getSubstitutionForTypeParameter(
                                inheritorParameter,
                                substituted,
                                arg,
                                true,
                                PsiUtil.getLanguageLevel(context));
                        if (PsiType.NULL.equals(substitution)
                            || substitution instanceof PsiWildcardType) continue;
                        if (substitution == null) {
                          result.consume(
                              createType(
                                  inheritor,
                                  facade.getElementFactory().createRawSubstitutor(inheritor),
                                  arrayDim));
                          return true;
                        }
                        inheritorSubstitutor =
                            inheritorSubstitutor.put(inheritorParameter, substitution);
                        break;
                      }
                    }

                    PsiType toAdd = createType(inheritor, inheritorSubstitutor, arrayDim);
                    if (baseType.isAssignableFrom(toAdd)) {
                      result.consume(toAdd);
                    }
                    return true;
                  }
                })
            .booleanValue();
      }
    };
  }