How do I get the current method from the active Eclipse editor?
Asked Answered
Z

2

10

I'm currently working on an Eclipse addon which would help me coding. Basically a library of String snippets.

When creating a new one, I'd love to give it an ID of sorts ClassName.MethodName.X.

Getting the editor is pretty straightforward:

IWorkbenchPage page = PlatformUI.getWorkbench()
                        .getActiveWorkbenchWindow().getActivePage();
IEditorPart activeEditor = page.getActiveEditor();
if(activeEditor.getClass().getName().endsWith("CompilationUnitEditor")){
// do something
}

Now... is there any way to use the Eclipse jdt APIs to get the name of the method my text cursor is currently in?

Edit: Ok. With the help of Andrew, here's what I got:

IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
IEditorPart activeEditor = page.getActiveEditor();

if(activeEditor instanceof JavaEditor) {
    ICompilationUnit root = (ICompilationUnit) EditorUtility.getEditorInputJavaElement(activeEditor, false);
    try {
        ITextSelection sel = (ITextSelection) ((JavaEditor) activeEditor)
            .getSelectionProvider().getSelection();
        int offset = sel.getOffset();
        IJavaElement element = root.getElementAt(offset);
        if(element.getElementType() == IJavaElement.METHOD){
            return element.getElementName());
        }
    } catch (JavaModelException e) {
        e.printStackTrace();
    }
}

Works pretty good. Although it's kind of a dirty solution to use restricted classes.

Zosima answered 12/3, 2012 at 13:9 Comment(0)
L
6

Not sure if you are asking for the method surrounding the current caret location, or the method that the caret location is selecting. I'll show you both.

First, surrounding method:

IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
IEditorPart activeEditor = page.getActiveEditor();
if(activeEditor instanceof JavaEditor) {
    IJavaElement elt = ((JavaEditor) activeEditor).getElementAt(((TextSelection) activeEditor.getSelection()).getOffset(), true);
    if (elt.getElementType == IJavaElement.METHOD) {
        return (IMethod) elt;
    }
}
return null;

The important methods are getElementAt and getSelection.

And here is how to find the method that is currently selected by the caret:

IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
IEditorPart activeEditor = page.getActiveEditor();
if(activeEditor instanceof JavaEditor) {
    ITypeRoot root = EditorUtility.getEditorInputJavaElement(this, false);
    TextSelection sel = ((TextSelection) activeEditor.getSelection());
    IJavaElement elt = root.codeSelect(sel.getOffset(), sel.getLength();
    if (elt.getElementType == IJavaElement.METHOD) {
        return (IMethod) elt;
    }
}
return null;

The interesting method here is codeSelect which resolves the current selection in the context of the given compilation unit or class file.

Actual code will be different since you need to check for null in many places, but you should not need to do any other instanceof tests.

Lemnos answered 12/3, 2012 at 21:56 Comment(6)
Unfortunately, getElementAt() is a protected abstract method. How would I use that?Zosima
Right....missed that. You can call getElementAt on the ITypeRoot. So, EditorUtility.getEditorInputJavaElement(this, false).getElementAt(...) should work.Lemnos
Well. I figured something out. Thanks for the hints ;)Zosima
It's a pity there appears to be no way to do this without using internal APIs.Spearmint
Internal APIs in Eclipse are just a recommendation. You can't get anything done without using them.Lemnos
@BrianDuff At least in this case it is possible to go without the internal API. I have added a way.Wardship
W
11

Here the same done without using internal Eclipse APIs:

IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
ITextEditor editor = (ITextEditor) page.getActiveEditor();
IJavaElement elem = JavaUI.getEditorInputJavaElement(editor.getEditorInput());
if (elem instanceof ICompilationUnit) {
    ITextSelection sel = (ITextSelection) editor.getSelectionProvider().getSelection();
    IJavaElement selected = ((ICompilationUnit) elem).getElementAt(sel.getOffset());
    if (selected != null && selected.getElementType() == IJavaElement.METHOD) {
         return (IMethod) selected;
    }
}
return null;
Wardship answered 6/11, 2012 at 1:56 Comment(1)
I think you misspelled unit (beeing elem) and selected has no declaration (IJavaElement). But it works. Thanks.Conah
L
6

Not sure if you are asking for the method surrounding the current caret location, or the method that the caret location is selecting. I'll show you both.

First, surrounding method:

IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
IEditorPart activeEditor = page.getActiveEditor();
if(activeEditor instanceof JavaEditor) {
    IJavaElement elt = ((JavaEditor) activeEditor).getElementAt(((TextSelection) activeEditor.getSelection()).getOffset(), true);
    if (elt.getElementType == IJavaElement.METHOD) {
        return (IMethod) elt;
    }
}
return null;

The important methods are getElementAt and getSelection.

And here is how to find the method that is currently selected by the caret:

IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
IEditorPart activeEditor = page.getActiveEditor();
if(activeEditor instanceof JavaEditor) {
    ITypeRoot root = EditorUtility.getEditorInputJavaElement(this, false);
    TextSelection sel = ((TextSelection) activeEditor.getSelection());
    IJavaElement elt = root.codeSelect(sel.getOffset(), sel.getLength();
    if (elt.getElementType == IJavaElement.METHOD) {
        return (IMethod) elt;
    }
}
return null;

The interesting method here is codeSelect which resolves the current selection in the context of the given compilation unit or class file.

Actual code will be different since you need to check for null in many places, but you should not need to do any other instanceof tests.

Lemnos answered 12/3, 2012 at 21:56 Comment(6)
Unfortunately, getElementAt() is a protected abstract method. How would I use that?Zosima
Right....missed that. You can call getElementAt on the ITypeRoot. So, EditorUtility.getEditorInputJavaElement(this, false).getElementAt(...) should work.Lemnos
Well. I figured something out. Thanks for the hints ;)Zosima
It's a pity there appears to be no way to do this without using internal APIs.Spearmint
Internal APIs in Eclipse are just a recommendation. You can't get anything done without using them.Lemnos
@BrianDuff At least in this case it is possible to go without the internal API. I have added a way.Wardship

© 2022 - 2024 — McMap. All rights reserved.