private void checkFunction(final RefactoringStatus result) {
    if ((fFunction.getElementType() & IRElement.MASK_C2) != IRElement.R_COMMON_FUNCTION
        && (fFunction.getElementType() & IRElement.MASK_C2) != IRElement.R_COMMON_FUNCTION) {
      result.merge(
          RefactoringStatus.createFatalErrorStatus(
              Messages.FunctionToS4Method_error_SelectionAlreadyS4_message));
      return;
    }
    final RAstNode node = (RAstNode) fFunction.getAdapter(IAstNode.class);
    if (RAst.hasErrors(node)) {
      result.merge(
          RefactoringStatus.createWarningStatus(
              Messages.FunctionToS4Method_warning_SelectionSyntaxError_message));
    }
    //		if (fSelectionRegion != null
    //				&& (fSelectionRegion.getOffset() != fOperationRegion.getOffset() ||
    // fSelectionRegion.getLength() != fOperationRegion.getLength())) {
    //			result.merge(RefactoringStatus.createWarningStatus("The selected code does not equal
    // exactly the found expression(s)."));
    //		}

    RElementName elementName = fFunction.getElementName();
    while (elementName.getNextSegment() != null) {
      elementName = elementName.getNamespace();
    }
    fFunctionName = elementName.getDisplayName();

    final ArgsDefinition argsDef = fFunction.getArgsDefinition();
    final int count = (argsDef != null) ? argsDef.size() : 0;
    fVariablesList = new ArrayList(count);
    boolean dots = false;
    for (int i = 0; i < count; i++) {
      final Arg arg = argsDef.get(i);
      final Variable variable = new Variable(arg);
      if (variable.getName().equals(RTerminal.S_ELLIPSIS)) {
        dots = true;
        variable.init(true);
      } else {
        variable.init(!dots);
      }
      fVariablesList.add(variable);
    }
  }
  private void createChanges(final TextFileChange change, final SubMonitor progress)
      throws BadLocationException, CoreException {
    fSourceUnit.connect(progress.newChild(1));
    try {
      final AbstractDocument document = fSourceUnit.getDocument(progress.newChild(1));
      final RCodeStyleSettings codeStyle = RRefactoringAdapter.getCodeStyle(fSourceUnit);

      RAstNode firstParentChild = (RAstNode) fFunction.getAdapter(IAstNode.class);
      while (true) {
        final RAstNode parent = firstParentChild.getRParent();
        if (parent == null
            || parent.getNodeType() == NodeType.SOURCELINES
            || parent.getNodeType() == NodeType.BLOCK) {
          break;
        }
        firstParentChild = parent;
      }

      final IRegion region = fAdapter.expandWhitespaceBlock(document, fOperationRegion);
      final int insertOffset =
          fAdapter
              .expandWhitespaceBlock(
                  document,
                  fAdapter.expandSelectionRegion(
                      document, new Region(firstParentChild.getOffset(), 0), fOperationRegion))
              .getOffset();
      final FDef fdefNode = (FDef) fFunction.getAdapter(FDef.class);
      final IRegion fbodyRegion =
          fAdapter.expandWhitespaceBlock(
              document,
              fAdapter.expandSelectionRegion(document, fdefNode.getContChild(), fOperationRegion));

      TextChangeCompatibility.addTextEdit(
          change,
          Messages.FunctionToS4Method_Changes_DeleteOld_name,
          new DeleteEdit(region.getOffset(), region.getLength()));

      final String nl = document.getDefaultLineDelimiter();
      final String argAssign = codeStyle.getArgAssignString();

      final StringBuilder sb = new StringBuilder();
      sb.append("setGeneric(\""); // $NON-NLS-1$
      sb.append(fFunctionName);
      sb.append("\","); // $NON-NLS-1$
      sb.append(nl);
      sb.append("function("); // $NON-NLS-1$
      boolean dots = false;
      for (final Variable variable : fVariablesList) {
        if (variable.getName().equals(RTerminal.S_ELLIPSIS)) {
          dots = true;
        }
        if (variable.getUseAsGenericArgument()) {
          sb.append(
              RElementName.create(RElementName.MAIN_DEFAULT, variable.getName()).getDisplayName());
          sb.append(", "); // $NON-NLS-1$
        }
      }
      if (!dots) {
        sb.append("..., "); // $NON-NLS-1$
      }
      sb.delete(sb.length() - 2, sb.length());
      sb.append(')');
      if (codeStyle.getNewlineFDefBodyBlockBefore()) {
        sb.append(nl);
      } else {
        sb.append(' ');
      }
      sb.append('{');
      sb.append(nl);
      sb.append("standardGeneric(\""); // $NON-NLS-1$
      sb.append(fFunctionName);
      sb.append("\")"); // $NON-NLS-1$
      sb.append(nl);
      sb.append("})"); // $NON-NLS-1$
      sb.append(nl);
      sb.append(nl);
      final String genericDef =
          RRefactoringAdapter.indent(sb, document, firstParentChild.getOffset(), fSourceUnit);
      TextChangeCompatibility.addTextEdit(
          change,
          Messages.FunctionToS4Method_Changes_AddGenericDef_name,
          new InsertEdit(insertOffset, genericDef));

      sb.setLength(0);
      sb.append("setMethod(\""); // $NON-NLS-1$
      sb.append(fFunctionName);
      sb.append("\","); // $NON-NLS-1$
      sb.append(nl);
      sb.append("signature("); // $NON-NLS-1$
      boolean hasType = false;
      for (final Variable variable : fVariablesList) {
        if (variable.getUseAsGenericArgument() && variable.getArgumentType() != null) {
          hasType = true;
          sb.append(
              RElementName.create(RElementName.MAIN_DEFAULT, variable.getName()).getDisplayName());
          sb.append(argAssign);
          sb.append("\""); // $NON-NLS-1$
          sb.append(variable.getArgumentType());
          sb.append("\", "); // $NON-NLS-1$
        }
      }
      if (hasType) {
        sb.delete(sb.length() - 2, sb.length());
      }
      sb.append("),"); // $NON-NLS-1$
      sb.append(nl);
      sb.append("function("); // $NON-NLS-1$
      final FDef.Args argsNode = fdefNode.getArgsChild();
      for (final Variable variable : fVariablesList) {
        sb.append(
            RElementName.create(RElementName.MAIN_DEFAULT, variable.getName()).getDisplayName());
        final FDef.Arg argNode = argsNode.getChild(variable.fArg.index);
        if (argNode.hasDefault()) {
          sb.append(argAssign);
          sb.append(
              document.get(
                  argNode.getDefaultChild().getOffset(), argNode.getDefaultChild().getLength()));
        }
        sb.append(", "); // $NON-NLS-1$
      }
      if (!fVariablesList.isEmpty()) {
        sb.delete(sb.length() - 2, sb.length());
      }
      sb.append(')');
      if (codeStyle.getNewlineFDefBodyBlockBefore()
          || fdefNode.getContChild().getNodeType() != NodeType.BLOCK) {
        sb.append(nl);
      } else {
        sb.append(' ');
      }
      sb.append(document.get(fbodyRegion.getOffset(), fbodyRegion.getLength()).trim());
      sb.append(")"); // $NON-NLS-1$
      sb.append(nl);
      final String methodDef =
          RRefactoringAdapter.indent(sb, document, firstParentChild.getOffset(), fSourceUnit);
      TextChangeCompatibility.addTextEdit(
          change,
          Messages.FunctionToS4Method_Changes_AddMethodDef_name,
          new InsertEdit(insertOffset, methodDef));
    } finally {
      fSourceUnit.disconnect(progress.newChild(1));
    }
  }
예제 #3
0
  /**
   * Generates content for the Roxygen comment for the given function definition
   *
   * @param rMethod function element
   * @param lineDelimiter the line delimiter to be used
   * @return
   * @throws CoreException thrown when the evaluation of the code template fails
   */
  public static EvaluatedTemplate getCommonFunctionRoxygenComment(
      final IRMethod rMethod, final String lineDelimiter) throws CoreException {
    final Template template =
        RUIPlugin.getDefault()
            .getRCodeGenerationTemplateStore()
            .findTemplate(RCodeTemplatesContextType.ROXYGEN_COMMONFUNCTION_TEMPLATE);
    if (template == null) {
      return null;
    }

    final ISourceUnit su = rMethod.getSourceUnit();
    final RCodeTemplatesContext context =
        new RCodeTemplatesContext(
            RCodeTemplatesContextType.ROXYGEN_COMMONFUNCTION_CONTEXTTYPE, su, lineDelimiter);
    context.setRElement(rMethod);

    try {
      final TemplateBuffer buffer = context.evaluate(template);
      if (buffer == null) {
        return null;
      }
      final EvaluatedTemplate data = new EvaluatedTemplate(buffer, lineDelimiter);

      final AbstractDocument content = data.startPostEdit();
      final StringBuilder tagBuffer = new StringBuilder(64);
      final TemplateVariable paramVariable =
          TemplatesUtil.findVariable(buffer, RCodeTemplatesContextType.ROXYGEN_PARAM_TAGS_VARIABLE);
      final Position[] paramPositions =
          new Position[(paramVariable != null) ? paramVariable.getOffsets().length : 0];
      for (int i = 0; i < paramPositions.length; i++) {
        paramPositions[i] = new Position(paramVariable.getOffsets()[i], paramVariable.getLength());
        content.addPosition(paramPositions[i]);
      }

      if (paramPositions.length > 0) {
        String[] tags = null;
        final ArgsDefinition args = rMethod.getArgsDefinition();
        if (args != null) {
          final int count = args.size();
          tags = new String[count];
          for (int i = 0; i < count; i++) {
            tagBuffer.append("@param "); // $NON-NLS-1$
            tagBuffer.append(args.get(i).name);
            tagBuffer.append(" "); // $NON-NLS-1$
            tags[i] = tagBuffer.toString();
            tagBuffer.setLength(0);
          }
        }
        for (final Position pos : paramPositions) {
          insertRoxygen(content, pos, tags);
        }
      }

      data.finishPostEdit();
      return data;
    } catch (final Exception e) {
      throw new CoreException(
          new Status(
              IStatus.ERROR,
              RUI.PLUGIN_ID,
              NLS.bind(
                  TemplateMessages.TemplateEvaluation_error_description, template.getDescription()),
              e));
    }
  }
예제 #4
0
  /**
   * Generates content for the Roxygen comment for the given method definition
   *
   * @param rMethod function element
   * @param lineDelimiter the line delimiter to be used
   * @return
   * @throws CoreException thrown when the evaluation of the code template fails
   */
  public static EvaluatedTemplate getMethodRoxygenComment(
      final IRMethod rMethod, final String lineDelimiter) throws CoreException {
    final Template template =
        RUIPlugin.getDefault()
            .getRCodeGenerationTemplateStore()
            .findTemplate(RCodeTemplatesContextType.ROXYGEN_S4METHOD_TEMPLATE);
    if (template == null) {
      return null;
    }

    final ISourceUnit su = rMethod.getSourceUnit();
    final RCodeTemplatesContext context =
        new RCodeTemplatesContext(
            RCodeTemplatesContextType.ROXYGEN_METHOD_CONTEXTTYPE, su, lineDelimiter);
    context.setRElement(rMethod);

    try {
      final TemplateBuffer buffer = context.evaluate(template);
      if (buffer == null) {
        return null;
      }
      final EvaluatedTemplate data = new EvaluatedTemplate(buffer, lineDelimiter);

      final AbstractDocument content = data.startPostEdit();
      final StringBuilder sb = new StringBuilder(64);

      final Position[] sigPositions;
      String sigText = null;
      {
        final TemplateVariable variable =
            TemplatesUtil.findVariable(buffer, RCodeTemplatesContextType.ROXYGEN_SIG_LIST_VARIABLE);
        sigPositions = new Position[(variable != null) ? variable.getOffsets().length : 0];
        for (int i = 0; i < sigPositions.length; i++) {
          sigPositions[i] = new Position(variable.getOffsets()[i], variable.getLength());
          content.addPosition(sigPositions[i]);
        }

        if (sigPositions.length > 0) {
          final ArgsDefinition args = rMethod.getArgsDefinition();
          if (args != null) {
            final int count = args.size();
            for (int i = 0; i < count; i++) {
              final Arg arg = args.get(i);
              if (arg.className == null || arg.className.equals("ANY")) { // $NON-NLS-1$
                break;
              }
              sb.append(arg.className);
              sb.append(","); // $NON-NLS-1$
            }
            if (sb.length() > 0) {
              sigText = sb.substring(0, sb.length() - 1);
              sb.setLength(0);
            }
          }
        }
      }
      final Position[] paramPositions;
      String[] paramTags = null;
      {
        final TemplateVariable variable =
            TemplatesUtil.findVariable(
                buffer, RCodeTemplatesContextType.ROXYGEN_PARAM_TAGS_VARIABLE);
        paramPositions = new Position[(variable != null) ? variable.getOffsets().length : 0];
        for (int i = 0; i < paramPositions.length; i++) {
          paramPositions[i] = new Position(variable.getOffsets()[i], variable.getLength());
          content.addPosition(paramPositions[i]);
        }

        if (paramPositions.length > 0) {
          String list = null;
          final ArgsDefinition args = rMethod.getArgsDefinition();
          if (args != null) {
            final int count = args.size();
            paramTags = new String[count];
            for (int i = 0; i < count; i++) {
              sb.append("@param "); // $NON-NLS-1$
              sb.append(args.get(i).name);
              sb.append(" "); // $NON-NLS-1$
              paramTags[i] = sb.toString();
              sb.setLength(0);
            }
          }
        }
      }

      if (sigPositions != null) {
        for (final Position pos : sigPositions) {
          insertRoxygen(content, pos, sigText);
        }
      }
      if (paramPositions != null) {
        for (final Position pos : paramPositions) {
          insertRoxygen(content, pos, paramTags);
        }
      }

      data.finishPostEdit();
      return data;
    } catch (final Exception e) {
      throw new CoreException(
          new Status(
              IStatus.ERROR,
              RUI.PLUGIN_ID,
              NLS.bind(
                  TemplateMessages.TemplateEvaluation_error_description, template.getDescription()),
              e));
    }
  }