diff lisp/oobr/br-eif.el @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children 4103f0995bd7
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/oobr/br-eif.el	Mon Aug 13 08:45:50 2007 +0200
@@ -0,0 +1,271 @@
+;;!emacs
+;;
+;; FILE:         br-eif.el
+;; SUMMARY:      Support routines for Eiffel inheritance browsing and error parsing.
+;; USAGE:        GNU Emacs Lisp Library
+;; KEYWORDS:     oop, tools
+;;
+;; AUTHOR:       Bob Weiner
+;; ORG:          Motorola Inc.
+;;
+;; ORIG-DATE:     7-Dec-89
+;; LAST-MOD:     21-Sep-95 at 14:13:50 by Bob Weiner
+;;
+;; Copyright (C) 1989-1995  Free Software Foundation, Inc.
+;; See the file BR-COPY for license information.
+;;
+;; This file is part of the OO-Browser.
+;;
+;; DESCRIPTION:  
+;; DESCRIP-END.
+
+;;; ************************************************************************
+;;; Other required Elisp libraries
+;;; ************************************************************************
+
+(require 'br-lib)
+
+;;; ************************************************************************
+;;; User visible variables
+;;; ************************************************************************
+
+(defvar eif-lib-search-dirs nil
+  "List of directories below which Eiffel Library source files are found.
+Subdirectories of Library source are also searched.  A Library is a stable
+group of classes.")
+
+(defvar eif-sys-search-dirs nil
+  "List of directories below which Eiffel System source files are found.
+Subdirectories of System source are also searched.  A System class is one
+that is not yet reusable and is likely to change before release.")
+
+(defconst eif-narrow-view-to-class nil
+ "*Non-nil means narrow buffer to just the matching class definition when displayed.")
+
+;;; ************************************************************************
+;;; Internal functions
+;;; ************************************************************************
+
+(defun eif-get-classes-from-source (filename &optional skip-tags
+				    skip-tags-cleanup)
+  "Scans FILENAME and returns cons of class list with parents-class alist.
+Handles multiple inheritance.  Assumes file existence and readability have
+already been checked.
+   With optional SKIP-TAGS non-nil, does not compute and store lookup tags
+for element definitions.  If SKIP-TAGS is nil, normally a cleanup
+function is called after scanning the elements.  SKIP-TAGS-CLEANUP
+non-nil suppresses this action."
+  ;; Multiple classes per file allowed
+  (let ((no-kill (get-file-buffer filename))
+	classes class end parents signatures start)
+    (if no-kill
+	(set-buffer no-kill)
+      (funcall br-view-file-function filename))
+    (save-excursion
+      (save-restriction
+	(widen)
+	(goto-char (point-min))
+	(while (re-search-forward eif-class-def-regexp nil t)
+	  (setq start (point)
+		class
+		(eif-set-case
+		 (buffer-substring (match-beginning 2) (match-end 2)))
+		classes (cons class classes)
+		parents (cons (cons (eif-get-parents-from-source
+				     filename class)
+				    class)
+			      parents))
+	  (eif-to-class-end)
+	  (setq end (point))
+	  (or skip-tags
+	      ;; Scan class features
+	      (setq signatures
+		    (eif-scan-features-in-class class start end))))))
+    (if skip-tags
+	nil
+      (eif-get-feature-tags
+       buffer-file-name (eif-sort-features signatures))
+      (or skip-tags-cleanup (br-feature-tags-save)))
+    (or no-kill (kill-buffer (current-buffer)))
+    (cons classes (delq nil parents))))
+
+(defun eif-get-parents-from-source (filename &optional class-name)
+  "Return list of downcased parents of Eiffel class in FILENAME.
+Return nil if file is not readable.  Assume that Eiffel keywords
+'inherit' and 'feature' occur at the beginning of lines, when present."
+  (let ((parents) (par)
+	(no-kill (get-file-buffer filename))
+	(obuf (current-buffer)))
+    (if no-kill
+	(set-buffer no-kill))
+    (if (or no-kill
+	    (if (file-readable-p filename)
+		 (let ((br-view-file-function 'br-insert-file-contents))
+		   (message "Scanning %s ..." filename)
+		   (funcall br-view-file-function filename)
+		   t)))
+	(progn
+	  (save-restriction
+	    (save-excursion
+	      (widen)
+	      (goto-char (point-min))
+	      (let ((case-fold-search t) ;; Ignore case in searches
+		    (end)
+		    indent)
+		(if (or (null class-name)
+			(let ((class-def (concat eif-class-name-before 
+						 (eif-set-case-type class-name)
+						 eif-class-name-after)))
+			  (re-search-forward class-def nil t)))
+		    (if (not (re-search-forward (concat "^inherit[ \t\n]+"
+							eif-parent-regexp)
+						nil t))
+			nil
+		      ;; Save first parent
+		      (setq parents (list
+				     (eif-set-case (buffer-substring
+						    (match-beginning 2)
+						    (match-end 2))))
+			    indent (save-excursion
+				     (goto-char (match-beginning 2))
+				     (current-column)))
+		      ;; Save any succeeding parents
+		      (save-excursion
+			(if (re-search-forward "^[a-zA-Z]" nil t)
+			    (setq end (1- (point)))))
+		      (forward-line 1)
+ 		      (while (< (point) end)
+			(back-to-indentation)
+			(and (<= (current-column) indent)
+			     (looking-at eif-identifier)
+			     (setq par (eif-set-case (buffer-substring
+						      (match-beginning 1)
+						      (match-end 1))))
+			     (if (or (br-member par parents)
+				     (br-member-sorted-strings
+				      par eif-reserved-words))
+				 nil
+			       (setq parents (cons par parents))))
+			(forward-line 1)))))))
+	  (or no-kill (kill-buffer (current-buffer)))
+	  (set-buffer obuf)
+	  (nreverse parents)))))
+
+(defun eif-select-path (paths-htable-elt &optional feature-p)
+  "Select proper pathname from PATHS-HTABLE-ELT based upon value of optional FEATURE-P.
+Selection is between path of class definition and path for features associated
+with the class."
+  (cdr paths-htable-elt))
+
+(defun eif-set-case (type)
+  "Return string TYPE identifier for use as a class name."
+  (downcase type))
+
+(defun eif-set-case-type (class-name)
+  "Return string CLASS-NAME for use as a type identifier."
+  (upcase class-name))
+
+
+(defun eif-to-class-end ()
+  "Assuming point is at start of class, move to start of line after end of class."
+  (interactive)
+  (if (and (re-search-forward "^end[ \t\n-]" nil t)
+	   (= (forward-line 1) 0))
+      nil
+    (goto-char (point-max))))
+
+(defun eif-to-comments-begin ()
+  "Skip back from current point past any preceding blank lines and comments."
+  (let ((opoint))
+    (while
+	(progn (setq opoint (point))
+	       ;; To previous line
+	       (and (= 0 (forward-line -1))
+		    ;; If begins with "--", then is a comment.
+		    (cond ((looking-at "[ \t]*--"))
+			  ((looking-at "[ \t]*$"))))))
+    (goto-char opoint)
+    ;; Skip past whitespace
+    (skip-chars-forward " \t\n")
+    (beginning-of-line)))
+
+;;; ************************************************************************
+;;; Internal variables
+;;; ************************************************************************
+
+(defconst eif-class-name-before "^[ \t]*\\(deferred[ \t\n]+\\|expanded[ \t\n]+\\)?class[ \t\n]+"
+  "Regexp preceding the class name in a class definition.")
+
+(defconst eif-class-name-after "[ \t\n]+"
+  "Regexp following the class name in a class definition.")
+
+(defconst eif-identifier-chars "A-Za-z0-9_"
+  "String of chars and char ranges that may be used within an Eiffel identifier.")
+
+(defconst eif-identifier (concat "\\([a-zA-Z][" eif-identifier-chars "]*\\)")
+  "Regular expression matching an Eiffel identifier.")
+
+(defconst eif-class-def-regexp
+  (concat eif-class-name-before eif-identifier eif-class-name-after)
+  "Regular expression used to match to class definitions in source text.
+Class name identifier is grouped expression 2.")
+
+(defconst eif-class-name-preceding
+  "\\([\[\{>;:][ \t\n]*\\|[a-zA-z][ \t\n]+\\)"
+  "Pattern preceding any valid non-comment use of an Eiffel class/type name.")
+
+(defconst eif-class-name-pat
+  (concat eif-class-name-preceding eif-identifier)
+  "Class name is grouped expression 2.")
+
+(defconst eif-lang-prefix "eif-"
+  "Prefix string that starts \"br-eif.el\" symbol names.")
+
+
+(defconst eif-parent-regexp (concat "[ \t\n]*\\(--.*[\n]\\)*[ \t\n]*"
+				    eif-identifier)
+  "Parent identifier is grouped expression 2.")
+
+(defconst eif-src-file-regexp ".\\.e$"
+  "Regular expression matching a unique part of Eiffel class filenames and no others.")
+
+(defvar eif-children-htable nil
+  "Htable whose elements are of the form: (LIST-OF-CHILD-CLASSES . CLASS-NAME).
+Used to traverse Eiffel inheritance graph.  'br-build-children-htable' builds
+this list.")
+(defvar eif-parents-htable nil
+  "Htable whose elements are of the form: (LIST-OF-PARENT-CLASSES . CLASS-NAME).
+Used to traverse Eiffel inheritance graph.  'br-build-parents-htable' builds
+this list.")
+(defvar eif-paths-htable nil
+  "Htable whose elements are of the form: (LIST-OF-CLASS-NAMES . DIRECTORY).
+DIRECTORY gives the location of classes found in LIST-OF-CLASS-NAMES.
+'br-build-paths-htable' builds this list.")
+
+(defvar eif-lib-parents-htable nil
+  "Htable whose elements are of the form: (LIST-OF-PARENT-CLASSES . CLASS-NAME).
+Only classes from stable software libraries are used to build the list.")
+(defvar eif-lib-paths-htable nil
+  "Htable whose elements are of the form: (LIST-OF-CLASS-NAMES . DIRECTORY).
+DIRECTORY gives the location of classes found in LIST-OF-CLASS-NAMES.
+Only classes from stable software libraries are used to build the list.")
+
+(defvar eif-sys-parents-htable nil
+  "Htable whose elements are of the form: (LIST-OF-PARENT-CLASSES . CLASS-NAME).
+Only classes from systems that are likely to change are used to build the list.")
+(defvar eif-sys-paths-htable nil
+  "Htable whose elements are of the form: (LIST-OF-CLASS-NAMES . DIRECTORY).
+DIRECTORY gives the location of classes found in LIST-OF-CLASS-NAMES.
+Only classes from systems that are likely to change are used to build the
+list.")
+
+(defvar eif-lib-prev-search-dirs nil
+  "Used to check if 'eif-lib-paths-htable' must be regenerated.")
+(defvar eif-sys-prev-search-dirs nil
+  "Used to check if 'eif-sys-paths-htable' must be regenerated.")
+
+(defvar eif-env-spec nil
+  "Non-nil value means Environment specification has been given but not yet built.
+Nil means current Environment has been built, though it may still require updating.")
+
+(provide 'br-eif)