]> code.delx.au - gnu-emacs-elpa/blob - packages/realgud/realgud/debugger/jdb/file.el
635d8442ca77671c17221f57734a5388ac5b7f29
[gnu-emacs-elpa] / packages / realgud / realgud / debugger / jdb / file.el
1 ;; Association list of fully qualified class names (package + class name)
2 ;; and their source files.
3 (defvar gud-jdb-class-source-alist nil
4 "Association list of fully qualified class names and source files.")
5
6 ;; This is used to hold a source file during analysis.
7 (defvar gud-jdb-analysis-buffer nil)
8
9 (defvar gud-jdb-classpath-string nil
10 "Holds temporary classpath values.")
11
12 (defun gud-jdb-build-source-files-list (path extn)
13 "Return a list of java source files (absolute paths).
14 PATH gives the directories in which to search for files with
15 extension EXTN. Normally EXTN is given as the regular expression
16 \"\\.java$\" ."
17 (apply 'nconc (mapcar (lambda (d)
18 (when (file-directory-p d)
19 (directory-files d t extn nil)))
20 path)))
21
22 ;; Move point past whitespace.
23 (defun gud-jdb-skip-whitespace ()
24 (skip-chars-forward " \n\r\t\014"))
25
26 ;; Move point past a "// <eol>" type of comment.
27 (defun gud-jdb-skip-single-line-comment ()
28 (end-of-line))
29
30 ;; Move point past a "/* */" or "/** */" type of comment.
31 (defun gud-jdb-skip-traditional-or-documentation-comment ()
32 (forward-char 2)
33 (catch 'break
34 (while (not (eobp))
35 (if (eq (following-char) ?*)
36 (progn
37 (forward-char)
38 (if (not (eobp))
39 (if (eq (following-char) ?/)
40 (progn
41 (forward-char)
42 (throw 'break nil)))))
43 (forward-char)))))
44
45 ;; Move point past any number of consecutive whitespace chars and/or comments.
46 (defun gud-jdb-skip-whitespace-and-comments ()
47 (gud-jdb-skip-whitespace)
48 (catch 'done
49 (while t
50 (cond
51 ((looking-at "//")
52 (gud-jdb-skip-single-line-comment)
53 (gud-jdb-skip-whitespace))
54 ((looking-at "/\\*")
55 (gud-jdb-skip-traditional-or-documentation-comment)
56 (gud-jdb-skip-whitespace))
57 (t (throw 'done nil))))))
58
59 ;; Move point past things that are id-like. The intent is to skip regular
60 ;; id's, such as class or interface names as well as package and interface
61 ;; names.
62 (defun gud-jdb-skip-id-ish-thing ()
63 (skip-chars-forward "^ /\n\r\t\014,;{"))
64
65 ;; Move point past a string literal.
66 (defun gud-jdb-skip-string-literal ()
67 (forward-char)
68 (while (not (cond
69 ((eq (following-char) ?\\)
70 (forward-char))
71 ((eq (following-char) ?\042))))
72 (forward-char))
73 (forward-char))
74
75 ;; Move point past a character literal.
76 (defun gud-jdb-skip-character-literal ()
77 (forward-char)
78 (while
79 (progn
80 (if (eq (following-char) ?\\)
81 (forward-char 2))
82 (not (eq (following-char) ?\')))
83 (forward-char))
84 (forward-char))
85
86 ;; Move point past the following block. There may be (legal) cruft before
87 ;; the block's opening brace. There must be a block or it's the end of life
88 ;; in petticoat junction.
89 (defun gud-jdb-skip-block ()
90
91 ;; Find the beginning of the block.
92 (while
93 (not (eq (following-char) ?{))
94
95 ;; Skip any constructs that can harbor literal block delimiter
96 ;; characters and/or the delimiters for the constructs themselves.
97 (cond
98 ((looking-at "//")
99 (gud-jdb-skip-single-line-comment))
100 ((looking-at "/\\*")
101 (gud-jdb-skip-traditional-or-documentation-comment))
102 ((eq (following-char) ?\042)
103 (gud-jdb-skip-string-literal))
104 ((eq (following-char) ?\')
105 (gud-jdb-skip-character-literal))
106 (t (forward-char))))
107
108 ;; Now at the beginning of the block.
109 (forward-char)
110
111 ;; Skip over the body of the block as well as the final brace.
112 (let ((open-level 1))
113 (while (not (eq open-level 0))
114 (cond
115 ((looking-at "//")
116 (gud-jdb-skip-single-line-comment))
117 ((looking-at "/\\*")
118 (gud-jdb-skip-traditional-or-documentation-comment))
119 ((eq (following-char) ?\042)
120 (gud-jdb-skip-string-literal))
121 ((eq (following-char) ?\')
122 (gud-jdb-skip-character-literal))
123 ((eq (following-char) ?{)
124 (setq open-level (+ open-level 1))
125 (forward-char))
126 ((eq (following-char) ?})
127 (setq open-level (- open-level 1))
128 (forward-char))
129 (t (forward-char))))))
130
131 ;; Find the package and class definitions in Java source file FILE. Assumes
132 ;; that FILE contains a legal Java program. BUF is a scratch buffer used
133 ;; to hold the source during analysis.
134 (defun gud-jdb-analyze-source (buf file)
135 (let ((l nil))
136 (set-buffer buf)
137 (insert-file-contents file nil nil nil t)
138 (goto-char 0)
139 (catch 'abort
140 (let ((p ""))
141 (while (progn
142 (gud-jdb-skip-whitespace)
143 (not (eobp)))
144 (cond
145
146 ;; Any number of semi's following a block is legal. Move point
147 ;; past them. Note that comments and whitespace may be
148 ;; interspersed as well.
149 ((eq (following-char) ?\073)
150 (forward-char))
151
152 ;; Move point past a single line comment.
153 ((looking-at "//")
154 (gud-jdb-skip-single-line-comment))
155
156 ;; Move point past a traditional or documentation comment.
157 ((looking-at "/\\*")
158 (gud-jdb-skip-traditional-or-documentation-comment))
159
160 ;; Move point past a package statement, but save the PackageName.
161 ((looking-at "package")
162 (forward-char 7)
163 (gud-jdb-skip-whitespace-and-comments)
164 (let ((s (point)))
165 (gud-jdb-skip-id-ish-thing)
166 (setq p (concat (buffer-substring s (point)) "."))
167 (gud-jdb-skip-whitespace-and-comments)
168 (if (eq (following-char) ?\073)
169 (forward-char))))
170
171 ;; Move point past an import statement.
172 ((looking-at "import")
173 (forward-char 6)
174 (gud-jdb-skip-whitespace-and-comments)
175 (gud-jdb-skip-id-ish-thing)
176 (gud-jdb-skip-whitespace-and-comments)
177 (if (eq (following-char) ?\073)
178 (forward-char)))
179
180 ;; Move point past the various kinds of ClassModifiers.
181 ((looking-at "public")
182 (forward-char 6))
183 ((looking-at "abstract")
184 (forward-char 8))
185 ((looking-at "final")
186 (forward-char 5))
187
188 ;; Move point past a ClassDeclaration, but save the class
189 ;; Identifier.
190 ((looking-at "class")
191 (forward-char 5)
192 (gud-jdb-skip-whitespace-and-comments)
193 (let ((s (point)))
194 (gud-jdb-skip-id-ish-thing)
195 (setq
196 l (nconc l (list (concat p (buffer-substring s (point)))))))
197 (gud-jdb-skip-block))
198
199 ;; Move point past an interface statement.
200 ((looking-at "interface")
201 (forward-char 9)
202 (gud-jdb-skip-block))
203
204 ;; Anything else means the input is invalid.
205 (t
206 (message "Error parsing file %s." file)
207 (throw 'abort nil))))))
208 l))
209
210 (defun gud-jdb-build-class-source-alist-for-file (file)
211 (mapcar
212 (lambda (c)
213 (cons c file))
214 (gud-jdb-analyze-source gud-jdb-analysis-buffer file)))
215
216 ;; Return an alist of fully qualified classes and the source files
217 ;; holding their definitions. SOURCES holds a list of all the source
218 ;; files to examine.
219 (defun gud-jdb-build-class-source-alist (sources)
220 (setq gud-jdb-analysis-buffer (get-buffer-create " *gud-jdb-scratch*"))
221 (prog1
222 (apply
223 'nconc
224 (mapcar
225 'gud-jdb-build-class-source-alist-for-file
226 sources))
227 (kill-buffer gud-jdb-analysis-buffer)
228 (setq gud-jdb-analysis-buffer nil)))