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,95 @@
-
+
+
+ unit
+
+ org.netbeans.libs.junit4
+
+
+
+ org.netbeans.insane
+
+
+
+ org.netbeans.modules.nbjunit
+
+
+
+ org.openide.filesystems
+
+
+
+ 9.0
+
+
+
+ org.openide.filesystems.nb
+
+
+
+ 9.0
+
+
+
+ org.openide.io
+
+
+
+ 1.11
+
+
+
+ org.openide.loaders
+
+
+
+ 7.61
+
+
+
+ org.openide.nodes
+
+
+
+ 7.2
+
+
+
+ org.openide.text
+
+
+
+ 6.16
+
+
+
+ org.openide.util
+
+
+
+ 9.3
+
+
+
+ org.openide.util.lookup
+
+
+
+ 8.0
+
+
+
+ org.netbeans.modules.libs.groovy
+
+
+
+ 1.0
+
+
+
+ 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.singleton(s), new UserTask() {
+ @Override
+ public void run(ResultIterator rit) throws Exception {
+ Result r = rit.getParserResult();
+ //0:line, 1:column
+ final int[] lc = getLineAndColumn(doc.getText(0, doc.getLength()), cursor);
+ final int line = lc[0];
+ final int col = lc[1];
+ final ModuleNode root = extractModuleNode(r);
+ final ClassNode cn = getClassNodeForLineAndColumn(root, line, col);
+ final MethodNode mn = getMethodNodeForLineAndColumn(cn, line, col);
+ if (mn != null) {
+ final SingleMethod lsm = new SingleMethod(s.getFileObject(), mn.getName());
+ sm.set(lsm);
+ }
+ }
+
+ });
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return sm.get();
}
static boolean canHandle(Node activatedNode) {
@@ -105,12 +327,24 @@
return false;
}
- EditorCookie ec = activatedNode.getLookup().lookup(EditorCookie.class);
+ final EditorCookie ec = activatedNode.getLookup().lookup(EditorCookie.class);
if (ec != null) {
- JEditorPane pane = NbDocument.findRecentEditorPane(ec);
- if (pane != null) {
- SingleMethod sm = getTestMethod(pane.getDocument(), pane.getCaret().getDot());
- if(sm != null) {
+ final AtomicReference doc = new AtomicReference<>();
+ final AtomicInteger dot = new AtomicInteger();
+ try {
+ EventQueue.invokeAndWait(() -> {
+ final JEditorPane pane = NbDocument.findRecentEditorPane(ec);
+ if (pane != null) {
+ doc.set(pane.getDocument());
+ dot.set(pane.getCaret().getDot());
+ }
+ });
+ } catch (InterruptedException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ if (doc.get() != null) {
+ SingleMethod sm = getTestMethod(doc.get(), dot.get());
+ if (sm != null) {
return true;
}
}
@@ -136,6 +370,8 @@
}
private static boolean isGroovyFile(FileObject fileObj) {
- return "groovy".equals(fileObj.getExt()) || "text/x-groovy".equals(FileUtil.getMIMEType(fileObj)); //NOI18N
+ final String ext = fileObj.getExt();
+ final String mtype = FileUtil.getMIMEType(fileObj);
+ return "groovy".equals(ext) || "text/x-groovy".equals(mtype); //NOI18N
}
}
diff --git a/groovy.support/src/org/netbeans/modules/groovy/support/resources/layer.xml b/groovy.support/src/org/netbeans/modules/groovy/support/resources/layer.xml
--- a/groovy.support/src/org/netbeans/modules/groovy/support/resources/layer.xml
+++ b/groovy.support/src/org/netbeans/modules/groovy/support/resources/layer.xml
@@ -53,6 +53,14 @@
+
+
+
+
+
+
+
+
diff --git a/gsf.testrunner.ui/src/org/netbeans/modules/gsf/testrunner/ui/TestMethodDebuggerAction.java b/gsf.testrunner.ui/src/org/netbeans/modules/gsf/testrunner/ui/TestMethodDebuggerAction.java
--- a/gsf.testrunner.ui/src/org/netbeans/modules/gsf/testrunner/ui/TestMethodDebuggerAction.java
+++ b/gsf.testrunner.ui/src/org/netbeans/modules/gsf/testrunner/ui/TestMethodDebuggerAction.java
@@ -65,14 +65,18 @@
* @author Theofanis Oikonomou
*/
@ActionID(id = "org.netbeans.modules.gsf.testrunner.TestMethodDebuggerAction", category = "CommonTestRunner")
-@ActionRegistration(displayName = "#LBL_Action_DebugTestMethod")
-@ActionReferences(value = {@ActionReference(path = "Editors/text/x-java/Popup", position=1797)})
+@ActionRegistration(lazy = false, displayName = "#LBL_Action_DebugTestMethod")
+@ActionReferences(value = {
+ @ActionReference(path = "Editors/text/x-java/Popup", position = 1797)})
@NbBundle.Messages({"LBL_Action_DebugTestMethod=Debug Focused Test Method"})
public class TestMethodDebuggerAction extends NodeAction {
+
private RequestProcessor.Task debugMethodTask;
private TestMethodDebuggerProvider debugMethodProvider;
-
- /** Creates a new instance of TestMethodDebuggerAction */
+
+ /**
+ * Creates a new instance of TestMethodDebuggerAction
+ */
public TestMethodDebuggerAction() {
putValue("noIconInMenu", Boolean.TRUE); //NOI18N
}
@@ -86,7 +90,7 @@
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
-
+
@Override
public boolean asynchronous() {
return false;
@@ -96,31 +100,31 @@
protected void performAction(final Node[] activatedNodes) {
final Collection extends TestMethodDebuggerProvider> providers = Lookup.getDefault().lookupAll(TestMethodDebuggerProvider.class);
RequestProcessor RP = new RequestProcessor("TestMethodDebuggerAction", 1, true); // NOI18N
- debugMethodTask = RP.create(new Runnable() {
- @Override
- public void run() {
- for (TestMethodDebuggerProvider provider : providers) {
- if (provider.canHandle(activatedNodes[0])) {
- debugMethodProvider = provider;
- break;
- }
- }
- }
- });
- final ProgressHandle ph = ProgressHandleFactory.createHandle(Bundle.Search_For_Provider(), debugMethodTask);
- debugMethodTask.addTaskListener(new TaskListener() {
- @Override
- public void taskFinished(org.openide.util.Task task) {
- ph.finish();
- if(debugMethodProvider == null) {
- StatusDisplayer.getDefault().setStatusText(Bundle.No_Provider_Found());
- } else {
- debugMethodProvider.debugTestMethod(activatedNodes[0]);
- }
- }
- });
- ph.start();
- debugMethodTask.schedule(0);
+ debugMethodTask = RP.create(new Runnable() {
+ @Override
+ public void run() {
+ for (TestMethodDebuggerProvider provider : providers) {
+ if (provider.canHandle(activatedNodes[0])) {
+ debugMethodProvider = provider;
+ break;
+ }
+ }
+ }
+ });
+ final ProgressHandle ph = ProgressHandleFactory.createHandle(Bundle.Search_For_Provider(), debugMethodTask);
+ debugMethodTask.addTaskListener(new TaskListener() {
+ @Override
+ public void taskFinished(org.openide.util.Task task) {
+ ph.finish();
+ if (debugMethodProvider == null) {
+ StatusDisplayer.getDefault().setStatusText(Bundle.No_Provider_Found());
+ } else {
+ debugMethodProvider.debugTestMethod(activatedNodes[0]);
+ }
+ }
+ });
+ ph.start();
+ debugMethodTask.schedule(0);
}
@Override
@@ -128,9 +132,9 @@
if (activatedNodes.length == 0) {
return false;
}
- if(debugMethodTask != null && !debugMethodTask.isFinished()) {
- return false;
- }
+ if (debugMethodTask != null && !debugMethodTask.isFinished()) {
+ return false;
+ }
Collection extends TestMethodDebuggerProvider> providers = Lookup.getDefault().lookupAll(TestMethodDebuggerProvider.class);
for (TestMethodDebuggerProvider provider : providers) {
if (provider.isTestClass(activatedNodes[0])) {
@@ -139,5 +143,5 @@
}
return false;
}
-
+
}
diff --git a/gsf.testrunner.ui/src/org/netbeans/modules/gsf/testrunner/ui/TestMethodRunnerAction.java b/gsf.testrunner.ui/src/org/netbeans/modules/gsf/testrunner/ui/TestMethodRunnerAction.java
--- a/gsf.testrunner.ui/src/org/netbeans/modules/gsf/testrunner/ui/TestMethodRunnerAction.java
+++ b/gsf.testrunner.ui/src/org/netbeans/modules/gsf/testrunner/ui/TestMethodRunnerAction.java
@@ -60,14 +60,18 @@
* @author Theofanis Oikonomou
*/
@ActionID(id = "org.netbeans.modules.gsf.testrunner.TestMethodRunnerAction", category = "CommonTestRunner")
-@ActionRegistration(displayName = "#LBL_Action_RunTestMethod")
-@ActionReferences(value = {@ActionReference(path = "Editors/text/x-java/Popup", position=1795)})
+@ActionRegistration(lazy = false, displayName = "#LBL_Action_RunTestMethod")
+@ActionReferences(value = {
+ @ActionReference(path = "Editors/text/x-java/Popup", position = 1795)})
@NbBundle.Messages({"LBL_Action_RunTestMethod=Run Focused Test Method"})
public class TestMethodRunnerAction extends NodeAction {
+
private RequestProcessor.Task runMethodTask;
private TestMethodRunnerProvider runMethodProvider;
-
- /** Creates a new instance of TestMethodRunnerAction */
+
+ /**
+ * Creates a new instance of TestMethodRunnerAction
+ */
public TestMethodRunnerAction() {
putValue("noIconInMenu", Boolean.TRUE); //NOI18N
}
@@ -81,7 +85,7 @@
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
-
+
@Override
public boolean asynchronous() {
return false;
@@ -89,37 +93,37 @@
@Override
@NbBundle.Messages({"Search_For_Provider=Searching for provider to handle the test method",
- "No_Provider_Found=No provider can handle the test method",
- "Scanning_In_Progress=Scanning in progress, cannot yet identify the name of the test method"})
+ "No_Provider_Found=No provider can handle the test method",
+ "Scanning_In_Progress=Scanning in progress, cannot yet identify the name of the test method"})
protected void performAction(final Node[] activatedNodes) {
final Collection extends TestMethodRunnerProvider> providers = Lookup.getDefault().lookupAll(TestMethodRunnerProvider.class);
- RequestProcessor RP = new RequestProcessor("TestMethodRunnerAction", 1, true); // NOI18N
- runMethodTask = RP.create(new Runnable() {
- @Override
- public void run() {
- for (TestMethodRunnerProvider provider : providers) {
- if (provider.canHandle(activatedNodes[0])) {
- runMethodProvider = provider;
- break;
- }
- }
- }
- });
- final ProgressHandle ph = ProgressHandleFactory.createHandle(Bundle.Search_For_Provider(), runMethodTask);
- runMethodTask.addTaskListener(new TaskListener() {
- @Override
- public void taskFinished(org.openide.util.Task task) {
- ph.finish();
- if(runMethodProvider == null) {
+ RequestProcessor RP = new RequestProcessor("TestMethodRunnerAction", 1, true); // NOI18N
+ runMethodTask = RP.create(new Runnable() {
+ @Override
+ public void run() {
+ for (TestMethodRunnerProvider provider : providers) {
+ if (provider.canHandle(activatedNodes[0])) {
+ runMethodProvider = provider;
+ break;
+ }
+ }
+ }
+ });
+ final ProgressHandle ph = ProgressHandleFactory.createHandle(Bundle.Search_For_Provider(), runMethodTask);
+ runMethodTask.addTaskListener(new TaskListener() {
+ @Override
+ public void taskFinished(org.openide.util.Task task) {
+ ph.finish();
+ if (runMethodProvider == null) {
boolean isIndexing = IndexingManager.getDefault().isIndexing();
StatusDisplayer.getDefault().setStatusText(isIndexing ? Bundle.Scanning_In_Progress() : Bundle.No_Provider_Found());
- } else {
- runMethodProvider.runTestMethod(activatedNodes[0]);
- }
- }
- });
- ph.start();
- runMethodTask.schedule(0);
+ } else {
+ runMethodProvider.runTestMethod(activatedNodes[0]);
+ }
+ }
+ });
+ ph.start();
+ runMethodTask.schedule(0);
}
@Override
@@ -127,9 +131,9 @@
if (activatedNodes.length == 0) {
return false;
}
- if(runMethodTask != null && !runMethodTask.isFinished()) {
- return false;
- }
+ if (runMethodTask != null && !runMethodTask.isFinished()) {
+ return false;
+ }
Collection extends TestMethodRunnerProvider> providers = Lookup.getDefault().lookupAll(TestMethodRunnerProvider.class);
for (TestMethodRunnerProvider provider : providers) {
if (provider.isTestClass(activatedNodes[0])) {
diff --git a/libs.groovy/nbproject/project.xml b/libs.groovy/nbproject/project.xml
--- a/libs.groovy/nbproject/project.xml
+++ b/libs.groovy/nbproject/project.xml
@@ -46,6 +46,7 @@
org.netbeans.modules.groovy.editor
+ org.netbeans.modules.groovy.supportorg.netbeans.modules.groovy.refactoringgroovy.langgroovyjarjarantlr