2014-10-21 4 views
2

Мне удалось создать всплывающее меню и получить IMethod, но я не знаю, как изменить метод. В этом примере предположим, что я хочу добавить текст system.out.println("Hello, world!"); в нижнюю часть существующего метода при нажатии кнопки.Как изменить тело функции в плагине eclipse?

То, что я в настоящее время находится ниже:

import org.eclipse.jface.action.IAction; 
import org.eclipse.jface.viewers.ISelection; 
import org.eclipse.jface.viewers.IStructuredSelection; 
import org.eclipse.swt.widgets.Shell; 
import org.eclipse.ui.IObjectActionDelegate; 
import org.eclipse.ui.IWorkbenchPart; 
import org.eclipse.jdt.core.IMethod; 

public class HelloWorldAction implements IObjectActionDelegate { 

    private Shell shell; 

    private IMethod currentMethod; 

    /** 
    * Constructor for Action1. 
    */ 
    public HelloWorldAction() { 
     super(); 
    } 

    /** 
    * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) 
    */ 
    public void setActivePart(IAction action, IWorkbenchPart targetPart) { 
     shell = targetPart.getSite().getShell(); 
    } 

    /** 
    * @see IActionDelegate#run(IAction) 
    */ 
    public void run(IAction action) { 
     //TODO: preform the actions. 
    } 

    /** 
    * @see IActionDelegate#selectionChanged(IAction, ISelection) 
    */ 
    public void selectionChanged(IAction action, ISelection selection) { 
     if (!(selection instanceof IStructuredSelection)) { 
      action.setEnabled(false); 
      return; 
     } 
     IStructuredSelection sel = (IStructuredSelection) selection; 

     if (!(sel.getFirstElement() instanceof IMethod)) { 
      //Only handles IMethods. 
      action.setEnabled(false); 
      return; 
     } 

     action.setEnabled(true); 
     this.currentMethod = (IMethod) sel.getFirstElement(); 
    } 
} 

Я застрял на модификации currentMethod. Я видел this help page on modifying code, но я не знаю, как получить Document, AST, или действительно любую из вещей, необходимых от IMethod. Каков правильный способ сделать это?

ответ

1

По Eclipse API:

Изменение единицу компиляции Наиболее простые модификации источника Java может быть сделано с помощью элемента API Java.

Например, вы можете запросить тип из единицы компиляции. После того, как у вас есть IType, вы можете использовать такие протоколы, как createField, createInitializer, createMethod или createType, чтобы добавить исходный код пользователей. Исходный код и информация о местонахождении элемента предоставляются в этих методах.

Я хотел бы попробовать использовать:

currentMethod.getCompilationUnit().getTypes()[0].createMethod(" hello world code goes here ",null,true,null); 
//not sure if progress monitor can be null, please check 

По Eclipse API:

IMethod createMethod (содержание строк, IJavaElement одноуровневых, булево сила, IProgressMonitor монитор) бросками JavaModelException

Создает и возвращает метод или конструктор этого типа с заданным содержимым. Необязательно, новый элемент может быть размещен до указанного брата-близнеца . Если ни один брат не указан, элемент будет добавлен к этого типа.

Возможно, что метод с такой же сигнатурой уже существует в этого типа. Значение параметра силы влияет на разрешение такого конфликта:

истинной - в этом случае метод создается с новым содержанием

ложные - в этом случае JavaModelException отбрасывается

Сообщите мне, если это то, что вы искали.

+0

Это полезно (хотя я решил это по-другому), но он не добавляет текст к существующему методу. Но это помогает. Я отправлю ответ с помощью решения, которое я использовал. – Pokechu22

1

У меня это выяснено.

Следующая базируется на the example of using AST from the documentation и присоединяет текст System.out.println("Hello" + " world"); до конца существующей функции.

import org.eclipse.jface.action.IAction; 
import org.eclipse.jface.text.Document; 
import org.eclipse.jface.viewers.ISelection; 
import org.eclipse.jface.viewers.IStructuredSelection; 
import org.eclipse.swt.widgets.Shell; 
import org.eclipse.text.edits.TextEdit; 
import org.eclipse.ui.IObjectActionDelegate; 
import org.eclipse.ui.IWorkbenchPart; 
import org.eclipse.jdt.core.ICompilationUnit; 
import org.eclipse.jdt.core.IMethod; 
import org.eclipse.jdt.core.dom.*; 
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 

public class HelloWorldAction implements IObjectActionDelegate { 

    private Shell shell; 

    private IMethod currentMethod; 

    /** 
    * Constructor for Action1. 
    */ 
    public AddFace2() { 
     super(); 
    } 

    /** 
    * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) 
    */ 
    public void setActivePart(IAction action, IWorkbenchPart targetPart) { 
     shell = targetPart.getSite().getShell(); 
    } 

    /** 
    * @see IActionDelegate#run(IAction) 
    */ 
    public void run(IAction action) { 
     //Following is based off of the sample at http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.jdt.doc.isv%2Fguide%2Fjdt_api_manip.htm 

     try { 
      ICompilationUnit cu = currentMethod.getCompilationUnit(); 
      String source = cu.getSource(); 
      Document document= new Document(source); 


      //Get the compilation unit for traversing AST 
      final ASTParser parser = ASTParser.newParser(AST.JLS8); 
      parser.setSource(currentMethod.getCompilationUnit()); 
      parser.setResolveBindings(true); 

      final CompilationUnit compilationUnit = (CompilationUnit) parser.createAST(null); 

      // record modification - to be later written with ASTRewrite 
      compilationUnit.recordModifications(); 

      // Get AST node for IMethod 
      int methodIndex = currentMethod.getCompilationUnit().getSource().indexOf(currentMethod.getSource()); 

      //Convert to a MethodDeclaration. 
      MethodDeclaration methodASTNode = (MethodDeclaration)NodeFinder.perform(compilationUnit.getRoot(), methodIndex, currentMethod.getSource().length()); 

      ASTRewrite rewrite = ASTRewrite.create(compilationUnit.getAST()); 

      Block blockOld = methodASTNode.getBody(); 

      //Create a copy of the old block. 
      AST blockAST = AST.newAST(AST.JLS8); 
      Block block = (Block) Block.copySubtree(blockAST, blockOld); 

      //Add "System.out.println("hello" + " world");". 
      MethodInvocation methodInvocation = blockAST.newMethodInvocation(); 

      QualifiedName name = blockAST.newQualifiedName(
        blockAST.newSimpleName("System"), 
        blockAST.newSimpleName("out")); 

      methodInvocation.setExpression(name); 
      methodInvocation.setName(blockAST.newSimpleName("println")); 
      InfixExpression infixExpression = blockAST.newInfixExpression(); 
      infixExpression.setOperator(InfixExpression.Operator.PLUS); 
      StringLiteral literal = blockAST.newStringLiteral(); 
      literal.setLiteralValue("Hello"); 
      infixExpression.setLeftOperand(literal); 
      literal = blockAST.newStringLiteral(); 
      literal.setLiteralValue(" world"); 
      infixExpression.setRightOperand(literal); 
      methodInvocation.arguments().add(infixExpression); 
      ExpressionStatement expressionStatement = blockAST.newExpressionStatement(methodInvocation); 
      block.statements().add(expressionStatement); 

      rewrite.replace(blockOld, block, null); 


      // computation of the text edits 
      TextEdit edits = rewrite.rewriteAST(document, cu.getJavaProject().getOptions(true)); 

      // computation of the new source code 
      edits.apply(document); 
      String newSource = document.get(); 

      // update of the compilation unit 
      cu.getBuffer().setContents(newSource); 

     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 


    } 

    /** 
    * @see IActionDelegate#selectionChanged(IAction, ISelection) 
    */ 
    public void selectionChanged(IAction action, ISelection selection) { 
     if (!(selection instanceof IStructuredSelection)) { 
      action.setEnabled(false); 
      return; 
     } 
     IStructuredSelection sel = (IStructuredSelection) selection; 

     if (!(sel.getFirstElement() instanceof IMethod)) { 
      //Only handles IMethods. 
      action.setEnabled(false); 
      return; 
     } 

     action.setEnabled(true); 
     this.currentMethod = (IMethod) sel.getFirstElement(); 
    } 

} 
Смежные вопросы