[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/d-mode 572d707 221/346: Improve comprehension of constness
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/d-mode 572d707 221/346: Improve comprehension of constness and storage classes |
Date: |
Sun, 29 Aug 2021 11:00:35 -0400 (EDT) |
branch: elpa/d-mode
commit 572d7078aaeb95342677a63309271629111b461d
Author: Vladimir Panteleev <git@thecybershadow.net>
Commit: Vladimir Panteleev <git@thecybershadow.net>
Improve comprehension of constness and storage classes
Implement these more properly and replace some older hacks with this
implementation.
---
d-mode.el | 166 +++++++++++++++++++++++++++++++----------------
tests/I0030.d.html | 2 +-
tests/fonts_types.d | 3 +
tests/fonts_types.d.html | 3 +
4 files changed, 117 insertions(+), 57 deletions(-)
diff --git a/d-mode.el b/d-mode.el
index ec3c5d8..859f737 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: 201909090915
+;; Version: 201909091501
;; Keywords: D programming language emacs cc-mode
;; Package-Requires: ((emacs "25.1"))
@@ -337,22 +337,59 @@ The expression is added to
`compilation-error-regexp-alist' and
d (c-make-keywords-re t
(c-lang-const d-type-modifier-kwds)))
+(c-lang-defconst d-common-storage-class-kwds
+ ;; D's storage classes (keywords that can prefix or entirely
+ ;; substitute a type in a parameter or variable declaration).
+ d `(;; Constness
+ ,@(c-lang-const d-type-modifier-kwds)
+ ;; Storage classes that apply to either parameters and declarations
+ "scope"))
+
+(c-lang-defconst d-decl-storage-class-kwds
+ d `(;; Common keywords
+ ,@(c-lang-const d-common-storage-class-kwds)
+ ;; auto (no-effect placeholder)
+ "auto"
+ ;; Storage class
+ "extern" "static" "__gshared"))
+
+(c-lang-defconst d-param-storage-class-kwds
+ d `(;; Common keywords
+ ,@(c-lang-const d-common-storage-class-kwds)
+ ;; Function parameters
+ "in" "out" "ref" "lazy"))
+
+(c-lang-defconst d-storage-class-kwds
+ d (c--delete-duplicates (append (c-lang-const d-decl-storage-class-kwds)
+ (c-lang-const d-param-storage-class-kwds))
+ :test 'string-equal))
+
+(c-lang-defconst d-storage-class-key
+ ;; Regex of `d-storage-class-kwds'.
+ d (c-make-keywords-re t
+ (c-lang-const d-storage-class-kwds)))
+
(c-lang-defconst c-paren-type-kwds
;; Keywords that may be followed by a parenthesis expression containing
;; type identifiers separated by arbitrary tokens.
d (append (list "delete" "throw")
(c-lang-const d-type-modifier-kwds)))
-;; D: Also exclude d-type-modifier-kwds
-(c-lang-defconst c-regular-keywords-regexp
- ;; Adorned regexp matching all keywords that should be fontified
- ;; with the keywords face. I.e. that aren't types or constants.
- d (c-make-keywords-re t
- (c--set-difference (c-lang-const c-keywords)
- (append (c-lang-const c-primitive-type-kwds)
- (c-lang-const c-constant-kwds)
- (c-lang-const d-type-modifier-kwds))
- :test 'string-equal)))
+;; D: Like `c-regular-keywords-regexp', but contains keywords which
+;; cannot occur in a function type.
+(c-lang-defconst d-non-func-type-kwds-re
+ d (concat "\\<"
+ (c-make-keywords-re t
+ (c--set-difference (c-lang-const c-keywords)
+ (append (c-lang-const c-primitive-type-kwds)
+ (c-lang-const
d-decl-storage-class-kwds))
+ :test 'string-equal))))
+
+;; D: Like `c-regular-keywords-regexp', but contains keywords which
+;; cannot occur in a function name.
+(c-lang-defconst d-non-func-name-kwds-re
+ d (concat "\\<"
+ (c-make-keywords-re t (c-lang-const c-keywords))))
(c-lang-defconst c-block-stmt-1-kwds
;; Statement keywords followed directly by a substatement.
@@ -401,7 +438,7 @@ The expression is added to `compilation-error-regexp-alist'
and
d nil)
(c-lang-defconst c-other-decl-kwds
- d nil)
+ d (c-lang-const d-storage-class-kwds))
(c-lang-defconst c-other-kwds
;; Keywords not accounted for by any other `*-kwds' language constant.
@@ -645,12 +682,13 @@ Each list item should be a regexp matching a single
identifier."
;; The method name regexp will match lines like
;; "return foo(x);" or "static if(x) {"
;; so we exclude type name 'static' or 'return' here
- (while (let ((type (match-string 1)))
- (and pt type
+ (while (let ((type (match-string 1))
+ (name (match-string 2)))
+ (and pt name
(save-match-data
- (string-match
- (concat "\\<" (c-lang-const c-regular-keywords-regexp))
- type))))
+ (or
+ (string-match (c-lang-const d-non-func-type-kwds-re) type)
+ (string-match (c-lang-const d-non-func-name-kwds-re)
name)))))
(setq pt (re-search-backward d-imenu-method-name-pattern nil t)))
pt)
;; Do not count invisible definitions.
@@ -846,20 +884,33 @@ Each list item should be a regexp matching a single
identifier."
(defun d-around--c-forward-decl-or-cast-1 (orig-fun &rest args)
;; checkdoc-params: (orig-fun args)
"Advice function for fixing cc-mode handling of D constructors."
- (if (not (c-major-mode-is 'd-mode))
- (apply orig-fun args)
- (progn
- (add-function :around (symbol-function 'c-forward-name)
- #'d-special-case-c-forward-name)
- (add-function :around (symbol-function 'c-forward-type)
- #'d-special-case-c-forward-type)
- (unwind-protect
- (apply orig-fun args)
- (remove-function (symbol-function 'c-forward-name)
- #'d-special-case-c-forward-name)
- (remove-function (symbol-function 'c-forward-type)
- #'d-special-case-c-forward-type)
- ))))
+ (cond
+ ((not (c-major-mode-is 'd-mode))
+ (apply orig-fun args))
+
+ ;; D: The logic in cc-mode's `c-forward-decl-or-cast-1' will
+ ;; recognize "someIdentifier in" as a variable declaration,
+ ;; fontifying someIdentifier as a type. Prevent this here.
+ ((save-excursion
+ (and
+ (looking-at c-identifier-start)
+ (progn
+ (c-forward-token-2)
+ (looking-at (c-make-keywords-re t '("in"))))))
+ nil)
+
+ (t
+ (add-function :around (symbol-function 'c-forward-name)
+ #'d-special-case-c-forward-name)
+ (add-function :around (symbol-function 'c-forward-type)
+ #'d-special-case-c-forward-type)
+ (unwind-protect
+ (apply orig-fun args)
+ (remove-function (symbol-function 'c-forward-name)
+ #'d-special-case-c-forward-name)
+ (remove-function (symbol-function 'c-forward-type)
+ #'d-special-case-c-forward-type)
+ ))))
(advice-add 'c-forward-decl-or-cast-1 :around
#'d-around--c-forward-decl-or-cast-1)
@@ -963,12 +1014,6 @@ Key bindings:
;;----------------------------------------------------------------------------
;; "Hideous hacks" to support appropriate font-lock behaviour.
;;
-;; * auto/const/immutable: If we leave them in c-modifier-kwds (like
-;; c++-mode) then in the form "auto var;" var will be highlighted in
-;; type name face. Moving auto/immutable to font-lock-add-keywords
-;; lets cc-mode seeing them as a type name, so the next symbol can
-;; be fontified as a variable.
-;;
;; * public/protected/private appear both in c-modifier-kwds and in
;; c-protection-kwds. This causes cc-mode to fail parsing the first
;; declaration after an access level label (because cc-mode trys to
@@ -998,26 +1043,10 @@ Key bindings:
(defun d-match-fun-decl (limit)
"Helper function." ;; checkdoc-params: limit
(d-try-match-decl d-fun-decl-pattern))
-(defun d-match-auto (limit)
- "Helper function." ;; checkdoc-params: limit
- (c-syntactic-re-search-forward
- (rx
- word-start
- (group
- (or
- "auto"
- "const"
- "immutable"
- "inout"
- "shared"
- "__gshared"))
- word-end)
- limit t))
(font-lock-add-keywords
'd-mode
- '((d-match-auto 1 font-lock-keyword-face t)
- (d-match-var-decl (1 font-lock-type-face) (2 font-lock-variable-name-face))
+ '((d-match-var-decl (1 font-lock-type-face) (2 font-lock-variable-name-face))
(d-match-fun-decl (1 font-lock-type-face) (2 font-lock-function-name-face)))
t)
@@ -1165,9 +1194,34 @@ Key bindings:
(defun d-forward-type (&optional brace-block-too)
"Modified version of `c-forward-type' for d-mode." ;; checkdoc-params:
brace-block-too
- (let ((start (point)) pos res name-res id-start id-end id-range)
+ (let ((start (point)) pos res name-res id-start id-end id-range
saw-storage-class)
+
+ ;; D: Parse storage classes and similar keywords.
+ ;; Technically these are not part of the type, but we parse them here
+ ;; because they can substitute the type declaration (for type inference).
+ (while (and
+ (looking-at (c-lang-const d-storage-class-key))
+
+ (save-excursion
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws)
+ (setq pos (point))
+ (looking-at c-identifier-start))) ; Variable name or
+ ; continuation, but NOT (
+ (goto-char pos)
+ (setq saw-storage-class t))
+
(cond
- ;; const/immutable/...
+ ;; D: Storage class substituting the type (e.g. auto)
+ ((and
+ saw-storage-class
+ (not (looking-at (c-lang-const d-type-modifier-key)))
+ (save-excursion
+ (c-forward-token-2) ; maybe variable/function name
+ (not (looking-at c-identifier-start)))) ; ( or ; or =
+ (setq res t))
+
+ ;; D: const/immutable/...(...)
((looking-at (c-lang-const d-type-modifier-key))
(when
(and
diff --git a/tests/I0030.d.html b/tests/I0030.d.html
index 9a529ca..af79491 100644
--- a/tests/I0030.d.html
+++ b/tests/I0030.d.html
@@ -1,6 +1,6 @@
<span class="comment-delimiter">// </span><span class="comment">#run:
(d-test-fontification)
</span>
-<span class="keyword">const class</span> C
+<span class="keyword">const class</span> <span class="type">C</span>
{
<span class="type">int</span> <span
class="function-name">getFoo</span>() <span class="keyword">const</span> {
<span class="keyword">return</span> 42; }
diff --git a/tests/fonts_types.d b/tests/fonts_types.d
index bd3406b..2762e77 100644
--- a/tests/fonts_types.d
+++ b/tests/fonts_types.d
@@ -8,3 +8,6 @@ assert(to!string(d) == to!string(double.max));
private void resetFile(string name, scope const(char)[] stdioOpenmode, bool
isPopened) @trusted {}
Parameter!("foo()").Foo var;
+
+void foo(in Type var);
+void foo(out Type var);
diff --git a/tests/fonts_types.d.html b/tests/fonts_types.d.html
index 837d207..37d10e9 100644
--- a/tests/fonts_types.d.html
+++ b/tests/fonts_types.d.html
@@ -8,3 +8,6 @@
<span class="keyword">private</span> <span class="type">void</span> <span
class="function-name">resetFile</span>(<span class="type">string</span> <span
class="variable-name">name</span>, <span class="keyword">scope
const</span>(<span class="type">char</span>)[] <span
class="variable-name">stdioOpenmode</span>, <span class="type">bool</span>
<span class="variable-name">isPopened</span>) <span
class="c-annotation-face">@trusted</span> {}
<span class="type">Parameter</span><span class="negation-char">!</span>(<span
class="string">"foo()"</span>).<span class="type">Foo</span> <span
class="variable-name">var</span>;
+
+<span class="type">void</span> <span class="function-name">foo</span>(<span
class="keyword">in</span> <span class="type">Type</span> <span
class="variable-name">var</span>);
+<span class="type">void</span> <span class="function-name">foo</span>(<span
class="keyword">out</span> <span class="type">Type</span> <span
class="variable-name">var</span>);
- [nongnu] elpa/d-mode b5fb492 204/346: Fix fontification of manifest (enum) constants, (continued)
- [nongnu] elpa/d-mode b5fb492 204/346: Fix fontification of manifest (enum) constants, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode e52434e 218/346: d-mode-test.el: Save actual result to file in case of mismatch, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 609816b 219/346: tests: Move d-forward-type tests to new test file, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 4d9f9ce 211/346: Drop support for Emacs 24, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode f2b4aec 205/346: Fix fontification of "a in b" expressions, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode f69e94e 207/346: Change test suite enumeration and activation, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode b0a59de 214/346: Fix mis-parsing of concatenating two variables, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 445c696 210/346: Implement a more complete description for D type syntax, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode ed0de34 222/346: Refactor "this" (constructor) handling, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode aaa704a 216/346: Fix coverage issues in d-forward-type, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 572d707 221/346: Improve comprehension of constness and storage classes,
ELPA Syncer <=
- [nongnu] elpa/d-mode 64afe5f 206/346: .travis.yml: Test against more Emacs versions, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 02733b0 223/346: Remove some redundant progns, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode c9febb3 299/346: d-mode-test: Always ignore .res files, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 2d4bc7d 318/346: Update comments, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 46a57f4 310/346: Fontify the special words inside version/debug/extern/pragma/__traits/scope, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 805eeba 078/346: Add links to build and coverage status to README., ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 8076559 081/346: Replace obsolete defadvice by the new advice-add., ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode ee38763 083/346: Use the new advising mechanism on new emacs versions., ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 5c06e99 087/346: add d-exceptions compilation error regexp, ELPA Syncer, 2021/08/29
- [nongnu] elpa/d-mode 5501b77 096/346: Prepare for a formal release., ELPA Syncer, 2021/08/29