public static GrMethod generateDelegate(
      PsiMethod prototype, IntroduceParameterData.ExpressionWrapper initializer, Project project) {
    final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);

    GrMethod result;
    if (prototype instanceof GrMethod) {
      result = (GrMethod) prototype.copy();
    } else {
      StringBuilder builder = new StringBuilder();
      builder.append(prototype.getModifierList().getText()).append(' ');

      if (prototype.getReturnTypeElement() != null) {
        builder.append(prototype.getReturnTypeElement().getText());
      }
      builder.append(' ').append(prototype.getName());
      builder.append(prototype.getParameterList().getText());
      builder.append("{}");
      result = factory.createMethodFromText(builder.toString());
    }

    StringBuilder call = new StringBuilder();
    call.append("def foo(){\n");
    final GrParameter[] parameters = result.getParameters();
    call.append(prototype.getName());
    if (initializer.getExpression() instanceof GrClosableBlock) {
      if (parameters.length > 0) {
        call.append('(');
        for (GrParameter parameter : parameters) {
          call.append(parameter.getName()).append(", ");
        }
        call.replace(call.length() - 2, call.length(), ")");
      }
      call.append(initializer.getText());
    } else {
      call.append('(');
      for (GrParameter parameter : parameters) {
        call.append(parameter.getName()).append(", ");
      }
      call.append(initializer.getText());
      call.append(")");
    }
    call.append("\n}");
    final GrOpenBlock block = factory.createMethodFromText(call.toString()).getBlock();

    result.getBlock().replace(block);
    final PsiElement parent = prototype.getParent();
    final GrMethod method = (GrMethod) parent.addBefore(result, prototype);
    GrReferenceAdjuster.shortenReferences(method);
    return method;
  }
  /**
   * Check the element. If the element is a PsiMethod, than we want to know if it's a @Provides
   * method, or a Constructor annotated w/ @Inject.
   *
   * <p>If element is a field, than we only want to see if it is annotated with @Inject.
   *
   * @return a {@link com.intellij.codeInsight.daemon.GutterIconNavigationHandler} for the
   *     appropriate type, or null if we don't care about it.
   */
  @Nullable
  @Override
  public LineMarkerInfo getLineMarkerInfo(@NotNull final PsiElement element) {
    // Check methods first (includes constructors).
    if (element instanceof PsiMethod) {
      PsiMethod methodElement = (PsiMethod) element;

      // @Provides
      if (PsiConsultantImpl.hasAnnotation(element, CLASS_PROVIDES)) {
        PsiTypeElement returnTypeElement = methodElement.getReturnTypeElement();
        if (returnTypeElement != null) {
          return new LineMarkerInfo<PsiElement>(
              element,
              returnTypeElement.getTextRange(),
              ICON,
              UPDATE_ALL,
              null,
              new ProvidesToInjectHandler(),
              LEFT);
        }
      }

      // Constructor injection.
      if (methodElement.isConstructor() && PsiConsultantImpl.hasAnnotation(element, CLASS_INJECT)) {
        PsiIdentifier nameIdentifier = methodElement.getNameIdentifier();
        if (nameIdentifier != null) {
          return new LineMarkerInfo<PsiElement>(
              element,
              nameIdentifier.getTextRange(),
              ICON,
              UPDATE_ALL,
              null,
              new ConstructorInjectToProvidesHandler(),
              LEFT);
        }
      }

      // Not a method, is it a Field?
    } else if (element instanceof PsiField) {
      // Field injection.
      PsiField fieldElement = (PsiField) element;
      PsiTypeElement typeElement = fieldElement.getTypeElement();

      if (PsiConsultantImpl.hasAnnotation(element, CLASS_INJECT) && typeElement != null) {
        return new LineMarkerInfo<PsiElement>(
            element,
            typeElement.getTextRange(),
            ICON,
            UPDATE_ALL,
            null,
            new FieldInjectToProvidesHandler(),
            LEFT);
      }
    }

    return null;
  }
Example #3
0
  @NotNull
  private List<MethodContract> visitStatements(
      List<ValueConstraint[]> states, PsiStatement... statements) {
    List<MethodContract> result = ContainerUtil.newArrayList();
    for (PsiStatement statement : statements) {
      if (statement instanceof PsiBlockStatement
          && ((PsiBlockStatement) statement).getCodeBlock().getStatements().length == 1) {
        result.addAll(
            visitStatements(
                states, ((PsiBlockStatement) statement).getCodeBlock().getStatements()));
      } else if (statement instanceof PsiIfStatement) {
        List<MethodContract> conditionResults =
            visitExpression(states, ((PsiIfStatement) statement).getCondition());

        PsiStatement thenBranch = ((PsiIfStatement) statement).getThenBranch();
        if (thenBranch != null) {
          result.addAll(
              visitStatements(
                  antecedentsOf(filterReturning(conditionResults, TRUE_VALUE)), thenBranch));
        }

        List<ValueConstraint[]> falseStates =
            antecedentsOf(filterReturning(conditionResults, FALSE_VALUE));
        PsiStatement elseBranch = ((PsiIfStatement) statement).getElseBranch();
        if (elseBranch != null) {
          result.addAll(visitStatements(falseStates, elseBranch));
        } else if (alwaysReturns(thenBranch)) {
          states = falseStates;
          continue;
        }
      } else if (statement instanceof PsiThrowStatement) {
        result.addAll(toContracts(states, THROW_EXCEPTION));
      } else if (statement instanceof PsiReturnStatement) {
        List<MethodContract> contracts =
            visitExpression(states, ((PsiReturnStatement) statement).getReturnValue());
        for (MethodContract contract : contracts) {
          if ((contract.returnValue == TRUE_VALUE || contract.returnValue == FALSE_VALUE)
              && !textMatches(myMethod.getReturnTypeElement(), PsiKeyword.BOOLEAN)) {
            continue;
          }

          result.add(contract);
        }
      } else if (statement instanceof PsiAssertStatement) {
        List<MethodContract> conditionResults =
            visitExpression(states, ((PsiAssertStatement) statement).getAssertCondition());
        result.addAll(
            toContracts(
                antecedentsOf(filterReturning(conditionResults, FALSE_VALUE)), THROW_EXCEPTION));
      }

      break; // visit only the first statement unless it's 'if' whose 'then' always returns and the
      // next statement is effectively 'else'
    }
    return result;
  }
  public JLabel getPopupEntryText(RearrangerSettings settings) {
    StringBuffer name = new StringBuffer(80);

    PsiMethod m = (PsiMethod) myEnd;
    if (m.getReturnTypeElement() != null && !settings.isShowTypeAfterMethod()) {
      name.append(m.getReturnTypeElement().getText());
      name.append(' ');
    }
    name.append(m.getName());
    PsiParameterList plist = m.getParameterList();
    if (settings.isShowParameterNames() || settings.isShowParameterTypes()) {
      if (plist != null) {
        name.append("(");
        for (int i = 0; i < plist.getParameters().length; i++) {
          if (i > 0) {
            name.append(", ");
          }
          if (settings.isShowParameterTypes()) {
            String modifiers = plist.getParameters()[i].getModifierList().getText();
            if (modifiers.length() > 0) {
              name.append(modifiers);
              name.append(' ');
            }
            name.append(plist.getParameters()[i].getTypeElement().getText());
            if (settings.isShowParameterNames()) {
              name.append(' ');
            }
          }
          if (settings.isShowParameterNames()) {
            name.append(plist.getParameters()[i].getName());
          }
        }
        name.append(")");
      }
    }
    if (m.getReturnTypeElement() != null && settings.isShowTypeAfterMethod()) {
      name.append(": ");
      name.append(m.getReturnTypeElement().getText());
    }
    return new JLabel(name.toString());
  }
Example #5
0
 @Nullable
 public static PsiTypeElement getPropertyTypeElement(final PsiMember member) {
   if (member instanceof PsiField) {
     return ((PsiField) member).getTypeElement();
   } else if (member instanceof PsiMethod) {
     final PsiMethod psiMethod = (PsiMethod) member;
     if (isSimplePropertyGetter(psiMethod)) {
       return psiMethod.getReturnTypeElement();
     } else if (isSimplePropertySetter(psiMethod)) {
       return psiMethod.getParameterList().getParameters()[0].getTypeElement();
     }
   }
   return null;
 }
 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 static void processPrimaryMethod(
      JavaChangeInfo changeInfo, PsiMethod method, PsiMethod baseMethod, boolean isOriginal)
      throws IncorrectOperationException {
    PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();

    if (changeInfo.isVisibilityChanged()) {
      PsiModifierList modifierList = method.getModifierList();
      final String highestVisibility =
          isOriginal
              ? changeInfo.getNewVisibility()
              : VisibilityUtil.getHighestVisibility(
                  changeInfo.getNewVisibility(),
                  VisibilityUtil.getVisibilityModifier(modifierList));
      VisibilityUtil.setVisibility(modifierList, highestVisibility);
    }

    if (changeInfo.isNameChanged()) {
      String newName =
          baseMethod == null
              ? changeInfo.getNewName()
              : RefactoringUtil.suggestNewOverriderName(
                  method.getName(), baseMethod.getName(), changeInfo.getNewName());

      if (newName != null && !newName.equals(method.getName())) {
        final PsiIdentifier nameId = method.getNameIdentifier();
        assert nameId != null;
        nameId.replace(
            JavaPsiFacade.getInstance(method.getProject())
                .getElementFactory()
                .createIdentifier(newName));
      }
    }

    final PsiSubstitutor substitutor =
        baseMethod == null
            ? PsiSubstitutor.EMPTY
            : ChangeSignatureProcessor.calculateSubstitutor(method, baseMethod);

    if (changeInfo.isReturnTypeChanged()) {
      PsiType newTypeElement =
          changeInfo
              .getNewReturnType()
              .getType(changeInfo.getMethod().getParameterList(), method.getManager());
      final PsiType returnType = substitutor.substitute(newTypeElement);
      // don't modify return type for non-Java overriders (EJB)
      if (method.getName().equals(changeInfo.getNewName())) {
        final PsiTypeElement typeElement = method.getReturnTypeElement();
        if (typeElement != null) {
          typeElement.replace(factory.createTypeElement(returnType));
        }
      }
    }

    PsiParameterList list = method.getParameterList();
    PsiParameter[] parameters = list.getParameters();

    final JavaParameterInfo[] parameterInfos = changeInfo.getNewParameters();
    final int delta =
        baseMethod != null
            ? baseMethod.getParameterList().getParametersCount()
                - method.getParameterList().getParametersCount()
            : 0;
    PsiParameter[] newParms = new PsiParameter[Math.max(parameterInfos.length - delta, 0)];
    final String[] oldParameterNames = changeInfo.getOldParameterNames();
    final String[] oldParameterTypes = changeInfo.getOldParameterTypes();
    for (int i = 0; i < newParms.length; i++) {
      JavaParameterInfo info = parameterInfos[i];
      int index = info.getOldIndex();
      if (index >= 0) {
        PsiParameter parameter = parameters[index];
        newParms[i] = parameter;

        String oldName = oldParameterNames[index];
        if (!oldName.equals(info.getName()) && oldName.equals(parameter.getName())) {
          PsiIdentifier newIdentifier = factory.createIdentifier(info.getName());
          parameter.getNameIdentifier().replace(newIdentifier);
        }

        String oldType = oldParameterTypes[index];
        if (!oldType.equals(info.getTypeText())) {
          parameter.normalizeDeclaration();
          PsiType newType =
              substitutor.substitute(
                  info.createType(changeInfo.getMethod().getParameterList(), method.getManager()));

          parameter.getTypeElement().replace(factory.createTypeElement(newType));
        }
      } else {
        newParms[i] = createNewParameter(changeInfo, info, substitutor);
      }
    }

    resolveParameterVsFieldsConflicts(newParms, method, list, changeInfo.toRemoveParm());
    fixJavadocsForChangedMethod(method, changeInfo, newParms.length);
    if (changeInfo.isExceptionSetOrOrderChanged()) {
      final PsiClassType[] newExceptions = getPrimaryChangedExceptionInfo(changeInfo);
      fixPrimaryThrowsLists(method, newExceptions);
    }
  }