Function: semantic-edits-change-over-tags

semantic-edits-change-over-tags is a byte-compiled function defined in edit.el.gz.

Signature

(semantic-edits-change-over-tags CHANGE)

Documentation

Return a cache list of tags surrounding a CHANGE encompassing tags.

CHANGE must not only include all overlapped tags (excepting possible parent tags) in their entirety. In this case, the change may be deleting or moving whole tags. The return value is a vector. Cell 0 is a list of all tags completely encompassed in change. Cell 1 is the cons cell into a master parser cache starting with the cell which occurs BEFORE the first position of CHANGE. Cell 2 is the parent of cell 1, or nil for the buffer cache. This function returns nil if any tag covered by change is not completely encompassed. See semantic-edits-change-leaf-tag for details on parents.

Source Code

;; Defined in /usr/src/emacs/lisp/cedet/semantic/edit.el.gz
(defun semantic-edits-change-over-tags (change)
  "Return a cache list of tags surrounding a CHANGE encompassing tags.
CHANGE must not only include all overlapped tags (excepting possible
parent tags) in their entirety.  In this case, the change may be deleting
or moving whole tags.
The return value is a vector.
Cell 0 is a list of all tags completely encompassed in change.
Cell 1 is the cons cell into a master parser cache starting with
the cell which occurs BEFORE the first position of CHANGE.
Cell 2 is the parent of cell 1, or nil for the buffer cache.
This function returns nil if any tag covered by change is not
completely encompassed.
See `semantic-edits-change-leaf-tag' for details on parents."
  (let* ((start (semantic-edits-os change))
	 (end (semantic-edits-oe change))
	 (tags (nreverse
		  (semantic-find-tag-by-overlay-in-region
		   start end)))
	 (parent nil)
	 (overlapped-tags nil)
	 inner-end ;; inner-start
	 (list-to-search nil))
    ;; By the time this is already called, we know that it is
    ;; not a leaf change, nor a between tag change.  That leaves
    ;; an overlap, and this condition.

    ;; A leaf is always first in this list.
    ;; Is the leaf encompassed in this change?
    (if (and tags
	     (>= (semantic-tag-start (car tags)) start)
	     (<= (semantic-tag-end (car tags)) end))
	(progn
	  ;; We encompass one whole change.
	  (setq overlapped-tags (list (car tags))
		;; inner-start (semantic-tag-start (car tags))
		inner-end (semantic-tag-end (car tags))
		tags (cdr tags))
	  ;; Keep looping while tags are inside the change.
	  (while (and tags
		      (>= (semantic-tag-start (car tags)) start)
		      (<= (semantic-tag-end (car tags)) end))

	    ;; Check if this new all-encompassing tag is a parent
	    ;; of that which went before.  Only check end because
	    ;; we know that start is less than inner-start since
	    ;; tags was sorted on that.
	    (if (> (semantic-tag-end (car tags)) inner-end)
		;; This is a parent.  Drop the children found
		;; so far.
		(setq overlapped-tags (list (car tags))
		      ;; inner-start (semantic-tag-start (car tags))
		      inner-end (semantic-tag-end (car tags))
		      )
	      ;; It is not a parent encompassing tag
	      (setq overlapped-tags (cons (car tags)
					    overlapped-tags)
		    ;; inner-start (semantic-tag-start (car tags))
		    ))
	    (setq tags (cdr tags)))
	  (if (not tags)
	      ;; There are no tags left, and all tags originally
	      ;; found are encompassed by the change.  Setup our list
	      ;; from the cache
	      (setq list-to-search semantic--buffer-cache);; We have a tag outside the list.  Check for
	    ;; We know we have a parent because it would
	    ;; completely cover the change.  A tag can only
	    ;; do that if it is a parent after we get here.
	    (when (and tags
		       (< (semantic-tag-start (car tags)) start)
		       (> (semantic-tag-end (car tags)) end))
	      ;; We have a parent.  Stuff in the search list.
	      (setq parent (car tags)
		    list-to-search (semantic-tag-components parent))
	      ;; If the first of TAGS is a parent (see above)
	      ;; then clear out the list.  All other tags in
	      ;; here must therefore be parents of the car.
	      (setq tags nil)
	      ;; One last check,  If start is before the first
	      ;; tag or after the last, we may have overlap into
	      ;; the characters that make up the definition of
	      ;; the tag we are parsing.
	      (when (or (semantic-tag-with-position-p (car list-to-search))
			(< start (semantic-tag-start
				  (car list-to-search)))
			(> end (semantic-tag-end
				(nth (1- (length list-to-search))
				     list-to-search))))
		;; We have a problem
		(setq list-to-search nil
		      parent nil))))

	  (when list-to-search

	    ;; Ok, return the vector only if all TAGS are
	    ;; confirmed as the lineage of `overlapped-tags'
	    ;; which must have a value by now.

	    ;; Loop over the search list to find the preceding CDR.
	    ;; Fortunately, (car overlapped-tags) happens to be
	    ;; the first tag positionally.
	    (let ((tokstart (semantic-tag-start (car overlapped-tags))))
	      (while (and list-to-search
			  ;; Assume always (car (cdr list-to-search)).
			  ;; A thrown error will be captured nicely, but
			  ;; that case shouldn't happen.

			  ;; We end when the start of the CDR is after the
			  ;; end of our asked change.
			  (cdr list-to-search)
			  (< (semantic-tag-start (car (cdr list-to-search)))
			     tokstart)
			  (setq list-to-search (cdr list-to-search)))))
	    ;; Create the return vector
	    (vector overlapped-tags
		    list-to-search
		    parent)
	    ))
      nil)))