]> code.delx.au - gnu-emacs/blobdiff - lisp/cedet/semantic/analyze/complete.el
Merge from mainline.
[gnu-emacs] / lisp / cedet / semantic / analyze / complete.el
index a44100b128fcfdf025b30159101219652b155c01..7f0c7d8a22a5f1f32f554063fd82212f7b8a41a5 100644 (file)
@@ -1,6 +1,6 @@
 ;;; semantic/analyze/complete.el --- Smart Completions
 
-;;; Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+;; Copyright (C) 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
 
 ;; Author: Eric M. Ludlam <zappo@gnu.org>
 
@@ -21,7 +21,7 @@
 
 ;;; Commentary:
 ;;
-;; Caclulate smart completions.
+;; Calculate smart completions.
 ;;
 ;; Uses the analyzer context routine to determine the best possible
 ;; list of completions.
@@ -32,6 +32,9 @@
 
 (require 'semantic/analyze)
 
+;; For semantic-find-* macros:
+(eval-when-compile (require 'semantic/find))
+
 ;;; Code:
 
 ;;; Helper Fcns
@@ -46,24 +49,6 @@ Used as options when completing.")
   "Do nothing with TYPE."
   nil)
 
-;; Old impl of the above.  I'm not sure what the issue is
-;  (let ((ans
-;         (:override-with-args
-;             ((semantic-analyze-find-tag (semantic-tag-name type)))
-;           ;; Be default, we don't know.
-;           nil))
-;        (out nil))
-;    (dolist (elt ans)
-;      (cond
-;       ((stringp elt)
-;        (push (semantic-tag-new-variable
-;               elt (semantic-tag-name type) nil)
-;              out))
-;       ((semantic-tag-p elt)
-;        (push elt out))
-;       (t nil)))
-;    (nreverse out)))
-
 (defun semantic-analyze-tags-of-class-list (tags classlist)
   "Return the tags in TAGS that are of classes in CLASSLIST."
   (let ((origc tags))
@@ -78,11 +63,15 @@ Used as options when completing.")
 ;;; MAIN completion calculator
 ;;
 ;;;###autoload
-(define-overloadable-function semantic-analyze-possible-completions (context)
+(define-overloadable-function semantic-analyze-possible-completions (context &rest flags)
   "Return a list of semantic tags which are possible completions.
 CONTEXT is either a position (such as point), or a precalculated
 context.  Passing in a context is useful if the caller also needs
 to access parts of the analysis.
+The remaining FLAGS arguments are passed to the mode specific completion engine.
+Bad flags should be ignored by modes that don't use them.
+See `semantic-analyze-possible-completions-default' for details on the default FLAGS.
+
 Completions run through the following filters:
   * Elements currently in scope
   * Constants currently in scope
@@ -103,19 +92,23 @@ in a buffer."
                         context
                       (semantic-analyze-current-context context)))
           (ans (if (not context)
-                   (error "Nothing to Complete.")
+                   (error "Nothing to complete")
                  (:override))))
       ;; If interactive, display them.
-      (when (interactive-p)
+      (when (called-interactively-p 'any)
        (with-output-to-temp-buffer "*Possible Completions*"
          (semantic-analyze-princ-sequence ans "" (current-buffer)))
        (shrink-window-if-larger-than-buffer
         (get-buffer-window "*Possible Completions*")))
       ans)))
 
-(defun semantic-analyze-possible-completions-default (context)
+(defun semantic-analyze-possible-completions-default (context &optional flags)
   "Default method for producing smart completions.
-Argument CONTEXT is an object specifying the locally derived context."
+Argument CONTEXT is an object specifying the locally derived context.
+The optional argument FLAGS changes which return options are returned.
+FLAGS can be any number of:
+  'no-tc     - do not apply data-type constraint.
+  'no-unique - do not apply unique by name filtering."
   (let* ((a context)
         (desired-type (semantic-analyze-type-constraint a))
         (desired-class (oref a prefixclass))
@@ -124,8 +117,13 @@ Argument CONTEXT is an object specifying the locally derived context."
         (completetext nil)
         (completetexttype nil)
         (scope (oref a scope))
-        (localvar (oref scope localvar))
-        (c nil))
+        (localvar (when scope (oref scope localvar)))
+        (origc nil)
+        (c nil)
+        (any nil)
+        (do-typeconstraint (not (memq 'no-tc flags)))
+        (do-unique (not (memq 'no-unique flags)))
+        )
 
     ;; Calculate what our prefix string is so that we can
     ;; find all our matching text.
@@ -175,33 +173,36 @@ Argument CONTEXT is an object specifying the locally derived context."
               ;; Argument list and local variables
               (semantic-find-tags-for-completion completetext localvar)
               ;; The current scope
-              (semantic-find-tags-for-completion completetext (oref scope fullscope))
+              (semantic-find-tags-for-completion completetext (when scope (oref scope fullscope)))
               ;; The world
               (semantic-analyze-find-tags-by-prefix completetext))
            )
       )
 
-    (let ((origc c)
+    (let ((loopc c)
          (dtname (semantic-tag-name desired-type)))
 
+      ;; Save off our first batch of completions
+      (setq origc c)
+
       ;; Reset c.
       (setq c nil)
 
       ;; Loop over all the found matches, and catagorize them
       ;; as being possible features.
-      (while origc
+      (while (and loopc do-typeconstraint)
 
        (cond
         ;; Strip operators
-        ((semantic-tag-get-attribute (car origc) :operator-flag)
+        ((semantic-tag-get-attribute (car loopc) :operator-flag)
          nil
          )
 
         ;; If we are completing from within some prefix,
         ;; then we want to exclude constructors and destructors
         ((and completetexttype
-              (or (semantic-tag-get-attribute (car origc) :constructor-flag)
-                  (semantic-tag-get-attribute (car origc) :destructor-flag)))
+              (or (semantic-tag-get-attribute (car loopc) :constructor-flag)
+                  (semantic-tag-get-attribute (car loopc) :destructor-flag)))
          nil
          )
 
@@ -212,17 +213,17 @@ Argument CONTEXT is an object specifying the locally derived context."
           ;; Ok, we now have a completion list based on the text we found
           ;; we want to complete on.  Now filter that stream against the
           ;; type we want to search for.
-          ((string= dtname (semantic-analyze-type-to-name (semantic-tag-type (car origc))))
-           (setq c (cons (car origc) c))
+          ((string= dtname (semantic-analyze-type-to-name (semantic-tag-type (car loopc))))
+           (setq c (cons (car loopc) c))
            )
 
           ;; Now anything that is a compound type which could contain
           ;; additional things which are of the desired type
-          ((semantic-tag-type (car origc))
-           (let ((att (semantic-analyze-tag-type (car origc) scope))
+          ((semantic-tag-type (car loopc))
+           (let ((att (semantic-analyze-tag-type (car loopc) scope))
                )
              (if (and att (semantic-tag-type-members att))
-                 (setq c (cons (car origc) c))))
+                 (setq c (cons (car loopc) c))))
            )
 
           ) ; cond
@@ -230,11 +231,11 @@ Argument CONTEXT is an object specifying the locally derived context."
 
         ;; No desired type, no other restrictions.  Just add.
         (t
-         (setq c (cons (car origc) c)))
+         (setq c (cons (car loopc) c)))
 
         ); cond
 
-       (setq origc (cdr origc)))
+       (setq loopc (cdr loopc)))
 
       (when desired-type
        ;; Some types, like the enum in C, have special constant values that
@@ -256,22 +257,24 @@ Argument CONTEXT is an object specifying the locally derived context."
     (when desired-class
       (setq c (semantic-analyze-tags-of-class-list c desired-class)))
 
-    ;; Pull out trash.
-    ;; NOTE TO SELF: Is this too slow?
-    ;; OTHER NOTE: Do we not want to strip duplicates by name and
-    ;; only by position?  When are duplicate by name but not by tag
-    ;; useful?
-    (setq c (semantic-unique-tag-table-by-name c))
+    (if do-unique
+       (if c
+           ;; Pull out trash.
+           ;; NOTE TO SELF: Is this too slow?
+           (setq c (semantic-unique-tag-table-by-name c))
+         (setq c (semantic-unique-tag-table-by-name origc)))
+      (when (not c)
+       (setq c origc)))
 
     ;; All done!
-
     c))
 
 (provide 'semantic/analyze/complete)
 
 ;; Local variables:
 ;; generated-autoload-file: "../loaddefs.el"
-;; generated-autoload-feature: semantic/loaddefs
+;; generated-autoload-load-name: "semantic/analyze/complete"
 ;; End:
 
+;; arch-tag: 97071c7e-2459-4e7a-8875-8cc5bbbc1f4d
 ;;; semantic/analyze/complete.el ends here