From b9cd2e7254d021f952a1a78ebf5fe967176ad7a8 Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Fri, 13 Apr 2018 14:36:47 -0500 Subject: [PATCH] Fix for issue #560: fix breakpoint activation for method with annotation --- .../codehaus/groovy/antlr/AntlrParserPlugin.java | 1 + .../codehaus/groovy/antlr/AntlrParserPlugin.java | 1 + .../apache/groovy/parser/antlr4/AstBuilder.java | 1 + .../codehaus/groovy/antlr/AntlrParserPlugin.java | 1 + .../test/debug/BreakpointLocationTests.groovy | 14 ++++++++++++++ .../core/compiler/GroovySnippetParser.java | 11 +---------- .../groovy/eclipse/core/util/TokenStream.java | 9 ++++++--- .../debug/ui/BreakpointLocationFinder.java | 16 +++++++++++++++- 8 files changed, 40 insertions(+), 14 deletions(-) diff --git a/base/org.codehaus.groovy24/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java b/base/org.codehaus.groovy24/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java index 99b0bb4736..7dfd8bf031 100644 --- a/base/org.codehaus.groovy24/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java +++ b/base/org.codehaus.groovy24/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java @@ -371,6 +371,7 @@ public ModuleNode buildAST(SourceUnit sourceUnit, ClassLoader classLoader, Reduc // GRECLIPSE add fixModuleNodeLocations(); + output.putNodeMetaData(LocationSupport.class, locations); // GRECLIPSE end } catch (ASTRuntimeException e) { diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java index 3d225385f5..73f56e30fc 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java @@ -372,6 +372,7 @@ public ModuleNode buildAST(SourceUnit sourceUnit, ClassLoader classLoader, Reduc // GRECLIPSE add fixModuleNodeLocations(); + output.putNodeMetaData(LocationSupport.class, locations); // GRECLIPSE end } catch (ASTRuntimeException e) { diff --git a/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/AstBuilder.java b/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/AstBuilder.java index 7b15dd589c..db840ed31e 100644 --- a/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/AstBuilder.java +++ b/base/org.codehaus.groovy26/src/org/apache/groovy/parser/antlr4/AstBuilder.java @@ -568,6 +568,7 @@ public ModuleNode visitCompilationUnit(CompilationUnitContext ctx) { runMethod.setLastColumnNumber(omega.getLastColumnNumber()); } } + moduleNode.putNodeMetaData(LocationSupport.class, locationSupport); sourceUnit.setComments(lexer.getComments()); // GRECLIPSE end diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java b/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java index b0d4f7648c..6ef310c3c5 100644 --- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java +++ b/base/org.codehaus.groovy26/src/org/codehaus/groovy/antlr/AntlrParserPlugin.java @@ -411,6 +411,7 @@ public ModuleNode buildAST(SourceUnit sourceUnit, ClassLoader classLoader, Reduc runMethod.setLastColumnNumber(last.getLastColumnNumber()); } } + output.putNodeMetaData(LocationSupport.class, locations); // GRECLIPSE end } catch (ASTRuntimeException e) { 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 d06c3a7e03..07bd46f3ec 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 @@ -373,4 +373,18 @@ final class BreakpointLocationTests extends GroovyEclipseTestSuite { assert node instanceof MethodNode assert node.lineNumber == 5 } + + @Test + void testBreakpointInClass13() { + def node = findBreakpointLocation 'def m', '''\ + class Class { + @Deprecated + def m() { + here() + } + } + '''.stripIndent() + + assert node instanceof MethodNode + } } diff --git a/ide/org.codehaus.groovy.eclipse.core/src/org/codehaus/groovy/eclipse/core/compiler/GroovySnippetParser.java b/ide/org.codehaus.groovy.eclipse.core/src/org/codehaus/groovy/eclipse/core/compiler/GroovySnippetParser.java index ed356228f4..b795d63bac 100644 --- a/ide/org.codehaus.groovy.eclipse.core/src/org/codehaus/groovy/eclipse/core/compiler/GroovySnippetParser.java +++ b/ide/org.codehaus.groovy.eclipse.core/src/org/codehaus/groovy/eclipse/core/compiler/GroovySnippetParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2009-2017 the original author or authors. + * Copyright 2009-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,6 @@ import org.codehaus.groovy.antlr.AntlrParserPlugin; import org.codehaus.groovy.antlr.GroovySourceAST; -import org.codehaus.groovy.antlr.LocationSupport; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.MethodNode; import org.codehaus.groovy.ast.ModuleNode; @@ -47,12 +46,6 @@ */ public class GroovySnippetParser { - private LocationSupport locations; - - public LocationSupport getLocations() { - return locations; - } - private CategorizedProblem[] problems; public CategorizedProblem[] getProblems() { @@ -108,8 +101,6 @@ private GroovyCompilationUnitDeclaration dietParse(CharSequence source) { CompilationResult compilationResult = new CompilationResult(unit, 0, 0, compilerOptions.maxProblemsPerUnit); GroovyCompilationUnitDeclaration gcud = (GroovyCompilationUnitDeclaration) parser.dietParse(unit, compilationResult); - locations = (LocationSupport) ReflectionUtils.getPrivateField(AntlrParserPlugin.class, "locations", - ReflectionUtils.getPrivateField(SourceUnit.class, "parserPlugin", gcud.getSourceUnit())); problems = compilationResult.getProblems(); return gcud; } diff --git a/ide/org.codehaus.groovy.eclipse.core/src/org/codehaus/groovy/eclipse/core/util/TokenStream.java b/ide/org.codehaus.groovy.eclipse.core/src/org/codehaus/groovy/eclipse/core/util/TokenStream.java index 3562139589..c2d532e774 100644 --- a/ide/org.codehaus.groovy.eclipse.core/src/org/codehaus/groovy/eclipse/core/util/TokenStream.java +++ b/ide/org.codehaus.groovy.eclipse.core/src/org/codehaus/groovy/eclipse/core/util/TokenStream.java @@ -1,5 +1,5 @@ /* - * Copyright 2009-2017 the original author or authors. + * Copyright 2009-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.codehaus.groovy.antlr.LocationSupport; import org.codehaus.groovy.ast.Comment; import org.codehaus.groovy.ast.ModuleNode; import org.codehaus.groovy.eclipse.core.ISourceBuffer; @@ -341,14 +342,16 @@ private boolean isComment(int index) { GroovySnippetParser parser = new GroovySnippetParser(); ModuleNode module = parser.parse(source); + LocationSupport locator = module.getNodeMetaData(LocationSupport.class); + // extract the comment ranges from the parse results List list = module.getContext().getComments(); int i = 0, n = (list == null ? 0 : list.size()); comments = new int[n * 2]; if (n > 0) { for (Comment comment : list) { - comments[i++] = parser.getLocations().findOffset(comment.sline, comment.scol); - comments[i++] = parser.getLocations().findOffset(comment.eline, comment.ecol); + comments[i++] = locator.findOffset(comment.sline, comment.scol); + comments[i++] = locator.findOffset(comment.eline, comment.ecol); } Arrays.sort(comments); // should be sorted already, but let's be sure } 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 3fc1007cea..285dcc0755 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 @@ -19,6 +19,7 @@ import java.util.Comparator; import java.util.TreeSet; +import org.codehaus.groovy.antlr.LocationSupport; import org.codehaus.groovy.ast.ASTNode; import org.codehaus.groovy.ast.AnnotationNode; import org.codehaus.groovy.ast.MethodNode; @@ -31,6 +32,7 @@ public class BreakpointLocationFinder { + protected final LocationSupport locator; protected final Iterable nodes; public BreakpointLocationFinder(ModuleNode module) { @@ -62,6 +64,7 @@ public void visitMethod(MethodNode method) { }.visitModule(module); this.nodes = Collections.unmodifiableSet(nodes); + this.locator = module.getNodeMetaData(LocationSupport.class); } public ASTNode findBreakpointLocation(int lineNumber) { @@ -75,7 +78,7 @@ public ASTNode findBreakpointLocation(int lineNumber) { // variable expression in a declaration expression with no initializer skipNext = true; } - } else if (node.getLineNumber() >= lineNumber) { + } else if (lineNumber(node) >= lineNumber) { bestMatch = node; break; } @@ -83,4 +86,15 @@ public ASTNode findBreakpointLocation(int lineNumber) { return bestMatch; } + + protected int lineNumber(ASTNode node) { + if (locator != null && node instanceof MethodNode) { + // annotations, modifiers and generics may be on separate line(s) + int[] row_col = locator.getRowCol(((MethodNode) node).getNameStart()); + if (row_col != null && row_col.length > 0) { + return row_col[0]; + } + } + return node.getLineNumber(); + } }