Skip to content

Commit 584dc9b

Browse files
committed
GRAILS-6583 added Andrew's code for GSP debugging
1 parent 804d6ef commit 584dc9b

File tree

4 files changed

+835
-0
lines changed

4 files changed

+835
-0
lines changed

maven/grails-web.mf

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ Import-Template:
2222
org.codehaus.groovy.ant.*;version="${groovy.version:[=.=.=, =.+1.0)}",
2323
org.codehaus.groovy.tools.*;version="${groovy.version:[=.=.=, =.+1.0)}",
2424
org.codehaus.groovy.syntax.*;version="${groovy.version:[=.=.=, =.+1.0)}",
25+
org.codehaus.groovy.ast.*;version="${groovy.version:[=.=.=, =.+1.0)}",
26+
org.codehaus.groovy.ast.expr.*;version="${groovy.version:[=.=.=, =.+1.0)}",
27+
org.codehaus.groovy.ast.stmt.*;version="${groovy.version:[=.=.=, =.+1.0)}",
2528
org.codehaus.groovy.grails.*;version="${grails.version:[=.=.=, =.+1.0)}",
2629
org.hibernate.*;version="${hibernate.version:[=.=.=, =.+1.0)}",
2730
com.opensymphony.module.sitemesh.*;version="${sitemesh.version:[=.=.=, =.+1.0)}",

src/java/org/codehaus/groovy/grails/web/pages/GroovyPageParser.java

+80
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ public class GroovyPageParser implements Tokens {
9191
private GSPWriter out;
9292
private String className;
9393
private String packageName;
94+
private String sourceName; // last segment of the file name (eg- index.gsp)
9495
private boolean finalPass = false;
9596
private int tagIndex;
9697
private Map<Object, Object> tagContext;
@@ -227,6 +228,7 @@ public GroovyPageParser(String name, String uri, String filename, InputStream in
227228
pageName = uri;
228229
environment = Environment.getCurrent();
229230
makeName(name);
231+
makeSourceName(filename);
230232
}
231233

232234
private Map<String, String> parseDirectives(String gspSource) {
@@ -683,6 +685,22 @@ else if (ix == 0 && c >= '0' && c <= '9') {
683685
className = buf.toString();
684686
}
685687

688+
/**
689+
* find the simple name of this gsp
690+
* @param filename the fully qualified file name
691+
*/
692+
private void makeSourceName(String filename) {
693+
if (filename != null) {
694+
int lastSegmentStart = filename.lastIndexOf('/');
695+
if (lastSegmentStart == -1) {
696+
lastSegmentStart = filename.lastIndexOf('\\');
697+
}
698+
sourceName = filename.substring(lastSegmentStart + 1);
699+
} else {
700+
sourceName = className;
701+
}
702+
}
703+
686704
private static boolean match(CharSequence pat, CharSequence text, int start) {
687705
int ix = start, ixz = text.length(), ixy = start + pat.length();
688706
if (ixz > ixy) {
@@ -831,6 +849,10 @@ private void page() {
831849
out.println("null");
832850
}
833851
out.println("}");
852+
853+
if (shouldAddLineNumbers()) {
854+
addLineNumbers();
855+
}
834856
}
835857
else {
836858
for (int i = 0; i < DEFAULT_IMPORTS.length; i++) {
@@ -839,6 +861,64 @@ private void page() {
839861
}
840862
}
841863
}
864+
865+
/**
866+
* Determines if the line numbers array should be added to the generated Groovy class.
867+
* @return true if they should
868+
*/
869+
private boolean shouldAddLineNumbers() {
870+
try {
871+
// for now, we support this through a system property.
872+
String prop = System.getenv("GROOVY_PAGE_ADD_LINE_NUMBERS");
873+
return Boolean.valueOf(prop).booleanValue();
874+
} catch (Exception e) {
875+
// something wild happened
876+
return false;
877+
}
878+
}
879+
880+
/**
881+
* Adds the line numbers array to the end of the generated Groovy ModuleNode
882+
* in a way suitable for the LineNumberTransform AST transform to operate on it
883+
*/
884+
private void addLineNumbers() {
885+
out.println();
886+
out.println("@org.codehaus.groovy.grails.web.transform.LineNumber(");
887+
out.print("\tlines = [");
888+
// get the line numbers here. this will mean that the last 2 lines will not be captured in the
889+
// line number information, but that's OK since a user cannot set a breakpoint there anyway.
890+
int[] lineNumbers = filterTrailing0s(out.getLineNumbers());
891+
892+
for (int i = 0; i < lineNumbers.length; i++) {
893+
out.print(lineNumbers[i]);
894+
if (i < lineNumbers.length - 1) {
895+
out.print(", ");
896+
}
897+
}
898+
out.println("],");
899+
out.println("\tsourceName = \"" + sourceName + "\"");
900+
out.println(")");
901+
out.println("class ___LineNumberPlaceholder { }");
902+
}
903+
904+
/**
905+
* Filters trailing 0s from the line number array
906+
* @param lineNumbers the line number array
907+
* @return a new array that removes all 0s from the end of it
908+
*/
909+
private int[] filterTrailing0s(int[] lineNumbers) {
910+
int startLocation = lineNumbers.length - 1;
911+
for (int i = lineNumbers.length -1; i >= 0; i--) {
912+
if (lineNumbers[i] > 0) {
913+
startLocation = i + 1;
914+
break;
915+
}
916+
}
917+
918+
int[] newLineNumbers = new int[startLocation];
919+
System.arraycopy(lineNumbers, 0, newLineNumbers, 0, startLocation);
920+
return newLineNumbers;
921+
}
842922

843923
private void endTag() {
844924
if (!finalPass) return;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2003-2010 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.codehaus.groovy.grails.web.transform;
17+
18+
import java.lang.annotation.ElementType;
19+
import java.lang.annotation.Retention;
20+
import java.lang.annotation.RetentionPolicy;
21+
import java.lang.annotation.Target;
22+
23+
import org.codehaus.groovy.transform.GroovyASTTransformationClass;
24+
25+
/**
26+
* @author Andrew Eisenberg
27+
* @created Jul 22, 2010
28+
*/
29+
@Retention(RetentionPolicy.SOURCE)
30+
@Target({ ElementType.TYPE })
31+
@GroovyASTTransformationClass({"org.codehaus.groovy.grails.web.transform.LineNumberTransform"})
32+
public @interface LineNumber {
33+
int[] lines();
34+
String sourceName();
35+
}

0 commit comments

Comments
 (0)