@@ -91,6 +91,7 @@ public class GroovyPageParser implements Tokens {
91
91
private GSPWriter out ;
92
92
private String className ;
93
93
private String packageName ;
94
+ private String sourceName ; // last segment of the file name (eg- index.gsp)
94
95
private boolean finalPass = false ;
95
96
private int tagIndex ;
96
97
private Map <Object , Object > tagContext ;
@@ -227,6 +228,7 @@ public GroovyPageParser(String name, String uri, String filename, InputStream in
227
228
pageName = uri ;
228
229
environment = Environment .getCurrent ();
229
230
makeName (name );
231
+ makeSourceName (filename );
230
232
}
231
233
232
234
private Map <String , String > parseDirectives (String gspSource ) {
@@ -683,6 +685,22 @@ else if (ix == 0 && c >= '0' && c <= '9') {
683
685
className = buf .toString ();
684
686
}
685
687
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
+
686
704
private static boolean match (CharSequence pat , CharSequence text , int start ) {
687
705
int ix = start , ixz = text .length (), ixy = start + pat .length ();
688
706
if (ixz > ixy ) {
@@ -831,6 +849,10 @@ private void page() {
831
849
out .println ("null" );
832
850
}
833
851
out .println ("}" );
852
+
853
+ if (shouldAddLineNumbers ()) {
854
+ addLineNumbers ();
855
+ }
834
856
}
835
857
else {
836
858
for (int i = 0 ; i < DEFAULT_IMPORTS .length ; i ++) {
@@ -839,6 +861,64 @@ private void page() {
839
861
}
840
862
}
841
863
}
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 ("\t lines = [" );
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 ("\t sourceName = \" " + 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
+ }
842
922
843
923
private void endTag () {
844
924
if (!finalPass ) return ;
0 commit comments