Warning, /sdk/kde-dev-scripts/kde-emacs/kde-emacs-semantic.el is written in an unsupported language. File is not indexed.
0001 ;; kde-emacs-semantic.el 0002 ;; 0003 ;; Copyright (C) 2002 Zack Rusin <zack@kde.org> 0004 ;; 0005 ;; This library is free software; you can redistribute it and/or 0006 ;; modify it under the terms of the GNU Lesser General Public 0007 ;; License as published by the Free Software Foundation; either 0008 ;; version 2.1 of the License, or (at your option) any later version. 0009 ;; 0010 ;; This library is distributed in the hope that it will be useful, 0011 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 ;; Lesser General Public License for more details. 0014 ;; 0015 ;; You should have received a copy of the GNU Lesser General Public 0016 ;; License along with this library; if not, write to the Free Software 0017 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0018 ;; 02110-1301 USA 0019 0020 ;;; Commentary: 0021 ;; Package provides four interactive functions: 0022 ;; - kde-function-doc-insert - creates a skeleton doxygen 0023 ;; documentation for function at point. 0024 ;; Customize it with kde-func-doc variables. 0025 ;; 0026 ;; - kde-function-expanded-at-point - returns t if function at point 0027 ;; has already been expanded. 0028 ;; 0029 ;; - kde-function-expand-at-point - expand (creates a stub) for function 0030 ;; at point (as long as function is a prototype 0031 ;; and haven't been expanded). 0032 ;; 0033 ;; - kde-create-skeletons - creates stubs for all methods in the current 0034 ;; header file. 0035 ;; 0036 ;; Package is very flexible, look at defcustom variables for things 0037 ;; you can customize. 0038 0039 ;;; Problems: 0040 ;; Most problems relate to C++ syntax which isn't handled correctly 0041 ;; by the Semantic package. For now templates aren't supported, I 0042 ;; have a temporary solution for other problems (e.g. const functions, 0043 ;; QT/KDE specific access specifiers) 0044 0045 ;;; Code: 0046 (require 'kde-emacs-vars) 0047 (require 'kde-emacs-general) 0048 0049 ;*---------------------------------------------------------------------*/ 0050 ;* User configuration ... */ 0051 ;*---------------------------------------------------------------------*/ 0052 ;;Not yet, not yet 0053 ;(defcustom kde-summary-function 'semantic-uml-prototype-nonterminal 0054 ; "*Function to use when showing info about the token" 0055 ; :group 'kde-devel 0056 ; :type semantic-token->text-custom-list 0057 ; ) 0058 0059 (defcustom kde-generate-docs-with-stubs nil 0060 "*Should function documentation be generated with the stubs." 0061 :group 'kde-devel 0062 :type 'boolean) 0063 0064 (defcustom kde-expand-arg-start "( " 0065 "*A string which specifies how the function arguments format should start. 0066 e.g. \"( \" would start function arguments list like : \"func( int arg\". 0067 and \" (\" will format the begining of the function argument list as 0068 follows : \"func (int arg\"." 0069 :group 'kde-devel 0070 :version "0.1" 0071 :type 'string) 0072 0073 (defcustom kde-expand-arg-end " )" 0074 "*Just like kde-expand-arg-start but specifies how the list should end." 0075 :group 'kde-devel 0076 :version "0.1" 0077 :type 'string) 0078 0079 (defcustom kde-expand-arg-break ", " 0080 "*Specifies how the arguments should be separated." 0081 :group 'kde-devel 0082 :version "0.1" 0083 :type 'string) 0084 0085 0086 ;*---------------------------------------------------------------------*/ 0087 ;* Functions ... */ 0088 ;*---------------------------------------------------------------------*/ 0089 ;; FIXME : semantic doesn't handle QT access specifiers 0090 ;(setq-default global-semantic-show-unmatched-syntax-mode nil) 0091 ;(setq-default global-semantic-show-dirty-mode nil) 0092 0093 (defun kde-format-func-arg (arg) 0094 "Formats one argument (from token to string)." 0095 (let ((ret "")) 0096 (if (semantic-token-variable-extra-spec arg 'const) 0097 (setq ret "const ")) 0098 (setq ret (concat ret (car (semantic-token-type arg)))) 0099 (if (semantic-token-variable-extra-spec arg 'pointer) 0100 (dotimes (idx (semantic-token-variable-extra-spec arg 'pointer)) 0101 (setq ret (concat ret "*")) 0102 ) 0103 ) 0104 (if (semantic-token-variable-extra-spec arg 'reference) 0105 (setq ret (concat ret "&")) 0106 ) 0107 (setq ret (concat ret " " (semantic-token-name arg))) 0108 ret 0109 )) 0110 0111 (defun kde-format-args (token) 0112 "Formats all arguments from token to string. 0113 Token has to be the function variable list e.g. 0114 from semantic-token-function-args" 0115 (let ((res kde-expand-arg-start) (idx 1)) 0116 (dolist (elt token res) 0117 (setq res (concat res (kde-format-func-arg elt))) 0118 (when (< idx (length token)) 0119 (setq res (concat res kde-expand-arg-break))) 0120 (setq idx (1+ idx)) 0121 ) 0122 (setq res (concat res kde-expand-arg-end)) 0123 ;; if it's something like "( )" replace it with "()" 0124 (when (string= res (concat kde-expand-arg-start kde-expand-arg-end)) 0125 (setq res (replace-regexp-in-string "([ \t]+)" "()" res))) 0126 res 0127 )) 0128 0129 (defun kde-function-in-tokens (FUNC TOKENS) 0130 "Search for function in tokens. FUNC has to be a function 0131 token and TOKENS have to be a list of functions from buffer." 0132 (let ((ret)(elt)) 0133 (while (and TOKENS (not ret)) 0134 (setq elt (car TOKENS)) 0135 (setq TOKENS (cdr TOKENS)) 0136 (if (and (string= (semantic-token-name FUNC) 0137 (semantic-token-name elt)) 0138 (equal (semantic-token-type FUNC) 0139 (semantic-token-type elt)) 0140 ;; FIXME (semantic) : Functions in some classes don't have the 0141 ;; 'parent property set !!! 0142 ;;(string= (semantic-token-function-parent FUNC1) 0143 ;; (semantic-token-function-parent FUNC2)) 0144 (string= (kde-format-args (semantic-token-function-args FUNC)) 0145 (kde-format-args (semantic-token-function-args elt)))) 0146 (setq ret t)) 0147 ) 0148 ret 0149 )) 0150 0151 ;; TODO support Q_SIGNALS too 0152 (defmacro kde-label-signals (pt) 0153 "Returns none-nil if the current access label == \"signals\"" 0154 `(save-excursion 0155 (goto-char ,pt) 0156 (if (looking-at ":") 0157 (re-search-backward "signals" (point-at-bol) t) 0158 ) 0159 )) 0160 0161 (defun kde-label-namespace (pt) 0162 "Return the namespace to which the variable/function at point PT belongs to." 0163 (save-excursion 0164 (goto-char pt) 0165 (if (looking-at "::") 0166 (let ((start) (end)) 0167 (re-search-backward "\\b\\w+" (point-at-bol) t) 0168 (setq start (match-beginning 0)) 0169 (setq end (match-end 0)) 0170 (buffer-substring-no-properties start end) 0171 ) 0172 ) 0173 )) 0174 0175 (defmacro kde-label-slots (pt) 0176 "Return none-nil if at PT there's slots access specifier." 0177 `(save-excursion 0178 (goto-char ,pt) 0179 (if (looking-at ":") 0180 ;; export this regex to a kde-emacs-vars defvar 0181 (re-search-backward "\\(public\\|protected\\|private\\)[ \t]+\\(slots\\|Q_SLOTS\\)" (point-at-bol) t)) 0182 )) 0183 0184 (defmacro kde-is-constructor (function) 0185 "Returns t if the FUNCTION is a constructor." 0186 `(semantic-token-function-extra-spec ,function 'constructor) 0187 ) 0188 0189 (defun kde-function-const (function) 0190 "Returns t if the FUNCTION has been declared as const, e.g. 0191 if given a token representing \"int getInt() const\" this functions 0192 would return t" 0193 (save-excursion 0194 (let ((start (semantic-token-start function)) 0195 (end (semantic-token-end function))) 0196 (goto-char end) 0197 (if (re-search-backward "const\b*;" start t) 0198 t 0199 nil) 0200 ) 0201 )) 0202 0203 (defun kde-is-prototype (function) 0204 "Returns t if the FUNCTION is only a prototype." 0205 (cond 0206 ((semantic-token-function-extra-spec function 'prototype) 0207 t) 0208 (t 0209 (kde-function-const function)) 0210 )) 0211 0212 0213 0214 (defun kde-function-at-point (pt) 0215 "Return function at pt as a token." 0216 (save-excursion 0217 (let ((token) 0218 (what (semantic-find-nonterminal-by-position pt (current-buffer))) 0219 (ctx)) 0220 (goto-char pt) 0221 (if (eq (semantic-token-token what) 'function) 0222 what 0223 (semantic-find-nonterminal-by-position pt (semantic-token-type-parts what))) 0224 ) 0225 )) 0226 0227 (defun kde-function-construct (token pclass) 0228 "Constructs a function string from the TOKEN, with the parent class PCLASS." 0229 (let ((fname (semantic-token-name token))) 0230 (if (semantic-token-function-destructor token) 0231 (setq fname (concat "~" fname)) 0232 ) 0233 (if pclass 0234 (setq fname (concat pclass "::" fname)) 0235 ) 0236 (if (and 0237 (not (kde-is-constructor token)) 0238 (not (semantic-token-function-destructor token))) 0239 (progn 0240 (cond 0241 ((stringp (semantic-token-type token)) 0242 (setq fname (concat (semantic-token-type token) "\n" fname)) 0243 ) 0244 (t 0245 (setq fname (concat (car (semantic-token-type token)) "\n" fname))) 0246 ) 0247 (if (semantic-token-function-extra-spec token 'const) 0248 (setq fname (concat "const " fname)) 0249 ) 0250 ) 0251 ) 0252 (setq fname (concat fname (kde-format-args (semantic-token-function-args token)))) 0253 (if (kde-function-const token) 0254 (setq fname (concat fname " const" )) 0255 ) 0256 (setq fname (concat fname "\n{" "\n}")) 0257 fname 0258 ) 0259 ) 0260 0261 (defun kde-class-expand (class-token) 0262 "Returns stubs for member functions as a string. 0263 class-token has to be a token representing either a class or a struct." 0264 (let ((ret "") 0265 (name (semantic-token-name class-token)) 0266 (parents (semantic-token-type-parent class-token)) 0267 (parts (semantic-token-type-parts class-token)) 0268 (cur-token) 0269 (cur-token-name) 0270 (asignal) 0271 (aslot) 0272 (namespace) 0273 ) 0274 (dolist (elt parts ret) 0275 (setq cur-token (semantic-token-token elt)) 0276 (setq cur-token-name (semantic-token-name elt)) 0277 (cond 0278 ((and 0279 (eq cur-token 'type) 0280 (stringp cur-token-name)) 0281 (cond 0282 ((string= cur-token-name "class") 0283 (kde-class-expand elt) 0284 ) 0285 ((string= cur-token-name "enum") 0286 ;;skip enums 0287 ) 0288 ((string= cur-token-name "struct") 0289 (kde-class-expand elt) 0290 ) 0291 ) 0292 ) 0293 ((and 0294 (eq cur-token 'function) 0295 (stringp cur-token-name)) 0296 ;;FUNCTION - generate a skeleton for it 0297 (if (and (kde-is-prototype elt) 0298 (not asignal)) 0299 (setq ret (concat ret (kde-function-construct elt name) "\n\n")) 0300 ) 0301 ;(insert (kde-function-documentation elt) "\n") 0302 ) 0303 ((and 0304 (eq cur-token 'label) 0305 (stringp cur-token-name)) 0306 (setq aslot nil 0307 asignal nil) 0308 ;;LABEL - unsets both signals and slots 0309 ) 0310 ((and 0311 (eq cur-token 'variable) 0312 cur-token-name) 0313 ;;VARIABLE - doesn't handle static variables correctly right now 0314 ) 0315 ((not (stringp cur-token-name)) 0316 (cond 0317 ((kde-label-signals (car (semantic-token-extent elt))) 0318 ;;SIGNALS - next prototypes belong to signals and we don't want to 0319 ;; expand those 0320 (setq asignal t 0321 aslot nil) 0322 ) 0323 ((kde-label-namespace (car (semantic-token-extent elt))) 0324 ;;NAMESPACE - semantic doesn't handle things like Qt::ButtonState correctly 0325 ;; so we do ;) 0326 (setq namespace (kde-label-namespace (car (semantic-token-extent elt)))) 0327 ) 0328 ((kde-label-slots (car (semantic-token-extent elt))) 0329 ;;SLOTS - for now just unset signals 0330 (setq aslot t 0331 asignal nil) 0332 ) 0333 (t 0334 (insert "something else at " (number-to-string (car (semantic-token-extent elt))) "\n")) 0335 )) 0336 (t 0337 (insert "Unknown type :: " (prin1-to-string elt) " >>" (prin1-to-string cur-token) "\n")) 0338 ) 0339 ) 0340 ret 0341 ) 0342 ) 0343 0344 (defun kde-expand-tokens (tokens) 0345 "Expands smenatic tokens to strings." 0346 (let ((ret "")) 0347 (dolist (elt tokens ret) 0348 (cond 0349 ((eq (semantic-token-token elt) 'type) 0350 (setq ret (concat ret (kde-class-expand elt))) 0351 ) 0352 ((eq (semantic-token-token elt) 'function) 0353 (if (kde-is-prototype elt) 0354 (setq ret (concat ret (kde-function-construct elt nil) "\n\n")) 0355 ) 0356 ) 0357 ((eq (semantic-token-token elt) 'variable) 0358 ;; skip 0359 ;;(kde-extract-variable elt) 0360 ) 0361 ((eq (semantic-token-token elt) 'include) 0362 ;;ignore includes for now 0363 ) 0364 (t (insert "Unknown type : " (prin1-to-string (semantic-token-type elt)) "\n")) 0365 ) 0366 ) 0367 ) 0368 ) 0369 0370 0371 (defun kde-tokens-in-file (FILENAME) 0372 "Returns all tokens from a file with the FILENAME." 0373 (let ((exists (file-readable-p FILENAME)) 0374 (buf (current-buffer)) 0375 (tokens)) 0376 (if exists 0377 (progn 0378 (find-file FILENAME) 0379 (setq tokens (semantic-bovinate-toplevel t)) 0380 (switch-to-buffer buf) 0381 tokens) 0382 nil) 0383 )) 0384 0385 (defun kde-function-in-file (FUNC FILENAME) 0386 "Returns non-nil if FUNC is in a file named FILENAME" 0387 (let ((tokens (kde-tokens-in-file FILENAME))) 0388 (if tokens 0389 (kde-function-in-tokens FUNC tokens) 0390 nil 0391 ) 0392 )) 0393 0394 (defun kde-function-is-expanded (FUNC) 0395 "Returns t if the function FUNC has been expanded." 0396 (let ((file (kde-file-get-cpp-h))) 0397 (if (cdr file) 0398 (if (kde-function-in-file FUNC (car file)) 0399 t 0400 nil 0401 ) 0402 nil) 0403 )) 0404 0405 (defun kde-function-expanded-at-point (PT) 0406 "Returns non-nil if the function at point PT has already been expanded." 0407 (interactive "d") 0408 (let ((func (kde-function-at-point PT))) 0409 (kde-function-is-expanded func) 0410 ) 0411 ) 0412 0413 (defun kde-create-skeletons () 0414 "Creates functions stubs in the source file, for all functions 0415 in the current header file." 0416 (interactive) 0417 (let* ((all-tokens (semantic-bovinate-toplevel t)) 0418 (filename (buffer-name)) 0419 (cppfile (car (kde-file-get-cpp-h))) 0420 (funcs (kde-expand-tokens all-tokens))) 0421 (find-file cppfile) 0422 (save-excursion 0423 (insert "#include \"" filename "\"\n\n") 0424 (insert funcs) 0425 ) 0426 ) 0427 ) 0428 0429 (defun kde-function-expand-at-point (PT) 0430 "Expand function at point PT." 0431 (interactive "d") 0432 (let ((object (semantic-find-nonterminal-by-position PT (current-buffer))) 0433 (func (kde-function-at-point PT)) 0434 (file) 0435 (buf) 0436 (parent)) 0437 (if (and object (equal (semantic-token-type object) "class")) 0438 (setq parent (semantic-token-name object))) 0439 (if (and (not (kde-function-expanded-at-point PT)) 0440 (kde-is-prototype func)) 0441 (progn 0442 (setq func (kde-function-construct func parent)) 0443 (setq file (car (kde-file-get-cpp-h))) 0444 (setq buf (current-buffer)) 0445 (find-file file) 0446 (save-excursion 0447 (goto-char (point-max)) 0448 (insert "\n" func "\n") 0449 ) 0450 (switch-to-buffer buf) 0451 ) 0452 (error "Function already expanded or defined!") 0453 ) 0454 ) 0455 ) 0456 0457 (provide 'kde-emacs-semantic)