private Domination dominates(
      PsiClass aClass, boolean accessible, String fqName, ClassCandidateInfo info) {
    final PsiClass otherClass = info.getElement();
    assert otherClass != null;
    String otherQName = otherClass.getQualifiedName();
    if (fqName.equals(otherQName)) {
      return Domination.DOMINATED_BY;
    }

    final PsiClass containingClass1 = aClass.getContainingClass();
    final PsiClass containingClass2 = otherClass.getContainingClass();
    if (containingClass1 != null
        && containingClass2 != null
        && containingClass2.isInheritor(containingClass1, true)
        && !isImported(myCurrentFileContext)) {
      // shadowing
      return Domination.DOMINATED_BY;
    }

    boolean infoAccessible = info.isAccessible();
    if (infoAccessible && !accessible) {
      return Domination.DOMINATED_BY;
    }
    if (!infoAccessible && accessible) {
      return Domination.DOMINATES;
    }

    // everything wins over class from default package
    boolean isDefault = StringUtil.getPackageName(fqName).length() == 0;
    boolean otherDefault =
        otherQName != null && StringUtil.getPackageName(otherQName).length() == 0;
    if (isDefault && !otherDefault) {
      return Domination.DOMINATED_BY;
    }
    if (!isDefault && otherDefault) {
      return Domination.DOMINATES;
    }

    // single import wins over on-demand
    boolean myOnDemand = isOnDemand(myCurrentFileContext, aClass);
    boolean otherOnDemand = isOnDemand(info.getCurrentFileResolveScope(), otherClass);
    if (myOnDemand && !otherOnDemand) {
      return Domination.DOMINATED_BY;
    }
    if (!myOnDemand && otherOnDemand) {
      return Domination.DOMINATES;
    }

    return Domination.EQUAL;
  }
 private static void generateImportCode(
     StringBuilder imports, String className, Collection<String> customRunners) {
   if (!StringUtil.isEmpty(StringUtil.getPackageName(className))) {
     generateImportCode(imports, className);
   }
   for (String customRunner : customRunners) {
     generateImportCode(imports, customRunner);
   }
 }
Example #3
0
 @Nullable
 public static JetClassOrObject getMainClass(@NotNull JetFile file) {
   List<JetDeclaration> classes =
       ContainerUtil.filter(
           file.getDeclarations(),
           new Condition<JetDeclaration>() {
             @Override
             public boolean value(JetDeclaration jetDeclaration) {
               return jetDeclaration instanceof JetClassOrObject;
             }
           });
   if (classes.size() == 1) {
     if (StringUtil.getPackageName(file.getName()).equals(classes.get(0).getName())) {
       return (JetClassOrObject) classes.get(0);
     }
   }
   return null;
 }
 private void appendClassName(PsiElement declaration) {
   if (declaration instanceof PsiClass) {
     final PsiClass psiClass = (PsiClass) declaration;
     final String ownerClassQN = getTopmostOwnerClassQualifiedName(psiClass);
     if (ownerClassQN != null) {
       appendClassName(ownerClassQN);
       final String ownerClassPackageName = StringUtil.getPackageName(ownerClassQN);
       if (!StringUtil.isEmpty(ownerClassPackageName)) {
         appendDemandedPackageName(ownerClassPackageName);
       }
     } else {
       final String classQN = psiClass.getQualifiedName();
       if (classQN != null) {
         appendClassName(classQN);
       }
     }
   }
 }
  public static boolean isSourceLevelAccessible(
      PsiElement context, PsiClass psiClass, final boolean pkgContext) {
    if (!JavaPsiFacade.getInstance(psiClass.getProject())
        .getResolveHelper()
        .isAccessible(psiClass, context, null)) {
      return false;
    }

    if (pkgContext) {
      PsiClass topLevel = PsiUtil.getTopLevelClass(psiClass);
      if (topLevel != null) {
        String fqName = topLevel.getQualifiedName();
        if (fqName != null && StringUtil.isEmpty(StringUtil.getPackageName(fqName))) {
          return false;
        }
      }
    }

    return true;
  }
  @NotNull
  private PsiClass[] findClassesInDumbMode(
      @NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
    String packageName = StringUtil.getPackageName(qualifiedName);
    PsiJavaPackage pkg = findPackage(packageName, scope);
    String className = StringUtil.getShortName(qualifiedName);
    if (pkg == null && packageName.length() < qualifiedName.length()) {
      PsiClass[] containingClasses = findClassesInDumbMode(packageName, scope);
      if (containingClasses.length == 1) {
        return PsiElementFinder.filterByName(className, containingClasses[0].getInnerClasses());
      }

      return PsiClass.EMPTY_ARRAY;
    }

    if (pkg == null || !pkg.containsClassNamed(className)) {
      return PsiClass.EMPTY_ARRAY;
    }

    return pkg.findClassByShortName(className, scope);
  }
  private boolean isOnDemand(PsiElement fileContext, PsiClass psiClass) {
    if (isImported(fileContext)) {
      return ((PsiImportStatementBase) fileContext).isOnDemand();
    }

    String fqn = psiClass.getQualifiedName();
    if (fqn == null) return false;

    PsiFile file = myPlace == null ? null : FileContextUtil.getContextFile(myPlace);

    String[] defaultPackages =
        file instanceof PsiJavaFile
            ? ((PsiJavaFile) file).getImplicitlyImportedPackages()
            : DEFAULT_PACKAGES;
    String packageName = StringUtil.getPackageName(fqn);
    for (String defaultPackage : defaultPackages) {
      if (defaultPackage.equals(packageName)) return true;
    }

    // class from my package imported implicitly
    return file instanceof PsiJavaFile && ((PsiJavaFile) file).getPackageName().equals(packageName);
  }
 private static void processAvailableTraces(
     RunConfigurationBase configuration, String[] fullTestNames) {
   final String tracesDirectory = getTracesDirectory(configuration);
   final TestDiscoveryIndex coverageIndex =
       TestDiscoveryIndex.getInstance(configuration.getProject());
   synchronized (ourTracesLock) {
     for (String fullTestName : fullTestNames) {
       final String className = StringUtil.getPackageName(fullTestName);
       final String methodName = StringUtil.getShortName(fullTestName);
       if (!StringUtil.isEmptyOrSpaces(className) && !StringUtil.isEmptyOrSpaces(methodName)) {
         final File testMethodTrace =
             new File(tracesDirectory, className + "-" + methodName + ".tr");
         if (testMethodTrace.exists()) {
           try {
             coverageIndex.updateFromTestTrace(testMethodTrace);
             FileUtil.delete(testMethodTrace);
           } catch (IOException e) {
             LOG.error("Can not load " + testMethodTrace, e);
           }
         }
       }
     }
   }
 }
 @NotNull
 public String getDisplayName() {
   final String className = getClassName();
   if (StringUtil.isEmpty(className)) return "<unnamed>";
   MethodInfo singleInfo = null;
   for (MethodInfo info : myParameterMap.values()) {
     if (info.isEnabled()) {
       if (singleInfo == null) {
         singleInfo = info;
       } else {
         singleInfo = null;
         break;
       }
     }
   }
   final String name =
       singleInfo != null
           ? StringUtil.getShortName(className) + "." + singleInfo.methodName
           : StringUtil.getShortName(className);
   return /*"["+getInjectedLanguageId()+"] " +*/ name
       + " ("
       + StringUtil.getPackageName(className)
       + ")";
 }
 public static MultiMap<PsiElement, String> checkConflicts(
     final MemberInfoBase<? extends PsiMember>[] infos,
     @NotNull final PsiClass subclass,
     @Nullable PsiClass superClass,
     @NotNull final PsiPackage targetPackage,
     @NotNull PsiDirectory targetDirectory,
     final InterfaceContainmentVerifier interfaceContainmentVerifier,
     boolean movedMembers2Super) {
   final Set<PsiMember> movedMembers = new HashSet<PsiMember>();
   final Set<PsiMethod> abstractMethods = new HashSet<PsiMethod>();
   final boolean isInterfaceTarget;
   final PsiElement targetRepresentativeElement;
   if (superClass != null) {
     isInterfaceTarget = superClass.isInterface();
     targetRepresentativeElement = superClass;
   } else {
     isInterfaceTarget = false;
     targetRepresentativeElement = targetDirectory;
   }
   for (MemberInfoBase<? extends PsiMember> info : infos) {
     PsiMember member = info.getMember();
     if (member instanceof PsiMethod) {
       if (!info.isToAbstract() && !isInterfaceTarget) {
         movedMembers.add(member);
       } else {
         abstractMethods.add((PsiMethod) member);
       }
     } else {
       movedMembers.add(member);
     }
   }
   final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
   final Set<PsiMethod> abstrMethods = new HashSet<PsiMethod>(abstractMethods);
   if (superClass != null) {
     for (PsiMethod method : subclass.getMethods()) {
       if (!movedMembers.contains(method) && !method.hasModifierProperty(PsiModifier.PRIVATE)) {
         if (method.findSuperMethods(superClass).length > 0) {
           abstrMethods.add(method);
         }
       }
     }
   }
   RefactoringConflictsUtil.analyzeAccessibilityConflicts(
       movedMembers,
       superClass,
       conflicts,
       VisibilityUtil.ESCALATE_VISIBILITY,
       targetRepresentativeElement,
       abstrMethods);
   if (superClass != null) {
     if (movedMembers2Super) {
       checkSuperclassMembers(superClass, infos, conflicts);
       if (isInterfaceTarget) {
         checkInterfaceTarget(infos, conflicts);
       }
     } else {
       final String qualifiedName = superClass.getQualifiedName();
       assert qualifiedName != null;
       if (superClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) {
         if (!Comparing.strEqual(
             StringUtil.getPackageName(qualifiedName), targetPackage.getQualifiedName())) {
           conflicts.putValue(
               superClass,
               RefactoringUIUtil.getDescription(superClass, true)
                   + " won't be accessible from "
                   + RefactoringUIUtil.getDescription(targetPackage, true));
         }
       }
     }
   }
   // check if moved methods use other members in the classes between Subclass and Superclass
   List<PsiElement> checkModuleConflictsList = new ArrayList<PsiElement>();
   for (PsiMember member : movedMembers) {
     if (member instanceof PsiMethod
         || member instanceof PsiClass && !(member instanceof PsiCompiledElement)) {
       ClassMemberReferencesVisitor visitor =
           movedMembers2Super
               ? new ConflictingUsagesOfSubClassMembers(
                   member,
                   movedMembers,
                   abstractMethods,
                   subclass,
                   superClass,
                   superClass != null ? null : targetPackage,
                   conflicts,
                   interfaceContainmentVerifier)
               : new ConflictingUsagesOfSuperClassMembers(
                   member, subclass, targetPackage, movedMembers, conflicts);
       member.accept(visitor);
     }
     ContainerUtil.addIfNotNull(checkModuleConflictsList, member);
   }
   for (final PsiMethod method : abstractMethods) {
     ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getParameterList());
     ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getReturnTypeElement());
     ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getTypeParameterList());
   }
   RefactoringConflictsUtil.analyzeModuleConflicts(
       subclass.getProject(),
       checkModuleConflictsList,
       new UsageInfo[0],
       targetRepresentativeElement,
       conflicts);
   final String fqName = subclass.getQualifiedName();
   final String packageName;
   if (fqName != null) {
     packageName = StringUtil.getPackageName(fqName);
   } else {
     final PsiFile psiFile = PsiTreeUtil.getParentOfType(subclass, PsiFile.class);
     if (psiFile instanceof PsiClassOwner) {
       packageName = ((PsiClassOwner) psiFile).getPackageName();
     } else {
       packageName = null;
     }
   }
   final boolean toDifferentPackage =
       !Comparing.strEqual(targetPackage.getQualifiedName(), packageName);
   for (final PsiMethod abstractMethod : abstractMethods) {
     abstractMethod.accept(
         new ClassMemberReferencesVisitor(subclass) {
           @Override
           protected void visitClassMemberReferenceElement(
               PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) {
             if (classMember != null && willBeMoved(classMember, movedMembers)) {
               boolean isAccessible = false;
               if (classMember.hasModifierProperty(PsiModifier.PRIVATE)) {
                 isAccessible = true;
               } else if (classMember.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)
                   && toDifferentPackage) {
                 isAccessible = true;
               }
               if (isAccessible) {
                 String message =
                     RefactoringUIUtil.getDescription(abstractMethod, false)
                         + " uses "
                         + RefactoringUIUtil.getDescription(classMember, true)
                         + " which won't be accessible from the subclass.";
                 message = CommonRefactoringUtil.capitalize(message);
                 conflicts.putValue(classMember, message);
               }
             }
           }
         });
     if (abstractMethod.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && toDifferentPackage) {
       if (!isInterfaceTarget) {
         String message =
             "Can't make "
                 + RefactoringUIUtil.getDescription(abstractMethod, false)
                 + " abstract as it won't be accessible from the subclass.";
         message = CommonRefactoringUtil.capitalize(message);
         conflicts.putValue(abstractMethod, message);
       }
     }
   }
   return conflicts;
 }
  private void buildText(
      @NotNull PsiClass aClass,
      @NotNull PsiSubstitutor substitutor,
      @NotNull StringBuilder buffer,
      @NotNull TextType textType,
      boolean annotated) {
    if (aClass instanceof PsiAnonymousClass) {
      ClassResolveResult baseResolveResult =
          ((PsiAnonymousClass) aClass).getBaseClassType().resolveGenerics();
      PsiClass baseClass = baseResolveResult.getElement();
      if (baseClass != null) {
        buildText(baseClass, baseResolveResult.getSubstitutor(), buffer, textType, false);
      }
      return;
    }

    boolean qualified = textType != TextType.PRESENTABLE;

    PsiClass enclosingClass = null;
    if (!aClass.hasModifierProperty(PsiModifier.STATIC)) {
      PsiElement parent = aClass.getParent();
      if (parent instanceof PsiClass && !(parent instanceof PsiAnonymousClass)) {
        enclosingClass = (PsiClass) parent;
      }
    }
    if (enclosingClass != null) {
      buildText(enclosingClass, substitutor, buffer, textType, false);
      buffer.append('.');
    } else if (qualified) {
      String fqn = aClass.getQualifiedName();
      if (fqn != null) {
        String prefix = StringUtil.getPackageName(fqn);
        if (!StringUtil.isEmpty(prefix)) {
          buffer.append(prefix);
          buffer.append('.');
        }
      }
    }

    if (annotated) {
      PsiNameHelper.appendAnnotations(buffer, getAnnotations(), qualified);
    }

    buffer.append(aClass.getName());

    PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
    if (typeParameters.length > 0) {
      int pos = buffer.length();
      buffer.append('<');

      for (int i = 0; i < typeParameters.length; i++) {
        PsiTypeParameter typeParameter = typeParameters[i];
        PsiUtilCore.ensureValid(typeParameter);

        if (i > 0) {
          buffer.append(',');
          if (textType == TextType.PRESENTABLE) buffer.append(' ');
        }

        PsiType substitutionResult = substitutor.substitute(typeParameter);
        if (substitutionResult == null) {
          buffer.setLength(pos);
          pos = -1;
          break;
        }
        PsiUtil.ensureValidType(substitutionResult);

        if (textType == TextType.PRESENTABLE) {
          buffer.append(substitutionResult.getPresentableText());
        } else if (textType == TextType.CANONICAL) {
          buffer.append(substitutionResult.getCanonicalText(annotated));
        } else {
          buffer.append(substitutionResult.getInternalCanonicalText());
        }
      }

      if (pos >= 0) {
        buffer.append('>');
      }
    }
  }
  private Domination dominates(
      PsiClass aClass, boolean accessible, String fqName, ClassCandidateInfo info) {
    final PsiClass otherClass = info.getElement();
    assert otherClass != null;
    String otherQName = otherClass.getQualifiedName();
    if (fqName.equals(otherQName)) {
      return Domination.DOMINATED_BY;
    }

    final PsiClass containingClass1 = aClass.getContainingClass();
    final PsiClass containingClass2 = otherClass.getContainingClass();
    if (myAccessClass != null && !Comparing.equal(containingClass1, containingClass2)) {
      if (myAccessClass.equals(containingClass1)) return Domination.DOMINATES;
      if (myAccessClass.equals(containingClass2)) return Domination.DOMINATED_BY;
    }

    // JLS 8.5:
    // A class may inherit two or more type declarations with the same name, either from two
    // interfaces or from its superclass and an interface.
    // It is a compile-time error to attempt to refer to any ambiguously inherited class or
    // interface by its simple name.
    if (containingClass1 != null
        && containingClass2 != null
        && containingClass2.isInheritor(containingClass1, true)
        && !isImported(myCurrentFileContext)) {
      if (!isAmbiguousInherited(containingClass1)) {
        // shadowing
        return Domination.DOMINATED_BY;
      }
    }

    boolean infoAccessible = info.isAccessible() && isAccessible(otherClass);
    if (infoAccessible && !accessible) {
      return Domination.DOMINATED_BY;
    }
    if (!infoAccessible && accessible) {
      return Domination.DOMINATES;
    }

    // everything wins over class from default package
    boolean isDefault = StringUtil.getPackageName(fqName).length() == 0;
    boolean otherDefault =
        otherQName != null && StringUtil.getPackageName(otherQName).length() == 0;
    if (isDefault && !otherDefault) {
      return Domination.DOMINATED_BY;
    }
    if (!isDefault && otherDefault) {
      return Domination.DOMINATES;
    }

    // single import wins over on-demand
    boolean myOnDemand = isOnDemand(myCurrentFileContext, aClass);
    boolean otherOnDemand = isOnDemand(info.getCurrentFileResolveScope(), otherClass);
    if (myOnDemand && !otherOnDemand) {
      return Domination.DOMINATED_BY;
    }
    if (!myOnDemand && otherOnDemand) {
      return Domination.DOMINATES;
    }

    return Domination.EQUAL;
  }
  @NotNull
  @Override
  public Runnable processFile(final PsiFile file) {
    VirtualFile vFile = file.getVirtualFile();
    if (vFile instanceof VirtualFileWindow) vFile = ((VirtualFileWindow) vFile).getDelegate();
    final Project project = file.getProject();
    if (vFile == null
        || !ProjectRootManager.getInstance(project).getFileIndex().isInSourceContent(vFile)) {
      return EmptyRunnable.INSTANCE;
    }
    final List<Pair<String, Boolean>> names = new ArrayList<Pair<String, Boolean>>();
    final Set<String> demandedForNested = new HashSet<>();
    collectNamesToImport(names, demandedForNested, (XmlFile) file);
    Collections.sort(names, (o1, o2) -> StringUtil.compare(o1.first, o2.first, true));
    final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project);
    final List<Pair<String, Boolean>> sortedNames =
        ImportHelper.sortItemsAccordingToSettings(names, settings);
    final HashSet<String> onDemand = new HashSet<String>();
    ImportHelper.collectOnDemandImports(sortedNames, onDemand, settings);
    onDemand.addAll(demandedForNested);
    final Set<String> imported = new HashSet<String>();
    final List<String> imports = new ArrayList<String>();
    for (Pair<String, Boolean> pair : sortedNames) {
      final String qName = pair.first;
      final String packageName = StringUtil.getPackageName(qName);
      if (imported.contains(packageName) || imported.contains(qName)) {
        continue;
      }
      if (onDemand.contains(packageName)) {
        imported.add(packageName);
        imports.add("<?import " + packageName + ".*?>");
      } else {
        imported.add(qName);
        imports.add("<?import " + qName + "?>");
      }
    }
    final PsiFileFactory factory = PsiFileFactory.getInstance(file.getProject());

    final XmlFile dummyFile =
        (XmlFile)
            factory.createFileFromText(
                "_Dummy_.fxml", StdFileTypes.XML, StringUtil.join(imports, "\n"));
    final XmlDocument document = dummyFile.getDocument();
    final XmlProlog newImportList = document != null ? document.getProlog() : null;
    if (newImportList == null) return EmptyRunnable.getInstance();
    return () -> {
      final XmlDocument xmlDocument = ((XmlFile) file).getDocument();
      final XmlProlog prolog = xmlDocument != null ? xmlDocument.getProlog() : null;
      if (prolog != null) {
        final Collection<XmlProcessingInstruction> instructions =
            PsiTreeUtil.findChildrenOfType(prolog, XmlProcessingInstruction.class);
        for (final XmlProcessingInstruction instruction : instructions) {
          final ASTNode node = instruction.getNode();
          final ASTNode nameNode = node.findChildByType(XmlTokenType.XML_NAME);
          if (nameNode != null && nameNode.getText().equals("import")) {
            instruction.delete();
          }
        }
        prolog.add(newImportList);
      } else {
        document.addBefore(newImportList, document.getRootTag());
      }
    };
  }