Function: semantic-analyze-current-context-default

semantic-analyze-current-context-default is a byte-compiled function defined in analyze.el.gz.

Signature

(semantic-analyze-current-context-default POSITION)

Documentation

Analyze the current context at POSITION.

Returns an object based on symbol semantic-analyze-context(var)/semantic-analyze-context(fun).

Source Code

;; Defined in /usr/src/emacs/lisp/cedet/semantic/analyze.el.gz
(defun semantic-analyze-current-context-default (position)
  "Analyze the current context at POSITION.
Returns an object based on symbol `semantic-analyze-context'."
  (let* ((semantic-analyze-error-stack nil)
	 (context-return nil)
	 (prefixandbounds (semantic-ctxt-current-symbol-and-bounds (or position (point))))
	 (prefix (car prefixandbounds))
	 (bounds (nth 2 prefixandbounds))
	 ;; @todo - vv too early to really know this answer! vv
	 (prefixclass (semantic-ctxt-current-class-list))
	 (semantic--prefixtypes nil)
	 (scope (semantic-calculate-scope position))
	 (function nil)
	 (fntag nil)
	 arg fntagend argtag
	 assign asstag newseq
	 )

    ;; Pattern for Analysis:
    ;;
    ;; Step 1: Calculate DataTypes in Scope:
    ;;
    ;;  a) Calculate the scope (above)
    ;;
    ;; Step 2: Parse context
    ;;
    ;; a) Identify function being called, or variable assignment,
    ;;    and find source tags for those references
    ;; b) Identify the prefix (text cursor is on) and find the source
    ;;    tags for those references.
    ;;
    ;; Step 3: Assemble an object
    ;;

    ;; Step 2 a:

    (setq function (semantic-ctxt-current-function))

    (when function
      ;; Calculate the argument for the function if there is one.
      (setq arg (semantic-ctxt-current-argument))

      ;; Find a tag related to the function name.
      (condition-case err
	  (setq fntag
		(semantic-analyze-find-tag-sequence function scope))
	(error (semantic-analyze-push-error err)))

      ;; fntag can have the last entry as just a string, meaning we
      ;; could not find the core datatype.  In this case, the searches
      ;; below will not work.
      (when (stringp (car (last fntag)))
	;; Take a wild guess!
	(setcar (last fntag) (semantic-tag (car (last fntag)) 'function))
	)

      (when fntag
	(let ((fcn (semantic-find-tags-by-class 'function fntag)))
	  (when (not fcn)
	    (let ((ty (semantic-find-tags-by-class 'type fntag)))
	      (when ty
		;; We might have a constructor with the same name as
		;; the found datatype.
		(setq fcn (semantic-find-tags-by-name
			   (semantic-tag-name (car ty))
			   (semantic-tag-type-members (car ty))))
		(if fcn
		    (let ((lp fcn))
		      (while lp
			(when (semantic-tag-get-attribute (car lp)
							  :constructor)
			  (setq fcn (cons (car lp) fcn)))
			(setq lp (cdr lp))))
		  ;; Give up, go old school
		  (setq fcn fntag))
		)))
	  (setq fntagend (car (reverse fcn))
		argtag
		(when (semantic-tag-p fntagend)
		  (nth (1- arg) (semantic-tag-function-arguments fntagend)))
		fntag fcn))))

    ;; Step 2 b:

    ;; Only do work if we have bounds (meaning a prefix to complete)
    (when bounds

      (if debug-on-error
	  (catch 'unfindable
	    (setq prefix (semantic-analyze-find-tag-sequence
			  prefix scope 'semantic--prefixtypes 'unfindable))
	    ;; If there's an alias, dereference it and analyze
	    ;; sequence again.
	    (when (setq newseq
			(semantic-analyze-dereference-alias prefix))
	      (setq prefix (semantic-analyze-find-tag-sequence
			    newseq scope 'semantic--prefixtypes 'unfindable))))
	;; Debug on error is off.  Capture errors and move on
	(condition-case err
	    ;; NOTE: This line is duplicated in
	    ;;       semantic-analyzer-debug-global-symbol
	    ;;       You will need to update both places.
	    (progn
	      (setq prefix (semantic-analyze-find-tag-sequence
			    prefix scope 'semantic--prefixtypes))
	      (when (setq newseq
			  (semantic-analyze-dereference-alias prefix))
		(setq prefix (semantic-analyze-find-tag-sequence
			      newseq scope 'semantic--prefixtypes))))
	  (error (semantic-analyze-push-error err))))
      )

    ;; Step 3:

    (cond
     (fntag
      ;; If we found a tag for our function, we can go into
      ;; functional context analysis mode, meaning we have a type
      ;; for the argument.
      (setq context-return
	    (semantic-analyze-context-functionarg
	     :buffer (current-buffer)
	     :function fntag
	     :index arg
	     :argument (list argtag)
	     :scope scope
	     :prefix prefix
	     :prefixclass prefixclass
	     :bounds bounds
	     :prefixtypes semantic--prefixtypes
	     :errors semantic-analyze-error-stack)))

      ;; No function, try assignment
     ((and (setq assign (semantic-ctxt-current-assignment))
	   ;; We have some sort of an assignment
	   (condition-case err
	       (setq asstag (semantic-analyze-find-tag-sequence
			     assign scope nil nil 'mustbeclassvariable))
	     (error (semantic-analyze-push-error err)
		    nil)))

      (setq context-return
	    (semantic-analyze-context-assignment
	     :buffer (current-buffer)
	     :assignee asstag
	     :scope scope
	     :bounds bounds
	     :prefix prefix
	     :prefixclass prefixclass
	     :prefixtypes semantic--prefixtypes
	     :errors semantic-analyze-error-stack)))

     ;; TODO: Identify return value condition.
     ;;((setq return .... what to do?)
     ;;  ...)

     (bounds
      ;; Nothing in particular
      (setq context-return
	    (semantic-analyze-context
	     :buffer (current-buffer)
	     :scope scope
	     :bounds bounds
	     :prefix prefix
	     :prefixclass prefixclass
	     :prefixtypes semantic--prefixtypes
	     :errors semantic-analyze-error-stack)))

     (t (setq context-return nil))
     )

    ;; Return our context.
    context-return))