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