[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/d-mode 060d1f3 249/346: Fix parsing of version(...) and ot
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/d-mode 060d1f3 249/346: Fix parsing of version(...) and other non-scope blocks |
Date: |
Sun, 29 Aug 2021 11:00:40 -0400 (EDT) |
branch: elpa/d-mode
commit 060d1f360e4bb320d2a41602ab84bbf4cafa7675
Author: Vladimir Panteleev <git@thecybershadow.net>
Commit: Vladimir Panteleev <git@thecybershadow.net>
Fix parsing of version(...) and other non-scope blocks
---
d-mode.el | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++------
tests/imenu2.d | 20 +++++++++-
2 files changed, 131 insertions(+), 12 deletions(-)
diff --git a/d-mode.el b/d-mode.el
index 97901f9..fa64a80 100644
--- a/d-mode.el
+++ b/d-mode.el
@@ -7,7 +7,7 @@
;; Maintainer: Russel Winder <russel@winder.org.uk>
;; Vladimir Panteleev <vladimir@thecybershadow.net>
;; Created: March 2007
-;; Version: 201909100950
+;; Version: 201909101232
;; Keywords: D programming language emacs cc-mode
;; Package-Requires: ((emacs "25.1"))
@@ -279,16 +279,6 @@ The expression is added to
`compilation-error-regexp-alist' and
;; declarations. In this case, like "mixin foo!(x) bar;"
d '("mixin" "align"))
-;;(c-lang-defconst c-other-block-decl-kwds
-;; ;; Keywords where the following block (if any) contains another
-;; ;; declaration level that should not be considered a class.
-;; ;; Each of these has associated offsets e.g.
-;; ;; 'with-open', 'with-close' and 'inwith'
-;; ;; that can be customized individually
-;; ;; TODO: maybe also do this for 'static if' ? in/out?
-;; ;; TODO: figure out how to make this work properly
-;; d '("with" "version" "extern"))
-
;; Remove "enum" from d-mode's value.
;; By default this c-typedef-decl-kwds includes c-brace-list-decl-kwds,
;; which is '("enum") by default.
@@ -1446,6 +1436,117 @@ Key bindings:
(advice-add 'c-forward-type :around #'d-around--c-forward-type)
;;----------------------------------------------------------------------------
+
+(c-lang-defconst d-flat-decl-maybe-block-kwds
+ ;; Keywords which don't introduce a scope, and may or may not be
+ ;; followed by a {...} block.
+ d (append (c-lang-const c-modifier-kwds)
+ (list "else" ; for version / static if
+ "if" ; static if
+ "version")))
+(c-lang-defconst d-flat-decl-maybe-block-re
+ d (c-make-keywords-re t (c-lang-const d-flat-decl-maybe-block-kwds)))
+
+(defun d-update-brace-stack (stack from to)
+ "Modified version of `c-update-brace-stack' for d-mode." ;; checkdoc-params:
(stack from to)
+ ;; Given a brace-stack which has the value STACK at position FROM, update it
+ ;; to its value at position TO, where TO is after (or equal to) FROM.
+ ;; Return a cons of either TO (if it is outside a literal) and this new
+ ;; value, or of the next position after TO outside a literal and the new
+ ;; value.
+ (let (match kwd-sym (prev-match-pos 1)
+ (s (cdr stack))
+ (bound-<> (car stack)))
+ (save-excursion
+ (cond
+ ((and bound-<> (<= to bound-<>))
+ (goto-char to)) ; Nothing to do.
+ (bound-<>
+ (goto-char bound-<>)
+ (setq bound-<> nil))
+ (t (goto-char from)))
+ (while (and (< (point) to)
+ (c-syntactic-re-search-forward
+ (if (<= (car s) 0)
+ c-brace-stack-thing-key
+ c-brace-stack-no-semi-key)
+ to 'after-literal)
+ (> (point) prev-match-pos)) ; prevent infinite loop.
+ (setq prev-match-pos (point))
+ (setq match (match-string-no-properties 1)
+ kwd-sym (c-keyword-sym match))
+ (cond
+ ((and (equal match "{")
+ (progn (backward-char)
+ (prog1 (looking-at "\\s(")
+ (forward-char))))
+ (setq s (if s
+ ;; D: Constructs such as "version", "static if", or
+ ;; "extern(...)" may or may not enclose their declarations
+ ;; in a {...} block. For this reason, we can't blindly
+ ;; update the cc-mode brace stack when we see these
keywords
+ ;; (otherwise, if they are not immediately succeeded by a
+ ;; {...} block, then the brace stack change will apply to
+ ;; the next encountered {...} block such as that of a
+ ;; function's).
+ (if (save-excursion
+ (backward-char)
+ (c-backward-syntactic-ws)
+ (when (eq (char-before) ?\))
+ (c-backward-sexp)
+ (c-backward-syntactic-ws))
+ (c-backward-token-2)
+ (looking-at (c-lang-const
d-flat-decl-maybe-block-re)))
+ ;; D: Keep the brace stack state from the parent
+ ;; context. I.e., the contents of a "static if" at the
+ ;; top level should remain top-level, but in a
function,
+ ;; it should remain non-top-level.
+ s
+ (cons (if (<= (car s) 0)
+ 1
+ (1+ (car s)))
+ (cdr s)))
+ (list 1))))
+ ((and (equal match "}")
+ (progn (backward-char)
+ (prog1 (looking-at "\\s)")
+ (forward-char))))
+ (setq s
+ (cond
+ ((and s (> (car s) 1))
+ (cons (1- (car s)) (cdr s)))
+ ((and (cdr s) (eq (car s) 1))
+ (cdr s))
+ (t s))))
+ ((and (equal match ":")
+ s
+ (eq (car s) 0))
+ (setq s (cons -1 (cdr s))))
+ ((and (equal match ",")
+ (eq (car s) -1))) ; at "," in "class foo : bar, ..."
+ ((member match '(";" "," ")"))
+ (when (and s (cdr s) (<= (car s) 0))
+ (setq s (cdr s))))
+ ((c-keyword-member kwd-sym 'c-flat-decl-block-kwds)
+ (push 0 s))))
+ ;; The failing `c-syntactic-re-search-forward' may have left us in the
+ ;; middle of a token, which might be a significant token. Fix this!
+ (c-beginning-of-current-token)
+ (cons (point)
+ (cons bound-<> s)))))
+
+(defun d-around--c-update-brace-stack (orig-fun &rest args)
+ ;; checkdoc-params: (orig-fun args)
+ "Advice function for fixing cc-mode handling of certain D constructs."
+ (apply
+ (if (c-major-mode-is 'd-mode)
+ #'d-update-brace-stack
+ orig-fun)
+ args))
+
+(advice-add 'c-update-brace-stack :around #'d-around--c-update-brace-stack)
+
+;;----------------------------------------------------------------------------
;;
;; Support for "Adjusting Alignment Rules for UCFS-Chains in D",
;; cf.
https://stackoverflow.com/questions/25797945/adjusting-alignment-rules-for-ucfs-chains-in-d
diff --git a/tests/imenu2.d b/tests/imenu2.d
index dd1ec13..2382538 100644
--- a/tests/imenu2.d
+++ b/tests/imenu2.d
@@ -1,6 +1,6 @@
// #min-version: 26.1
// #run: (d-test-get-imenu-lines)
-// #out: (5 6 8 13 18 20)
+// #out: (5 6 8 13 18 20 24 28 33 37)
void run(Parameter!("foo()") command) {}
Parameter!("foo()") run(string command) {}
@@ -18,3 +18,21 @@ static if (false)
int fun();
else
int gun();
+
+version (all)
+{
+ int fun();
+}
+else
+{
+ int gun();
+}
+
+static if (true)
+{
+ int fun();
+}
+else
+{
+ int gun();
+}
- [nongnu] elpa/d-mode 1598b12 248/346: Switch to GPL v3 (or later), (continued)
- [nongnu] elpa/d-mode 1598b12 248/346: Switch to GPL v3 (or later), ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 24fffad 242/346: Fix parsing of declarations after "static else", ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode a8aad35 241/346: Fix imenu false positive with "static if", ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 6a19457 244/346: Fix function calls being mis-parsed as declarations after static else, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 3077252 238/346: Correctness fix in d-forward-type, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 1e5c7c3 227/346: Fix parsing of declarations following protection group, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode f8c37b9 260/346: Implement parsing module names in import and module declarations, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 3c7db4a 255/346: Fix imenu context with multiple nesting, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 3ed3b7b 257/346: Simplify imenu testing code, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode f1d37dd 263/346: Fix byte-compiled version, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 060d1f3 249/346: Fix parsing of version(...) and other non-scope blocks,
ELPA Syncer <=
- [nongnu] elpa/d-mode 2529eb2 259/346: Add a TODO, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 8d30f6b 246/346: Add back the old imenu implementation for Emacs 25, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 7d39bdf 269/346: Add missing "package" keyword to c-modifier-kwds, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode ed4428c 272/346: Fix fontification of "invariant", ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 300708d 268/346: Fix imenu for template members, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 685a8cc 271/346: Expand "is" rule for other infix keyword variants and negation, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 4dd90f3 277/346: Consolidate c-forward-decl-or-cast-1 "else" patch, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 6417bf5 279/346: d-mode-test: Stop catching exceptions, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 7c72767 280/346: d-mode-test: Fix saving results of mis-indenting tests, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode acaf2fb 278/346: Call d-forward-decl-or-cast-1 directly, ELPA Syncer, 2021/08/29