;;; semantic/scope.el --- Analyzer Scope Calculations
-;; Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+;; Copyright (C) 2007-2015 Free Software Foundation, Inc.
;; Author: Eric M. Ludlam <eric@siege-engine.com>
(declare-function semantic-analyze-princ-sequence "semantic/analyze")
(declare-function semanticdb-typecache-merge-streams "semantic/db-typecache")
(declare-function semanticdb-typecache-add-dependant "semantic/db-typecache")
+(declare-function semantic-tag-similar-p "semantic/tag-ls")
;;; Code:
;;
;; Methods for basic management of the structure in semanticdb.
;;
-(defmethod semantic-reset ((obj semantic-scope-cache))
+(cl-defmethod semantic-reset ((obj semantic-scope-cache))
"Reset OBJ back to it's empty settings."
(oset obj tag nil)
(oset obj scopetypes nil)
(oset obj typescope nil)
)
-(defmethod semanticdb-synchronize ((cache semantic-scope-cache)
+(cl-defmethod semanticdb-synchronize ((cache semantic-scope-cache)
new-tags)
"Synchronize a CACHE with some NEW-TAGS."
(semantic-reset cache))
-(defmethod semanticdb-partial-synchronize ((cache semantic-scope-cache)
+(cl-defmethod semanticdb-partial-synchronize ((cache semantic-scope-cache)
new-tags)
"Synchronize a CACHE with some changed NEW-TAGS."
;; If there are any includes or datatypes changed, then clear.
"Get the current cached scope, and reset it."
(when semanticdb-current-table
(let ((co (semanticdb-cache-get semanticdb-current-table
- semantic-scope-cache)))
+ 'semantic-scope-cache)))
(semantic-reset co))))
-(defmethod semantic-scope-set-typecache ((cache semantic-scope-cache)
+(cl-defmethod semantic-scope-set-typecache ((cache semantic-scope-cache)
types-in-scope)
"Set the :typescope property on CACHE to some types.
TYPES-IN-SCOPE is a list of type tags whos members are
;; tag can be passed in and a scope derived from it.
(defun semantic-scope-tag-clone-with-scope (tag scopetags)
- "Close TAG, and return it. Add SCOPETAGS as a tag-local scope.
+ "Clone TAG, and return it. Add SCOPETAGS as a tag-local scope.
Stores the SCOPETAGS as a set of tag properties on the cloned tag."
(let ((clone (semantic-tag-clone tag))
)
(save-excursion
(goto-char position)
(let ((code-scoped-types nil))
- ;; Lets ask if any types are currently scoped. Scoped
+ ;; Let's ask if any types are currently scoped. Scoped
;; classes and types provide their public methods and types
;; in source code, but are unrelated hierarchically.
(let ((sp (semantic-ctxt-scoped-types)))
;; Get this thing as a tag
(let ((tmp (cond
((stringp (car sp))
- (semanticdb-typecache-find (car sp)))
- ;(semantic-analyze-find-tag (car sp) 'type))
+ (or (semanticdb-typecache-find (car sp))
+ ;; If we did not find it in the typecache,
+ ;; look in the tags we found so far
+ (car (semantic-deep-find-tags-by-name
+ (car sp)
+ code-scoped-types))))
((semantic-tag-p (car sp))
- (if (semantic-analyze-tag-prototype-p (car sp))
- (semanticdb-typecache-find (semantic-tag-name (car sp)))
- ;;(semantic-analyze-find-tag (semantic-tag-name (car sp)) 'type)
+ (if (semantic-tag-prototype-p (car sp))
+ (or (semanticdb-typecache-find (semantic-tag-name (car sp)))
+ (car (semantic-deep-find-tags-by-name
+ (semantic-tag-name (car sp))
+ code-scoped-types)))
(car sp)))
(t nil))))
(when tmp
;; Analyze the stack of tags we are nested in as parents.
;;
- ;; If we have a pparent tag, lets go there
+ ;; If we have a pparent tag, let's go there
;; an analyze that stack of tags.
(when (and pparent (semantic-tag-with-position-p pparent))
(semantic-go-to-tag pparent)
(setq stack (reverse stack))
;; Add things to STACK until we cease finding tags of class type.
(while (and stack (eq (semantic-tag-class (car stack)) 'type))
- ;; Otherwise, just add this to the returnlist.
- (setq returnlist (cons (car stack) returnlist))
- (setq stack (cdr stack)))
+ ;; Otherwise, just add this to the returnlist, but make
+ ;; sure we didn't already have that tag in scopetypes
+ (unless (member (car stack) scopetypes)
+ (setq returnlist (cons (car stack) returnlist)))
+ (setq stack (cdr stack)))
(setq returnlist (nreverse returnlist))
))
(miniscope (semantic-scope-cache "mini"))
ptag)
- ;; Find the next entry in the refereneced type for
+ ;; Find the next entry in the referenced type for
;; our function, and append to return list till our
;; returnlist is empty.
(while snlist
;;------------------------------------------------------------
(define-overloadable-function semantic-analyze-scoped-tags (typelist parentlist)
- "Return accessable tags when TYPELIST and PARENTLIST is in scope.
+ "Return accessible tags when TYPELIST and PARENTLIST is in scope.
Tags returned are not in the global name space, but are instead
scoped inside a class or namespace. Such items can be referenced
without use of \"object.function()\" style syntax due to an
))
(setq typelist (cdr typelist)))
- ;; Loop over the types (which should be sorted by postion
+ ;; Loop over the types (which should be sorted by position)
;; adding to the scopelist as we go, and using the scopelist
;; for additional searching!
(while typelist2
currentscope))
(setq typelist2 (cdr typelist2)))
- ;; Collect all the types (class, etc) that are in our heratage.
+ ;; Collect all the types (class, etc) that are in our heritage.
;; These are types that we can extract members from, not those
- ;; delclared in using statements, or the like.
+ ;; declared in using statements, or the like.
;; Get the PARENTS including nesting scope for this location.
(while parentlist
(oset miniscope scope currentscope)
(leftover nil)
)
(dolist (S allslots)
- (when (or (not (semantic-tag-of-class-p S 'function))
- (not (semantic-tag-function-parent S)))
- (setq leftover (cons S leftover)))
- )
+ ;; We have to specially deal with 'using' tags here, since those
+ ;; pull in namespaces or classes into the current scope.
+ ;; (Should this go into c.el? If so, into which override?)
+ (if (semantic-tag-of-class-p S 'using)
+ (let* ((fullname (semantic-analyze-unsplit-name
+ (list (semantic-tag-name type)
+ (semantic-tag-name S))))
+ ;; Search the typecache, first for the unqualified name
+ (usingtype (or
+ (semanticdb-typecache-find (semantic-tag-name S))
+ ;; If that didn't return anything, use
+ ;; fully qualified name
+ (semanticdb-typecache-find fullname)))
+ (filename (when usingtype (semantic-tag-file-name usingtype))))
+ (when usingtype
+ ;; Use recursion to examine that namespace or class
+ (let ((tags (semantic-completable-tags-from-type usingtype)))
+ (if filename
+ ;; If we have a filename, copy the tags with it
+ (dolist (cur tags)
+ (setq leftover (cons (semantic-tag-copy cur nil filename)
+ leftover)))
+ ;; Otherwise just run with it
+ (setq leftover (append tags leftover))))))
+ (when (or (not (semantic-tag-of-class-p S 'function))
+ (not (semantic-tag-function-parent S)))
+ (setq leftover (cons S leftover)))))
(nreverse leftover)))
(defun semantic-analyze-scoped-type-parts (type &optional scope noinherit protection)
(let* ((TAG (semantic-current-tag))
(scopecache
(semanticdb-cache-get semanticdb-current-table
- semantic-scope-cache))
+ 'semantic-scope-cache))
)
(when (not (semantic-equivalent-tag-p TAG (oref scopecache tag)))
(semantic-reset scopecache))
(oset scopecache localargs localargs)
(oset scopecache localvar localvar)
)))
- ;; Make sure we become dependant on the typecache.
+ ;; Make sure we become dependent on the typecache.
(semanticdb-typecache-add-dependant scopecache)
;; Handy debug output.
(when (called-interactively-p 'any)
(require 'eieio-datadebug)
(data-debug-show scopecache))
- ;; Return ourselves
- scopecache))))
+ ;; Return ourselves, but make a clone first so that the caller
+ ;; can reset the scope cache without affecting others.
+ (clone scopecache)))))
(defun semantic-scope-find (name &optional class scope-in)
"Find the tag with NAME, and optional CLASS in the current SCOPE-IN.
;;; DUMP
;;
-(defmethod semantic-analyze-show ((context semantic-scope-cache))
+(cl-defmethod semantic-analyze-show ((context semantic-scope-cache))
"Insert CONTEXT into the current buffer in a nice way."
(require 'semantic/analyze)
(semantic-analyze-princ-sequence (oref context scopetypes) "-> ScopeTypes: " )
;; generated-autoload-load-name: "semantic/scope"
;; End:
-;; arch-tag: 056ab514-3e28-4d6e-84ed-9283dce5a01e
;;; semantic/scope.el ends here