emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/js2-mode c47ea93e81 1/2: Fix js2-node-get-enclosing-sco


From: ELPA Syncer
Subject: [elpa] externals/js2-mode c47ea93e81 1/2: Fix js2-node-get-enclosing-scope on a statement function's name
Date: Wed, 28 Jun 2023 00:58:53 -0400 (EDT)

branch: externals/js2-mode
commit c47ea93e81efd9469c5d9558c48e911755e9d206
Author: Mihai Bazon <mihai.bazon@gmail.com>
Commit: Mihai Bazon <mihai.bazon@gmail.com>

    Fix js2-node-get-enclosing-scope on a statement function's name
    
    When called with a statement function's name node,
    js2-node-get-enclosing-scope would errorneously return the function itself.
    That's not really the scope where this name is defined (it should be the
    function's parent scope).
    
    This bug affects js2-refactor's rename variable functionality.  Example:
    
        (function(){
            function |foo() {
                var |foo = 5;
                console.log(|foo);
            }
            foo();
        })();
    
    (where '|' marks possible cursor position).  Type M-x js2r-rename-var with
    the cursor on one of the marked positions, and it'll offer to rename the
    following occurrences (marked with underscores):
    
        (function(){
            function _foo_() {
                var _foo_ = 5;
                console.log(_foo_);
            }
            foo();
        })();
    
    This is incorrect, as the name is shadowed inside the function.  It should
    instead rename these two:
    
        (function(){
            function _foo_() {
                var foo = 5;
                console.log(foo);
            }
            _foo_();
        })();
    
    This patch fixes this.
---
 js2-mode.el     |  9 +++++++++
 tests/parser.el | 13 +++++++++++--
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/js2-mode.el b/js2-mode.el
index 11ebb37340..637bb7687c 100644
--- a/js2-mode.el
+++ b/js2-mode.el
@@ -2344,6 +2344,15 @@ If any given node in NODES is nil, doesn't record that 
link."
 (defun js2-node-get-enclosing-scope (node)
   "Return the innermost `js2-scope' node surrounding NODE.
 Returns nil if there is no enclosing scope node."
+  ;; when node is the name of a function statement, the enclosing
+  ;; scope is not that function itself but the surrounding scope.
+  (let ((parent (js2-node-parent node)))
+    (when (and (js2-name-node-p node)
+               (js2-function-node-p parent)
+               (eq 'FUNCTION_STATEMENT (js2-function-node-form parent))
+               (eq node (js2-function-node-name parent)))
+      (setq node parent)))
+  ;; dig up to find the closest scope parent
   (while (and (setq node (js2-node-parent node))
               (not (js2-scope-p node))))
   node)
diff --git a/tests/parser.el b/tests/parser.el
index 32c33e55d7..f6e6abcda0 100644
--- a/tests/parser.el
+++ b/tests/parser.el
@@ -1214,11 +1214,14 @@ the test."
     (should (= (js2-symbol-decl-type var-entry) js2-VAR))
     (should (js2-name-node-p (js2-symbol-ast-node var-entry)))))
 
-(defun js2-test-scope-of-nth-variable-satisifies-predicate (variable nth 
predicate)
+(defun js2-get-nth-variable-enclosing-scope (variable nth)
   (goto-char (point-min))
   (dotimes (_ (1+ nth)) (search-forward variable))
   (forward-char -1)
-  (let ((scope (js2-node-get-enclosing-scope (js2-node-at-point))))
+  (js2-node-get-enclosing-scope (js2-node-at-point)))
+
+(defun js2-test-scope-of-nth-variable-satisifies-predicate (variable nth 
predicate)
+  (let ((scope (js2-get-nth-variable-enclosing-scope variable nth)))
     (should (funcall predicate (js2-get-defining-scope scope variable)))))
 
 (js2-deftest for-node-is-declaration-scope "for (let i = 0; i; ++i) {};"
@@ -1239,6 +1242,12 @@ the test."
   (js2-mode--and-parse)
   (js2-test-scope-of-nth-variable-satisifies-predicate "x" 0 
#'js2-comp-loop-node-p))
 
+(js2-deftest function-name-enclosing-scope-is-parent-scope "(function(){ var 
bar; function foo(){} })()"
+  (js2-mode--and-parse)
+  (let ((scope1 (js2-get-nth-variable-enclosing-scope "bar" 0))
+        (scope2 (js2-get-nth-variable-enclosing-scope "foo" 0)))
+    (should (eq scope1 scope2))))
+
 (js2-deftest array-comp-has-parent-scope
              "var a,b=[for (i of [[1,2]]) for (j of i) j * a];"
   (js2-mode--and-parse)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]