;;; semantic/scope.el --- Analyzer Scope Calculations
-;; Copyright (C) 2007-2011 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:
;; 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
;; declared in using statements, or the like.
;; Get the PARENTS including nesting scope for this location.
(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)
(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.