private static boolean generateDelegate(GrChangeInfoImpl grInfo) {
    final GrMethod method = grInfo.getMethod();
    final PsiClass psiClass = method.getContainingClass();
    GrMethod newMethod = (GrMethod) method.copy();
    newMethod = (GrMethod) psiClass.addAfter(newMethod, method);
    StringBuilder buffer = new StringBuilder();
    buffer.append("\n");
    if (method.isConstructor()) {
      buffer.append("this");
    } else {
      if (!PsiType.VOID.equals(method.getReturnType())) {
        buffer.append("return ");
      }
      buffer.append(
          GrChangeSignatureUtil.getNameWithQuotesIfNeeded(
              grInfo.getNewName(), method.getProject()));
    }

    generateParametersForDelegateCall(grInfo, method, buffer);

    final GrCodeBlock codeBlock =
        GroovyPsiElementFactory.getInstance(method.getProject())
            .createMethodBodyFromText(buffer.toString());
    newMethod.setBlock(codeBlock);
    newMethod.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, false);

    CodeStyleManager.getInstance(method.getProject()).reformat(newMethod);
    return processPrimaryMethodInner(grInfo, method, null);
  }
  private static void processConstructor(GrMethod constructor, JavaChangeInfo changeInfo) {
    final PsiClass containingClass = constructor.getContainingClass();
    final PsiClass baseClass = changeInfo.getMethod().getContainingClass();
    final PsiSubstitutor substitutor =
        TypeConversionUtil.getSuperClassSubstitutor(
            baseClass, containingClass, PsiSubstitutor.EMPTY);

    GrOpenBlock block = constructor.getBlock();
    GrConstructorInvocation invocation =
        GroovyPsiElementFactory.getInstance(constructor.getProject())
            .createConstructorInvocation("super()");
    invocation =
        (GrConstructorInvocation) block.addStatementBefore(invocation, getFirstStatement(block));
    processMethodUsage(
        invocation.getInvokedExpression(),
        changeInfo,
        changeInfo.isParameterSetOrOrderChanged() || changeInfo.isParameterNamesChanged(),
        changeInfo.isExceptionSetChanged(),
        GrClosureSignatureUtil.ArgInfo.<PsiElement>empty_array(),
        substitutor);
  }
  private boolean validateInputData() {
    if (!isGroovyMethodName(getNewName())) {
      showErrorHint(message("name.is.wrong", getNewName()));
      return false;
    }

    if (!checkType(myReturnTypeCodeFragment, true)) {
      showErrorHint(message("return.type.is.wrong"));
      return false;
    }

    List<GrTableParameterInfo> parameterInfos = myParameterModel.getParameterInfos();
    for (int i = 0; i < parameterInfos.size(); i++) {
      GrTableParameterInfo info = parameterInfos.get(i);
      if (!StringUtil.isJavaIdentifier(info.getName())) {
        showErrorHint(message("name.is.wrong", info.getName()));
        return false;
      }
      if (!checkType(info.getTypeFragment(), i == parameterInfos.size() - 1)) {
        showErrorHint(message("type.for.parameter.is.incorrect", info.getName()));
        return false;
      }
      String defaultValue = info.getDefaultValue();
      final String initializer = info.getDefaultInitializerFragment().getText();
      if (info.getOldIndex() < 0
          && defaultValue.trim().length() == 0
          && initializer.trim().length() == 0) {
        showErrorHint(message("specify.default.value", info.getName()));
        return false;
      }
    }

    ThrownExceptionInfo[] exceptionInfos = myExceptionTableModel.getThrownExceptions();
    PsiTypeCodeFragment[] typeCodeFragments = myExceptionTableModel.getTypeCodeFragments();
    for (int i = 0; i < exceptionInfos.length; i++) {
      ThrownExceptionInfo exceptionInfo = exceptionInfos[i];
      PsiTypeCodeFragment typeCodeFragment = typeCodeFragments[i];
      try {
        PsiType type = typeCodeFragment.getType();
        if (!(type instanceof PsiClassType)) {
          showErrorHint(
              GroovyRefactoringBundle.message(
                  "changeSignature.wrong.type.for.exception", typeCodeFragment.getText()));
          return false;
        }

        PsiClassType throwable =
            JavaPsiFacade.getInstance(myMethod.getProject())
                .getElementFactory()
                .createTypeByFQClassName("java.lang.Throwable", myMethod.getResolveScope());
        if (!throwable.isAssignableFrom(type)) {
          showErrorHint(
              GroovyRefactoringBundle.message(
                  "changeSignature.not.throwable.type", typeCodeFragment.getText()));
          return false;
        }
        exceptionInfo.setType((PsiClassType) type);
      } catch (PsiTypeCodeFragment.TypeSyntaxException e) {
        showErrorHint(
            GroovyRefactoringBundle.message(
                "changeSignature.wrong.type.for.exception", typeCodeFragment.getText()));
        return false;
      } catch (PsiTypeCodeFragment.NoTypeException e) {
        showErrorHint(GroovyRefactoringBundle.message("changeSignature.no.type.for.exception"));
        return false;
      }
    }

    return true;
  }
Ejemplo n.º 4
0
  private void doMoveMethod(PsiSubstitutor substitutor, GrMemberInfo info) {
    GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject);
    GrMethod method = (GrMethod) info.getMember();
    PsiMethod sibling = method;
    PsiMethod anchor = null;
    while (sibling != null) {
      sibling = PsiTreeUtil.getNextSiblingOfType(sibling, PsiMethod.class);
      if (sibling != null) {
        anchor =
            MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(
                method.getContainingClass(),
                myTargetSuperClass,
                sibling.getSignature(PsiSubstitutor.EMPTY),
                false);
        if (anchor != null) {
          break;
        }
      }
    }

    GrMethod methodCopy = (GrMethod) method.copy();
    if (method.findSuperMethods(myTargetSuperClass).length == 0) {
      deleteOverrideAnnotationIfFound(methodCopy);
    }

    final boolean isOriginalMethodAbstract =
        method.hasModifierProperty(PsiModifier.ABSTRACT)
            || method.hasModifierProperty(PsiModifier.DEFAULT);
    if (myTargetSuperClass.isInterface() || info.isToAbstract()) {
      GroovyChangeContextUtil.clearContextInfo(method);
      RefactoringUtil.makeMethodAbstract(myTargetSuperClass, methodCopy);
      if (myTargetSuperClass.isInterface()) {
        PsiUtil.setModifierProperty(methodCopy, PsiModifier.ABSTRACT, false);
      }
      replaceMovedMemberTypeParameters(
          methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);

      final GrMethod movedElement =
          anchor != null
              ? (GrMethod) myTargetSuperClass.addBefore(methodCopy, anchor)
              : (GrMethod) myTargetSuperClass.add(methodCopy);
      CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(method.getProject());
      if (styleSettings.INSERT_OVERRIDE_ANNOTATION) {
        if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myTargetSuperClass.isInterface()
            || PsiUtil.isLanguageLevel6OrHigher(mySourceClass)) {
          new AddAnnotationFix(CommonClassNames.JAVA_LANG_OVERRIDE, method)
              .invoke(method.getProject(), null, mySourceClass.getContainingFile());
        }
      }

      GrDocComment oldDoc = method.getDocComment();
      if (oldDoc != null) {
        GrDocCommentUtil.setDocComment(movedElement, oldDoc);
      }

      myDocCommentPolicy.processCopiedJavaDoc(
          methodCopy.getDocComment(), oldDoc, isOriginalMethodAbstract);

      myMembersAfterMove.add(movedElement);
      if (isOriginalMethodAbstract) {
        deleteMemberWithDocComment(method);
      }
    } else {
      if (isOriginalMethodAbstract) {
        PsiUtil.setModifierProperty(myTargetSuperClass, PsiModifier.ABSTRACT, true);
      }

      // fixReferencesToStatic(methodCopy, movedMembers);
      replaceMovedMemberTypeParameters(
          methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
      final PsiMethod superClassMethod =
          myTargetSuperClass.findMethodBySignature(methodCopy, false);
      final GrMethod movedElement;
      if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
        movedElement = (GrMethod) superClassMethod.replace(methodCopy);
      } else {
        movedElement =
            anchor != null
                ? (GrMethod) myTargetSuperClass.addBefore(methodCopy, anchor)
                : (GrMethod) myTargetSuperClass.add(methodCopy);
        myMembersAfterMove.add(movedElement);
      }

      GrDocCommentUtil.setDocComment(movedElement, method.getDocComment());

      deleteMemberWithDocComment(method);
    }
  }
  private static boolean processPrimaryMethodInner(
      JavaChangeInfo changeInfo, GrMethod method, @Nullable PsiMethod baseMethod) {
    if (changeInfo.isNameChanged()) {
      String newName =
          baseMethod == null
              ? changeInfo.getNewName()
              : RefactoringUtil.suggestNewOverriderName(
                  method.getName(), baseMethod.getName(), changeInfo.getNewName());
      if (newName != null && !newName.equals(method.getName())) {
        method.setName(changeInfo.getNewName());
      }
    }

    final GrModifierList modifierList = method.getModifierList();
    if (changeInfo.isVisibilityChanged()) {
      modifierList.setModifierProperty(changeInfo.getNewVisibility(), true);
    }

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

    final PsiMethod context = changeInfo.getMethod();
    GrTypeElement oldReturnTypeElement = method.getReturnTypeElementGroovy();
    if (changeInfo.isReturnTypeChanged()) {
      CanonicalTypes.Type newReturnType = changeInfo.getNewReturnType();
      if (newReturnType == null) {
        if (oldReturnTypeElement != null) {
          oldReturnTypeElement.delete();
          if (modifierList.getModifiers().length == 0) {
            modifierList.setModifierProperty(GrModifier.DEF, true);
          }
        }
      } else {
        PsiType type = newReturnType.getType(context, method.getManager());
        GrReferenceAdjuster.shortenAllReferencesIn(
            method.setReturnType(substitutor.substitute(type)));
        if (oldReturnTypeElement == null) {
          modifierList.setModifierProperty(GrModifier.DEF, false);
        }
      }
    }

    JavaParameterInfo[] newParameters = changeInfo.getNewParameters();
    final GrParameterList parameterList = method.getParameterList();
    GrParameter[] oldParameters = parameterList.getParameters();
    final PsiParameter[] oldBaseParams =
        baseMethod != null ? baseMethod.getParameterList().getParameters() : null;

    Set<GrParameter> toRemove = new HashSet<GrParameter>(oldParameters.length);
    ContainerUtil.addAll(toRemove, oldParameters);

    GrParameter anchor = null;
    final GrDocComment docComment = method.getDocComment();
    final GrDocTag[] tags = docComment == null ? null : docComment.getTags();

    for (JavaParameterInfo newParameter : newParameters) {
      // if old parameter name differs from base method parameter name we don't change it
      final String newName;
      final int oldIndex = newParameter.getOldIndex();
      if (oldIndex >= 0 && oldBaseParams != null) {
        final String oldName = oldParameters[oldIndex].getName();
        if (oldName.equals(oldBaseParams[oldIndex].getName())) {
          newName = newParameter.getName();
        } else {
          newName = oldName;
        }
      } else {
        newName = newParameter.getName();
      }

      final GrParameter oldParameter = oldIndex >= 0 ? oldParameters[oldIndex] : null;

      if (docComment != null && oldParameter != null) {
        final String oldName = oldParameter.getName();
        for (GrDocTag tag : tags) {
          if ("@param".equals(tag.getName())) {
            final GrDocParameterReference parameterReference = tag.getDocParameterReference();
            if (parameterReference != null && oldName.equals(parameterReference.getText())) {
              parameterReference.handleElementRename(newName);
            }
          }
        }
      }

      GrParameter grParameter =
          createNewParameter(substitutor, context, parameterList, newParameter, newName);
      if (oldParameter != null) {
        grParameter.getModifierList().replace(oldParameter.getModifierList());
      }

      if ("def".equals(newParameter.getTypeText())) {
        grParameter.getModifierList().setModifierProperty(GrModifier.DEF, true);
      } else if (StringUtil.isEmpty(newParameter.getTypeText())) {
        grParameter.getModifierList().setModifierProperty(GrModifier.DEF, false);
      }

      anchor = (GrParameter) parameterList.addAfter(grParameter, anchor);
    }

    for (GrParameter oldParameter : toRemove) {
      oldParameter.delete();
    }
    JavaCodeStyleManager.getInstance(parameterList.getProject())
        .shortenClassReferences(parameterList);
    CodeStyleManager.getInstance(parameterList.getProject()).reformat(parameterList);

    if (changeInfo.isExceptionSetOrOrderChanged()) {
      final ThrownExceptionInfo[] infos = changeInfo.getNewExceptions();
      PsiClassType[] exceptionTypes = new PsiClassType[infos.length];
      for (int i = 0; i < infos.length; i++) {
        ThrownExceptionInfo info = infos[i];
        exceptionTypes[i] = (PsiClassType) info.createType(method, method.getManager());
      }

      PsiReferenceList thrownList =
          GroovyPsiElementFactory.getInstance(method.getProject()).createThrownList(exceptionTypes);
      thrownList = (PsiReferenceList) method.getThrowsList().replace(thrownList);
      JavaCodeStyleManager.getInstance(thrownList.getProject()).shortenClassReferences(thrownList);
      CodeStyleManager.getInstance(method.getProject()).reformat(method.getThrowsList());
    }
    return true;
  }