我设法创建了一个弹出菜单并获得IMethod
,但我不知道如何修改该方法。对于此示例,假设我想在单击按钮时将文本system.out.println("Hello, world!");
添加到现有方法的底部。
我目前的情况如下:
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
所需的任何内容。这样做的正确方法是什么?
答案 0 :(得分:1)
根据Eclipse API:
修改编译单元Java源代码的最简单修改 可以使用Java元素API完成。
例如,您可以从编译单元查询类型。一旦您 拥有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
使用给定内容创建并返回此类型的方法或构造函数。 可选地,新元素可以在指定之前定位 兄弟。如果未指定兄弟,则将附加元素 这种类型。
可能已存在具有相同签名的方法 这个类型。 force参数的值会影响分辨率 这样的冲突:
true - 在这种情况下,使用新内容
创建方法false - 在这种情况下会抛出JavaModelException
如果您正在寻找,请告诉我。
答案 1 :(得分: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();
}
}