diff --git a/groovy.support/nbproject/project.properties b/groovy.support/nbproject/project.properties
--- a/groovy.support/nbproject/project.properties
+++ b/groovy.support/nbproject/project.properties
@@ -36,7 +36,7 @@
#
# Contributor(s):
javac.compilerargs=-Xlint -Xlint:-serial
-javac.source=1.6
+javac.source=1.8
cp.extra=${tools.jar}
nbm.homepage=http://wiki.netbeans.org/groovy
nbm.module.author=Martin Adamek, Petr Hejl, Matthias Schmidt
diff --git a/groovy.support/nbproject/project.xml b/groovy.support/nbproject/project.xml
--- a/groovy.support/nbproject/project.xml
+++ b/groovy.support/nbproject/project.xml
@@ -108,6 +108,14 @@
+ org.netbeans.api.templates
+
+
+
+ 1.0
+
+
+ org.netbeans.modules.gsf.testrunner
@@ -141,7 +149,7 @@
11.62
-
+
org.netbeans.modules.java.source.base
@@ -160,6 +168,14 @@
+ org.netbeans.modules.libs.groovy
+
+
+
+ 1.0
+
+
+ org.netbeans.modules.maven
@@ -323,14 +339,6 @@
- org.netbeans.api.templates
-
-
-
- 1.0
-
-
- org.openide.nodes
@@ -347,14 +355,6 @@
- org.openide.util.ui
-
-
-
- 9.3
-
-
- org.openide.util
@@ -371,6 +371,14 @@
+ org.openide.util.ui
+
+
+
+ 9.3
+
+
+ org.openide.windows
@@ -379,7 +387,59 @@
-
+
+
+ unit
+
+ org.netbeans.libs.junit4
+
+
+
+ org.netbeans.insane
+
+
+
+ org.netbeans.modules.nbjunit
+
+
+
+ org.openide.filesystems
+
+
+
+ org.openide.filesystems.nb
+
+
+
+ org.openide.io
+
+
+
+ org.openide.loaders
+
+
+
+ org.openide.nodes
+
+
+
+ org.openide.text
+
+
+
+ org.openide.util
+
+
+
+ org.openide.util.lookup
+
+
+
+ org.netbeans.modules.libs.groovy
+
+
+
+ org.netbeans.modules.groovy.antprojectorg.netbeans.modules.groovy.editor
diff --git a/groovy.support/src/org/netbeans/modules/groovy/support/actions/DebugMethodAction.java b/groovy.support/src/org/netbeans/modules/groovy/support/actions/DebugMethodAction.java
deleted file mode 100644
--- a/groovy.support/src/org/netbeans/modules/groovy/support/actions/DebugMethodAction.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
- *
- * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
- * Other names may be trademarks of their respective owners.
- *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common
- * Development and Distribution License("CDDL") (collectively, the
- * "License"). You may not use this file except in compliance with the
- * License. You can obtain a copy of the License at
- * http://www.netbeans.org/cddl-gplv2.html
- * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
- * specific language governing permissions and limitations under the
- * License. When distributing the software, include this License Header
- * Notice in each file and include the License file at
- * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the GPL Version 2 section of the License file that
- * accompanied this code. If applicable, add the following below the
- * License Header, with the fields enclosed by brackets [] replaced by
- * your own identifying information:
- * "Portions Copyrighted [year] [name of copyright owner]"
- *
- * If you wish your version of this file to be governed by only the CDDL
- * or only the GPL Version 2, indicate your decision by adding
- * "[Contributor] elects to include this software in this distribution
- * under the [CDDL or GPL Version 2] license." If you do not indicate a
- * single choice of license, a recipient has the option to distribute
- * your version of this file under either the CDDL, the GPL Version 2 or
- * to extend the choice of license to its licensees as provided above.
- * However, if you add GPL Version 2 code and therefore, elected the GPL
- * Version 2 license, then the option applies only if the new code is
- * made subject to such option by the copyright holder.
- *
- * Contributor(s):
- *
- * Portions Copyrighted 2012 Sun Microsystems, Inc.
- */
-
-package org.netbeans.modules.groovy.support.actions;
-
-import java.util.Collection;
-import org.netbeans.modules.gsf.testrunner.ui.api.TestMethodDebuggerProvider;
-import org.openide.awt.ActionID;
-import org.openide.awt.ActionReference;
-import org.openide.awt.ActionRegistration;
-import org.openide.nodes.Node;
-import org.openide.util.HelpCtx;
-import org.openide.util.Lookup;
-import org.openide.util.NbBundle;
-import org.openide.util.actions.NodeAction;
-
-/**
- *
- * @author Martin Janicek
- */
-//@ActionID(id = "org.netbeans.modules.groovy.support.actions.DebugMethodAction", category = "CommonTestRunner")
-//@ActionRegistration(displayName = "#LBL_Action_DebugTestMethod")
-//@ActionReference(path = "Editors/text/x-groovy/Popup", position=860)
-//@NbBundle.Messages({"LBL_Action_DebugTestMethod=Debug Focused Test Method"})
-public class DebugMethodAction extends NodeAction {
-
- public DebugMethodAction() {
- putValue("noIconInMenu", Boolean.TRUE); //NOI18N
- }
-
- @Override
- public String getName() {
- return NbBundle.getMessage(DebugMethodAction.class, "LBL_Action_DebugTestMethod");
- }
-
- @Override
- public HelpCtx getHelpCtx() {
- return HelpCtx.DEFAULT_HELP;
- }
-
- @Override
- public boolean asynchronous() {
- return false;
- }
-
- @Override
- protected void performAction(Node[] activatedNodes) {
- Collection extends TestMethodDebuggerProvider> providers = Lookup.getDefault().lookupAll(TestMethodDebuggerProvider.class);
- for (TestMethodDebuggerProvider provider : providers) {
- if(provider.canHandle(activatedNodes[0])) {
- provider.debugTestMethod(activatedNodes[0]);
- break;
- }
- }
- }
-
- @Override
- protected boolean enable(Node[] activatedNodes) {
- return false;
-// if (activatedNodes.length == 0) {
-// return false;
-// }
-// Collection extends TestMethodDebuggerProvider> providers = Lookup.getDefault().lookupAll(TestMethodDebuggerProvider.class);
-// for (TestMethodDebuggerProvider provider : providers) {
-// if(provider.canHandle(activatedNodes[0])) {
-// return true;
-// }
-// }
-// return false;
- }
-
-}
diff --git a/groovy.support/src/org/netbeans/modules/groovy/support/actions/GroovyTestClassInfoTask.java b/groovy.support/src/org/netbeans/modules/groovy/support/actions/GroovyTestClassInfoTask.java
deleted file mode 100644
--- a/groovy.support/src/org/netbeans/modules/groovy/support/actions/GroovyTestClassInfoTask.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
- *
- * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
- * Other names may be trademarks of their respective owners.
- *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common
- * Development and Distribution License("CDDL") (collectively, the
- * "License"). You may not use this file except in compliance with the
- * License. You can obtain a copy of the License at
- * http://www.netbeans.org/cddl-gplv2.html
- * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
- * specific language governing permissions and limitations under the
- * License. When distributing the software, include this License Header
- * Notice in each file and include the License file at
- * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the GPL Version 2 section of the License file that
- * accompanied this code. If applicable, add the following below the
- * License Header, with the fields enclosed by brackets [] replaced by
- * your own identifying information:
- * "Portions Copyrighted [year] [name of copyright owner]"
- *
- * If you wish your version of this file to be governed by only the CDDL
- * or only the GPL Version 2, indicate your decision by adding
- * "[Contributor] elects to include this software in this distribution
- * under the [CDDL or GPL Version 2] license." If you do not indicate a
- * single choice of license, a recipient has the option to distribute
- * your version of this file under either the CDDL, the GPL Version 2 or
- * to extend the choice of license to its licensees as provided above.
- * However, if you add GPL Version 2 code and therefore, elected the GPL
- * Version 2 license, then the option applies only if the new code is
- * made subject to such option by the copyright holder.
- *
- * Contributor(s):
- *
- * Portions Copyrighted 2012 Sun Microsystems, Inc.
- */
-package org.netbeans.modules.groovy.support.actions;
-
-import com.sun.source.tree.Tree.Kind;
-import com.sun.source.util.TreePath;
-import java.util.Iterator;
-import java.util.List;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.util.Elements;
-import org.netbeans.api.java.source.CancellableTask;
-import org.netbeans.api.java.source.CompilationController;
-import org.netbeans.api.java.source.JavaSource.Phase;
-import org.openide.filesystems.FileObject;
-
-/**
- *
- * @author Martin Janicek
- */
-public final class GroovyTestClassInfoTask implements CancellableTask {
-
- private FileObject fileObject;
-
- private final int caretPosition;
- private String className;
- private String methodName;
-
- private static String ANNOTATION = "org.junit.Test"; //NOI18N
- private static String TESTCASE = "junit.framework.TestCase"; //NOI18N
-
- GroovyTestClassInfoTask(int caretPosition) {
- this.caretPosition = caretPosition;
- }
-
- @Override
- public void cancel() {
- }
-
- @Override
- public void run(CompilationController controller) throws Exception {
- controller.toPhase(Phase.RESOLVED);
- fileObject = controller.getFileObject();
- TypeElement typeElement = null;
- List extends TypeElement> topLevelElements = controller.getTopLevelElements();
- for (Iterator extends TypeElement> it = topLevelElements.iterator(); it.hasNext();) {
- typeElement = it.next();
- if (typeElement.getKind() == ElementKind.CLASS) {
- className = typeElement.getSimpleName().toString();
- break;
- }
- }
- Elements elements = controller.getElements();
- TypeElement testcase = elements.getTypeElement(TESTCASE);
- boolean junit3 = (testcase != null && typeElement != null) ? controller.getTypes().isSubtype(typeElement.asType(), testcase.asType()) : false;
- TreePath tp = controller.getTreeUtilities().pathFor(caretPosition);
- while (tp != null && tp.getLeaf().getKind() != Kind.METHOD) {
- tp = tp.getParentPath();
- }
- if (tp != null) {
- Element element = controller.getTrees().getElement(tp);
- String mn = element.getSimpleName().toString();
- if (junit3){
- methodName = mn.startsWith("test") ? mn : null; //NOI18N
- }else{
- List extends AnnotationMirror> allAnnotationMirrors = elements.getAllAnnotationMirrors(element);
- for (Iterator extends AnnotationMirror> it = allAnnotationMirrors.iterator(); it.hasNext();) {
- AnnotationMirror annotationMirror = it.next();
- typeElement = (TypeElement) annotationMirror.getAnnotationType().asElement();
- if (typeElement.getQualifiedName().contentEquals(ANNOTATION)) {
- methodName = mn;
- break;
- }
- }
- }
- }
- }
-
- public FileObject getFileObject() {
- return fileObject;
- }
-
- String getClassName() {
- return className;
- }
-
- String getMethodName() {
- return methodName;
- }
-}
diff --git a/groovy.support/src/org/netbeans/modules/groovy/support/actions/TestMethodAction.java b/groovy.support/src/org/netbeans/modules/groovy/support/actions/TestMethodAction.java
deleted file mode 100644
--- a/groovy.support/src/org/netbeans/modules/groovy/support/actions/TestMethodAction.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
- *
- * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
- * Other names may be trademarks of their respective owners.
- *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common
- * Development and Distribution License("CDDL") (collectively, the
- * "License"). You may not use this file except in compliance with the
- * License. You can obtain a copy of the License at
- * http://www.netbeans.org/cddl-gplv2.html
- * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
- * specific language governing permissions and limitations under the
- * License. When distributing the software, include this License Header
- * Notice in each file and include the License file at
- * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the GPL Version 2 section of the License file that
- * accompanied this code. If applicable, add the following below the
- * License Header, with the fields enclosed by brackets [] replaced by
- * your own identifying information:
- * "Portions Copyrighted [year] [name of copyright owner]"
- *
- * If you wish your version of this file to be governed by only the CDDL
- * or only the GPL Version 2, indicate your decision by adding
- * "[Contributor] elects to include this software in this distribution
- * under the [CDDL or GPL Version 2] license." If you do not indicate a
- * single choice of license, a recipient has the option to distribute
- * your version of this file under either the CDDL, the GPL Version 2 or
- * to extend the choice of license to its licensees as provided above.
- * However, if you add GPL Version 2 code and therefore, elected the GPL
- * Version 2 license, then the option applies only if the new code is
- * made subject to such option by the copyright holder.
- *
- * Contributor(s):
- *
- * Portions Copyrighted 2012 Sun Microsystems, Inc.
- */
-
-package org.netbeans.modules.groovy.support.actions;
-
-import java.util.Collection;
-import org.netbeans.modules.gsf.testrunner.ui.api.TestMethodRunnerProvider;
-import org.openide.awt.ActionID;
-import org.openide.awt.ActionReference;
-import org.openide.awt.ActionRegistration;
-import org.openide.nodes.Node;
-import org.openide.util.*;
-import org.openide.util.actions.NodeAction;
-
-/**
- *
- * @author mjanicek
- */
-//@ActionID(id = "org.netbeans.modules.groovy.support.actions.TestMethodAction", category = "CommonTestRunner")
-//@ActionRegistration(displayName = "#LBL_Action_RunTestMethod")
-//@ActionReference(path = "Editors/text/x-groovy/Popup", position=850)
-//@NbBundle.Messages({"LBL_Action_RunTestMethod=Run Focused Test Method"})
-public class TestMethodAction extends NodeAction {
-
- public TestMethodAction() {
- putValue("noIconInMenu", Boolean.TRUE); //NOI18N
- }
-
- @Override
- public String getName() {
- return NbBundle.getMessage(TestMethodAction.class, "LBL_Action_RunTestMethod");
- }
-
- @Override
- public HelpCtx getHelpCtx() {
- return HelpCtx.DEFAULT_HELP;
- }
-
- @Override
- public boolean asynchronous() {
- return false;
- }
-
- @Override
- protected void performAction(Node[] activatedNodes) {
- Collection extends TestMethodRunnerProvider> providers = Lookup.getDefault().lookupAll(TestMethodRunnerProvider.class);
- for (TestMethodRunnerProvider provider : providers) {
- if (provider.canHandle(activatedNodes[0])) {
- provider.runTestMethod(activatedNodes[0]);
- break;
- }
- }
- }
-
- @Override
- protected boolean enable(Node[] activatedNodes) {
- return false;
-// if (activatedNodes.length == 0) {
-// return false;
-// }
-// Collection extends TestMethodRunnerProvider> providers = Lookup.getDefault().lookupAll(TestMethodRunnerProvider.class);
-// for (TestMethodRunnerProvider provider : providers) {
-// if (provider.canHandle(activatedNodes[0])) {
-// return true;
-// }
-// }
-// return false;
- }
-}
diff --git a/groovy.support/src/org/netbeans/modules/groovy/support/actions/TestMethodUtil.java b/groovy.support/src/org/netbeans/modules/groovy/support/actions/TestMethodUtil.java
--- a/groovy.support/src/org/netbeans/modules/groovy/support/actions/TestMethodUtil.java
+++ b/groovy.support/src/org/netbeans/modules/groovy/support/actions/TestMethodUtil.java
@@ -39,17 +39,29 @@
*
* Portions Copyrighted 2012 Sun Microsystems, Inc.
*/
-
package org.netbeans.modules.groovy.support.actions;
+import java.awt.EventQueue;
import java.io.IOException;
-import java.lang.ref.Reference;
-import java.util.concurrent.Future;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import java.io.LineNumberReader;
+import java.io.StringReader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
import javax.swing.JEditorPane;
import javax.swing.text.Document;
-import org.netbeans.api.java.source.JavaSource;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.ModuleNode;
+import org.netbeans.modules.parsing.api.ParserManager;
+import org.netbeans.modules.parsing.api.ResultIterator;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.api.UserTask;
+import org.netbeans.modules.parsing.spi.ParseException;
+import org.netbeans.modules.parsing.spi.Parser.Result;
import org.netbeans.spi.project.SingleMethod;
import org.openide.cookies.EditorCookie;
import org.openide.filesystems.FileObject;
@@ -58,6 +70,7 @@
import org.openide.loaders.DataObject;
import org.openide.nodes.Node;
import org.openide.text.NbDocument;
+import org.openide.util.Parameters;
/**
*
@@ -65,37 +78,246 @@
*/
public final class TestMethodUtil {
- private static final Logger LOGGER = Logger.getLogger(TestMethodUtil.class.getName());
- private Reference resolver;
+ private static final String GROOVY_PARSER_RESULT_CLASS_NAME = "org.netbeans.modules.groovy.editor.api.parser.GroovyParserResult";
+
+ private static final String GPR_GET_ROOT_ELEMENT = "getRootElement";
+
+ private static final String AST_GET_MODULE_NODE = "getModuleNode";
static boolean isTestClass(Node activatedNode) {
FileObject fo = getFileObjectFromNode(activatedNode);
if (fo != null) {
- if (!isGroovyFile(fo)) {
- return false;
- }
//TODO add more checks here when action gets enabled?
+ return isGroovyFile(fo);
}
return false;
}
- static SingleMethod getTestMethod(Document doc, int cursor){
- SingleMethod sm = null;
- if (doc != null){
- JavaSource js = JavaSource.forDocument(doc);
- GroovyTestClassInfoTask task = new GroovyTestClassInfoTask(cursor);
+ /**
+ * Given the text from a Document, will read through the lines, adding 1 to
+ * a counter for each line, plus the length of the given line until the
+ * value is greater than or equal to the cursor, and this gives us the line.
+ * Next, the offset in the line which would make the counter equal to the
+ * cursor value is taken to represent the column. This is done to map to the
+ * Groovy AST nodes line and columns to match to classes and methods. The
+ * return from this method can be used to find the class and method the
+ * cursor is in. Remember, the Groovy lines and columns are index 1 with
+ * relation to the AST node classes.
+ *
+ * @param srcText the Groovy source as represented in the edited Groovy
+ * document; it must be this text as the expectation is a line will always
+ * end in a \n
+ * @param cursor the cursor offset in the given text.
+ * @return the line and column of the cursor offset in the text as an
+ * integer array such that index 0 is the line, and index 1 is the column
+ */
+ public static int[] getLineAndColumn(final String srcText, final int cursor) {
+ Parameters.notNull("srcText", srcText);
+ Parameters.notEmpty("srcText", srcText);
+ int[] ret = new int[]{-1, -1};
+ if (cursor > 0) {
try {
- if (js != null) {
- Future f = js.runWhenScanFinished(task, true);
- if (f.isDone() && task.getFileObject() != null && task.getMethodName() != null){
- sm = new SingleMethod(task.getFileObject(), task.getMethodName());
+ final StringReader sr = new StringReader(srcText);
+ final LineNumberReader lr = new LineNumberReader(sr);
+ int counter = 0;
+ String line;
+ while ((line = lr.readLine()) != null) {
+ //remember, we went over a line, and it has a \n
+ counter += line.length();
+ if (counter >= cursor) {
+ //lr incs line number at every line it reads,
+ //and started at 0
+ ret[0] = lr.getLineNumber();
+ //if we take away what we just added, then take the whole
+ //away from the cursor, then we are left with the number
+ //it takes to equal the cursor, and then since the chars
+ //and positions in the line are 0 indexed, we need to add
+ //1; if 0 or 0 length, then that should also work out
+ //correctly as if the cursor is on the line, it is in
+ //column 1
+ ret[1] = (cursor - (counter - line.length())) + 1;
+ break;
}
+ //account for the newline now as we don't care about it
+ //until we are done with the "current" line. The extra value
+ //will throw off the above calculation if added too soon, but
+ //if not added at all will also throw it off. So, add it here.
+ counter++;
}
} catch (IOException ex) {
- LOGGER.log(Level.WARNING, null, ex);
+ throw new RuntimeException(ex);
+ }
+ } else if (cursor == 0) {
+ //first line and start of first line
+ ret[0] = 1;
+ ret[1] = 1;
+ }
+ return ret;
+ }
+
+ /**
+ * Given a start and end line and a start and end column plus a given line
+ * and column, tests if the given line and column falls between the start
+ * and end values in relation to Groovy code and the Groovy AST.
+ *
+ * @param startLine the start line
+ * @param startCol the start column
+ * @param endLine the end line
+ * @param endCol the end column
+ * @param line the line to test
+ * @param col the column to test
+ * @return whether the line and column fall between the given start and end
+ * values
+ */
+ public static boolean isBetweenLinesAndColumns(final int startLine,
+ final int startCol,
+ final int endLine,
+ final int endCol,
+ final int line,
+ final int col) {
+ boolean ret = false;
+ if (line >= startLine && line <= endLine) {
+ //at the momment we are approximately
+ //in the method bounds, so we'll assume
+ //true, then adjust accordingly
+ //as this is simpler than embedded ifs
+ //and logic as we only care about the col
+ //if we are on one of the bounding lines
+ ret = true;
+
+ //even though above we say true, we may take it back
+ //if on the same line as the start line and not in
+ //the method bounds
+ if (line == startLine && !(col >= startCol)) {
+ ret = false;
+ }
+
+ //even though above we may say true, we may take it back
+ //if on the same line as the end line and not in
+ //the method bounds
+ if (line == endLine && !(col <= endCol)) {
+ ret = false;
}
}
- return sm;
+ return ret;
+ }
+
+ /**
+ * Gets the Groovy AST ModuleNode associated with the given Source result.
+ * This is currently done with reflection due to the dependency graph of
+ * "Groovy Support" and "Groovy Editor". This is hopefully just temporary
+ * until the modules can be refactored into a better DAG.
+ *
+ * @param r the Result to extract from
+ * @return the ModuleNode if the Result is in fact a "GroovyParserResult",
+ * the sources have been parsed, and the {@link ModuleNode ModuleNode} has
+ * been set. If not set or the wrong "Result" time, then null will be
+ * returned.
+ */
+ public static ModuleNode extractModuleNode(final Result r) {
+ //below line long to show up properly in enumerations
+ //TODO TestMethodUtil.extractModuleNode refactor "Groovy Support" and "Groovy Editor" to have a better DAG to remove need to use reflection to extract Groovy ModuleNode
+ ModuleNode ret = null;
+ try {
+ //no need to test result type as it will have the method or it won't
+ //and this makes it easier to test
+ final Method getRE = r.getClass().getMethod(GPR_GET_ROOT_ELEMENT);
+ final Object astRoot = getRE.invoke(r);
+ if (astRoot != null) {
+ final Method getMN = astRoot.getClass().getMethod(AST_GET_MODULE_NODE);
+ final ModuleNode lmn = ModuleNode.class.cast(getMN.invoke(astRoot));
+ ret = lmn;
+ }
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+ //push it up to the NB caller
+ throw new RuntimeException("The given result doesn't appear to come from parsing a Groovy file.", e);
+ }
+ return ret;
+ }
+
+ /**
+ * Given a root {@link ModuleNode ModuleNode}, finds and returns the
+ * {@link ClassNode ClassNode} for the given line and column. It is possible
+ * in some situations for this to be null.
+ *
+ * @param root the root ModuleNode
+ * @param line the line
+ * @param col the column
+ * @return the ClassNode for the line and column (cursor)
+ */
+ public static ClassNode getClassNodeForLineAndColumn(final ModuleNode root,
+ final int line,
+ final int col) {
+ ClassNode ret = null;
+ if (root != null) {
+ final List classes = root.getClasses();
+ for (ClassNode cn : classes) {
+ if (isBetweenLinesAndColumns(cn.getLineNumber(), cn.getColumnNumber(),
+ cn.getLastLineNumber(), cn.getLastColumnNumber(),
+ line, col)) {
+ return cn;
+ }
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Given a {@link ClassNode ClassNode}, finds and returns the
+ * {@link MethodNode MethodNode} for the given line and column. It is
+ * possible in some situations for this to be null.
+ *
+ * @param cn the ClassNode
+ * @param line the line
+ * @param col the column
+ * @return the MethodNode for the line and column (cursor)
+ */
+ public static MethodNode getMethodNodeForLineAndColumn(final ClassNode cn,
+ final int line,
+ final int col) {
+ MethodNode ret = null;
+ if (cn != null) {
+ final List methods = cn.getMethods();
+ for (MethodNode mn : methods) {
+ if (isBetweenLinesAndColumns(mn.getLineNumber(), mn.getColumnNumber(),
+ mn.getLastLineNumber(), mn.getLastColumnNumber(),
+ line, col)) {
+ return mn;
+ }
+ }
+ }
+ return ret;
+ }
+
+ public static SingleMethod getTestMethod(final Document doc, final int cursor) {
+ final AtomicReference sm = new AtomicReference<>();
+ if (doc != null) {
+
+ Source s = Source.create(doc);
+ try {
+ ParserManager.parseWhenScanFinished(Collections.