Add 2012 to FSF copyright years for Emacs files
[bpt/emacs.git] / lisp / cedet / semantic / symref / filter.el
... / ...
CommitLineData
1;;; semantic/symref/filter.el --- Filter symbol reference hits for accuracy.
2
3;; Copyright (C) 2009-2012 Free Software Foundation, Inc.
4
5;; Author: Eric M. Ludlam <eric@siege-engine.com>
6
7;; This file is part of GNU Emacs.
8
9;; GNU Emacs is free software: you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation, either version 3 of the License, or
12;; (at your option) any later version.
13
14;; GNU Emacs is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18
19;; You should have received a copy of the GNU General Public License
20;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
21
22;;; Commentary:
23;;
24;; Filter symbol reference hits for accuracy.
25;;
26;; Most symbol referencing tools, such as find/grep only find matching
27;; strings, but cannot determine the difference between an actual use,
28;; and something else with a similar name, or even a string in a comment.
29;;
30;; This file provides utilities for filtering down to accurate matches
31;; starting at a basic filter level that doesn't use symref, up to filters
32;; across symref results.
33
34;;; Code:
35
36(require 'semantic)
37(require 'semantic/analyze)
38(declare-function srecode-active-template-region "srecode/fields")
39(declare-function srecode-delete "srecode/fields")
40(declare-function srecode-field "srecode/fields")
41(declare-function srecode-template-inserted-region "srecode/fields")
42(declare-function srecode-overlaid-activate "srecode/fields")
43(declare-function semantic-idle-summary-useful-context-p "semantic/idle")
44
45;;; FILTERS
46;;
47(defun semantic-symref-filter-hit (target &optional position)
48 "Determine if the tag TARGET is used at POSITION in the current buffer.
49Return non-nil for a match."
50 (semantic-analyze-current-symbol
51 (lambda (start end prefix)
52 (let ((tag (car (nreverse prefix))))
53 (and (semantic-tag-p tag)
54 (semantic-equivalent-tag-p target tag))))
55 position))
56
57;;; IN-BUFFER FILTERING
58
59;; The following does filtering in-buffer only, and not against
60;; a symref results object.
61
62(defun semantic-symref-hits-in-region (target hookfcn start end)
63 "Find all occurrences of the symbol TARGET that match TARGET the tag.
64For each match, call HOOKFCN.
65HOOKFCN takes three arguments that match
66`semantic-analyze-current-symbol's use of HOOKFCN.
67 ( START END PREFIX )
68
69Search occurs in the current buffer between START and END."
70 (require 'semantic/idle)
71 (save-excursion
72 (goto-char start)
73 (let* ((str (semantic-tag-name target))
74 (case-fold-search semantic-case-fold)
75 (regexp (concat "\\<" (regexp-quote str) "\\>")))
76 (while (re-search-forward regexp end t)
77 (when (semantic-idle-summary-useful-context-p)
78 (semantic-analyze-current-symbol
79 (lambda (start end prefix)
80 (let ((tag (car (nreverse prefix))))
81 ;; check for semantic match on the text match.
82 (when (and (semantic-tag-p tag)
83 (semantic-equivalent-tag-p target tag))
84 (save-excursion
85 (funcall hookfcn start end prefix)))))
86 (point)))))))
87
88(defun semantic-symref-rename-local-variable ()
89 "Fancy way to rename the local variable under point.
90Depends on the SRecode Field editing API."
91 (interactive)
92 ;; Do the replacement as needed.
93 (let* ((ctxt (semantic-analyze-current-context))
94 (target (car (reverse (oref ctxt prefix))))
95 (tag (semantic-current-tag))
96 )
97
98 (when (or (not target)
99 (not (semantic-tag-with-position-p target)))
100 (error "Cannot identify symbol under point"))
101
102 (when (not (semantic-tag-of-class-p target 'variable))
103 (error "Can only rename variables"))
104
105 (when (or (< (semantic-tag-start target) (semantic-tag-start tag))
106 (> (semantic-tag-end target) (semantic-tag-end tag)))
107 (error "Can only rename variables declared in %s"
108 (semantic-tag-name tag)))
109
110 ;; I think we're good for this example. Give it a go through
111 ;; our fancy interface from SRecode.
112 (require 'srecode/fields)
113
114 ;; Make sure there is nothing active.
115 (let ((ar (srecode-active-template-region)))
116 (when ar (srecode-delete ar)))
117
118 (let ((srecode-field-archive nil)
119 (region nil)
120 )
121 (semantic-symref-hits-in-region
122 target (lambda (start end prefix)
123 ;; For every valid hit, create one field.
124 (srecode-field "LOCAL" :name "LOCAL" :start start :end end))
125 (semantic-tag-start tag) (semantic-tag-end tag))
126
127 ;; Now that the fields are setup, create the region.
128 (setq region (srecode-template-inserted-region
129 "REGION" :start (semantic-tag-start tag)
130 :end (semantic-tag-end tag)))
131
132 ;; Activate the region.
133 (srecode-overlaid-activate region)
134
135 )
136 ))
137
138(provide 'semantic/symref/filter)
139
140;;; semantic/symref/filter.el ends here