From 3f4a0d5370ae6c34afe180df96add3b8522f4af1 Mon Sep 17 00:00:00 2001 From: mattkae Date: Wed, 11 May 2022 09:23:58 -0400 Subject: initial commit --- elpa/js2-refactor-20210306.2003/js2r-vars.el | 376 +++++++++++++++++++++++++++ 1 file changed, 376 insertions(+) create mode 100644 elpa/js2-refactor-20210306.2003/js2r-vars.el (limited to 'elpa/js2-refactor-20210306.2003/js2r-vars.el') diff --git a/elpa/js2-refactor-20210306.2003/js2r-vars.el b/elpa/js2-refactor-20210306.2003/js2r-vars.el new file mode 100644 index 0000000..fc27eae --- /dev/null +++ b/elpa/js2-refactor-20210306.2003/js2r-vars.el @@ -0,0 +1,376 @@ +;;; js2r-vars.el --- Variable declaration manipulation functions for js2-refactor -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2014 Magnar Sveen +;; Copyright (C) 2015-2016 Magnar Sveen and Nicolas Petton + +;; Author: Magnar Sveen , +;; Nicolas Petton +;; Keywords: conveniences + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Code: + +(require 'multiple-cursors-core) +(require 'dash) + +(require 'js2r-helpers) + +;; Helpers + +(defun js2r--name-node-at-point (&optional pos) + (setq pos (or pos (point))) + (let ((current-node (js2-node-at-point pos))) + (unless (js2-name-node-p current-node) + (setq current-node (js2-node-at-point (- (point) 1)))) + (if (not (and current-node (js2-name-node-p current-node))) + (error "Point is not on an identifier.") + current-node))) + +(defun js2r--local-name-node-at-point (&optional pos) + (setq pos (or pos (point))) + (let ((current-node (js2r--name-node-at-point pos))) + (unless (js2r--local-name-node-p current-node) + (error "Point is not on a local identifier")) + current-node)) + +(defun js2r--local-name-node-p (node) + (let ((parent (js2-node-parent node))) + (and parent (js2-name-node-p node) + ;; is not foo in { foo: 1 } + (not (and (js2-object-prop-node-p parent) + (eq node (js2-object-prop-node-left parent)) + ;; could be { foo } though, in which case the node + ;; is parent's both left and right. + (not (eq node (js2-object-prop-node-right parent))))) + ;; is not foo in x.foo + (not (and (js2-prop-get-node-p parent) + (eq node (js2-prop-get-node-right parent)))) + ;; is not foo in import { foo as bar } from ... + ;; could be bar, though. + (not (and (js2-export-binding-node-p parent) + (eq node (js2-export-binding-node-extern-name parent)) + (not (eq node (js2-export-binding-node-local-name parent)))))))) + +(defun js2r--name-node-defining-scope (name-node) + (unless (js2r--local-name-node-p name-node) + (error "Node is not on a local identifier")) + (js2-get-defining-scope + (js2-node-get-enclosing-scope name-node) + (js2-name-node-name name-node))) + +(defun js2r--local-usages-of-name-node (name-node) + (unless (js2r--local-name-node-p name-node) + (error "Node is not on a local identifier")) + (let* ((name (js2-name-node-name name-node)) + (scope (js2r--name-node-defining-scope name-node)) + (result nil)) + (js2-visit-ast + scope + (lambda (node end-p) + (when (and (not end-p) + (js2r--local-name-node-p node) + (string= name (js2-name-node-name node)) + (eq scope (js2r--name-node-defining-scope node))) + (add-to-list 'result node)) + t)) + result)) + +(defun js2r--local-var-positions (name-node) + (-map 'js2-node-abs-pos (js2r--local-usages-of-name-node name-node))) + +(defun js2r--var-defining-node (var-node) + (unless (js2r--local-name-node-p var-node) + (error "Node is not on a local identifier")) + (let* ((name (js2-name-node-name var-node)) + (scope (js2r--name-node-defining-scope var-node))) + (js2-symbol-ast-node + (js2-scope-get-symbol scope name)))) + + +;; Add to jslint globals annotation + +(defun current-line-contents () + "Find the contents of the current line, minus indentation." + (buffer-substring (save-excursion (back-to-indentation) (point)) + (save-excursion (end-of-line) (point)))) + +(require 'thingatpt) + +(defun js2r-add-to-globals-annotation () + (interactive) + (let ((var (thing-at-point 'symbol))) + (save-excursion + (beginning-of-buffer) + (when (not (string-match "^/\\* *global " (current-line-contents))) + (newline) + (forward-line -1) + (insert "/* global */") + (newline) + (forward-line -1)) + (while (not (string-match "*/" (current-line-contents))) + (forward-line)) + (end-of-line) + (delete-char -2) + (unless (looking-back "global ") + (while (looking-back " ") + (delete-char -1)) + (insert ", ")) + (insert (concat var " */"))))) + + +;; Rename variable + +;;;###autoload +(defun js2r-rename-var () + "Renames the variable on point and all occurrences in its lexical scope." + (interactive) + (js2r--guard) + (js2r--wait-for-parse + (let* ((current-node (js2r--local-name-node-at-point)) + (len (js2-node-len current-node)) + (current-start (js2-node-abs-pos current-node)) + (current-end (+ current-start len)) + (delta (- (point) current-start))) + (save-excursion + (mapc (lambda (beg) + (when (not (= beg current-start)) + (goto-char (+ beg delta)) + (set-mark (+ beg len)) + (mc/create-fake-cursor-at-point))) + (js2r--local-var-positions current-node))) + (push-mark current-end) + (activate-mark)) + (mc/maybe-multiple-cursors-mode))) + +(add-to-list 'mc--default-cmds-to-run-once 'js2r-rename-var) + +;; Change local variable to use this. instead + +(defun js2r-var-to-this () + "Changes the variable on point to use this.var instead." + (interactive) + (js2r--guard) + (js2r--wait-for-parse + (save-excursion + (let ((node (js2-node-at-point))) + (when (js2-var-decl-node-p node) + (let ((kids (js2-var-decl-node-kids node))) + (when (cdr kids) + (error "Currently does not support converting multivar statements.")) + (goto-char (js2-node-abs-pos (car kids)))))) + (--each (js2r--local-var-positions (js2r--local-name-node-at-point)) + (goto-char it) + (cond ((looking-back "var ") (delete-char -4)) + ((looking-back "let ") (delete-char -4)) + ((looking-back "const ") (delete-char -6))) + (insert "this."))))) + +;; Inline var + +(defun js2r-inline-var () + (interactive) + (js2r--guard) + (js2r--wait-for-parse + (save-excursion + (let* ((current-node (js2r--local-name-node-at-point)) + (definer (js2r--var-defining-node current-node)) + (definer-start (js2-node-abs-pos definer)) + (var-init (js2-node-parent definer)) + (initializer (js2-var-init-node-initializer + var-init))) + (unless initializer + (error "Var is not initialized when defined.")) + (let* ((var-len (js2-node-len current-node)) + (init-beg (js2-node-abs-pos initializer)) + (init-end (+ init-beg (js2-node-len initializer))) + (var-init-beg (copy-marker (js2-node-abs-pos var-init))) + (var-init-end (copy-marker (+ var-init-beg (js2-node-len var-init)))) + (contents (buffer-substring init-beg init-end))) + (mapc (lambda (beg) + (when (not (= beg definer-start)) + (goto-char beg) + (delete-char var-len) + (insert contents))) + (js2r--local-var-positions current-node)) + (js2r--delete-var-init var-init-beg var-init-end)))))) + + +(defun js2r--was-single-var () + (save-excursion + (goto-char (point-at-bol)) + (or (looking-at "^[[:space:]]*\\(var\\|const\\|let\\)[[:space:]]?;?$") + (looking-at "^[[:space:]]*,[[:space:]]*$")))) + +(defun js2r--was-starting-var () + (or (looking-back "var ") + (looking-back "const ") + (looking-back "let "))) + +(defun js2r--was-ending-var () + (looking-at ";")) + +(defun js2r--delete-var-init (beg end) + (goto-char beg) + (delete-char (- end beg)) + (cond + ((js2r--was-single-var) + (delete-region (point-at-bol) (point-at-eol)) + (delete-blank-lines)) + + ((js2r--was-starting-var) + (delete-char 1) + (if (looking-at " ") + (delete-char 1) + (join-line -1))) + + ((js2r--was-ending-var) + (if (looking-back ", ") + (delete-char -1) + (join-line) + (delete-char 1)) + (delete-char -1)) + + (t (delete-char 2)))) + +;; two cases +;; - it's the only var -> remove the line +;; - there are several vars -> remove the node then clean up commas + + +;; Extract variable + +(defun js2r--start-of-parent-stmt () + (js2-node-abs-pos (js2r--closest-stmt-node))) + +(defun js2r--object-literal-key-behind (pos) + (save-excursion + (goto-char pos) + (when (looking-back "\\sw: ?") + (backward-char 2) + (js2-name-node-name (js2r--name-node-at-point))))) + +(defun js2r--line-above-is-blank () + (save-excursion + (forward-line -1) + (string= "" (current-line-contents)))) + +;;;###autoload +(defun js2r-extract-var () + (interactive) + (js2r--guard) + (js2r--wait-for-parse + (let ((keyword (if js2r-prefer-let-over-var "let" "var"))) + (if (use-region-p) + (js2r--extract-var-between (region-beginning) (region-end) keyword) + (let ((node (js2r--closest-extractable-node))) + (js2r--extract-var-between (js2-node-abs-pos node) + (js2-node-abs-end node) keyword)))))) + +;;;###autoload +(defun js2r-extract-let () + (interactive) + (js2r--guard) + (js2r--wait-for-parse + (if (use-region-p) + (js2r--extract-var-between (region-beginning) (region-end) "let") + (let ((node (js2r--closest-extractable-node))) + (js2r--extract-var-between (js2-node-abs-pos node) + (js2-node-abs-end node) "let"))))) + +;;;###autoload +(defun js2r-extract-const () + (interactive) + (js2r--guard) + (js2r--wait-for-parse + (if (use-region-p) + (js2r--extract-var-between (region-beginning) (region-end) "const") + (let ((node (js2r--closest-extractable-node))) + (js2r--extract-var-between (js2-node-abs-pos node) + (js2-node-abs-end node) "const"))))) + +(add-to-list 'mc--default-cmds-to-run-once 'js2r-extract-var) +(add-to-list 'mc--default-cmds-to-run-once 'js2r-extract-let) +(add-to-list 'mc--default-cmds-to-run-once 'js2r-extract-const) + +(defun js2r--extract-var-between (beg end keyword) + (interactive "r") + (unless (js2r--single-complete-expression-between-p beg end) + (error "Can only extract single, complete expressions to var")) + + (let ((deactivate-mark nil) + (expression (buffer-substring beg end)) + (orig-var-end (make-marker)) + (new-var-end (make-marker)) + (name (or (js2r--object-literal-key-behind beg) "name"))) + + (delete-region beg end) + (insert name) + (set-marker orig-var-end (point)) + + (goto-char (js2r--start-of-parent-stmt)) + (js2r--insert-var name keyword) + (set-marker new-var-end (point)) + (insert " = " expression ";") + (when (or (js2r--line-above-is-blank) + (string-match-p "^function " expression)) + (newline)) + (newline) + (indent-region new-var-end orig-var-end) + (save-excursion + (goto-char new-var-end) + (set-mark (- (point) (length name))) + (mc/create-fake-cursor-at-point)) + (goto-char orig-var-end) + (set-mark (- (point) (length name))) + (set-marker orig-var-end nil) + (set-marker new-var-end nil)) + (mc/maybe-multiple-cursors-mode)) + +(defun js2r--insert-var (name keyword) + "Insert a var definition for NAME." + (insert (format "%s %s" keyword name))) + +(defun js2r-split-var-declaration () + "Split a variable declaration into separate variable +declarations for each declared variable." + (interactive) + (js2r--guard) + (js2r--wait-for-parse + (save-excursion + (let* ((declaration (or (js2r--closest #'js2-var-decl-node-p) (error "No var declaration at point."))) + (kids (js2-var-decl-node-kids declaration)) + (stmt (js2-node-parent-stmt declaration)) + (tt (js2-var-decl-node-decl-type declaration)) + (keyword (cond + ((= tt js2-VAR) "var") + ((= tt js2-LET) "let") + ((= tt js2-CONST) "const")))) + (goto-char (js2-node-abs-end stmt)) + (mapc (lambda (kid) + (js2r--insert-var (js2-node-string kid) keyword) + (insert ";") + (newline) + (if (save-excursion + (goto-char (js2-node-abs-end kid)) + (looking-at ", *\n *\n")) + (newline))) + kids) + (delete-char -1) ;; delete final newline + (let ((end (point))) + (js2r--goto-and-delete-node stmt) + (indent-region (point) end)))))) + +(provide 'js2r-vars) +;;; js2-vars.el ends here -- cgit v1.2.1