Beispiel #1
0
  @Override
  @Nullable
  public Collection<PsiImportStatementBase> findRedundantImports(final PsiJavaFile file) {
    final PsiImportList importList = file.getImportList();
    if (importList == null) return null;
    final PsiImportStatementBase[] imports = importList.getAllImportStatements();
    if (imports.length == 0) return null;

    Set<PsiImportStatementBase> allImports =
        new THashSet<PsiImportStatementBase>(Arrays.asList(imports));
    final Collection<PsiImportStatementBase> redundant;
    if (FileTypeUtils.isInServerPageFile(file)) {
      // remove only duplicate imports
      redundant = ContainerUtil.newIdentityTroveSet();
      ContainerUtil.addAll(redundant, imports);
      redundant.removeAll(allImports);
      for (PsiImportStatementBase importStatement : imports) {
        if (importStatement instanceof JspxImportStatement
            && importStatement.isForeignFileImport()) {
          redundant.remove(importStatement);
        }
      }
    } else {
      redundant = allImports;
      final List<PsiFile> roots = file.getViewProvider().getAllFiles();
      for (PsiElement root : roots) {
        root.accept(
            new JavaRecursiveElementWalkingVisitor() {
              @Override
              public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
                if (!reference.isQualified()) {
                  final JavaResolveResult resolveResult = reference.advancedResolve(false);
                  if (!inTheSamePackage(file, resolveResult.getElement())) {
                    final PsiElement resolveScope = resolveResult.getCurrentFileResolveScope();
                    if (resolveScope instanceof PsiImportStatementBase) {
                      final PsiImportStatementBase importStatementBase =
                          (PsiImportStatementBase) resolveScope;
                      redundant.remove(importStatementBase);
                    }
                  }
                }
                super.visitReferenceElement(reference);
              }

              private boolean inTheSamePackage(PsiJavaFile file, PsiElement element) {
                if (element instanceof PsiClass
                    && ((PsiClass) element).getContainingClass() == null) {
                  final PsiFile containingFile = element.getContainingFile();
                  if (containingFile instanceof PsiJavaFile) {
                    return Comparing.strEqual(
                        file.getPackageName(), ((PsiJavaFile) containingFile).getPackageName());
                  }
                }
                return false;
              }
            });
      }
    }
    return redundant;
  }
 private static PsiImportStatementBase extractImport(
     final PsiJavaFile aFile, final boolean isStatic) {
   final PsiImportList importList = aFile.getImportList();
   assert importList != null : aFile;
   final PsiImportStatementBase[] statements =
       isStatic ? importList.getImportStaticStatements() : importList.getImportStatements();
   assert statements.length == 1 : aFile.getText();
   return statements[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) {
     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 CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
   final PsiElementFactory elementFactory = psiFacade.getElementFactory();
   if (imports.size() < codeStyleSettings.NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND) {
     importList.add(elementFactory.createImportStaticStatement(aClass, memberName));
   } else {
     for (PsiImportStaticStatement importStatement : imports) {
       importStatement.delete();
     }
     importList.add(elementFactory.createImportStaticStatement(aClass, "*"));
   }
   return true;
 }
Beispiel #4
0
 @Override
 public void optimizeImports(@NotNull PsiFile file) throws IncorrectOperationException {
   CheckUtil.checkWritable(file);
   if (file instanceof PsiJavaFile) {
     PsiImportList newList = prepareOptimizeImportsResult((PsiJavaFile) file);
     if (newList != null) {
       final PsiImportList importList = ((PsiJavaFile) file).getImportList();
       if (importList != null) {
         importList.replace(newList);
       }
     }
   }
 }
Beispiel #5
0
 @NotNull
 private File fileToFile(PsiJavaFile javaFile, List<String> additionalImports) {
   PsiImportList importList = javaFile.getImportList();
   List<Import> imports =
       importList == null
           ? Collections.<Import>emptyList()
           : importsToImportList(importList.getAllImportStatements());
   for (String i : additionalImports) imports.add(new Import(i));
   return new File(
       quoteKeywords(javaFile.getPackageName()),
       imports,
       classesToClassList(javaFile.getClasses()),
       createMainFunction(javaFile));
 }
Beispiel #6
0
  public ASTNode getDefaultAnchor(
      @NotNull PsiImportList list, @NotNull PsiImportStatementBase statement) {
    PsiJavaCodeReferenceElement ref = statement.getImportReference();
    if (ref == null) return null;

    int entryIndex = findEntryIndex(statement);
    PsiImportStatementBase[] allStatements = list.getAllImportStatements();
    int[] entries = ArrayUtil.newIntArray(allStatements.length);
    List<PsiImportStatementBase> statements = new ArrayList<PsiImportStatementBase>();
    for (int i = 0; i < allStatements.length; i++) {
      PsiImportStatementBase statement1 = allStatements[i];
      int entryIndex1 = findEntryIndex(statement1);
      entries[i] = entryIndex1;
      if (entryIndex1 == entryIndex) {
        statements.add(statement1);
      }
    }

    if (statements.isEmpty()) {
      int index;
      for (index = entries.length - 1; index >= 0; index--) {
        if (entries[index] < entryIndex) break;
      }
      index++;
      return index < entries.length
          ? SourceTreeToPsiMap.psiElementToTree(allStatements[index])
          : null;
    } else {
      String refText = ref.getCanonicalText();
      if (statement.isOnDemand()) {
        refText += ".";
      }

      PsiImportStatementBase insertBefore = null;
      PsiImportStatementBase insertAfter = null;
      for (PsiImportStatementBase statement1 : statements) {
        PsiJavaCodeReferenceElement ref1 = statement1.getImportReference();
        if (ref1 == null) {
          continue;
        }
        String refTextThis = ref1.getCanonicalText();
        if (statement1.isOnDemand()) {
          refTextThis += ".";
        }

        int comp = Comparing.compare(refText, refTextThis);
        if (comp < 0 && insertBefore == null) {
          insertBefore = statement1;
        }
        if (comp > 0) {
          insertAfter = statement1;
        }
      }

      if (insertBefore != null) return insertBefore.getNode();
      if (insertAfter != null) return insertAfter.getNode().getTreeNext();
      return null;
    }
  }
Beispiel #7
0
 public static boolean isStaticallyImported(
     @NotNull PsiMember member, @NotNull PsiElement context) {
   final PsiClass memberClass = member.getContainingClass();
   if (memberClass == null) {
     return false;
   }
   final PsiClass containingClass = PsiTreeUtil.getParentOfType(context, PsiClass.class);
   if (InheritanceUtil.isInheritorOrSelf(containingClass, memberClass, true)) {
     return false;
   }
   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 String memberName = member.getName();
   if (memberName == null) {
     return false;
   }
   final PsiImportStatementBase existingImportStatement =
       importList.findSingleImportStatement(memberName);
   if (existingImportStatement instanceof PsiImportStaticStatement) {
     final PsiClass importClass =
         ((PsiImportStaticStatement) existingImportStatement).resolveTargetClass();
     if (InheritanceUtil.isInheritorOrSelf(importClass, memberClass, true)) {
       return true;
     }
   }
   final String memberClassName = memberClass.getQualifiedName();
   if (memberClassName == null) {
     return false;
   }
   final PsiImportStaticStatement onDemandImportStatement =
       findOnDemandImportStaticStatement(importList, memberClassName);
   if (onDemandImportStatement != null) {
     if (!hasOnDemandImportStaticConflict(memberClassName, memberName, context)) {
       return true;
     }
   }
   return false;
 }
 /**
  * @param strict if strict is true this method checks if the conflicting class which is imported
  *     is actually used in the file. If it isn't the on demand import can be overridden with an
  *     exact import for the fqName without breaking stuff.
  */
 private static boolean hasOnDemandImportConflict(
     @NotNull String fqName, @NotNull PsiJavaFile file, boolean strict) {
   final PsiImportList imports = file.getImportList();
   if (imports == null) {
     return false;
   }
   final PsiImportStatement[] importStatements = imports.getImportStatements();
   final String shortName = ClassUtil.extractClassName(fqName);
   final String packageName = ClassUtil.extractPackageName(fqName);
   for (final PsiImportStatement importStatement : importStatements) {
     if (!importStatement.isOnDemand()) {
       continue;
     }
     final PsiJavaCodeReferenceElement importReference = importStatement.getImportReference();
     if (importReference == null) {
       continue;
     }
     final String packageText = importReference.getText();
     if (packageText.equals(packageName)) {
       continue;
     }
     final PsiElement element = importReference.resolve();
     if (element == null || !(element instanceof PsiPackage)) {
       continue;
     }
     final PsiPackage aPackage = (PsiPackage) element;
     final PsiClass[] classes = aPackage.getClasses();
     for (final PsiClass aClass : classes) {
       final String className = aClass.getName();
       if (!shortName.equals(className)) {
         continue;
       }
       if (!strict) {
         return true;
       }
       final String qualifiedClassName = aClass.getQualifiedName();
       if (qualifiedClassName == null || fqName.equals(qualifiedClassName)) {
         continue;
       }
       return containsReferenceToConflictingClass(file, qualifiedClassName);
     }
   }
   return hasJavaLangImportConflict(fqName, file);
 }
Beispiel #9
0
 public static void addImportIfNeeded(@NotNull PsiClass aClass, @NotNull PsiElement context) {
   final PsiFile file = context.getContainingFile();
   if (!(file instanceof PsiJavaFile)) {
     return;
   }
   final PsiJavaFile javaFile = (PsiJavaFile) file;
   final PsiClass outerClass = aClass.getContainingClass();
   if (outerClass == null) {
     if (PsiTreeUtil.isAncestor(javaFile, aClass, true)) {
       return;
     }
   } else if (PsiTreeUtil.isAncestor(outerClass, context, true)) {
     final PsiElement brace = outerClass.getLBrace();
     if (brace != null && brace.getTextOffset() < context.getTextOffset()) {
       return;
     }
   }
   final String qualifiedName = aClass.getQualifiedName();
   if (qualifiedName == null) {
     return;
   }
   final PsiImportList importList = javaFile.getImportList();
   if (importList == null) {
     return;
   }
   final String containingPackageName = javaFile.getPackageName();
   @NonNls final String packageName = ClassUtil.extractPackageName(qualifiedName);
   if (containingPackageName.equals(packageName)
       || importList.findSingleClassImportStatement(qualifiedName) != null) {
     return;
   }
   if (importList.findOnDemandImportStatement(packageName) != null
       && !hasDefaultImportConflict(qualifiedName, javaFile)
       && !hasOnDemandImportConflict(qualifiedName, javaFile)) {
     return;
   }
   final Project project = importList.getProject();
   final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
   final PsiElementFactory elementFactory = psiFacade.getElementFactory();
   final PsiImportStatement importStatement = elementFactory.createImportStatement(aClass);
   importList.add(importStatement);
 }
  private void doTestStaticImports(final PsiJavaFile javaFile, boolean okToLoadTree) {
    final PsiImportList importList = javaFile.getImportList();
    final PsiImportStatementBase[] allImportStatements = importList.getAllImportStatements();
    assertEquals(6, allImportStatements.length);
    final PsiImportStatement[] importStatements = importList.getImportStatements();
    assertEquals(2, importStatements.length);
    final PsiImportStaticStatement[] importStaticStatements =
        importList.getImportStaticStatements();
    assertEquals(4, importStaticStatements.length);
    assertFalse(importStatements[0].isOnDemand());
    assertTrue(importStaticStatements[0].isOnDemand());
    assertFalse(importStatements[0].isOnDemand());
    assertTrue(importStaticStatements[1].isOnDemand());
    assertFalse(importStaticStatements[2].isOnDemand());
    assertFalse(importStaticStatements[3].isOnDemand());

    assertEquals("sort", importStaticStatements[2].getReferenceName());
    assertEquals("sort", importStaticStatements[3].getReferenceName());

    final PsiImportStaticStatement classReference1 = importStaticStatements[1];
    final PsiElement element1 = classReference1.resolveTargetClass();
    assertNotNull(element1);
    assertTrue(element1 instanceof PsiClass);
    assertEquals("java.util.Arrays", ((PsiClass) element1).getQualifiedName());

    final PsiImportStaticStatement classReference3 = importStaticStatements[3];
    final PsiElement element3 = classReference3.resolveTargetClass();
    assertNotNull(element3);
    assertTrue(element3 instanceof PsiClass);
    assertEquals("java.util.Arrays", ((PsiClass) element3).getQualifiedName());

    if (okToLoadTree) {
      assertEquals(
          "java.util.Collections", importStaticStatements[0].getImportReference().getText());
      assertEquals("java.util.Arrays", importStaticStatements[1].getImportReference().getText());
      assertEquals(
          "java.util.Collections.sort", importStaticStatements[2].getImportReference().getText());
      assertEquals(
          "java.util.Arrays.sort", importStaticStatements[3].getImportReference().getText());
    }
  }
Beispiel #11
0
 private static boolean hasExactImportConflict(String fqName, PsiJavaFile file) {
   final PsiImportList imports = file.getImportList();
   if (imports == null) {
     return false;
   }
   final PsiImportStatement[] importStatements = imports.getImportStatements();
   final int lastDotIndex = fqName.lastIndexOf((int) '.');
   final String shortName = fqName.substring(lastDotIndex + 1);
   final String dottedShortName = '.' + shortName;
   for (final PsiImportStatement importStatement : importStatements) {
     if (importStatement.isOnDemand()) {
       continue;
     }
     final String importName = importStatement.getQualifiedName();
     if (importName == null) {
       return false;
     }
     if (!importName.equals(fqName) && importName.endsWith(dottedShortName)) {
       return true;
     }
   }
   return false;
 }
Beispiel #12
0
 private static boolean hasExactImportStaticConflict(
     String qualifierClass, String memberName, PsiElement context) {
   final PsiFile file = context.getContainingFile();
   if (!(file instanceof PsiJavaFile)) {
     return false;
   }
   final PsiJavaFile javaFile = (PsiJavaFile) file;
   final PsiImportList importList = javaFile.getImportList();
   if (importList == null) {
     return false;
   }
   final PsiImportStaticStatement[] importStaticStatements =
       importList.getImportStaticStatements();
   for (PsiImportStaticStatement importStaticStatement : importStaticStatements) {
     if (importStaticStatement.isOnDemand()) {
       continue;
     }
     final String name = importStaticStatement.getReferenceName();
     if (!memberName.equals(name)) {
       continue;
     }
     final PsiJavaCodeReferenceElement importReference =
         importStaticStatement.getImportReference();
     if (importReference == null) {
       continue;
     }
     final PsiElement qualifier = importReference.getQualifier();
     if (qualifier == null) {
       continue;
     }
     final String qualifierText = qualifier.getText();
     if (!qualifierClass.equals(qualifierText)) {
       return true;
     }
   }
   return false;
 }
Beispiel #13
0
 private static List<PsiImportStaticStatement> getMatchingImports(
     @NotNull PsiImportList importList, @NotNull String className) {
   final List<PsiImportStaticStatement> imports = new ArrayList();
   for (PsiImportStaticStatement staticStatement : importList.getImportStaticStatements()) {
     final PsiClass psiClass = staticStatement.resolveTargetClass();
     if (psiClass == null) {
       continue;
     }
     if (!className.equals(psiClass.getQualifiedName())) {
       continue;
     }
     imports.add(staticStatement);
   }
   return imports;
 }
Beispiel #14
0
 private static boolean hasOnDemandImportStaticConflict(
     String fqName, String memberName, PsiElement context, boolean strict) {
   final PsiFile file = context.getContainingFile();
   if (!(file instanceof PsiJavaFile)) {
     return false;
   }
   final PsiJavaFile javaFile = (PsiJavaFile) file;
   final PsiImportList importList = javaFile.getImportList();
   if (importList == null) {
     return false;
   }
   final PsiImportStaticStatement[] importStaticStatements =
       importList.getImportStaticStatements();
   for (PsiImportStaticStatement importStaticStatement : importStaticStatements) {
     if (!importStaticStatement.isOnDemand()) {
       continue;
     }
     final PsiClass targetClass = importStaticStatement.resolveTargetClass();
     if (targetClass == null) {
       continue;
     }
     final String name = targetClass.getQualifiedName();
     if (fqName.equals(name)) {
       continue;
     }
     final PsiField field = targetClass.findFieldByName(memberName, true);
     if (field != null && (!strict || memberReferenced(field, javaFile))) {
       return true;
     }
     final PsiMethod[] methods = targetClass.findMethodsByName(memberName, true);
     if (methods.length > 0 && (!strict || membersReferenced(methods, javaFile))) {
       return true;
     }
   }
   return false;
 }
Beispiel #15
0
 @Nullable
 private static PsiImportStaticStatement findOnDemandImportStaticStatement(
     PsiImportList importList, String qualifierClass) {
   final PsiImportStaticStatement[] importStaticStatements =
       importList.getImportStaticStatements();
   for (PsiImportStaticStatement importStaticStatement : importStaticStatements) {
     if (!importStaticStatement.isOnDemand()) {
       continue;
     }
     final PsiJavaCodeReferenceElement importReference =
         importStaticStatement.getImportReference();
     if (importReference == null) {
       continue;
     }
     final String text = importReference.getText();
     if (qualifierClass.equals(text)) {
       return importStaticStatement;
     }
   }
   return null;
 }
Beispiel #16
0
  public PsiImportList prepareOptimizeImportsResult(@NotNull final PsiJavaFile file) {
    CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(file.getProject());

    final Set<String> namesToImportStaticly = new THashSet<String>();
    String[] names =
        collectNamesToImport(
            file,
            namesToImportStaticly); // Note: this array may contain "<packageOrClassName>.*" for
                                    // unresolved imports!
    Arrays.sort(names);

    ArrayList<String> namesList = new ArrayList<String>();
    ImportLayoutTable table = mySettings.IMPORT_LAYOUT_TABLE;
    if (table != null) {
      int[] entriesForName = ArrayUtil.newIntArray(names.length);
      for (int i = 0; i < names.length; i++) {
        entriesForName[i] = findEntryIndex(names[i]);
      }

      Entry[] entries = table.getEntries();
      for (int i = 0; i < entries.length; i++) {
        Entry entry = entries[i];
        if (entry instanceof PackageEntry) {
          for (int j = 0; j < names.length; j++) {
            if (entriesForName[j] == i) {
              namesList.add(names[j]);
              names[j] = null;
            }
          }
        }
      }
    }
    for (String name : names) {
      if (name != null) namesList.add(name);
    }
    names = ArrayUtil.toStringArray(namesList);

    TObjectIntHashMap<String> packageToCountMap = new TObjectIntHashMap<String>();
    TObjectIntHashMap<String> classToCountMap = new TObjectIntHashMap<String>();
    for (String name : names) {
      String packageOrClassName = getPackageOrClassName(name);
      if (packageOrClassName.length() == 0) continue;
      if (namesToImportStaticly.contains(name)) {
        int count = classToCountMap.get(packageOrClassName);
        classToCountMap.put(packageOrClassName, count + 1);
      } else {
        int count = packageToCountMap.get(packageOrClassName);
        packageToCountMap.put(packageOrClassName, count + 1);
      }
    }

    final Set<String> classesOrPackagesToImportOnDemand = new THashSet<String>();
    class MyVisitorProcedure implements TObjectIntProcedure<String> {
      private final boolean myIsVisitingPackages;

      MyVisitorProcedure(boolean isVisitingPackages) {
        myIsVisitingPackages = isVisitingPackages;
      }

      public boolean execute(final String packageOrClassName, final int count) {
        if (isToUseImportOnDemand(packageOrClassName, count, !myIsVisitingPackages)) {
          classesOrPackagesToImportOnDemand.add(packageOrClassName);
        }
        return true;
      }
    }
    classToCountMap.forEachEntry(new MyVisitorProcedure(false));
    packageToCountMap.forEachEntry(new MyVisitorProcedure(true));

    Set<String> classesToUseSingle =
        findSingleImports(file, names, classesOrPackagesToImportOnDemand, namesToImportStaticly);

    try {
      final String text =
          buildImportListText(
              names, classesOrPackagesToImportOnDemand, classesToUseSingle, namesToImportStaticly);
      String ext = StdFileTypes.JAVA.getDefaultExtension();
      final PsiJavaFile dummyFile =
          (PsiJavaFile)
              PsiFileFactory.getInstance(file.getProject())
                  .createFileFromText("_Dummy_." + ext, StdFileTypes.JAVA, text);
      codeStyleManager.reformat(dummyFile);

      PsiImportList resultList = dummyFile.getImportList();
      PsiImportList oldList = file.getImportList();
      if (oldList.isReplaceEquivalent(resultList)) return null;
      return resultList;
    } catch (IncorrectOperationException e) {
      LOG.error(e);
      return null;
    }
  }
  public static void invoke(
      final Project project, PsiFile file, final Editor editor, PsiElement element) {
    if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;

    final PsiJavaCodeReferenceElement refExpr = (PsiJavaCodeReferenceElement) element.getParent();
    final PsiClass aClass = (PsiClass) refExpr.resolve();
    if (aClass == null) {
      return;
    }
    final PsiClass containingClass = PsiUtil.getTopLevelClass(refExpr);
    if (aClass != containingClass) {
      PsiImportList importList = ((PsiJavaFile) file).getImportList();
      if (importList == null) {
        return;
      }
      boolean alreadyImported = false;
      for (PsiImportStaticStatement statement : importList.getImportStaticStatements()) {
        if (!statement.isOnDemand()) continue;
        PsiClass staticResolve = statement.resolveTargetClass();
        if (aClass == staticResolve) {
          alreadyImported = true;
          break;
        }
      }
      if (!alreadyImported) {
        PsiImportStaticStatement importStaticStatement =
            JavaPsiFacade.getInstance(file.getProject())
                .getElementFactory()
                .createImportStaticStatement(aClass, "*");
        importList.add(importStaticStatement);
      }
    }

    List<PsiFile> roots = file.getViewProvider().getAllFiles();
    for (final PsiFile root : roots) {
      PsiElement copy = root.copy();
      final PsiManager manager = root.getManager();

      final TIntArrayList expressionToDequalifyOffsets = new TIntArrayList();
      copy.accept(
          new JavaRecursiveElementWalkingVisitor() {
            int delta;

            @Override
            public void visitReferenceElement(PsiJavaCodeReferenceElement expression) {
              if (isParameterizedReference(expression)) return;
              PsiElement qualifierExpression = expression.getQualifier();
              if (qualifierExpression instanceof PsiJavaCodeReferenceElement
                  && ((PsiJavaCodeReferenceElement) qualifierExpression).isReferenceTo(aClass)) {
                try {
                  PsiElement resolved = expression.resolve();
                  int end = expression.getTextRange().getEndOffset();
                  qualifierExpression.delete();
                  delta += end - expression.getTextRange().getEndOffset();
                  PsiElement after = expression.resolve();
                  if (manager.areElementsEquivalent(after, resolved)) {
                    expressionToDequalifyOffsets.add(
                        expression.getTextRange().getStartOffset() + delta);
                  }
                } catch (IncorrectOperationException e) {
                  LOG.error(e);
                }
              }
              super.visitElement(expression);
            }
          });

      expressionToDequalifyOffsets.forEachDescending(
          new TIntProcedure() {
            @Override
            public boolean execute(int offset) {
              PsiJavaCodeReferenceElement expression =
                  PsiTreeUtil.findElementOfClassAtOffset(
                      root, offset, PsiJavaCodeReferenceElement.class, false);
              if (expression == null) {
                return false;
              }
              PsiElement qualifierExpression = expression.getQualifier();
              if (qualifierExpression instanceof PsiJavaCodeReferenceElement
                  && ((PsiJavaCodeReferenceElement) qualifierExpression).isReferenceTo(aClass)) {
                qualifierExpression.delete();
                if (editor != null) {
                  HighlightManager.getInstance(project)
                      .addRangeHighlight(
                          editor,
                          expression.getTextRange().getStartOffset(),
                          expression.getTextRange().getEndOffset(),
                          EditorColorsManager.getInstance()
                              .getGlobalScheme()
                              .getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES),
                          false,
                          null);
                }
              }

              return true;
            }
          });
    }
  }
Beispiel #18
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;
  }