Skip to content

Commit

Permalink
Support for class load breakpoints from Groovy Editor's vertical ruler
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Apr 14, 2018
1 parent f6e50db commit 19d742f
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -221,7 +222,8 @@ final class BreakpointLocationTests extends GroovyEclipseTestSuite {
}
'''.stripIndent()

assert node?.lineNumber == 2
assert node instanceof ClassNode
assert node.lineNumber == 1
}

@Test
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -123,71 +127,80 @@ 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<String, Object> 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<String, Object> 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<String, Object> 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);
}
}
}

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<String, Object> 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<String, Object> 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();
}
});
}
}

0 comments on commit 19d742f

Please sign in to comment.