]> code.delx.au - gnu-emacs/blobdiff - lisp/cedet/semantic/analyze/complete.el
Merge from mainline.
[gnu-emacs] / lisp / cedet / semantic / analyze / complete.el
index 675364589cddf458f603b27b3cd40351538e1c51..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>
 
@@ -63,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
@@ -98,9 +102,13 @@ in a 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))
@@ -109,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.
@@ -160,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
          )
 
@@ -197,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
@@ -215,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
@@ -241,15 +257,16 @@ 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)