diff --git a/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/debug/BreakpointLocationTests.groovy b/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/debug/BreakpointLocationTests.groovy index 853d191658..014acd1ea5 100644 --- a/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/debug/BreakpointLocationTests.groovy +++ b/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/debug/BreakpointLocationTests.groovy @@ -16,6 +16,7 @@ package org.codehaus.groovy.eclipse.test.debug import org.codehaus.groovy.ast.ASTNode +import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.ConstructorNode import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.MethodNode @@ -221,7 +222,8 @@ final class BreakpointLocationTests extends GroovyEclipseTestSuite { } '''.stripIndent() - assert node?.lineNumber == 2 + assert node instanceof ClassNode + assert node.lineNumber == 1 } @Test @@ -352,8 +354,8 @@ final class BreakpointLocationTests extends GroovyEclipseTestSuite { } '''.stripIndent() - assert node instanceof ConstructorNode - assert node.lineNumber == 5 + assert node instanceof ClassNode + assert node.lineNumber == 4 } @Test diff --git a/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/debug/ui/BreakpointLocationFinder.java b/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/debug/ui/BreakpointLocationFinder.java index 06628761da..7637ecc4c1 100644 --- a/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/debug/ui/BreakpointLocationFinder.java +++ b/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/debug/ui/BreakpointLocationFinder.java @@ -23,6 +23,7 @@ import org.codehaus.groovy.ast.ASTNode; import org.codehaus.groovy.ast.AnnotatedNode; import org.codehaus.groovy.ast.AnnotationNode; +import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.FieldNode; import org.codehaus.groovy.ast.MethodNode; import org.codehaus.groovy.ast.ModuleNode; @@ -56,19 +57,27 @@ protected void visitExpression(Expression expression) { } @Override - public void visitMethod(MethodNode method) { - if (method.getLineNumber() > 0) { - nodes.add(method); + public void visitMethod(MethodNode node) { + if (node.getNameStart() > 0) { + nodes.add(node); } - super.visitMethod(method); + super.visitMethod(node); } @Override - public void visitField(FieldNode field) { - if (field.getLineNumber() > 0) { - nodes.add(field); + public void visitField(FieldNode node) { + if (node.getNameStart() > 0) { + nodes.add(node); } - super.visitField(field); + super.visitField(node); + } + + @Override + public void visitClass(ClassNode node) { + if (node.getNameStart() > 0) { + nodes.add(node); + } + super.visitClass(node); } }.visitModule(module); @@ -98,7 +107,7 @@ public ASTNode findBreakpointLocation(int lineNumber) { } protected int lineNumber(ASTNode node) { - if (locator != null && (node instanceof MethodNode || node instanceof FieldNode)) { + if (locator != null && (node instanceof AnnotatedNode && !(node instanceof Expression))) { // annotations, modifiers and generics may be on separate line(s) int[] row_col = locator.getRowCol(((AnnotatedNode) node).getNameStart()); if (row_col != null && row_col.length > 0) { diff --git a/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/debug/ui/BreakpointLocationVerifierJob.java b/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/debug/ui/BreakpointLocationVerifierJob.java index 111b97ee71..ae73c43b36 100644 --- a/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/debug/ui/BreakpointLocationVerifierJob.java +++ b/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/debug/ui/BreakpointLocationVerifierJob.java @@ -20,6 +20,7 @@ import org.codehaus.groovy.antlr.LocationSupport; import org.codehaus.groovy.ast.ASTNode; +import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.FieldNode; import org.codehaus.groovy.ast.MethodNode; import org.codehaus.groovy.ast.ModuleNode; @@ -34,6 +35,7 @@ import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.Signature; +import org.eclipse.jdt.debug.core.IJavaClassPrepareBreakpoint; import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; import org.eclipse.jdt.debug.core.JDIDebugModel; import org.eclipse.jdt.groovy.core.util.GroovyUtils; @@ -107,9 +109,11 @@ public IStatus run(IProgressMonitor monitor) { ModuleNode module = Adapters.adapt(fEditorPart, ModuleNode.class); if (module != null) { ASTNode found = new BreakpointLocationFinder(module).findBreakpointLocation(fLineNumber); - if (found instanceof FieldNode && ((FieldNode) found).getNameEnd() > 0) { + if (found instanceof ClassNode && ((ClassNode) found).getNameStart() > 0) { + createNewClassBreakpoint((ClassNode) found, module.getNodeMetaData(LocationSupport.class)); + } else if (found instanceof FieldNode && ((FieldNode) found).getNameStart() > 0) { createNewFieldBreakpoint((FieldNode) found, module.getNodeMetaData(LocationSupport.class)); - } else if (found instanceof MethodNode && ((MethodNode) found).getNameEnd() > 0) { + } else if (found instanceof MethodNode && ((MethodNode) found).getNameStart() > 0) { createNewMethodBreakpoint((MethodNode) found, module.getNodeMetaData(LocationSupport.class)); } else if (found != null) { createNewLineBreakpoint(found); @@ -123,20 +127,57 @@ public IStatus run(IProgressMonitor monitor) { } // cannot find a valid location - report(ActionMessages.BreakpointLocationVerifierJob_not_valid_location); + JDIDebugUIPlugin.getStandardDisplay().asyncExec(() -> { + IEditorStatusLine statusLine = Adapters.adapt(fEditorPart, IEditorStatusLine.class); + if (statusLine != null) { + statusLine.setMessage(true, ActionMessages.BreakpointLocationVerifierJob_not_valid_location, null); + } + if (JDIDebugUIPlugin.getActiveWorkbenchShell() != null) { + Display.getCurrent().beep(); + } + }); return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), ActionMessages.BreakpointLocationVerifierJob_not_valid_location); } + private void createNewLineBreakpoint(ASTNode node) throws CoreException { + // make sure that breakpoint doesn't exist on this line; line may have moved by the validator + if (JDIDebugModel.lineBreakpointExists(fTypeName, node.getLineNumber()) == null) { + // TODO: Find surrounding declaration for more accurate attributes + Map newAttributes = new HashMap<>(); + int start = node.getStart(), end = node.getEnd(); + if (fType != null) { + BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(newAttributes, fType, start, end); + } + JDIDebugModel.createLineBreakpoint(fResource, fTypeName, node.getLineNumber(), start, end, 0, true, newAttributes); + } + } + + private void createNewClassBreakpoint(ClassNode node, LocationSupport locator) throws CoreException { + if (fType != null) { + int start = node.getNameStart(), end = node.getNameEnd(); + IJavaElement element = fType.getTypeRoot().getElementAt(start); + if (element != null) { + int memberType = (!node.isInterface() + ? IJavaClassPrepareBreakpoint.TYPE_CLASS + : IJavaClassPrepareBreakpoint.TYPE_INTERFACE); + Map attributes = new HashMap<>(); + BreakpointUtils.addJavaBreakpointAttributes(attributes, element); + BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, element, start, end); + JDIDebugModel.createClassPrepareBreakpoint(fResource, node.getName(), memberType, start, end, true, attributes); + } + } + } + private void createNewFieldBreakpoint(FieldNode node, LocationSupport locator) throws CoreException { if (fType != null) { int start = node.getNameStart(), end = node.getNameEnd(); - IJavaElement elem = fType.getTypeRoot().getElementAt(start); - if (elem != null) { + IJavaElement element = fType.getTypeRoot().getElementAt(start); + if (element != null) { int lineNumber = locator.getRowCol(start)[0]; Map attributes = new HashMap<>(); - BreakpointUtils.addJavaBreakpointAttributes(attributes, elem); - BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, fType, start, end); - JDIDebugModel.createWatchpoint(fResource, fTypeName, node.getName(), lineNumber, start, end, 0, true, attributes); + BreakpointUtils.addJavaBreakpointAttributes(attributes, element); + BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, element, start, end); + JDIDebugModel.createWatchpoint(fResource, node.getDeclaringClass().getName(), node.getName(), lineNumber, start, end, 0, true, attributes); } } } @@ -144,50 +185,22 @@ private void createNewFieldBreakpoint(FieldNode node, LocationSupport locator) t private void createNewMethodBreakpoint(MethodNode node, LocationSupport locator) throws CoreException { if (fType != null) { int start = node.getNameStart(), end = node.getNameEnd(); - IJavaElement elem = fType.getTypeRoot().getElementAt(start); - if (elem != null) { + IJavaElement element = fType.getTypeRoot().getElementAt(start); + if (element != null) { int lineNumber = locator.getRowCol(start)[0]; Map attributes = new HashMap<>(); - BreakpointUtils.addJavaBreakpointAttributes(attributes, elem); - BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, fType, start, end); - JDIDebugModel.createMethodBreakpoint(fResource, fTypeName, node.getName(), createMethodSignature(node), true, false, false, lineNumber, start, end, 0, true, attributes); + BreakpointUtils.addJavaBreakpointAttributes(attributes, element); + BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, element, start, end); + JDIDebugModel.createMethodBreakpoint(fResource, node.getDeclaringClass().getName(), node.getName(), createMethodSignature(node), true, false, false, lineNumber, start, end, 0, true, attributes); } } } - private String createMethodSignature(MethodNode node) { + //-------------------------------------------------------------------------- + + private static String createMethodSignature(MethodNode node) { String[] parameterTypes = GroovyUtils.getParameterTypeSignatures(node, true); String returnType = GroovyUtils.getTypeSignature(node.getReturnType(), true, true); return Signature.createMethodSignature(parameterTypes, returnType).replace('.', '/'); } - - /** - * Create a new breakpoint at the right position. - */ - private void createNewLineBreakpoint(ASTNode node) throws CoreException { - // check to make sure that breakpoint doesn't exist on this line - // line may have moved by the validator - if (JDIDebugModel.lineBreakpointExists(fTypeName, node.getLineNumber()) != null) { - return; - } - Map newAttributes = new HashMap<>(10); - int start= node.getStart(); - int end= node.getEnd(); - if (fType != null) { - BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(newAttributes, fType, start, end); - } - JDIDebugModel.createLineBreakpoint(fResource, fTypeName, node.getLineNumber(), start, end, 0, true, newAttributes); - } - - private void report(final String message) { - JDIDebugUIPlugin.getStandardDisplay().asyncExec(() -> { - IEditorStatusLine statusLine = Adapters.adapt(fEditorPart, IEditorStatusLine.class); - if (statusLine != null) { - statusLine.setMessage(true, message, null); - } - if (message != null && JDIDebugUIPlugin.getActiveWorkbenchShell() != null) { - Display.getCurrent().beep(); - } - }); - } }