Mercurial > hg > xemacs-beta
comparison lisp/oobr/br-python.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 ;;!emacs | |
2 ;; | |
3 ;; FILE: br-python.el | |
4 ;; SUMMARY: Support routines for Python inheritance browsing. | |
5 ;; USAGE: GNU Emacs Lisp Library | |
6 ;; KEYWORDS: oop, tools, python | |
7 ;; | |
8 ;; AUTHOR: Harri Pasanen, based on Smalltalk and C++ browsers | |
9 ;; by Bob Weiner | |
10 ;; ORG: Tekla Oy | |
11 ;; | |
12 ;; ORIG-DATE: 5-Apr-96 | |
13 ;; LAST-MOD: 12-Apr | |
14 ;; | |
15 ;; Copyright (C) 1990-1995 Free Software Foundation, Inc. | |
16 ;; See the file BR-COPY for license information. | |
17 ;; | |
18 ;; This file is part of the OO-Browser. | |
19 ;; | |
20 ;; DESCRIPTION: | |
21 ;; | |
22 ;; See 'python-class-def-regexp' for regular expression that matches class | |
23 ;; definitions. | |
24 ;; | |
25 ;; DESCRIP-END. | |
26 | |
27 ;;; ************************************************************************ | |
28 ;;; Other required Elisp libraries | |
29 ;;; ************************************************************************ | |
30 | |
31 (mapcar 'require '(br-lib hypb)) | |
32 | |
33 ;;; ************************************************************************ | |
34 ;;; User visible variables | |
35 ;;; ************************************************************************ | |
36 | |
37 (defvar python-lib-search-dirs nil | |
38 "List of directories below which Python Library source files are found. | |
39 Subdirectories of Library source are also searched. A Library is a stable | |
40 group of classes.") | |
41 | |
42 (defvar python-sys-search-dirs nil | |
43 "List of directories below which Python System source files are found. | |
44 Subdirectories of System source are also searched. A System class is one | |
45 that is not yet reusable and is likely to change before release.") | |
46 | |
47 (defconst python-narrow-view-to-class nil | |
48 "*Non-nil means narrow buffer to just the matching class definition when displayed.") | |
49 | |
50 ;;; following is reserved for future, currently does not work | |
51 (defconst python-duplicate-classnames-across-modules nil | |
52 "*Non-nil means that the module name is prepended to class names.") | |
53 | |
54 ;;; ************************************************************************ | |
55 ;;; Internal functions | |
56 ;;; ************************************************************************ | |
57 | |
58 (defun python-get-classes-from-source (filename &optional skip-tags | |
59 skip-tags-cleanup) | |
60 "Scans FILENAME and returns cons of class list with parents-class alist. | |
61 Handles multiple inheritance. Assumes file existence and readability have | |
62 already been checked." | |
63 (let ((no-kill (get-file-buffer filename)) | |
64 classes class parents parent-cons) | |
65 (if no-kill | |
66 (set-buffer no-kill) | |
67 (funcall br-view-file-function filename)) | |
68 (save-restriction | |
69 (save-excursion | |
70 (widen) | |
71 (goto-char (point-min)) | |
72 (or skip-tags | |
73 (progn (setq signatures (python-scan-features)) | |
74 (goto-char (point-min)))) | |
75 (while (re-search-forward python-class-def-regexp nil t) | |
76 (setq has-parents | |
77 (= ?\( (char-after (point)))) | |
78 (setq class (buffer-substring (match-beginning 1) (match-end 1)) | |
79 parent-cons | |
80 (cons | |
81 ;; Return parents as a list, or nil if no parents | |
82 (if has-parents (python-scan-parents)) | |
83 class)) | |
84 ;; Assume class name not found within a comment. | |
85 (setq classes (cons class classes) | |
86 parents (cons parent-cons parents)) | |
87 (or skip-tags | |
88 ;; Scan members defined within class | |
89 (setq signatures | |
90 (append | |
91 signatures | |
92 (python-scan-features-in-class class (point) | |
93 (python-locate-class-end)) | |
94 ))))) | |
95 (if skip-tags | |
96 nil | |
97 (python-get-feature-tags buffer-file-name (python-sort-features | |
98 signatures)) | |
99 (or skip-tags-cleanup (br-feature-tags-save))) | |
100 (or no-kill (kill-buffer (current-buffer))) | |
101 (cons classes (delq nil parents))))) | |
102 | |
103 | |
104 (defun python-scan-parents () | |
105 "Return list of parents names from a Python class definition. | |
106 Point must be after the '(' that begins the parent list and before the | |
107 first parent entry when this function is called." | |
108 (let ((parent-list) (again t) | |
109 parent) | |
110 (while (and again (re-search-forward python-parent-class-name nil t)) | |
111 (setq again (= ?, (char-after (point))) | |
112 parent (buffer-substring (match-beginning 3) | |
113 (match-end 3)) | |
114 parent-list (cons parent parent-list))) | |
115 (nreverse parent-list))) | |
116 | |
117 (defun python-locate-class-end () | |
118 "Look up the end of class. Point is assumed to be in the class definition. | |
119 Do this by looking up the first line that begins with python-identifier-chars." | |
120 (save-excursion | |
121 (let ((result-point (point-max))) | |
122 (if (re-search-forward | |
123 (concat "^[" python-identifier-chars "]") nil t) | |
124 (progn | |
125 (setq result-point (- (match-beginning 0) 1)) | |
126 (if (python-within-string-p) | |
127 (python-locate-class-end) | |
128 result-point)) | |
129 result-point)))) | |
130 | |
131 (defun python-get-parents-from-source (filename class-name) | |
132 "Scan source in FILENAME and return list of parents of CLASS-NAME. | |
133 Assume file existence has already been checked." | |
134 (or (null class-name) | |
135 (car (car (br-rassoc | |
136 class-name | |
137 (cdr (python-get-classes-from-source filename))))))) | |
138 | |
139 (defun python-select-path (paths-htable-elt &optional feature-p) | |
140 "Select proper pathname from PATHS-HTABLE-ELT based upon value of optional FEATURE-P. | |
141 Selection is between path of class definition and path for features associated | |
142 with the class." | |
143 (cdr paths-htable-elt)) | |
144 | |
145 (defun python-set-case (type) | |
146 "Return string TYPE identifier for use as a class name." | |
147 type) | |
148 | |
149 (defun python-set-case-type (class-name) | |
150 "Return string CLASS-NAME for use as a type identifier." | |
151 class-name) | |
152 | |
153 (defun python-to-comments-begin () | |
154 "Skip back from current point past any preceding Python comments. | |
155 Presently NoOp" | |
156 ) | |
157 | |
158 (defun python-class-definition-regexp (class &optional regexp-flag) | |
159 "Return regexp to uniquely match the definition of CLASS name. | |
160 Optional REGEXP-FLAG non-nil means CLASS has already been quoted for use in a | |
161 regular expression. (not meaningful for Python)" | |
162 (concat python-class-name-before class whitespace)) | |
163 | |
164 ;;; ************************************************************************ | |
165 ;;; Internal variables | |
166 ;;; ************************************************************************ | |
167 | |
168 (defconst python-type-tag-separator "@" | |
169 "String that separates a tag's type from its normalized definition form. | |
170 This should be a single character which is unchanged when quoted for use as a | |
171 literal in a regular expression.") | |
172 | |
173 (defconst python-identifier-chars "a-zA-Z0-9_" | |
174 "String of chars and char ranges that may be used within a Python identifier.") | |
175 | |
176 (defconst python-identifier (concat "\\([a-zA-Z_][" python-identifier-chars "]*\\)") | |
177 "Regular expression matching a Python identifier.") | |
178 | |
179 (defconst whitespace "[ \t]*") | |
180 | |
181 (defconst python-parent-class-name | |
182 (concat whitespace | |
183 "\\(" python-identifier "\\.\\)*" ; possible module name precedes | |
184 python-identifier whitespace) | |
185 "Regular expression matching optional Python parent class") | |
186 | |
187 (defconst python-class-name-before "^class[ \t]+" | |
188 "Regexp preceding the class name in a class definition. | |
189 Note: this does not allow for nested classes.") | |
190 | |
191 (defconst python-class-name-after | |
192 (concat whitespace python-parent-class-name whitespace ":") | |
193 "Regexp following the class name in a class definition.") | |
194 | |
195 (defconst python-class-def-regexp | |
196 (concat python-class-name-before python-identifier whitespace) | |
197 ; (concat python-class-name-before python-identifier python-class-name-after) | |
198 "Regular expression used to match to class definitions in source text. | |
199 Class name identifier is grouped expression 1. Parent identifier is grouped | |
200 expression 2.") | |
201 | |
202 | |
203 (defconst python-lang-prefix "python-" | |
204 "Prefix string that starts \"br-python.el\" symbol names.") | |
205 | |
206 (defconst python-src-file-regexp ".\\.py$" | |
207 "Regular expression matching a unique part of Python source file name and no others.") | |
208 | |
209 (defvar python-children-htable nil | |
210 "Htable whose elements are of the form: (LIST-OF-CHILD-CLASSES . CLASS-NAME). | |
211 Used to traverse Python inheritance graph. 'br-build-children-htable' builds | |
212 this list.") | |
213 (defvar python-parents-htable nil | |
214 "Htable whose elements are of the form: (LIST-OF-PARENT-CLASSES . CLASS-NAME). | |
215 Used to traverse Python inheritance graph. 'br-build-parents-htable' builds | |
216 this list.") | |
217 (defvar python-paths-htable nil | |
218 "Htable whose elements are of the form: (LIST-OF-CLASS-NAMES . FILE-PATH). | |
219 FILE-PATH gives the location of classes found in LIST-OF-CLASS-NAMES. | |
220 'br-build-paths-htable' builds this list.") | |
221 | |
222 | |
223 (defvar python-lib-parents-htable nil | |
224 "Htable whose elements are of the form: (LIST-OF-PARENT-CLASSES . CLASS-NAME). | |
225 Only classes from stable software libraries are used to build the list.") | |
226 (defvar python-lib-paths-htable nil | |
227 "Htable whose elements are of the form: (LIST-OF-CLASS-NAMES . FILE-PATH). | |
228 FILE-PATH gives the location of classes found in LIST-OF-CLASS-NAMES. | |
229 Only classes from stable software libraries are used to build the list.") | |
230 | |
231 (defvar python-sys-parents-htable nil | |
232 "Htable whose elements are of the form: (LIST-OF-PARENT-CLASSES . CLASS-NAME). | |
233 Only classes from systems that are likely to change are used to build the list.") | |
234 (defvar python-sys-paths-htable nil | |
235 "Alist whose elements are of the form: (LIST-OF-CLASS-NAMES . FILE-PATH). | |
236 FILE-PATH gives the location of classes found in LIST-OF-CLASS-NAMES. | |
237 Only classes from systems that are likely to change are used to build the | |
238 list.") | |
239 | |
240 (defvar python-lib-prev-search-dirs nil | |
241 "Used to check if 'python-lib-classes-htable' must be regenerated.") | |
242 (defvar python-sys-prev-search-dirs nil | |
243 "Used to check if 'python-sys-classes-htable' must be regenerated.") | |
244 | |
245 (defvar python-env-spec nil | |
246 "Non-nil value means Environment specification has been given but not yet built. | |
247 Nil means current Environment has been built, though it may still require updating.") | |
248 | |
249 (provide 'br-python) | |
250 | |
251 | |
252 | |
253 | |
254 | |
255 |