mooz / js2-mode

Improved JavaScript editing mode for GNU Emacs
GNU General Public License v3.0
1.33k stars 186 forks source link

New static initialization blocks support has problems with named IIFE and 'use strict' #599

Closed nexushoratio closed 9 months ago

nexushoratio commented 9 months ago

I finally updated js2-mode and immediately noticed some problems with my existing code. It would pause/hang on every change. I managed to narrow it down to the following example:

(function foo() {
  'use strict';

  class C {

    static {
    }

  }
}());

In particular, it has to be both:

Basically, this is a pattern I use for userscript libraries. The IIFE having a name makes debugging easier than an anonymous function.

When I load the file (or make a change, or run js2-mode-reset), I get the following:

Error running timer ‘js2-mode-idle-reparse’: (wrong-type-argument js2-infix-node #s(js2-scope 131 60 7 ((STATIC t)) nil nil nil #s(js2-function-node 111 2 1 nil nil nil nil nil nil nil nil nil 0 nil nil 0 FUNCTION FUNCTION_EXPRESSION #s(js2-name-node 39 11 3 nil nil "foo" nil) nil nil nil 12 13 nil nil nil nil nil) nil))

I do not recall which version I upgraded from, and have not yet tested to see when it was introduced, but the recent Support for static initialization blocks (https://github.com/mooz/js2-mode/issues/594). seems to be a likely candidate.

Fairly trivial .emacs file:

(package-initialize)

(defalias 'javascript-mode 'js2-mode)

(menu-bar-mode -1)
(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(display-fill-column-indicator-character 124)
 '(fill-column 78)
 '(global-auto-revert-mode t)
 '(global-display-fill-column-indicator-mode t)
 '(indent-tabs-mode nil)
 '(js-indent-level 2)
 '(js2-concat-multiline-strings 'eol)
 '(magit-commit-show-diff nil)
 '(package-archives
   '(("gnu" . "https://elpa.gnu.org/packages/")
     ("nongnu" . "https://elpa.nongnu.org/nongnu/")
     ("melpa" . "https://melpa.org/packages/")))
 '(package-selected-packages '(js2-mode))
 '(sh-basic-offset 2)
 '(show-trailing-whitespace t)
 '(standard-indent 2)
 '(whitespace-action '(auto-cleanup))
 '(whitespace-style
   '(face trailing tabs spaces lines newline empty indentation::tab indentation::space indentation space-after-tab::tab space-after-tab::space space-after-tab space-before-tab::space space-before-tab space-mark tab-mark newline-mark)))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )

I still consider myself an emacs newbie, so not sure how to run with only js2-mode in an isolated enviroment to verify this is not due to some strange combination of things installed. If info is needed, pointers appreciated.

Running mainline Debian bookworm:

$ dpkg -l | grep -e emacs -e elpa
ii  dh-elpa-helper                       2.0.16                                    all          helper package for emacs lisp extensions
ii  elpa-ag                              0.48-1.1                                  all          Emacs frontend to ag
ii  elpa-dash                            2.19.1+git20220608.1.0ac1ecf+dfsg-1       all          modern list manipulation library for Emacs
ii  elpa-git-commit                      3.3.0-2                                   all          Major mode for editing git commit message
ii  elpa-magit                           3.3.0-2                                   all          Emacs interface for Git
ii  elpa-magit-section                   3.3.0-2                                   all          Collapsible sections like in Magit
ii  elpa-s                               1.12.0-5                                  all          string manipulation library for Emacs
ii  elpa-with-editor                     3.0.5-1                                   all          call program using Emacs as $EDITOR
ii  emacs                                1:28.2+1-15                               all          GNU Emacs editor (metapackage)
ii  emacs-bin-common                     1:28.2+1-15                               amd64        GNU Emacs editor's shared, architecture dependent files
ii  emacs-common                         1:28.2+1-15                               all          GNU Emacs editor's shared, architecture independent infrastructure
ii  emacs-common-non-dfsg                1:28.2+1-2                                all          GNU Emacs common non-DFSG items, including the core documentation
ii  emacs-el                             1:28.2+1-15                               all          GNU Emacs LISP (.el) files
ii  emacs-nox                            1:28.2+1-15                               amd64        GNU Emacs editor (without GUI support)
ii  emacsen-common                       3.0.5                                     all          Common facilities for all emacsen

$ ls .emacs.d/elpa/
archives/  gnupg/  js2-mode-20231225.1150/
dgutov commented 9 months ago

Hi! Not sure from which version you upgraded -- the affected code has been there for a number of years now.

I can also reproduce the same error without IIFE, just with use strict and a static block inside a class.

Anyway, I've pushed a change which should hopefully serve as a good enough workaround, see if you still have problems.

nexushoratio commented 9 months ago

Thanks. I'll give it a try as soon as I can and report back.

FTR, I downgraded to 20230408 and I had no problems with long pauses or error messages. I did experience the issue expressed in #594 .

nexushoratio commented 9 months ago

Ahh, noticed it was on melpa already.

Works great. Many thanks!

dgutov commented 9 months ago

I downgraded to 20230408 and I had no problems with long pauses or error messages

Okay, that actually makes sense: there was no support for static at that time. Though I'd expect the behavior to be the same in both of these cases: file fails to parse, shows some errors in the buffer and in Messages.

Works great. Many thanks!

Welcome!