public void migrateClassTypeParameter(
      final PsiReferenceParameterList referenceParameterList, final PsiClassType migrationType) {
    final PsiClass psiClass = PsiTreeUtil.getParentOfType(referenceParameterList, PsiClass.class);
    LOG.assertTrue(psiClass != null);

    final PsiClass superClass = psiClass.getSuperClass();
    LOG.assertTrue(superClass != null);

    myLabeler.getTypeEvaluator().setType(new TypeMigrationUsageInfo(superClass), migrationType);

    final Map<PsiElement, Pair<PsiReference[], PsiType>> roots =
        new HashMap<PsiElement, Pair<PsiReference[], PsiType>>();

    markTypeParameterUsages(psiClass, migrationType, referenceParameterList, roots);

    final Set<PsiElement> processed = new HashSet<PsiElement>();
    for (Map.Entry<PsiElement, Pair<PsiReference[], PsiType>> entry : roots.entrySet()) {
      final PsiElement member = entry.getKey();
      final PsiType type = entry.getValue().second;

      if (member instanceof PsiParameter
          && ((PsiParameter) member).getDeclarationScope() instanceof PsiMethod) {
        myLabeler.migrateMethodCallExpressions(type, (PsiParameter) member, psiClass);
      }

      final PsiReference[] references = entry.getValue().first;
      for (PsiReference usage : references) {
        myLabeler.migrateRootUsageExpression(usage, processed);
      }
    }
  }
 /** signature should be changed for methods with type parameters */
 private void prepareMethodsChangeSignature(
     final PsiClass currentClass,
     final PsiElement memberToChangeSignature,
     final PsiType memberType) {
   if (memberToChangeSignature instanceof PsiMethod) {
     final PsiMethod method =
         MethodSignatureUtil.findMethodBySuperMethod(
             currentClass, (PsiMethod) memberToChangeSignature, true);
     if (method != null && method.getContainingClass() == currentClass) {
       myLabeler.addRoot(new TypeMigrationUsageInfo(method), memberType, method, false);
     }
   } else if (memberToChangeSignature instanceof PsiParameter
       && ((PsiParameter) memberToChangeSignature).getDeclarationScope() instanceof PsiMethod) {
     final PsiMethod superMethod =
         (PsiMethod) ((PsiParameter) memberToChangeSignature).getDeclarationScope();
     final int parameterIndex =
         superMethod.getParameterList().getParameterIndex((PsiParameter) memberToChangeSignature);
     final PsiMethod method =
         MethodSignatureUtil.findMethodBySuperMethod(currentClass, superMethod, true);
     if (method != null && method.getContainingClass() == currentClass) {
       final PsiParameter parameter = method.getParameterList().getParameters()[parameterIndex];
       if (!parameter.getType().equals(memberType)) {
         myLabeler.addRoot(new TypeMigrationUsageInfo(parameter), memberType, parameter, false);
       }
     }
   }
 }
示例#3
0
  @NotNull
  @Override
  public UsageInfo[] findUsages() {
    myLabeler = new TypeMigrationLabeler(myRules, myRootTypes);

    try {
      return myLabeler.getMigratedUsages(!isPreviewUsages(), myRoot);
    } catch (TypeMigrationLabeler.MigrateException e) {
      setPreviewUsages(true);
      myLabeler.clearStopException();
      return myLabeler.getMigratedUsages(false, myRoot);
    }
  }
示例#4
0
  public static void change(UsageInfo[] usages, TypeMigrationLabeler labeler, Project project) {
    final List<SmartPsiElementPointer<PsiNewExpression>> newExpressionsToCheckDiamonds =
        new SmartList<>();
    final TypeMigrationLabeler.MigrationProducer producer = labeler.createMigratorFor(usages);

    final SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(project);
    List<UsageInfo> nonCodeUsages = new ArrayList<>();
    for (UsageInfo usage : usages) {
      if (((TypeMigrationUsageInfo) usage).isExcluded()) continue;
      final PsiElement element = usage.getElement();
      if (element instanceof PsiVariable
          || element instanceof PsiMember
          || element instanceof PsiExpression
          || element instanceof PsiReferenceParameterList) {
        producer.change(
            (TypeMigrationUsageInfo) usage,
            expression ->
                newExpressionsToCheckDiamonds.add(
                    smartPointerManager.createSmartPsiElementPointer(expression)));
      } else {
        nonCodeUsages.add(usage);
      }
    }

    for (SmartPsiElementPointer<PsiNewExpression> newExpressionPointer :
        newExpressionsToCheckDiamonds) {
      final PsiNewExpression newExpression = newExpressionPointer.getElement();
      if (newExpression != null) {
        labeler.postProcessNewExpression(newExpression);
      }
    }

    for (UsageInfo usageInfo : nonCodeUsages) {
      final PsiElement element = usageInfo.getElement();
      if (element != null) {
        final PsiReference reference = element.getReference();
        if (reference != null) {
          final Object target = producer.getConversion(usageInfo);
          if (target instanceof PsiMember) {
            try {
              reference.bindToElement((PsiElement) target);
            } catch (IncorrectOperationException ignored) {
            }
          }
        }
      }
    }

    producer.flush();
  }
示例#5
0
 @Override
 protected void previewRefactoring(@NotNull final UsageInfo[] usages) {
   MigrationPanel panel = new MigrationPanel(myRoot, myLabeler, myProject, isPreviewUsages());
   String name;
   if (myRoot.length == 1) {
     String fromType =
         assertNotNull(TypeMigrationLabeler.getElementType(myRoot[0])).getPresentableText();
     String toType = myRootTypes.fun(myRoot[0]).getPresentableText();
     String text;
     text = getPresentation(myRoot[0]);
     name = "Migrate Type of " + text + " from \'" + fromType + "\' to \'" + toType + "\'";
   } else {
     final int rootsInPresentationCount =
         myRoot.length > MAX_ROOT_IN_PREVIEW_PRESENTATION
             ? MAX_ROOT_IN_PREVIEW_PRESENTATION
             : myRoot.length;
     String[] rootsPresentation = new String[rootsInPresentationCount];
     for (int i = 0; i < rootsInPresentationCount; i++) {
       final PsiElement root = myRoot[i];
       rootsPresentation[i] =
           root instanceof PsiNamedElement ? ((PsiNamedElement) root).getName() : root.getText();
     }
     rootsPresentation = StringUtil.surround(rootsPresentation, "\'", "\'");
     name = "Migrate Type of " + StringUtil.join(rootsPresentation, ", ");
     if (myRoot.length > MAX_ROOT_IN_PREVIEW_PRESENTATION) {
       name += "...";
     }
   }
   Content content =
       UsageViewManager.getInstance(myProject).addContent(name, false, panel, true, true);
   panel.setContent(content);
   ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.FIND).activate(null);
 }
示例#6
0
 @Override
 protected boolean preprocessUsages(@NotNull Ref<UsageInfo[]> refUsages) {
   if (hasFailedConversions()) {
     if (ApplicationManager.getApplication().isUnitTestMode()) {
       throw new RuntimeException(StringUtil.join(myLabeler.getFailedConversionsReport(), "\n"));
     }
     FailedConversionsDialog dialog =
         new FailedConversionsDialog(myLabeler.getFailedConversionsReport(), myProject);
     if (!dialog.showAndGet()) {
       final int exitCode = dialog.getExitCode();
       prepareSuccessful();
       if (exitCode == FailedConversionsDialog.VIEW_USAGES_EXIT_CODE) {
         previewRefactoring(refUsages.get());
       }
       return false;
     }
   }
   prepareSuccessful();
   return true;
 }
  private void processMemberType(
      final PsiElement element,
      final TypeParameterSearcher parameterSearcher,
      final PsiClass psiClass,
      final PsiSubstitutor substitutor,
      final Map<PsiElement, Pair<PsiReference[], PsiType>> roots) {
    final PsiType elementType = TypeMigrationLabeler.getElementType(element);
    if (elementType != null && elementType.accept(parameterSearcher).booleanValue()) {
      final PsiType memberType = substitutor.substitute(elementType);

      prepareMethodsChangeSignature(psiClass, element, memberType);

      final List<PsiReference> refs =
          TypeMigrationLabeler.filterReferences(
              psiClass, ReferencesSearch.search(element, psiClass.getUseScope()));

      roots.put(
          element,
          Pair.create(
              myLabeler.markRootUsages(
                  element, memberType, refs.toArray(new PsiReference[refs.size()])),
              memberType));
    }
  }
示例#8
0
 public boolean hasFailedConversions() {
   return myLabeler.hasFailedConversions();
 }