[elpa] master eb33e68 29/33: Get rid of js2-with-underscore-as-word-syntax
branch: master commit eb33e68d4f4bd1c9aefe4d660f59c3e53d6c1e61 Author: Dmitry Gutov Commit: Dmitry Gutov Get rid of js2-with-underscore-as-word-syntax --- js2-mode.el | 73 -- 1 files changed, 35 insertions(+), 38 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 348b0d1..e0c9d78 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -6914,7 +6914,7 @@ of a simple name. Called before EXPR has a parent node." "\\)" "\\s-*\\({[^}]+}\\)?" ; optional type "\\s-*\\[?\\([[:alnum:]_$\.]+\\)?\\]?" ; name - "\\>") + "\\_>") "Matches jsdoc tags with optional type and optional param name.") (defconst js2-jsdoc-typed-tag-regexp @@ -11044,7 +11044,7 @@ and comments have been removed." (and (looking-at js2-indent-operator-re) (or (not (looking-at ":")) (save-excursion - (and (js2-re-search-backward "[?:{]\\|\\" nil t) + (and (js2-re-search-backward "[?:{]\\|\\_" nil t) (looking-at "?")) (defun js2-continued-expression-p () @@ -11073,20 +11073,20 @@ spanning several lines requires that the start of the loop is indented to the same column as the current line." (interactive) (save-excursion -(when (looking-at "\\s-*\\") +(when (looking-at "\\s-*\\_") (if (save-excursion (skip-chars-backward "[ \t\n]*}") (looking-at "[ \t\n]*}")) (save-excursion -(backward-list) (backward-word 1) (looking-at "\\")) -(js2-re-search-backward "\\" (point-at-bol) t) -(or (looking-at "\\") +(backward-list) (backward-word 1) (looking-at "\\_")) +(js2-re-search-backward "\\_" (point-at-bol) t) +(or (looking-at "\\_") (let ((saved-indent (current-indentation))) - (while (and (js2-re-search-backward "^[ \t]*\\<" nil t) + (while (and (js2-re-search-backward "^[ \t]*\\_<" nil t) (/= (current-indentation) saved-indent))) - (and (looking-at "[ \t]*\\") + (and (looking-at "[ \t]*\\_") (not (js2-re-search-forward - "\\" (point-at-eol) t)) + "\\_" (point-at-eol) t)) (= (current-indentation) saved-indent (defun js2-multiline-decl-indentation () @@ -11224,8 +11224,8 @@ indentation is aligned to that column." (let* ((ctrl-stmt-indent (js2-ctrl-statement-indentation)) (at-closing-bracket (looking-at "[]})]")) (same-indent-p (or at-closing-bracket - (looking-at "\\[^:]") - (and (looking-at "\\[^:]") + (and (looking-at "\\_") + (setq beg (progn (forward-symbol -1) (point)) +end (progn (forward-symbol 1) (point))) +(setq beg (progn (forward-symbol 1) (point)) + end (progn (forward-symbol -1) (point + (replace-regexp-in-string + "[\"']" "" + (buffer-substring-no-properties beg end) (defun js2-mode-forward-sibling () "Move to the end of the sibling following point in parent.
[elpa] master 709ff60 05/33: Add a NEWS entry for d4d9c54
branch: master commit 709ff6075fdfe2a5349b76ce1ce1b732ae63b12c Author: Dmitry Gutov Commit: Dmitry Gutov Add a NEWS entry for d4d9c54 --- NEWS.md |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/NEWS.md b/NEWS.md index eea51d3..0ca9029 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,9 @@ # History of user-visible changes +## Next + +* `js2-pretty-multiline-declarations` can take the value `dynamic` now. + ## 20150202 Support for:
[elpa] master 5e5df54 27/33: Merge pull request #242 from jacksonrayhamilton/strict-mode
branch: master commit 5e5df5416e74ed062d2acf39880f2f31dba9a124 Merge: 09a86b2 2469440 Author: Dmitry Gutov Commit: Dmitry Gutov Merge pull request #242 from jacksonrayhamilton/strict-mode Strict mode --- js2-mode.el | 283 +-- tests/parser.el | 90 -- 2 files changed, 315 insertions(+), 58 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index fbbfeef..48a2c77 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -736,6 +736,7 @@ List of chars built up while scanning various tokens.") (end -1) (string "") number + number-base regexp-flags comment-type follows-eol-p) @@ -833,6 +834,9 @@ Will only be used when we finish implementing the interpreter.") (js2-deflocal js2-is-in-destructuring nil "True while parsing destructuring expression.") +(js2-deflocal js2-in-use-strict-directive nil + "True while inside a script or function under strict mode.") + (defcustom js2-global-externs nil "A list of any extern names you'd like to consider always declared. This list is global and is used by all `js2-mode' files. @@ -1668,6 +1672,9 @@ the correct number of ARGS must be provided." (js2-msg "msg.no.paren.after.with" "missing ) after with-statement object") +(js2-msg "msg.no.with.strict" + "with statements not allowed in strict mode") + (js2-msg "msg.no.paren.after.let" "missing ( after let") @@ -1783,6 +1790,18 @@ the correct number of ARGS must be provided." (js2-msg "msg.destruct.assign.no.init" "Missing = in destructuring declaration") +(js2-msg "msg.no.octal.strict" + "Octal numbers prohibited in strict mode.") + +(js2-msg "msg.dup.obj.lit.prop.strict" + "Property '%s' already defined in this object literal.") + +(js2-msg "msg.dup.param.strict" + "Parameter '%s' already declared in this function.") + +(js2-msg "msg.bad.id.strict" + "'%s' is not a valid identifier for this use in strict mode.") + ;; ScriptRuntime (js2-msg "msg.no.properties" "%s has no properties.") @@ -3754,10 +3773,13 @@ Returns 0 if NODE is nil or its identifier field is nil." (js2-current-token-beg))) (value (js2-current-token-string)) (num-value (js2-token-number - (js2-current-token)) + (js2-current-token))) +(num-base (js2-token-number-base + (js2-current-token)) "AST node for a number literal." value ; the original string, e.g. "6.02e23" - num-value) ; the parsed number value + num-value ; the parsed number value + num-base) ; the number's base (put 'cl-struct-js2-number-node 'js2-visitor 'js2-visit-none) (put 'cl-struct-js2-number-node 'js2-printer 'js2-print-number-node) @@ -3954,10 +3976,11 @@ optional `js2-expr-node'" len left right op-pos))) "AST node for an object literal prop:value entry. -The `left' field is the property: a name node, string node or number node. -The `right' field is a `js2-node' representing the initializer value. -If the property is abbreviated, the node's `SHORTHAND' property is non-nil -and both fields have the same value.") +The `left' field is the property: a name node, string node, +number node or expression node. The `right' field is a +`js2-node' representing the initializer value. If the property +is abbreviated, the node's `SHORTHAND' property is non-nil and +both fields have the same value.") (put 'cl-struct-js2-object-prop-node 'js2-visitor 'js2-visit-infix-node) (put 'cl-struct-js2-object-prop-node 'js2-printer 'js2-print-object-prop-node) @@ -6101,8 +6124,8 @@ its relevant fields and puts it into `js2-ti-tokens'." while (js2-digit-p c (js2-unget-char) (let ((str (js2-set-string-from-buffer token))) - (setf (js2-token-number token) - (js2-string-to-number str base))) + (setf (js2-token-number token) (js2-string-to-number str base) + (js2-token-number-base token) base)) (throw 'return js2-NUMBER)) ;; is it a string? (when (or (memq c '(?\" ?\')) @@ -7862,6 +7885,15 @@ Returns t on match, nil if no match." (defsubst js2-exit-switch () (pop js2-loop-and-switch-set)) +(defsubst js2-get-directive (node) + "Return NODE's value if it is a directive, nil otherwise. + +A directive is an otherwise-meaningless expression statement +consisting of a string literal,
[elpa] master d39764f 02/33: Merge pull request #231 from shicks/computed
branch: master commit d39764f8a780e457a58123056dd07b89d6b2e245 Merge: ac93b9e c13eda4 Author: Dmitry Gutov Commit: Dmitry Gutov Merge pull request #231 from shicks/computed Generalize object literal parsing to understand computed function names --- js2-mode.el | 123 ++- tests/parser.el | 12 + 2 files changed, 88 insertions(+), 47 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 2dd5d9d..54f9c19 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -3952,6 +3952,7 @@ and both fields have the same value.") (defun js2-print-object-prop-node (n i) (let* ((left (js2-object-prop-node-left n)) + (right (js2-object-prop-node-right n)) (computed (not (or (js2-string-node-p left) (js2-number-node-p left) (js2-name-node-p left) @@ -3964,7 +3965,7 @@ and both fields have the same value.") (if (not (js2-node-get-prop n 'SHORTHAND)) (progn (insert ": ") - (js2-print-ast (js2-object-prop-node-right n) 0) + (js2-print-ast right 0) (cl-defstruct (js2-getter-setter-node (:include js2-infix-node) @@ -3981,13 +3982,23 @@ property `GETTER_SETTER' set to js2-GET, js2-SET, or js2-FUNCTION. ") (put 'cl-struct-js2-getter-setter-node 'js2-printer 'js2-print-getter-setter) (defun js2-print-getter-setter (n i) - (let ((pad (js2-make-pad i)) -(left (js2-getter-setter-node-left n)) -(right (js2-getter-setter-node-right n))) + (let* ((pad (js2-make-pad i)) + (left (js2-getter-setter-node-left n)) + (right (js2-getter-setter-node-right n)) + (computed (not (or (js2-string-node-p left) +(js2-number-node-p left) +(js2-name-node-p left) (insert pad) (if (/= (js2-node-type n) js2-FUNCTION) (insert (if (= (js2-node-type n) js2-GET) "get " "set "))) +(when (and (js2-function-node-p right) + (eq 'STAR (js2-function-node-generator-type right))) + (insert "*")) +(when computed + (insert "[")) (js2-print-ast left 0) +(when computed + (insert "]")) (js2-print-ast right 0))) (cl-defstruct (js2-prop-get-node @@ -10344,38 +10355,41 @@ If ONLY-OF-P is non-nil, only the 'for (foo of bar)' form is allowed." (let ((pos (js2-current-token-beg)) (static nil) (continue t) -tt elems elem after-comma) +tt elems elem after-comma previous-token) (while continue (setq tt (js2-get-prop-name-token) static nil -elem nil) +elem nil +previous-token nil) + ;; Handle 'static' keyword only if we're in a class (when (and class-p (= js2-NAME tt) (string= "static" (js2-current-token-string))) (js2-record-face 'font-lock-keyword-face) (setq static t tt (js2-get-prop-name-token))) + ;; Handle generator * before the property name for in-line functions + (when (and (>= js2-language-version 200) + (= js2-MUL tt)) +(setq previous-token (js2-current-token) + tt (js2-get-prop-name-token))) + ;; Handle 'get' or 'set' keywords + (let ((prop (js2-current-token-string))) +(when (and (>= js2-language-version 200) + (= js2-NAME tt) + (or (string= prop "get") + (string= prop "set")) + (member (js2-peek-token) + (list js2-NAME js2-STRING js2-NUMBER js2-LB))) + (setq previous-token (js2-current-token) +tt (js2-get-prop-name-token (cond - ;; {foo: ...}, {'foo': ...}, {foo, bar, ...}, - ;; {get foo() {...}}, {set foo(x) {...}}, or {foo(x) {...}} - ;; TODO(sdh): support *foo() {...} - ((or (= js2-NAME tt) -(= tt js2-STRING)) + ;; Found a property (of any sort) + ((member tt (list js2-NAME js2-STRING js2-NUMBER js2-LB)) (setq after-comma nil - elem (js2-parse-named-prop tt)) + elem (js2-parse-named-prop tt pos previous-token)) (if (and (null elem) (not js2-recover-from-parse-errors)) (setq continue nil))) - ;; {[Symbol.iterator]: ...} - ((and (= tt js2-LB) - (>= js2-language-version 200)) -(let ((expr (js2-parse-expr))) - (js2-must-match js2-RB "msg.missing.computed.rb") - (setq after-comma nil -elem (js2-parse-plain-property expr - ;; {12: x} or {10.7: x} - ((= tt js2-NUMBER) -(setq after-comma nil - elem (js2-parse-plain-property (make-js2-number-node ;; Break out of loop, and handle trailing commas. ((or (= tt js2-RC) (= tt js2-EOF)) @@ -10405,42 +10419,55 @@ If ONLY-
[elpa] master 12e5a21 28/33: Remove js2-current-indent
branch: master commit 12e5a216519a4955cd02975880f4556e15506577 Author: Dmitry Gutov Commit: Dmitry Gutov Remove js2-current-indent --- js2-mode.el | 11 +-- 1 files changed, 1 insertions(+), 10 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 48a2c77..348b0d1 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -11305,15 +11305,6 @@ indentation is aligned to that column." (interactive) (while (forward-comment 1))) -(defun js2-current-indent (&optional pos) - "Return column of indentation on current line. -If POS is non-nil, go to that point and return indentation for that line." - (save-excursion -(if pos -(goto-char pos)) -(back-to-indentation) -(current-column))) - (defun js2-arglist-close () "Return non-nil if we're on a line beginning with a close-paren/brace." (save-excursion @@ -11368,7 +11359,7 @@ of the buffer to the current point. NORMAL-COL is the indentation column computed by the heuristic guesser based on current paren, bracket, brace and statement nesting. If BACKWARDS, cycle positions in reverse." - (let ((cur-indent (js2-current-indent)) + (let ((cur-indent (current-indentation)) (old-buffer-undo-list buffer-undo-list) ;; Emacs 21 only has `count-lines', not `line-number-at-pos' (current-line (save-excursion
[elpa] master c13eda4 01/33: Generalize object literal parsing to support short-hand function/generator/getter/setter declarations with all kinds of keys (string, named, computed, numeric).
branch: master commit c13eda48a6fa3af690cf36d799dc813de61f198a Author: Stephen Hicks Commit: Stephen Hicks Generalize object literal parsing to support short-hand function/generator/getter/setter declarations with all kinds of keys (string, named, computed, numeric). Previously only a subset of combinations were supported, but appear to be allowed by the spec. --- js2-mode.el | 123 ++- tests/parser.el | 12 + 2 files changed, 88 insertions(+), 47 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 2dd5d9d..54f9c19 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -3952,6 +3952,7 @@ and both fields have the same value.") (defun js2-print-object-prop-node (n i) (let* ((left (js2-object-prop-node-left n)) + (right (js2-object-prop-node-right n)) (computed (not (or (js2-string-node-p left) (js2-number-node-p left) (js2-name-node-p left) @@ -3964,7 +3965,7 @@ and both fields have the same value.") (if (not (js2-node-get-prop n 'SHORTHAND)) (progn (insert ": ") - (js2-print-ast (js2-object-prop-node-right n) 0) + (js2-print-ast right 0) (cl-defstruct (js2-getter-setter-node (:include js2-infix-node) @@ -3981,13 +3982,23 @@ property `GETTER_SETTER' set to js2-GET, js2-SET, or js2-FUNCTION. ") (put 'cl-struct-js2-getter-setter-node 'js2-printer 'js2-print-getter-setter) (defun js2-print-getter-setter (n i) - (let ((pad (js2-make-pad i)) -(left (js2-getter-setter-node-left n)) -(right (js2-getter-setter-node-right n))) + (let* ((pad (js2-make-pad i)) + (left (js2-getter-setter-node-left n)) + (right (js2-getter-setter-node-right n)) + (computed (not (or (js2-string-node-p left) +(js2-number-node-p left) +(js2-name-node-p left) (insert pad) (if (/= (js2-node-type n) js2-FUNCTION) (insert (if (= (js2-node-type n) js2-GET) "get " "set "))) +(when (and (js2-function-node-p right) + (eq 'STAR (js2-function-node-generator-type right))) + (insert "*")) +(when computed + (insert "[")) (js2-print-ast left 0) +(when computed + (insert "]")) (js2-print-ast right 0))) (cl-defstruct (js2-prop-get-node @@ -10344,38 +10355,41 @@ If ONLY-OF-P is non-nil, only the 'for (foo of bar)' form is allowed." (let ((pos (js2-current-token-beg)) (static nil) (continue t) -tt elems elem after-comma) +tt elems elem after-comma previous-token) (while continue (setq tt (js2-get-prop-name-token) static nil -elem nil) +elem nil +previous-token nil) + ;; Handle 'static' keyword only if we're in a class (when (and class-p (= js2-NAME tt) (string= "static" (js2-current-token-string))) (js2-record-face 'font-lock-keyword-face) (setq static t tt (js2-get-prop-name-token))) + ;; Handle generator * before the property name for in-line functions + (when (and (>= js2-language-version 200) + (= js2-MUL tt)) +(setq previous-token (js2-current-token) + tt (js2-get-prop-name-token))) + ;; Handle 'get' or 'set' keywords + (let ((prop (js2-current-token-string))) +(when (and (>= js2-language-version 200) + (= js2-NAME tt) + (or (string= prop "get") + (string= prop "set")) + (member (js2-peek-token) + (list js2-NAME js2-STRING js2-NUMBER js2-LB))) + (setq previous-token (js2-current-token) +tt (js2-get-prop-name-token (cond - ;; {foo: ...}, {'foo': ...}, {foo, bar, ...}, - ;; {get foo() {...}}, {set foo(x) {...}}, or {foo(x) {...}} - ;; TODO(sdh): support *foo() {...} - ((or (= js2-NAME tt) -(= tt js2-STRING)) + ;; Found a property (of any sort) + ((member tt (list js2-NAME js2-STRING js2-NUMBER js2-LB)) (setq after-comma nil - elem (js2-parse-named-prop tt)) + elem (js2-parse-named-prop tt pos previous-token)) (if (and (null elem) (not js2-recover-from-parse-errors)) (setq continue nil))) - ;; {[Symbol.iterator]: ...} - ((and (= tt js2-LB) - (>= js2-language-version 200)) -(let ((expr (js2-parse-expr))) - (js2-must-match js2-RB "msg.missing.computed.rb") - (setq after-comma nil -elem (js2-parse-plain-property expr - ;; {12: x} or {10.7: x} - ((= tt js2-NUMBER) -(setq after-comma nil - elem (js2-parse-plain-property (make-js2-number-node ;; Break out of loo
[elpa] master 7850d12 25/33: Cleanup
branch: master commit 7850d12ab8e6963c13e084440ca175d4ea12524e Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Cleanup --- js2-mode.el | 12 ++-- 1 files changed, 2 insertions(+), 10 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 767d536..89e18ab 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -8097,8 +8097,7 @@ NODE is either `js2-array-node', `js2-object-node', or `js2-name-node'. Return a list of `js2-name-node' nodes representing the symbols declared; probably to check them for errors." - (funcall #'js2-define-destruct-symbols-internal - node decl-type face ignore-not-in-block)) + (js2-define-destruct-symbols-internal node decl-type face ignore-not-in-block)) (defvar js2-illegal-strict-identifiers '("eval" "arguments") @@ -8127,14 +8126,7 @@ for strict mode errors caused by PARAMS." (defun js2-parse-function-params (function-type fn-node pos) "Parse the parameters of a function of FUNCTION-TYPE -represented by FN-NODE at POS. - -Return a list of lists of arguments to apply many times to -`js2-check-strict-function-params' to retroactively check for -strict mode errors that occurred. Because the function body is -parsed after its parameters, and the body might activate strict -mode for that function, the check has to occur after the body is -parsed." +represented by FN-NODE at POS." (if (js2-match-token js2-RP) (setf (js2-function-node-rp fn-node) (- (js2-current-token-beg) pos)) (let ((paren-free-arrow (and (eq function-type 'FUNCTION_ARROW)
[elpa] master 6255edb 18/33: Cleanup
branch: master commit 6255edb2458553cfb6483b59ce7b127e4a7f2445 Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Cleanup --- js2-mode.el | 62 +++--- 1 files changed, 33 insertions(+), 29 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 14ec664..18cda80 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -2465,12 +2465,12 @@ NAME can be a Lisp symbol or string. SYMBOL is a `js2-symbol'." len buffer))) "The root node of a js2 AST." - buffer ; the source buffer from which the code was parsed - comments ; a Lisp list of comments, ordered by start position - errors ; a Lisp list of errors found during parsing - warnings ; a Lisp list of warnings found during parsing - node-count ; number of nodes in the tree, including the root - in-strict-mode) ; t if the script is running under strict mode + buffer ; the source buffer from which the code was parsed + comments ; a Lisp list of comments, ordered by start position + errors ; a Lisp list of errors found during parsing + warnings ; a Lisp list of warnings found during parsing + node-count ; number of nodes in the tree, including the root + in-strict-mode); t if the script is running under strict mode (put 'cl-struct-js2-ast-root 'js2-visitor 'js2-visit-ast-root) (put 'cl-struct-js2-ast-root 'js2-printer 'js2-print-script) @@ -8099,12 +8099,15 @@ declared; probably to check them for errors." (js2-node-len node name-nodes) +(defvar js2-illegal-strict-identifiers + '("eval" "arguments") + "Identifiers not allowed as variables in strict mode.") + (defun js2-check-strict-identifier (name-node) "Check that NAME-NODE makes a legal strict mode identifier." (when js2-in-use-strict-directive (let ((param-name (js2-name-node-name name-node))) - (when (or (string= param-name "eval") -(string= param-name "arguments")) + (when (member param-name js2-illegal-strict-identifiers) (js2-report-error "msg.bad.id.strict" param-name (js2-node-abs-pos name-node) (js2-node-len name-node)) @@ -8116,8 +8119,7 @@ for strict mode errors caused by PARAMS." (let ((param-name (js2-name-node-name param))) (js2-check-strict-identifier param) (when (cl-some (lambda (param) - (string= (js2-name-node-name param) - param-name)) + (string= (js2-name-node-name param) param-name)) preceding-params) (js2-report-error "msg.dup.param.strict" param-name (js2-node-abs-pos param) (js2-node-len param))) @@ -8140,7 +8142,7 @@ parsed." (eq (js2-current-token-type) js2-NAME))) params param param-name-nodes new-param-name-nodes - deferred-error-checking-arguments + error-checking-arguments default-found rest-param-at) (when paren-free-arrow (js2-unget-token)) @@ -8153,14 +8155,16 @@ parsed." (js2-get-token) (when default-found (js2-report-error "msg.no.default.after.default.param")) - (setq param (js2-parse-destruct-primary-expr)) - (setq new-param-name-nodes (js2-define-destruct-symbols - param js2-LP 'js2-function-param)) - (setq deferred-error-checking-arguments - (append deferred-error-checking-arguments - (list (list param-name-nodes - new-param-name-nodes - (setq param-name-nodes (append param-name-nodes new-param-name-nodes)) + (setq param (js2-parse-destruct-primary-expr) + new-param-name-nodes (js2-define-destruct-symbols + param js2-LP 'js2-function-param) + error-checking-arguments (append + error-checking-arguments + (list + (list + param-name-nodes + new-param-name-nodes))) + param-name-nodes (append param-name-nodes new-param-name-nodes)) (push param params)) ;; variable name (t @@ -8174,11 +8178,12 @@ parsed." (js2-record-face 'js2-function-param) (setq param (js2-create-name-node)) (js2-def
[elpa] master ac205a4 16/33: Octal syntax is an error in strict mode
branch: master commit ac205a435c93be083d43c6b823309b8ec2742eae Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Octal syntax is an error in strict mode --- js2-mode.el | 23 +-- tests/parser.el |4 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index d47fc80..fcb1dcc 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -736,6 +736,7 @@ List of chars built up while scanning various tokens.") (end -1) (string "") number + number-base regexp-flags comment-type follows-eol-p) @@ -1789,6 +1790,9 @@ the correct number of ARGS must be provided." (js2-msg "msg.destruct.assign.no.init" "Missing = in destructuring declaration") +(js2-msg "msg.no.octal.strict" + "Octal numbers prohibited in strict mode.") + (js2-msg "msg.dup.param.strict" "Parameter '%s' already declared in this function.") @@ -3768,10 +3772,13 @@ Returns 0 if NODE is nil or its identifier field is nil." (js2-current-token-beg))) (value (js2-current-token-string)) (num-value (js2-token-number - (js2-current-token)) + (js2-current-token))) +(num-base (js2-token-number-base + (js2-current-token)) "AST node for a number literal." value ; the original string, e.g. "6.02e23" - num-value) ; the parsed number value + num-value ; the parsed number value + num-base) ; the number's base (put 'cl-struct-js2-number-node 'js2-visitor 'js2-visit-none) (put 'cl-struct-js2-number-node 'js2-printer 'js2-print-number-node) @@ -6115,8 +6122,8 @@ its relevant fields and puts it into `js2-ti-tokens'." while (js2-digit-p c (js2-unget-char) (let ((str (js2-set-string-from-buffer token))) - (setf (js2-token-number token) - (js2-string-to-number str base))) + (setf (js2-token-number token) (js2-string-to-number str base) + (js2-token-number-base token) base)) (throw 'return js2-NUMBER)) ;; is it a string? (when (or (memq c '(?\" ?\')) @@ -10286,7 +10293,7 @@ For instance, @[expr], @*::[expr], or ns::[expr]." "Parse a literal (leaf) expression of some sort. Includes complex literals such as functions, object-literals, array-literals, array comprehensions and regular expressions." - (let (tt) + (let (tt node) (setq tt (js2-current-token-type)) (cond ((= tt js2-CLASS) @@ -10307,7 +10314,11 @@ array-literals, array comprehensions and regular expressions." ((= tt js2-NAME) (js2-parse-name tt)) ((= tt js2-NUMBER) - (make-js2-number-node)) + (setq node (make-js2-number-node)) + (when (and js2-in-use-strict-directive + (= (js2-number-node-num-base node) 8)) +(js2-report-error "msg.no.octal.literal")) + node) ((or (= tt js2-STRING) (= tt js2-NO_SUBS_TEMPLATE)) (make-js2-string-node :type tt)) ((= tt js2-TEMPLATE_HEAD) diff --git a/tests/parser.el b/tests/parser.el index 04a19c3..0e92037 100644 --- a/tests/parser.el +++ b/tests/parser.el @@ -287,6 +287,10 @@ the test." "'use strict';\nwith ({}) {}" :syntax-error "with" :errors-count 1) +(js2-deftest-parse function-strict-octal + "'use strict';\nvar number = 0644;" + :syntax-error "0644" :errors-count 1) + ;;; Spread operator (js2-deftest-parse spread-in-array-literal
[elpa] master 5b25da2 30/33: Add NEWS entry and bump version
branch: master commit 5b25da2ab33471f2d24265369ba39b9ff626de87 Author: Dmitry Gutov Commit: Dmitry Gutov Add NEWS entry and bump version --- js2-mode.el |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index e0c9d78..d3ab885 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -7,7 +7,7 @@ ;; Dmitry Gutov ;; URL: https://github.com/mooz/js2-mode/ ;; http://code.google.com/p/js2-mode/ -;; Version: 20150202 +;; Version: 20150713 ;; Keywords: languages, javascript ;; Package-Requires: ((emacs "24.1") (cl-lib "0.5"))
[elpa] master 663efb1 24/33: Remove strict mode slots on nodes.
branch: master commit 663efb19158aaba34fb4c59f399df85e7678e0d0 Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Remove strict mode slots on nodes. --- js2-mode.el | 22 -- 1 files changed, 8 insertions(+), 14 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 0975854..767d536 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -2465,12 +2465,11 @@ NAME can be a Lisp symbol or string. SYMBOL is a `js2-symbol'." len buffer))) "The root node of a js2 AST." - buffer ; the source buffer from which the code was parsed - comments ; a Lisp list of comments, ordered by start position - errors ; a Lisp list of errors found during parsing - warnings ; a Lisp list of warnings found during parsing - node-count ; number of nodes in the tree, including the root - in-strict-mode); t if the script is running under strict mode + buffer ; the source buffer from which the code was parsed + comments ; a Lisp list of comments, ordered by start position + errors ; a Lisp list of errors found during parsing + warnings ; a Lisp list of warnings found during parsing + node-count); number of nodes in the tree, including the root (put 'cl-struct-js2-ast-root 'js2-visitor 'js2-visit-ast-root) (put 'cl-struct-js2-ast-root 'js2-printer 'js2-print-script) @@ -3347,8 +3346,7 @@ The `params' field is a Lisp list of nodes. Each node is either a simple ignore-dynamic ; ignore value of the dynamic-scope flag (interpreter only) needs-activation ; t if we need an activation object for this frame generator-type ; STAR, LEGACY, COMPREHENSION or nil - member-expr ; nonstandard Ecma extension from Rhino - in-strict-mode) ; t if the function is running under strict mode + member-expr) ; nonstandard Ecma extension from Rhino (put 'cl-struct-js2-function-node 'js2-visitor 'js2-visit-function-node) (put 'cl-struct-js2-function-node 'js2-printer 'js2-print-function-node) @@ -7984,8 +7982,7 @@ Scanner should be initialized." ((null directive) (setq in-directive-prologue nil)) ((string= directive "use strict") -(setq js2-in-use-strict-directive t) -(setf (js2-ast-root-in-strict-mode root) t) +(setq js2-in-use-strict-directive t) ;; add function or statement to script (setq end (js2-node-end n)) (js2-block-node-push root n)) @@ -8027,8 +8024,6 @@ Scanner should be initialized." not-in-directive-prologue node directive) -;; Inherit strict mode. -(setf (js2-function-node-in-strict-mode fn-node) js2-in-use-strict-directive) (cl-incf js2-nesting-of-function) (unwind-protect (while (not (or (= (setq tt (js2-peek-token)) js2-ERROR) @@ -8049,8 +8044,7 @@ Scanner should be initialized." ;; to the function name and parameters. (when (not js2-in-use-strict-directive) (setq js2-in-use-strict-directive t) - (throw 'reparse t)) - (setf (js2-function-node-in-strict-mode fn-node) t))) + (throw 'reparse t node) (js2-get-token) (js2-parse-function-stmt
[elpa] master f3a899b 32/33: And actually update NEWS
branch: master commit f3a899bb1c36e25e078eed2890eb2fecb22f4175 Author: Dmitry Gutov Commit: Dmitry Gutov And actually update NEWS --- NEWS.md |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/NEWS.md b/NEWS.md index 3673503..300bc84 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,7 +1,8 @@ # History of user-visible changes -## Next +## 20150713 +* More comprehensive strict mode warnings and syntax errors. * New minor mode: `js2-highlight-unused-variables-mode`. * `js2-pretty-multiline-declarations` can take the value `dynamic` now.
[elpa] master 53f3f52 31/33: Actually remove the macro
branch: master commit 53f3f52f8d04a9cbbfac166819dfee2fca237477 Author: Dmitry Gutov Commit: Dmitry Gutov Actually remove the macro --- js2-mode.el | 11 --- 1 files changed, 0 insertions(+), 11 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index d3ab885..14e3b72 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -2204,17 +2204,6 @@ Returns nil if element is not found in the list." (defsubst js2-flag-not-set-p (flags flag) (zerop (logand flags flag))) -(defmacro js2-with-underscore-as-word-syntax (&rest body) - "Evaluate BODY with the _ character set to be word-syntax." - (declare (indent 0) (debug t)) - (let ((old-syntax (make-symbol "old-syntax"))) - `(let ((,old-syntax (string (char-syntax ?_ - (unwind-protect - (progn - (modify-syntax-entry ?_ "w" js2-mode-syntax-table) - ,@body) - (modify-syntax-entry ?_ ,old-syntax js2-mode-syntax-table) - ;;; AST struct and function definitions ;; flags for ast node property 'member-type (used for e4x operators)
[elpa] master 46e1492 23/33: Reparse strict functions.
branch: master commit 46e149258bd43ced7d8632df6dfdc8be0d56ef33 Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Reparse strict functions. --- js2-mode.el | 97 ++- 1 files changed, 49 insertions(+), 48 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 660da2c..0975854 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -7959,7 +7959,7 @@ Scanner should be initialized." (end js2-ts-cursor) ; in case file is empty root n tt (in-directive-prologue t) -(saved-strict-mode js2-in-use-strict-directive) +(js2-in-use-strict-directive js2-in-use-strict-directive) directive) ;; initialize buffer-local parsing vars (setf root (make-js2-ast-root :buffer (buffer-name) :pos pos) @@ -7989,7 +7989,6 @@ Scanner should be initialized." ;; add function or statement to script (setq end (js2-node-end n)) (js2-block-node-push root n)) -(setq js2-in-use-strict-directive saved-strict-mode) ;; add comments to root in lexical order (when js2-scanned-comments ;; if we find a comment beyond end of normal kids, use its end @@ -8026,7 +8025,6 @@ Scanner should be initialized." tt end not-in-directive-prologue -(saved-strict-mode js2-in-use-strict-directive) node directive) ;; Inherit strict mode. @@ -8047,13 +8045,16 @@ Scanner should be initialized." ((null directive) (setq not-in-directive-prologue t)) ((string= directive "use strict") - (setq js2-in-use-strict-directive t) + ;; Back up and reparse the function, because new rules apply + ;; to the function name and parameters. + (when (not js2-in-use-strict-directive) + (setq js2-in-use-strict-directive t) + (throw 'reparse t)) (setf (js2-function-node-in-strict-mode fn-node) t))) node) (js2-get-token) (js2-parse-function-stmt - (cl-decf js2-nesting-of-function) - (setq js2-in-use-strict-directive saved-strict-mode)) + (cl-decf js2-nesting-of-function)) (setq end (js2-current-token-end)) ; assume no curly and leave at current token (if (js2-must-match js2-RC "msg.no.brace.after.body" pos) (setq end (js2-current-token-end))) @@ -8141,14 +8142,11 @@ parsed after its parameters, and the body might activate strict mode for that function, the check has to occur after the body is parsed." (if (js2-match-token js2-RP) - (progn (setf (js2-function-node-rp fn-node) (- (js2-current-token-beg) pos)) - ;; Return an empty list for consistency. - '()) + (setf (js2-function-node-rp fn-node) (- (js2-current-token-beg) pos)) (let ((paren-free-arrow (and (eq function-type 'FUNCTION_ARROW) (eq (js2-current-token-type) js2-NAME))) params param param-name-nodes new-param-name-nodes - error-checking-arguments default-found rest-param-at) (when paren-free-arrow (js2-unget-token)) @@ -8163,14 +8161,9 @@ parsed." (js2-report-error "msg.no.default.after.default.param")) (setq param (js2-parse-destruct-primary-expr) new-param-name-nodes (js2-define-destruct-symbols - param js2-LP 'js2-function-param) - error-checking-arguments (append - error-checking-arguments - (list - (list - param-name-nodes - new-param-name-nodes))) - param-name-nodes (append param-name-nodes new-param-name-nodes)) + param js2-LP 'js2-function-param)) + (js2-check-strict-function-params param-name-nodes new-param-name-nodes) + (setq param-name-nodes (append param-name-nodes new-param-name-nodes)) (push param params)) ;; variable name (t @@ -8184,12 +8177,8 @@ parsed." (js2-record-face 'js2-function-param) (setq param (js2-create-name-node)) (js2-define-symbol js2-LP (js2-current-token-string) param) - (setq error-checking-arguments (append - error-checking-arguments - (list - (list param-name-nodes -(list param
[elpa] master e0ecf99 14/33: Check identifiers in strict mode.
branch: master commit e0ecf99444a65b13ec01331a1ff9d2bf4ede4fcf Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Check identifiers in strict mode. --- js2-mode.el | 117 ++- tests/parser.el | 34 2 files changed, 132 insertions(+), 19 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 9a224c5..12801bb 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -1786,6 +1786,12 @@ the correct number of ARGS must be provided." (js2-msg "msg.destruct.assign.no.init" "Missing = in destructuring declaration") +(js2-msg "msg.dup.param.strict" + "Parameter '%s' already declared in this function.") + +(js2-msg "msg.bad.id.strict" + "'%s' is not a valid identifier for this use in strict mode.") + ;; ScriptRuntime (js2-msg "msg.no.properties" "%s has no properties.") @@ -8009,6 +8015,8 @@ Scanner should be initialized." (saved-strict-mode js2-in-use-strict-directive) node directive) +;; Inherit strict mode. +(setf (js2-function-node-in-strict-mode fn-node) js2-in-use-strict-directive) (cl-incf js2-nesting-of-function) (unwind-protect (while (not (or (= (setq tt (js2-peek-token)) js2-ERROR) @@ -8041,9 +8049,13 @@ Scanner should be initialized." (js2-node-add-children fn-node pn) pn)) -(defun js2-define-destruct-symbols (node decl-type face &optional ignore-not-in-block) +(defun js2-define-destruct-symbols +(node decl-type face &optional ignore-not-in-block name-nodes) "Declare and fontify destructuring parameters inside NODE. -NODE is either `js2-array-node', `js2-object-node', or `js2-name-node'." +NODE is either `js2-array-node', `js2-object-node', or `js2-name-node'. + +Return a list of `js2-name-node' nodes representing the symbols +declared; probably to check them for errors." (cond ((js2-name-node-p node) (let (leftpos) @@ -8052,26 +8064,70 @@ NODE is either `js2-array-node', `js2-object-node', or `js2-name-node'." (when face (js2-set-face (setq leftpos (js2-node-abs-pos node)) (+ leftpos (js2-node-len node)) - face 'record + face 'record)) + (setq name-nodes (append name-nodes (list node) ((js2-object-node-p node) (dolist (elem (js2-object-node-elems node)) - (js2-define-destruct-symbols - ;; In abbreviated destructuring {a, b}, right == left. - (js2-object-prop-node-right elem) - decl-type face ignore-not-in-block))) + (setq name-nodes +(append name-nodes +(js2-define-destruct-symbols + ;; In abbreviated destructuring {a, b}, right == left. + (js2-object-prop-node-right elem) + decl-type face ignore-not-in-block name-nodes) ((js2-array-node-p node) (dolist (elem (js2-array-node-elems node)) (when elem -(js2-define-destruct-symbols elem decl-type face ignore-not-in-block +(setq name-nodes + (append name-nodes + (js2-define-destruct-symbols + elem decl-type face ignore-not-in-block name-nodes)) (t (js2-report-error "msg.no.parm" nil (js2-node-abs-pos node) -(js2-node-len node) +(js2-node-len node + name-nodes) + +(defun js2-check-strict-identifier (name-node) + "Check that NAME-NODE makes a legal strict mode identifier." + (when js2-in-use-strict-directive +(let ((param-name (js2-name-node-name name-node))) + (when (or (string= param-name "eval") +(string= param-name "arguments")) +(js2-report-error "msg.bad.id.strict" param-name + (js2-node-abs-pos name-node) (js2-node-len name-node)) + +(defun js2-check-strict-function-params (preceding-params params) + "Given PRECEDING-PARAMS in a function's parameter list, check +for strict mode errors caused by PARAMS." + (when js2-in-use-strict-directive +(dolist (param params) + (let ((param-name (js2-name-node-name param))) +(js2-check-strict-identifier param) +(when (cl-some (lambda (param) + (string= (js2-name-node-name param) + param-name)) + preceding-params) + (js2-report-error "msg.dup.param.strict" param-name +(js2-node-abs-pos param) (js2-node-len param))) (defun js2-parse-function-params (function-type fn-node pos) + "Parse the parameters of a function of FUNCTION-TYPE +represented by FN-NODE at POS. + +Return a list of lists of arguments to apply many times to +`js2-check-strict-function-params' to retroactively check for +strict mode errors that occurred. Because the function body is +parsed after its parameters, and the body might activate strict +mode for
[elpa] master ad4c5cc 20/33: Report the correct octal number error
branch: master commit ad4c5ccae4df5bd8664160341123deb72362e503 Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Report the correct octal number error --- js2-mode.el |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 5745dc5..e667df0 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -10329,7 +10329,7 @@ array-literals, array comprehensions and regular expressions." (setq node (make-js2-number-node)) (when (and js2-in-use-strict-directive (= (js2-number-node-num-base node) 8)) -(js2-report-error "msg.no.octal.literal")) +(js2-report-error "msg.no.octal.strict")) node) ((or (= tt js2-STRING) (= tt js2-NO_SUBS_TEMPLATE)) (make-js2-string-node :type tt))
[elpa] master 2469440 26/33: Fix bug where properties where checked for strict mode compliance
branch: master commit 24694401ec6479a5e59425b010f57b69cf15bafb Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Fix bug where properties where checked for strict mode compliance --- js2-mode.el |5 - tests/parser.el |3 +++ 2 files changed, 7 insertions(+), 1 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 89e18ab..48a2c77 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -9668,7 +9668,10 @@ If NODE is non-nil, it is the AST node associated with the symbol." ;; tt express assignment (=, |=, ^=, ..., %=) (setq op-pos (- (js2-current-token-beg) pos) ; relative left pn) -(js2-check-strict-identifier left) +;; The assigned node could be a js2-prop-get-node (foo.bar = 0), we only +;; care about assignment to strict variable names. +(when (js2-name-node-p left) + (js2-check-strict-identifier left)) (setq right (js2-parse-assign-expr) pn (make-js2-assign-node :type tt :pos pos diff --git a/tests/parser.el b/tests/parser.el index b9c9c68..bfc5653 100644 --- a/tests/parser.el +++ b/tests/parser.el @@ -281,6 +281,9 @@ the test." "'use strict';\narguments = 'fufufu';" :syntax-error "arguments" :errors-count 1) +(js2-deftest-parse function-property-strict-assignment + "'use strict';\narguments.okay = 'alright';") + (js2-deftest-parse function-strict-with "'use strict';\nwith ({}) {}" :syntax-error "with" :errors-count 1)
[elpa] master f1edac7 19/33: Don't treat a block-scoped const as redeclaration
branch: master commit f1edac7db39c7ef433f9d597c71014a90fd61488 Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Don't treat a block-scoped const as redeclaration --- js2-mode.el |8 ++-- tests/parser.el |8 +--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 18cda80..5745dc5 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -9559,8 +9559,12 @@ If NODE is non-nil, it is the AST node associated with the symbol." (len (if node (js2-node-len node (cond ((and symbol ; already defined - (or (= sdt js2-CONST) ; old version is const - (= decl-type js2-CONST) ; new version is const + (or (if js2-in-use-strict-directive + ;; two const-bound vars in this block have same name + (and (= sdt js2-CONST) +(eq defining-scope js2-current-scope)) + (or (= sdt js2-CONST) ; old version is const + (= decl-type js2-CONST))) ; new version is const ;; two let-bound vars in this block have same name (and (= sdt js2-LET) (eq defining-scope js2-current-scope diff --git a/tests/parser.el b/tests/parser.el index 93c47ab..b9c9c68 100644 --- a/tests/parser.el +++ b/tests/parser.el @@ -247,7 +247,7 @@ the test." (js2-deftest-parse function-with-rest-after-default-parameter "function foo(a = 1, ...rest) {\n}") -;;; Strict identifiers +;;; Strict mode errors (js2-deftest-parse function-bad-strict-parameters "'use strict';\nfunction foo(eval, {arguments}, bar) {\n}" @@ -281,8 +281,6 @@ the test." "'use strict';\narguments = 'fufufu';" :syntax-error "arguments" :errors-count 1) -;;; Strict syntax errors - (js2-deftest-parse function-strict-with "'use strict';\nwith ({}) {}" :syntax-error "with" :errors-count 1) @@ -295,6 +293,10 @@ the test." "'use strict';\nvar object = {a: 1, a: 2, 'a': 3, ['a']: 4, 1: 5, '1': 6, [1 + 1]: 7};" :syntax-error "a" :errors-count 4) ; "a" has 3 dupes, "1" has 1 dupe. +;; errors... or lackthereof. +(js2-deftest-parse function-strict-const-scope + "'use strict';\nconst a;\nif (1) {\n const a;\n}") + ;;; Spread operator (js2-deftest-parse spread-in-array-literal
[elpa] master d6e6cd6 06/33: Fix object keys highlighting (closes #234)
branch: master commit d6e6cd6a5249d86248e825425b73066f0fc3286e Author: Dmitry Gutov Commit: Dmitry Gutov Fix object keys highlighting (closes #234) Regression from c13eda4. --- js2-mode.el | 11 ++- 1 files changed, 6 insertions(+), 5 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 082a5d0..d775d65 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -10439,7 +10439,6 @@ When `js2-is-in-destructuring' is t, forms like {a, b, c} will be permitted." (js2-create-name-node)) ;; Anything else is an error (t (js2-report-error "msg.bad.prop" -expr (prop (and previous-token (js2-token-string previous-token))) (property-type (when previous-token (if (= (js2-token-type previous-token) js2-MUL) @@ -10459,19 +10458,21 @@ When `js2-is-in-destructuring' is t, forms like {a, b, c} will be permitted." (js2-parse-getter-setter-prop pos key property-type)) ;; regular prop (t - (prog1 - (setq expr (js2-parse-plain-property key)) + (let ((beg (js2-current-token-beg)) +(end (js2-current-token-end)) +(expr (js2-parse-plain-property key))) (when (and (= tt js2-NAME) (not js2-is-in-destructuring) js2-highlight-external-variables (js2-node-get-prop expr 'SHORTHAND)) (js2-record-name-node key)) -(js2-set-face (js2-current-token-beg) (js2-current-token-end) +(js2-set-face beg end (if (js2-function-node-p (js2-object-prop-node-right expr)) 'font-lock-function-name-face 'font-lock-variable-name-face) - 'record)) + 'record) +expr) (defun js2-parse-plain-property (prop) "Parse a non-getter/setter property in an object literal.
[elpa] master 254c78c 07/33: Highlight unused and/or uninitialized variables
branch: master commit 254c78c1b3ccc3af05ff3298bee669e6fa8a5c70 Author: Lele Gaifax Commit: Dmitry Gutov Highlight unused and/or uninitialized variables Adding new js2-highlight-unused-variables-mode. Closes #212, closes #233 --- js2-mode.el | 171 ++- tests/parser.el | 145 ++ 2 files changed, 314 insertions(+), 2 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index d775d65..c1aaa21 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -1155,6 +1155,11 @@ another file, or you've got a potential bug." :type 'boolean :group 'js2-mode) +(defcustom js2-warn-about-unused-function-arguments nil + "Non-nil to treat function arguments like declared-but-unused variables." + :type 'booleanp + :group 'js2-mode) + (defcustom js2-include-jslint-globals t "Non-nil to include the identifiers from JSLint global declaration (see http://www.jslint.com/lint.html#global) in the @@ -1793,6 +1798,12 @@ the correct number of ARGS must be provided." (js2-msg "msg.undeclared.variable" ; added by js2-mode "Undeclared variable or function '%s'") +(js2-msg "msg.unused.variable" ; added by js2-mode + "Unused variable or function '%s'") + +(js2-msg "msg.uninitialized.variable" ; added by js2-mode + "Variable '%s' referenced but never initialized") + (js2-msg "msg.ref.undefined.prop" "Reference to undefined property '%s'") @@ -7081,6 +7092,160 @@ it is considered declared." (js2-report-warning "msg.undeclared.variable" name pos (- end pos) 'js2-external-variable)) +(defun js2--add-or-update-symbol (symbol inition used vars) + "Add or update SYMBOL entry in VARS, an hash table. +SYMBOL is a js2-name-node, INITION either nil, t, or ?P, +respectively meaning that SYMBOL is a mere declaration, an +assignment or a function parameter; when USED is t, the symbol +node is assumed to be an usage and thus added to the list stored +in the cdr of the entry. +" + (let* ((nm (js2-name-node-name symbol)) + (es (js2-node-get-enclosing-scope symbol)) + (ds (js2-get-defining-scope es nm))) +(when (and ds (not (equal nm "arguments"))) + (let* ((sym (js2-scope-get-symbol ds nm)) + (var (gethash sym vars)) + (err-var-p (js2-catch-node-p ds))) +(unless inition + (setq inition err-var-p)) +(if var +(progn + (when (and inition (not (equal (car var) ?P))) +(setcar var inition)) + (when used +(push symbol (cdr var + ;; do not consider the declaration of catch parameter as an usage + (when (and err-var-p used) +(setq used nil)) + (puthash sym (cons inition (if used (list symbol))) vars)) + +(defun js2--classify-variables () + "Collect and classify variables declared or used within js2-mode-ast. +Traverse the whole ast tree returning a summary of the variables +usage as an hash-table, keyed by their corresponding symbol table +entry. +Each variable is described by a tuple where the car is a flag +indicating whether the variable has been initialized and the cdr +is a possibly empty list of name nodes where it is used. External +symbols, i.e. those not present in the whole scopes hierarchy, +are ignored." + (let ((vars (make-hash-table :test #'eq :size 100))) +(js2-visit-ast + js2-mode-ast + (lambda (node end-p) + (when (null end-p) + (cond + ((js2-var-init-node-p node) + ;; take note about possibly initialized declarations + (let ((target (js2-var-init-node-target node)) + (initializer (js2-var-init-node-initializer node))) + (when target + (let* ((parent (js2-node-parent node)) + (grandparent (if parent (js2-node-parent parent))) + (inited (not (null initializer + (unless inited + (setq inited + (and grandparent + (js2-for-in-node-p grandparent) + (memq target +(mapcar #'js2-var-init-node-target +(js2-var-decl-node-kids + (js2-for-in-node-iterator grandparent))) + (js2--add-or-update-symbol target inited nil vars) + + ((js2-assign-node-p node) + ;; take note about assignments + (let ((left (js2-assign-node-left node))) + (when (js2-name-node-p left) + (js2--add-or-update-symbol left t nil vars + + ((js2-prop-get-node-p node) + ;; handle x.y.z nodes, considering only x + (let ((left (js2-prop-get-node-left node))) + (when (js2-name-node-p left)
[elpa] master 1277c7d 12/33: Track script and function strict mode.
branch: master commit 1277c7d296a834b943fcfed144fbc6adee4ae293 Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Track script and function strict mode. --- js2-mode.el | 78 ++- 1 files changed, 61 insertions(+), 17 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index e4b0ed4..9a224c5 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -833,6 +833,9 @@ Will only be used when we finish implementing the interpreter.") (js2-deflocal js2-is-in-destructuring nil "True while parsing destructuring expression.") +(js2-deflocal js2-in-use-strict-directive nil + "True while inside a script or function under strict mode.") + (defcustom js2-global-externs nil "A list of any extern names you'd like to consider always declared. This list is global and is used by all `js2-mode' files. @@ -2446,11 +2449,12 @@ NAME can be a Lisp symbol or string. SYMBOL is a `js2-symbol'." len buffer))) "The root node of a js2 AST." - buffer ; the source buffer from which the code was parsed - comments ; a Lisp list of comments, ordered by start position - errors ; a Lisp list of errors found during parsing - warnings ; a Lisp list of warnings found during parsing - node-count); number of nodes in the tree, including the root + buffer ; the source buffer from which the code was parsed + comments ; a Lisp list of comments, ordered by start position + errors ; a Lisp list of errors found during parsing + warnings ; a Lisp list of warnings found during parsing + node-count ; number of nodes in the tree, including the root + in-strict-mode) ; t if the script is running under strict mode (put 'cl-struct-js2-ast-root 'js2-visitor 'js2-visit-ast-root) (put 'cl-struct-js2-ast-root 'js2-printer 'js2-print-script) @@ -3327,7 +3331,8 @@ The `params' field is a Lisp list of nodes. Each node is either a simple ignore-dynamic ; ignore value of the dynamic-scope flag (interpreter only) needs-activation ; t if we need an activation object for this frame generator-type ; STAR, LEGACY, COMPREHENSION or nil - member-expr) ; nonstandard Ecma extension from Rhino + member-expr ; nonstandard Ecma extension from Rhino + in-strict-mode) ; t if the function is running under strict mode (put 'cl-struct-js2-function-node 'js2-visitor 'js2-visit-function-node) (put 'cl-struct-js2-function-node 'js2-printer 'js2-print-function-node) @@ -7862,6 +7867,15 @@ Returns t on match, nil if no match." (defsubst js2-exit-switch () (pop js2-loop-and-switch-set)) +(defsubst js2-get-directive (node) + "Return NODE's value if it is a directive, nil otherwise. + +A directive is an otherwise-meaningless expression statement +consisting of a string literal, such as \"use strict\"." + (and (js2-expr-stmt-node-p node) + (js2-string-node-p (setq node (js2-expr-stmt-node-expr node))) + (js2-string-node-value node))) + (defun js2-parse (&optional buf cb) "Tell the js2 parser to parse a region of JavaScript. @@ -7923,14 +7937,18 @@ leaving a statement, an expression, or a function definition." Scanner should be initialized." (let ((pos js2-ts-cursor) (end js2-ts-cursor) ; in case file is empty -root n tt) +root n tt +(in-directive-prologue t) +(saved-strict-mode js2-in-use-strict-directive) +directive) ;; initialize buffer-local parsing vars (setf root (make-js2-ast-root :buffer (buffer-name) :pos pos) js2-current-script-or-fn root js2-current-scope root js2-nesting-of-function 0 js2-labeled-stmt nil - js2-recorded-identifiers nil) ; for js2-highlight + js2-recorded-identifiers nil ; for js2-highlight + js2-in-use-strict-directive nil) (while (/= (setq tt (js2-get-token)) js2-EOF) (if (= tt js2-FUNCTION) (progn @@ -7939,10 +7957,19 @@ Scanner should be initialized." (js2-parse-function-stmt ;; not a function - parse a statement (js2-unget-token) -(setq n (js2-parse-statement))) +(setq n (js2-parse-statement)) +(when in-directive-prologue + (setq directive (js2-get-directive n)) + (cond + ((null directive) +(setq in-directive-prologue nil)) + ((string= directive "use strict") +(setq js2-in-use-strict-directive t) +(setf (js2-ast-root-in-strict-mode root) t) ;; add function or statement to script (setq end (js2-node-end n)) (js2-block-node-push root n)) +(setq js2-in-use-strict-directive saved-strict-mode) ;; add comments to root in lexical order (when js2-scanned-comments ;; if we find a comment beyond end
[elpa] master 498bcca 21/33: Fix refactoring regression.
branch: master commit 498bcca61fc9718f1d9d6eb931d9095f39e452ad Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Fix refactoring regression. --- js2-mode.el | 18 +- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index e667df0..25071b7 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -8295,15 +8295,15 @@ arrow function), NAME is js2-name-node." ;;of the with object. (setf (js2-function-node-ignore-dynamic fn-node) t)) ;; dynamically bind all the per-function variables -(let ((js2-current-script-or-fn fn-node) - (js2-current-scope fn-node) - (js2-nesting-of-with 0) - (js2-end-flags 0) - js2-label-set - js2-loop-set - js2-loop-and-switch-set - (error-checking-arguments (js2-parse-function-params - function-type fn-node pos))) +(let* ((js2-current-script-or-fn fn-node) + (js2-current-scope fn-node) + (js2-nesting-of-with 0) + (js2-end-flags 0) + js2-label-set + js2-loop-set + js2-loop-and-switch-set + (error-checking-arguments (js2-parse-function-params + function-type fn-node pos))) (when (eq function-type 'FUNCTION_ARROW) (js2-must-match js2-ARROW "msg.bad.arrow.args")) (if (and (>= js2-language-version 180)
[elpa] master 7c423dd 10/33: Define const variables in the current block.
branch: master commit 7c423dd5ebcb5f2e89377feed463c2f26360dbdf Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Define const variables in the current block. --- js2-mode.el |7 --- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index fbbfeef..5804480 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -9430,14 +9430,15 @@ If NODE is non-nil, it is the AST node associated with the symbol." ((= sdt js2-FUNCTION) "msg.function.redecl") (t "msg.parm.redecl")) name pos len)) - ((= decl-type js2-LET) - (if (and (not ignore-not-in-block) + ((or (= decl-type js2-LET) + (= decl-type js2-CONST)) + (if (and (= decl-type js2-LET) + (not ignore-not-in-block) (or (= (js2-node-type js2-current-scope) js2-IF) (js2-loop-node-p js2-current-scope))) (js2-report-error "msg.let.decl.not.in.block") (js2-define-new-symbol decl-type name node))) ((or (= decl-type js2-VAR) - (= decl-type js2-CONST) (= decl-type js2-FUNCTION)) (if symbol (if (and js2-strict-var-redeclaration-warning (= sdt js2-VAR))
[elpa] master a632b02 04/33: Merge pull request #232 from jacksonrayhamilton/unset-identifiers
branch: master commit a632b0244c876103caf3ec735cb90d53ab5b2ddb Merge: d39764f 6d4aa28 Author: Dmitry Gutov Commit: Dmitry Gutov Merge pull request #232 from jacksonrayhamilton/unset-identifiers Don't unset `js2-recorded-identifiers' --- js2-mode.el |3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 54f9c19..082a5d0 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -7079,8 +7079,7 @@ it is considered declared." (member name js2-additional-externs) (js2-get-defining-scope scope name pos)) (js2-report-warning "msg.undeclared.variable" name pos (- end pos) - 'js2-external-variable -(setq js2-recorded-identifiers nil))) + 'js2-external-variable)) (defun js2-set-default-externs () "Set the value of `js2-default-externs' based on the various
[elpa] master c588e31 17/33: Duplicate object keys are an error in strict mode
branch: master commit c588e31dd71809699be373af1ca13367b252e352 Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Duplicate object keys are an error in strict mode --- js2-mode.el | 51 +++ tests/parser.el |4 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index fcb1dcc..14ec664 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -1793,6 +1793,9 @@ the correct number of ARGS must be provided." (js2-msg "msg.no.octal.strict" "Octal numbers prohibited in strict mode.") +(js2-msg "msg.dup.obj.lit.prop.strict" + "Property '%s' already defined in this object literal.") + (js2-msg "msg.dup.param.strict" "Parameter '%s' already declared in this function.") @@ -3975,10 +3978,11 @@ optional `js2-expr-node'" len left right op-pos))) "AST node for an object literal prop:value entry. -The `left' field is the property: a name node, string node or number node. -The `right' field is a `js2-node' representing the initializer value. -If the property is abbreviated, the node's `SHORTHAND' property is non-nil -and both fields have the same value.") +The `left' field is the property: a name node, string node, +number node or expression node. The `right' field is a +`js2-node' representing the initializer value. If the property +is abbreviated, the node's `SHORTHAND' property is non-nil and +both fields have the same value.") (put 'cl-struct-js2-object-prop-node 'js2-visitor 'js2-visit-infix-node) (put 'cl-struct-js2-object-prop-node 'js2-printer 'js2-print-object-prop-node) @@ -10663,11 +10667,27 @@ If ONLY-OF-P is non-nil, only the 'for (foo of bar)' form is allowed." (apply #'js2-node-add-children result (js2-object-node-elems result)) result)) +(defun js2-property-key-string (property-node) + "Return the key of PROPERTY-NODE (a `js2-object-prop-node' or +`js2-getter-setter-node') as a string, or nil if it can't be +represented as a string (e.g., the key is computed by an +expression)." + (let ((key (js2-infix-node-left property-node))) +(cond + ((js2-name-node-p key) + (js2-name-node-name key)) + ((js2-string-node-p key) + (js2-string-node-value key)) + ((js2-number-node-p key) + (js2-number-node-value key) + (defun js2-parse-object-literal-elems (&optional class-p) (let ((pos (js2-current-token-beg)) (static nil) (continue t) -tt elems elem after-comma previous-token) +tt elems elem +elem-key-string previous-elem-key-string +after-comma previous-token) (while continue (setq tt (js2-get-prop-name-token) static nil @@ -10726,8 +10746,22 @@ If ONLY-OF-P is non-nil, only the 'for (foo of bar)' form is allowed." (setq after-comma (js2-current-token-end))) (js2-unget-token) (unless class-p (setq continue nil - ;; Append any parsed element. - (if elem (push elem elems))) ; end loop + (when elem +(setq elem-key-string (js2-property-key-string elem)) +(when (and js2-in-use-strict-directive + elem-key-string + (cl-some +(lambda (previous-elem) + (and (setq previous-elem-key-string + (js2-property-key-string previous-elem)) + (string= previous-elem-key-string elem-key-string))) +elems)) + (js2-report-error "msg.dup.obj.lit.prop.strict" +elem-key-string +(js2-node-abs-pos (js2-infix-node-left elem)) +(js2-node-len (js2-infix-node-left elem +;; Append any parsed element. +(push elem elems))) ; end loop (js2-must-match js2-RC "msg.no.brace.prop") (nreverse elems))) @@ -10789,7 +10823,8 @@ When `js2-is-in-destructuring' is t, forms like {a, b, c} will be permitted." (defun js2-parse-plain-property (prop) "Parse a non-getter/setter property in an object literal. -PROP is the node representing the property: a number, name or string." +PROP is the node representing the property: a number, name, +string or expression." (let* ((tt (js2-get-token)) (pos (js2-node-pos prop)) colon expr result) diff --git a/tests/parser.el b/tests/parser.el index 0e92037..93c47ab 100644 --- a/tests/parser.el +++ b/tests/parser.el @@ -291,6 +291,10 @@ the test." "'use strict';\nvar number = 0644;" :syntax-error "0644" :errors-count 1) +(js2-deftest-parse function-strict-duplicate-keys + "'use strict';\nvar object = {a: 1, a: 2, 'a': 3, ['a']: 4, 1: 5, '1': 6, [1 + 1]: 7};" + :syntax-error "a" :errors-count 4) ; "a" has 3 dupes, "1" has 1 dupe. + ;;; Spread o
[elpa] master a5b586f 13/33: Test const scoping.
branch: master commit a5b586f22dace6436d133ba48a602203f485b9d6 Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Test const scoping. --- tests/parser.el | 37 + 1 files changed, 29 insertions(+), 8 deletions(-) diff --git a/tests/parser.el b/tests/parser.el index 1a93f36..8be0833 100644 --- a/tests/parser.el +++ b/tests/parser.el @@ -721,19 +721,40 @@ the test." (should (= (js2-symbol-decl-type var-entry) js2-VAR)) (should (js2-name-node-p (js2-symbol-ast-node var-entry) -(js2-deftest for-node-is-declaration-scope "for (let i = 0; i; ++i) {};" - (js2-mode) - (search-forward "i") +(defun js2-test-scope-of-nth-variable-satisifies-predicate (variable nth predicate) + (goto-char (point-min)) + (dotimes (n (1+ nth)) (search-forward variable)) (forward-char -1) (let ((scope (js2-node-get-enclosing-scope (js2-node-at-point -(should (js2-for-node-p (js2-get-defining-scope scope "i") +(should (funcall predicate (js2-get-defining-scope scope variable) + +(js2-deftest for-node-is-declaration-scope "for (let i = 0; i; ++i) {};" + (js2-mode) + (js2-test-scope-of-nth-variable-satisifies-predicate "i" 0 #'js2-for-node-p)) + +(js2-deftest const-scope-sloppy-script "{const a;} a;" + (js2-mode) + (js2-test-scope-of-nth-variable-satisifies-predicate "a" 0 #'js2-script-node-p) + (js2-test-scope-of-nth-variable-satisifies-predicate "a" 1 #'js2-script-node-p)) + +(js2-deftest const-scope-strict-script "'use strict'; { const a; } a;" + (js2-mode) + (js2-test-scope-of-nth-variable-satisifies-predicate "a" 0 #'js2-block-node-p) + (js2-test-scope-of-nth-variable-satisifies-predicate "a" 1 #'null)) + +(js2-deftest const-scope-sloppy-function "function f() { { const a; } a; }" + (js2-mode) + (js2-test-scope-of-nth-variable-satisifies-predicate "a" 0 #'js2-function-node-p) + (js2-test-scope-of-nth-variable-satisifies-predicate "a" 1 #'js2-function-node-p)) + +(js2-deftest const-scope-strict-function "function f() { 'use strict'; { const a; } a; }" + (js2-mode) + (js2-test-scope-of-nth-variable-satisifies-predicate "a" 0 #'js2-block-node-p) + (js2-test-scope-of-nth-variable-satisifies-predicate "a" 1 #'null)) (js2-deftest array-comp-is-result-scope "[x * 2 for (x in y)];" (js2-mode) - (search-forward "x") - (forward-char -1) - (let ((scope (js2-node-get-enclosing-scope (js2-node-at-point -(should (js2-comp-loop-node-p (js2-get-defining-scope scope "x") + (js2-test-scope-of-nth-variable-satisifies-predicate "x" 0 #'js2-comp-loop-node-p)) (js2-deftest array-comp-has-parent-scope "var a,b=[for (i of [[1,2]]) for (j of i) j * a];"
[elpa] master 6d4aa28 03/33: Don't unset `js2-recorded-identifiers'
branch: master commit 6d4aa286dfc8eb8d5ffbdcbfb575391ef829a108 Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Don't unset `js2-recorded-identifiers' --- js2-mode.el |3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 54f9c19..082a5d0 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -7079,8 +7079,7 @@ it is considered declared." (member name js2-additional-externs) (js2-get-defining-scope scope name pos)) (js2-report-warning "msg.undeclared.variable" name pos (- end pos) - 'js2-external-variable -(setq js2-recorded-identifiers nil))) + 'js2-external-variable)) (defun js2-set-default-externs () "Set the value of `js2-default-externs' based on the various
[elpa] master 88d7565 11/33: Respect strict mode.
branch: master commit 88d75654b22a10e061b1d7e13642ac74dba58b46 Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton Respect strict mode. --- js2-mode.el |9 +++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 5804480..e4b0ed4 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -9431,7 +9431,9 @@ If NODE is non-nil, it is the AST node associated with the symbol." (t "msg.parm.redecl")) name pos len)) ((or (= decl-type js2-LET) - (= decl-type js2-CONST)) + ;; strict mode const is scoped to the current LexicalEnvironment + (and js2-compiler-strict-mode + (= decl-type js2-CONST))) (if (and (= decl-type js2-LET) (not ignore-not-in-block) (or (= (js2-node-type js2-current-scope) js2-IF) @@ -9439,7 +9441,10 @@ If NODE is non-nil, it is the AST node associated with the symbol." (js2-report-error "msg.let.decl.not.in.block") (js2-define-new-symbol decl-type name node))) ((or (= decl-type js2-VAR) - (= decl-type js2-FUNCTION)) + (= decl-type js2-FUNCTION) + ;; sloppy mode const is scoped to the current VariableEnvironment + (and (not js2-compiler-strict-mode) + (= decl-type js2-CONST))) (if symbol (if (and js2-strict-var-redeclaration-warning (= sdt js2-VAR)) (js2-add-strict-warning "msg.var.redecl" name)
[elpa] master e6cb7bf 15/33: with statements are syntax errors in strict mode
branch: master commit e6cb7bfc53b100d484487850b18a82cc57464e4f Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton with statements are syntax errors in strict mode --- js2-mode.el |5 + tests/parser.el |6 ++ 2 files changed, 11 insertions(+), 0 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 12801bb..d47fc80 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -1671,6 +1671,9 @@ the correct number of ARGS must be provided." (js2-msg "msg.no.paren.after.with" "missing ) after with-statement object") +(js2-msg "msg.no.with.strict" + "with statements not allowed in strict mode") + (js2-msg "msg.no.paren.after.let" "missing ( after let") @@ -9141,6 +9144,8 @@ does not match an existing label, reports an error and returns nil." (defun js2-parse-with () "Parser for with-statement. Last matched token must be js2-WITH." + (when js2-in-use-strict-directive +(js2-report-error "msg.no.with.strict")) (let ((pos (js2-current-token-beg)) obj body pn lp rp) (if (js2-must-match js2-LP "msg.no.paren.with") diff --git a/tests/parser.el b/tests/parser.el index a3b693b..04a19c3 100644 --- a/tests/parser.el +++ b/tests/parser.el @@ -281,6 +281,12 @@ the test." "'use strict';\narguments = 'fufufu';" :syntax-error "arguments" :errors-count 1) +;;; Strict syntax errors + +(js2-deftest-parse function-strict-with + "'use strict';\nwith ({}) {}" + :syntax-error "with" :errors-count 1) + ;;; Spread operator (js2-deftest-parse spread-in-array-literal
[elpa] master 2763c9a 33/33: Merge commit 'f3a899bb1c36e25e078eed2890eb2fecb22f4175' from js2-mode
branch: master commit 2763c9abdc4a8d5769ff25126534d94d316d0278 Merge: af721ab f3a899b Author: Dmitry Gutov Commit: Dmitry Gutov Merge commit 'f3a899bb1c36e25e078eed2890eb2fecb22f4175' from js2-mode --- packages/js2-mode/NEWS.md |6 + packages/js2-mode/js2-mode.el | 685 - packages/js2-mode/tests/parser.el | 247 +- 3 files changed, 766 insertions(+), 172 deletions(-) diff --git a/packages/js2-mode/NEWS.md b/packages/js2-mode/NEWS.md index eea51d3..300bc84 100644 --- a/packages/js2-mode/NEWS.md +++ b/packages/js2-mode/NEWS.md @@ -1,5 +1,11 @@ # History of user-visible changes +## 20150713 + +* More comprehensive strict mode warnings and syntax errors. +* New minor mode: `js2-highlight-unused-variables-mode`. +* `js2-pretty-multiline-declarations` can take the value `dynamic` now. + ## 20150202 Support for: diff --git a/packages/js2-mode/js2-mode.el b/packages/js2-mode/js2-mode.el index 4fc2823..4a6e733 100644 --- a/packages/js2-mode/js2-mode.el +++ b/packages/js2-mode/js2-mode.el @@ -7,7 +7,7 @@ ;; Dmitry Gutov ;; URL: https://github.com/mooz/js2-mode/ ;; http://code.google.com/p/js2-mode/ -;; Version: 20150202 +;; Version: 20150713 ;; Keywords: languages, javascript ;; Package-Requires: ((emacs "24.1") (cl-lib "0.5")) @@ -188,7 +188,8 @@ Set `js2-include-rhino-externs' to t to include them.") (defvar js2-node-externs (mapcar 'symbol-name '(__dirname __filename Buffer clearInterval clearTimeout require -console exports global module process setInterval setTimeout)) +console exports global module process setInterval setTimeout +querystring)) "Node.js externs. Set `js2-include-node-externs' to t to include them.") @@ -735,6 +736,7 @@ List of chars built up while scanning various tokens.") (end -1) (string "") number + number-base regexp-flags comment-type follows-eol-p) @@ -832,6 +834,9 @@ Will only be used when we finish implementing the interpreter.") (js2-deflocal js2-is-in-destructuring nil "True while parsing destructuring expression.") +(js2-deflocal js2-in-use-strict-directive nil + "True while inside a script or function under strict mode.") + (defcustom js2-global-externs nil "A list of any extern names you'd like to consider always declared. This list is global and is used by all `js2-mode' files. @@ -1155,6 +1160,11 @@ another file, or you've got a potential bug." :type 'boolean :group 'js2-mode) +(defcustom js2-warn-about-unused-function-arguments nil + "Non-nil to treat function arguments like declared-but-unused variables." + :type 'booleanp + :group 'js2-mode) + (defcustom js2-include-jslint-globals t "Non-nil to include the identifiers from JSLint global declaration (see http://www.jslint.com/lint.html#global) in the @@ -1662,6 +1672,9 @@ the correct number of ARGS must be provided." (js2-msg "msg.no.paren.after.with" "missing ) after with-statement object") +(js2-msg "msg.no.with.strict" + "with statements not allowed in strict mode") + (js2-msg "msg.no.paren.after.let" "missing ( after let") @@ -1777,6 +1790,18 @@ the correct number of ARGS must be provided." (js2-msg "msg.destruct.assign.no.init" "Missing = in destructuring declaration") +(js2-msg "msg.no.octal.strict" + "Octal numbers prohibited in strict mode.") + +(js2-msg "msg.dup.obj.lit.prop.strict" + "Property '%s' already defined in this object literal.") + +(js2-msg "msg.dup.param.strict" + "Parameter '%s' already declared in this function.") + +(js2-msg "msg.bad.id.strict" + "'%s' is not a valid identifier for this use in strict mode.") + ;; ScriptRuntime (js2-msg "msg.no.properties" "%s has no properties.") @@ -1793,6 +1818,12 @@ the correct number of ARGS must be provided." (js2-msg "msg.undeclared.variable" ; added by js2-mode "Undeclared variable or function '%s'") +(js2-msg "msg.unused.variable" ; added by js2-mode + "Unused variable or function '%s'") + +(js2-msg "msg.uninitialized.variable" ; added by js2-mode + "Variable '%s' referenced but never initialized") + (js2-msg "msg.ref.undefined.prop" "Reference to undefined property '%s'") @@ -2173,17 +2204,6 @@ Returns nil if element is not found in the list." (defsubst js2-flag-not-set-p (flags flag) (zerop (logand flags flag))) -(defmacro js2-with-underscore-as-word-syntax (&rest body) - "Evaluate BODY with the _ character set to be word-syntax." - (declare (indent 0) (debug t)) - (let ((old-syntax (make-symbol "old-syntax"))) - `(let ((,old-syntax (string (char-syntax ?_ - (unwind-protect - (progn - (modify-syntax-entry ?_ "w" js2-mode-syntax-table) - ,@body) - (modify-syntax-entry ?_ ,old-syntax js2-mode-syntax-table) - ;;; AST struct and function definitions ;; flags for as
[elpa] master 09a86b2 09/33: js2-node-externs: Add querystring
branch: master commit 09a86b226ceccf40ad8d8f211eb50b4bbad8b84b Author: Dmitry Gutov Commit: Dmitry Gutov js2-node-externs: Add querystring --- js2-mode.el |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index c1aaa21..fbbfeef 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -188,7 +188,8 @@ Set `js2-include-rhino-externs' to t to include them.") (defvar js2-node-externs (mapcar 'symbol-name '(__dirname __filename Buffer clearInterval clearTimeout require -console exports global module process setInterval setTimeout)) +console exports global module process setInterval setTimeout +querystring)) "Node.js externs. Set `js2-include-node-externs' to t to include them.")
[elpa] master updated (af721ab -> 2763c9a)
dgutov pushed a change to branch master. from af721ab * ada-mode: Use lexical-binding since it requires Emacs-24.2 anyway new c13eda4 Generalize object literal parsing to support short-hand function/generator/getter/setter declarations with all kinds of keys (string, named, computed, numeric). new d39764f Merge pull request #231 from shicks/computed new 6d4aa28 Don't unset `js2-recorded-identifiers' new a632b02 Merge pull request #232 from jacksonrayhamilton/unset-identifiers new 709ff60 Add a NEWS entry for d4d9c54 new d6e6cd6 Fix object keys highlighting (closes #234) new 254c78c Highlight unused and/or uninitialized variables new 422be2d Add NEWS entry new 09a86b2 js2-node-externs: Add querystring new 7c423dd Define const variables in the current block. new 88d7565 Respect strict mode. new 1277c7d Track script and function strict mode. new a5b586f Test const scoping. new e0ecf99 Check identifiers in strict mode. new e6cb7bf with statements are syntax errors in strict mode new ac205a4 Octal syntax is an error in strict mode new c588e31 Duplicate object keys are an error in strict mode new 6255edb Cleanup new f1edac7 Don't treat a block-scoped const as redeclaration new ad4c5cc Report the correct octal number error new 498bcca Fix refactoring regression. new 1391f2e setq inline new 46e1492 Reparse strict functions. new 663efb1 Remove strict mode slots on nodes. new 7850d12 Cleanup new 2469440 Fix bug where properties where checked for strict mode compliance new 5e5df54 Merge pull request #242 from jacksonrayhamilton/strict-mode new 12e5a21 Remove js2-current-indent new eb33e68 Get rid of js2-with-underscore-as-word-syntax new 5b25da2 Add NEWS entry and bump version new 53f3f52 Actually remove the macro new f3a899b And actually update NEWS new 2763c9a Merge commit 'f3a899bb1c36e25e078eed2890eb2fecb22f4175' from js2-mode Summary of changes: packages/js2-mode/NEWS.md |6 + packages/js2-mode/js2-mode.el | 685 - packages/js2-mode/tests/parser.el | 247 +- 3 files changed, 766 insertions(+), 172 deletions(-)
[elpa] master 1391f2e 22/33: setq inline
branch: master commit 1391f2e8e3f3d29c5c5c0def6206fc4b0077ae40 Author: Jackson Ray Hamilton Commit: Jackson Ray Hamilton setq inline --- js2-mode.el | 25 +++-- 1 files changed, 15 insertions(+), 10 deletions(-) diff --git a/js2-mode.el b/js2-mode.el index 25071b7..660da2c 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -8063,13 +8063,10 @@ Scanner should be initialized." (js2-node-add-children fn-node pn) pn)) -(defun js2-define-destruct-symbols +(defun js2-define-destruct-symbols-internal (node decl-type face &optional ignore-not-in-block name-nodes) - "Declare and fontify destructuring parameters inside NODE. -NODE is either `js2-array-node', `js2-object-node', or `js2-name-node'. - -Return a list of `js2-name-node' nodes representing the symbols -declared; probably to check them for errors." + "Internal version of `js2-define-destruct-symbols'. The only +difference is that NAME-NODES is passed down recursively." (cond ((js2-name-node-p node) (let (leftpos) @@ -8084,7 +8081,7 @@ declared; probably to check them for errors." (dolist (elem (js2-object-node-elems node)) (setq name-nodes (append name-nodes -(js2-define-destruct-symbols +(js2-define-destruct-symbols-internal ;; In abbreviated destructuring {a, b}, right == left. (js2-object-prop-node-right elem) decl-type face ignore-not-in-block name-nodes) @@ -8093,12 +8090,21 @@ declared; probably to check them for errors." (when elem (setq name-nodes (append name-nodes - (js2-define-destruct-symbols + (js2-define-destruct-symbols-internal elem decl-type face ignore-not-in-block name-nodes)) (t (js2-report-error "msg.no.parm" nil (js2-node-abs-pos node) (js2-node-len node name-nodes) +(defun js2-define-destruct-symbols (node decl-type face &optional ignore-not-in-block) + "Declare and fontify destructuring parameters inside NODE. +NODE is either `js2-array-node', `js2-object-node', or `js2-name-node'. + +Return a list of `js2-name-node' nodes representing the symbols +declared; probably to check them for errors." + (funcall #'js2-define-destruct-symbols-internal + node decl-type face ignore-not-in-block)) + (defvar js2-illegal-strict-identifiers '("eval" "arguments") "Identifiers not allowed as variables in strict mode.") @@ -10755,9 +10761,8 @@ expression)." (js2-unget-token) (unless class-p (setq continue nil (when elem -(setq elem-key-string (js2-property-key-string elem)) (when (and js2-in-use-strict-directive - elem-key-string + (setq elem-key-string (js2-property-key-string elem)) (cl-some (lambda (previous-elem) (and (setq previous-elem-key-string
[elpa] master 422be2d 08/33: Add NEWS entry
branch: master commit 422be2dd68974ac84d5e6b70d321b5a524059215 Author: Dmitry Gutov Commit: Dmitry Gutov Add NEWS entry --- NEWS.md |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/NEWS.md b/NEWS.md index 0ca9029..3673503 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,7 @@ ## Next +* New minor mode: `js2-highlight-unused-variables-mode`. * `js2-pretty-multiline-declarations` can take the value `dynamic` now. ## 20150202