aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2007-03-08 21:50:51 +0000
committerAlan Mackenzie2007-03-08 21:50:51 +0000
commit9c184ed25c8db6d68268c06dbba1736eb4f003e5 (patch)
tree6a87b1467c0c8b9024d69d595043e73e683c1114
parent4cc4ad8ae5e861baf67d28669bcb589864334e63 (diff)
downloademacs-9c184ed25c8db6d68268c06dbba1736eb4f003e5.tar.gz
emacs-9c184ed25c8db6d68268c06dbba1736eb4f003e5.zip
(c-unfind-enclosing-token, c-unfind-coalesced-tokens, c-before-change): new
functions; (c-maybe-stale-found-type): new variable. An ad hoc attempt to remove stale tokens from the cache `c-found-types'.
-rw-r--r--lisp/progmodes/cc-mode.el141
1 files changed, 139 insertions, 2 deletions
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index e2891bde98d..a79ca3cac6e 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -412,8 +412,142 @@ preferably use the `c-mode-menu' language constant directly."
412;; temporary changes in some font lock support modes, causing extra 412;; temporary changes in some font lock support modes, causing extra
413;; unnecessary work and font lock glitches due to interactions between 413;; unnecessary work and font lock glitches due to interactions between
414;; various text properties. 414;; various text properties.
415 415;;
416(defun c-after-change (beg end len) 416;; (2007-02-12): The macro `combine-after-change-calls' ISN'T used any
417;; more.
418
419(defun c-unfind-enclosing-token (pos)
420 ;; If POS is wholly inside a token, remove that id from
421 ;; `c-found-types', should it be present. Return t if we were in an
422 ;; id, else nil.
423 (save-excursion
424 (let ((tok-beg (progn (goto-char pos)
425 (and (c-beginning-of-current-token) (point))))
426 (tok-end (progn (goto-char pos)
427 (and (c-end-of-current-token) (point)))))
428 (when (and tok-beg tok-end)
429 (c-unfind-type (buffer-substring-no-properties tok-beg tok-end))
430 t))))
431
432(defun c-unfind-coalesced-tokens (beg end)
433 ;; unless the non-empty region (beg end) is entirely WS and there's at
434 ;; least one character of WS just before or after this region, remove
435 ;; the tokens which touch the region from `c-found-types' should they
436 ;; be present.
437 (or (c-partial-ws-p beg end)
438 (save-excursion
439 (progn
440 (goto-char beg)
441 (or (eq beg (point-min))
442 (c-skip-ws-backward (1- beg))
443 (/= (point) beg)
444 (= (c-backward-token-2) 1)
445 (c-unfind-type (buffer-substring-no-properties
446 (point) beg)))
447 (goto-char end)
448 (or (eq end (point-max))
449 (c-skip-ws-forward (1+ end))
450 (/= (point) end)
451 (progn (forward-char) (c-end-of-current-token) nil)
452 (c-unfind-type (buffer-substring-no-properties
453 end (point))))))))
454
455;; c-maybe-stale-found-type records a place near the region being
456;; changed where an element of `found-types' might become stale. It
457;; is set in c-before-change and is either nil, or has the form:
458;;
459;; (c-decl-id-start "foo" 97 107 " (* ooka) " "o"), where
460;;
461;; o - `c-decl-id-start' is the c-type text property value at buffer
462;; pos 96.
463;;
464;; o - 97 107 is the region potentially containing the stale type -
465;; this is delimited by a non-nil c-type text property at 96 and
466;; either another one or a ";", "{", or "}" at 107.
467;;
468;; o - " (* ooka) " is the (before change) buffer portion containing
469;; the suspect type (here "ooka").
470;;
471;; o - "o" is the buffer contents which is about to be deleted. This
472;; would be the empty string for an insertion.
473(defvar c-maybe-stale-found-type nil)
474(make-variable-buffer-local 'c-maybe-stale-found-type)
475
476(defun c-before-change (beg end)
477 ;; Function to be put on `before-change-function'. Currently
478 ;; (2007-02) it is used only to remove stale entries from the
479 ;; `c-found-types' cache, and to record entries which a
480 ;; `c-after-change' function might confirm as stale.
481 ;;
482 ;; Note that this function must be FAST rather than accurate. Note
483 ;; also that it only has any effect when font locking is enabled.
484 ;; We exploit this by checking for font-lock-*-face instead of doing
485 ;; rigourous syntactic analysis.
486
487 ;; If either change boundary is wholly inside an identifier, delete
488 ;; it/them from the cache. Don't worry about being inside a string
489 ;; or a comment - "wrongly" removing a symbol from `c-found-types'
490 ;; isn't critical.
491 (setq c-maybe-stale-found-type nil)
492 (save-restriction
493 (widen)
494 (save-excursion
495 ;; Are we inserting/deleting stuff in the middle of an identifier?
496 (c-unfind-enclosing-token beg)
497 (c-unfind-enclosing-token end)
498 ;; Are we coalescing two tokens together, e.g. "fo o" -> "foo"?
499 (when (< beg end)
500 (c-unfind-coalesced-tokens beg end))
501 ;; Are we (potentially) disrupting the syntactic context which
502 ;; makes a type a type? E.g. by inserting stuff after "foo" in
503 ;; "foo bar;", or before "foo" in "typedef foo *bar;"?
504 ;;
505 ;; We search for appropriate c-type properties "near" the change.
506 ;; First, find an appropriate boundary for this property search.
507 (let (lim
508 type type-pos
509 marked-id term-pos
510 (end1
511 (if (eq (get-text-property end 'face) 'font-lock-comment-face)
512 (previous-single-property-change end 'face)
513 end)))
514 (when (>= end1 beg) ; Don't hassle about changes entirely in comments.
515 ;; Find a limit for the search for a `c-type' property
516 (while
517 (and (/= (skip-chars-backward "^;{}") 0)
518 (> (point) (point-min))
519 (memq (c-get-char-property (1- (point)) 'face)
520 '(font-lock-comment-face font-lock-string-face))))
521 (setq lim (max (point-min) (1- (point))))
522
523 ;; Look for the latest `c-type' property before end1
524 (when (and (> end1 1)
525 (setq type-pos
526 (if (get-text-property (1- end1) 'c-type)
527 end1
528 (previous-single-property-change end1 'c-type nil lim))))
529 (setq type (get-text-property (max (1- type-pos) lim) 'c-type))
530
531 (when (memq type '(c-decl-id-start c-decl-type-start))
532 ;; Get the identifier, if any, that the property is on.
533 (goto-char (1- type-pos))
534 (setq marked-id
535 (when (looking-at "\\(\\sw\\|\\s_\\)")
536 (c-beginning-of-current-token)
537 (buffer-substring-no-properties (point) type-pos)))
538
539 (goto-char end1)
540 (skip-chars-forward "^;{}") ; FIXME!!! loop for comment, maybe
541 (setq lim (point))
542 (setq term-pos
543 (or (next-single-property-change end 'c-type nil lim) lim))
544 (setq c-maybe-stale-found-type
545 (list type marked-id
546 type-pos term-pos
547 (buffer-substring-no-properties type-pos term-pos)
548 (buffer-substring-no-properties beg end))))))))))
549
550(defun c-after-change (beg end old-len)
417 ;; Function put on `after-change-functions' to adjust various caches 551 ;; Function put on `after-change-functions' to adjust various caches
418 ;; etc. Prefer speed to finesse here, since there will be an order 552 ;; etc. Prefer speed to finesse here, since there will be an order
419 ;; of magnitude more calls to this function than any of the 553 ;; of magnitude more calls to this function than any of the
@@ -441,6 +575,7 @@ preferably use the `c-mode-menu' language constant directly."
441 (when (> beg end) 575 (when (> beg end)
442 (setq beg end))) 576 (setq beg end)))
443 577
578 (c-trim-found-types beg end old-len) ; maybe we don't need all of these.
444 (c-invalidate-sws-region-after beg end) 579 (c-invalidate-sws-region-after beg end)
445 (c-invalidate-state-cache beg) 580 (c-invalidate-state-cache beg)
446 (c-invalidate-find-decl-cache beg) 581 (c-invalidate-find-decl-cache beg)
@@ -577,6 +712,8 @@ that requires a literal mode spec at compile time."
577 712
578 ;; Install the functions that ensure that various internal caches 713 ;; Install the functions that ensure that various internal caches
579 ;; don't become invalid due to buffer changes. 714 ;; don't become invalid due to buffer changes.
715 (make-local-hook 'before-change-functions)
716 (add-hook 'before-change-functions 'c-before-change nil t)
580 (make-local-hook 'after-change-functions) 717 (make-local-hook 'after-change-functions)
581 (add-hook 'after-change-functions 'c-after-change nil t)) 718 (add-hook 'after-change-functions 'c-after-change nil t))
582 719