Subject: 31.0.50; [PATCH] csharp-ts-mode does not highlight type in typeof() expressions

From: Jostein Kjønigsen <[email-masked]>
Date: Mon, 6 Jan 2025 15:12:14 +0100

Hey everyone.

When using csharp-ts-mode to edit C# files, you may encounter the use of the typeof() operator in typeof()-expressions. The typeof() operater has 1 required parameter, which is always a type-name.

    public class Gnu
    {
        public void Demo()
        {
            var type = typeof(IQueryable);
        }
    }

This type parameter should be fontified using font-lock-type-face. Currently it is not.

There are explicit rules in csharp-ts-mode defined to attempt to fontify this, but they do not seem to be working:

     ,@(when (csharp-ts-mode--test-type-of-expression)
         '((type_of_expression (identifier) @font-lock-type-face))
         '((typeof_expression (identifier) @font-lock-type-face)))

Based on my inspection in treesit-explore mode, I see the grammar reports back these nodes as typeof_expression-nodes, but these rules are not activated because the preceeding (when ...) condition fails.

(defun csharp-ts-mode--test-type-of-expression ()
  "Return non-nil if (type_of_expression) is in the grammar."
  (ignore-errors
    (treesit-query-compile 'c-sharp "(type_of_expression)" t)
    t))

Changing this implementation to the following (matching the node-names I see in treesit-explore mode) makes highlighting work for me:

(defun csharp-ts-mode--test-type-of-expression ()
  "Return non-nil if (type_of_expression) is in the grammar."
  (ignore-errors
    (treesit-query-compile 'c-sharp "(typeof_expression)" t)
    t))

Attached is a patch which provides this change.

Note: This bug/fix was reproduced using tree-sitter-c-sharp grammar built on December 18th, 2024. I haven't tested with other versions.

Kind regards
Jostein

￼

--

In GNU Emacs 31.0.50 (build 5, aarch64-apple-darwin24.0.0, NS
 appkit-2566.00 Version 15.0.1 (Build 24A348)) of 2024-12-11 built on
 SOK67R3KWV97
Repository revision: a9bc12318121acb513a5735f641602001510a932
Repository branch: master
Windowing system distributor 'Apple', version 10.3.2566
System Description:  macOS 15.0.1

Configured using:
 'configure --with-tree-sitter --with-native-compilation --with-json
 --with-imagemagick
 PKG_CONFIG_PATH=:/usr/local/lib/pkgconfig:/opt/local/lib/pkgconfig'

Configured features:
ACL GLIB GNUTLS IMAGEMAGICK LCMS2 LIBXML2 MODULES NATIVE_COMP NOTIFY
KQUEUE NS PDUMPER PNG RSVG SQLITE3 THREADS TOOLKIT_SCROLL_BARS
TREE_SITTER WEBP XIM ZLIB

Important settings:
  value of $LC_ALL: en_US.UTF-8
  value of $LC_CTYPE: UTF-8
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: C#

Minor modes in effect:
  electric-pair-mode: t
  highlight-symbol-mode: t
  flycheck-mode: t
  editorconfig-mode: t
  company-mode: t
  indent-bars--ts-mode: t
  indent-bars-mode: t
  eglot-inlay-hints-mode: t
  eglot--managed-mode: t
  flymake-mode: t
  which-function-mode: t
  helm-mode: t
  helm-minibuffer-history-mode: t
  async-bytecomp-package-mode: t
  delete-selection-mode: t
  global-auto-revert-mode: t
  yas-global-mode: t
  yas-minor-mode: t
  global-nlinum-mode: t
  nlinum-mode: t
  ido-yes-or-no-mode: t
  override-global-mode: t
  server-mode: t
  global-hl-line-mode: t
  pixel-scroll-precision-mode: t
  doom-modeline-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  minibuffer-regexp-mode: t
  column-number-mode: t
  line-number-mode: t
  auto-fill-function: #[128 \304\300\301#\207 [yas--auto-fill do-auto-fill :around nil apply] 5 advice]
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  hs-minor-mode: t

Load-path shadows:
/Users/josteink/.emacs.d/elpa/transient-20240421.1327/transient hides /Users/josteink/build/emacs/lisp/transient
/Users/josteink/.emacs.d/elpa/editorconfig-20240318.2049/editorconfig hides /Users/josteink/build/emacs/lisp/editorconfig
/Users/josteink/.emacs.d/elpa/editorconfig-20240318.2049/editorconfig-conf-mode hides /Users/josteink/build/emacs/lisp/editorconfig-conf-mode
/Users/josteink/.emacs.d/elpa/editorconfig-20240318.2049/editorconfig-core hides /Users/josteink/build/emacs/lisp/editorconfig-core
/Users/josteink/.emacs.d/elpa/editorconfig-20240318.2049/editorconfig-core-handle hides /Users/josteink/build/emacs/lisp/editorconfig-core-handle
/Users/josteink/.emacs.d/elpa/editorconfig-20240318.2049/editorconfig-fnmatch hides /Users/josteink/build/emacs/lisp/editorconfig-fnmatch

Features:
(shadow sort mail-extr emacsbug csharp-mode cc-langs help-fns radix-tree
facemenu crm grep helm-command helm-elisp helm-eval edebug helm-info
misearch multi-isearch bug-reference markdown-mode pulse elec-pair
typescript-ts-mode js c-ts-common cc-mode cc-fonts cc-guess cc-menus
cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs vc-git
vc-dispatcher winner tramp-archive tramp-gvfs add-log
ido-completing-read+ memoize minibuf-eldef org-duration diary-lib
diary-loaddefs cal-iso oc-basic ol-eww ol-rmail ol-mhe ol-irc ol-info
ol-gnus nnselect gnus-art mm-uu mml2015 mm-view mml-smime smime dig
gnus-sum gnus-group gnus-undo gnus-start gnus-dbus dbus gnus-cloud
nnimap nnmail mail-source utf7 nnoo gnus-spec gnus-int gnus-range
gnus-win ol-docview doc-view jka-compr ol-bibtex bibtex ol-bbdb ol-w3m
ol-doi org-link-doi org-agenda org-element org-persist org-id
org-element-ast inline avl-tree org-refile elisp-slime-nav
highlight-symbol flycheck editorconfig editorconfig-core
editorconfig-core-handle editorconfig-fnmatch company-oddmuse
company-keywords company-etags etags fileloop company-gtags
company-dabbrev-code company-dabbrev company-files company-clang
company-capf company-cmake company-semantic company-template
company-bbdb company indent-bars-ts indent-bars face-remap color eglot
external-completion jsonrpc flymake diff ert ewoc debug backtrace
which-func hideshow disp-table cus-edit pp cus-start cus-load eww vtable
url-queue shr pixel-fill kinsoku url-file svg xml dom mm-url gnus
nnheader range wid-edit helm-imenu helm-mode helm-misc helm-files
image-dired image-dired-tags image-dired-external image-dired-util
image-mode exif tramp trampver tramp-integration files-x tramp-message
tramp-compat xdg shell parse-time iso8601 tramp-loaddefs helm-buffers
helm-occur helm-tags helm-locate helm-grep helm-regexp helm-utils
helm-help helm-types helm helm-global-bindings helm-easymenu helm-core
async-bytecomp helm-source helm-multi-match helm-lib async imenu
ob-plantuml delsel autorevert filenotify org ob ob-tangle ob-ref ob-lob
ob-table ob-exp org-macro org-src sh-script smie executable ob-comint
org-pcomplete pcomplete org-list org-footnote org-faces org-entities
noutline outline ob-emacs-lisp ob-core ob-eval org-cycle org-table ol
org-fold org-fold-core org-keys oc org-loaddefs thingatpt find-func
cal-menu calendar cal-loaddefs org-version org-compat org-macs yasnippet
paredit mm-archive message sendmail yank-media dired dired-loaddefs
rfc822 mml mml-sec epa derived epg rfc6068 gnus-util time-date
mailabbrev gmm-utils mailheader mm-decode mm-bodies mm-encode mail-utils
gnutls network-stream url-cache url-http url-auth mail-parse rfc2231
rfc2047 rfc2045 mm-util ietf-drums mail-prsvr url-gw nsm puny epg-config
nlinum linum ido-yes-or-no advice ido use-package-bind-key bind-key xref
server hl-line pixel-scroll cua-base compile-eslint compile
text-property-search all-the-icons all-the-icons-faces data-material
data-weathericons data-octicons data-fileicons data-faicons
data-alltheicons doom-modeline doom-modeline-segments doom-modeline-env
doom-modeline-core shrink-path f s dash nerd-icons nerd-icons-faces
nerd-icons-data nerd-icons-data-mdicon nerd-icons-data-flicon
nerd-icons-data-codicon nerd-icons-data-devicon nerd-icons-data-sucicon
nerd-icons-data-wicon nerd-icons-data-faicon nerd-icons-data-powerline
nerd-icons-data-octicon nerd-icons-data-pomicon nerd-icons-data-ipsicon
dracula-theme use-package-ensure use-package-core
all-the-icons-autoloads bitwarden-autoloads bmx-mode-autoloads
cargo-autoloads cmake-mode-autoloads format-spec edmacro kmacro
combobulate-display combobulate-ztree combobulate-envelope
combobulate-manipulation python project compat comint ansi-osc ring
ansi-color combobulate-procedure combobulate-navigation combobulate-misc
combobulate-setup tempo combobulate-interface combobulate-settings
diff-mode track-changes easy-mmode treesit generator combobulate-rules
company-autoloads copilot-mode-autoloads crontab-mode-autoloads
bui-autoloads dockerfile-mode-autoloads doom-modeline-autoloads
dracula-theme-autoloads editorconfig-autoloads elisp-slime-nav-autoloads
expand-region-autoloads flycheck-autoloads helm-autoloads
helm-core-autoloads async-autoloads highlight-symbol-autoloads
ido-yes-or-no-autoloads ido-completing-read+-autoloads comp comp-cstr
cl-extra help-mode warnings comp-run comp-common rx
indent-bars-autoloads finder-inf lsp-treemacs-autoloads
lsp-mode-autoloads magit-autoloads pcase git-commit-autoloads
magit-section-autoloads markdown-mode-autoloads memoize-autoloads
multiple-cursors-autoloads nerd-icons-autoloads nlinum-autoloads
paredit-autoloads pkg-info-autoloads epl-autoloads popup-autoloads
powershell-autoloads quelpa-use-package-autoloads quelpa-autoloads
shrink-path-autoloads f-autoloads spinner-autoloads swift-mode-autoloads
transient-autoloads treemacs-autoloads cfrs-autoloads posframe-autoloads
ht-autoloads hydra-autoloads lv-autoloads pfuture-autoloads
ace-window-autoloads avy-autoloads s-autoloads dash-autoloads
undo-tree-autoloads queue-autoloads wfnames-autoloads info
with-editor-autoloads wsd-mode-autoloads yasnippet-autoloads package
browse-url url url-proxy url-privacy url-expand url-methods url-history
url-cookie generate-lisp-file url-domsuf url-util mailcap url-handlers
url-parse auth-source cl-seq eieio eieio-core cl-macs icons
password-cache json subr-x map byte-opt gv bytecomp byte-compile
url-vars cl-loaddefs cl-lib rmc iso-transl tooltip cconv eldoc paren
electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel
term/ns-win ns-win ucs-normalize mule-util term/common-win tool-bar dnd
fontset image regexp-opt fringe tabulated-list replace newcomment
text-mode lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow
isearch easymenu timer select scroll-bar mouse jit-lock font-lock syntax
font-core term/tty-colors frame minibuffer nadvice seq simple cl-generic
indonesian philippine cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
composite emoji-zwj charscript charprop case-table epa-hook
jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs
theme-loaddefs faces cus-face macroexp files window text-properties
overlay sha1 md5 base64 format env code-pages mule custom widget keymap
hashtable-print-readable backquote threads kqueue cocoa ns lcms2
multi-tty make-network-process native-compile emacs)

Memory information:
((conses 16 1340125 283321) (symbols 48 53880 0)
 (strings 32 314514 8847) (string-bytes 1 9290186) (vectors 16 109175)
 (vector-slots 8 2175883 319679) (floats 8 1370 14387)
 (intervals 56 38780 7503) (buffers 992 60))

—
Kind Regards
Jostein Kjønigsen