X-Git-Url: https://code.delx.au/gnu-emacs-elpa/blobdiff_plain/12586e57f6c2ee480a5fbb4beee3919aadf32ad3..66fe8de8e9b0ac501d29c613f365353262868eb5:/js2-mode.el diff --git a/js2-mode.el b/js2-mode.el index e804fbbb1..ba492d7c2 100644 --- a/js2-mode.el +++ b/js2-mode.el @@ -277,6 +277,11 @@ end of the line, otherwise, at the beginning of the next line." :type 'boolean :group 'js2-mode) +(defcustom js2-mode-assume-strict nil + "Non-nil to start files in strict mode automatically." + :type 'boolean + :group 'js2-mode) + (defcustom js2-mode-show-strict-warnings t "Non-nil to emit Ecma strict-mode warnings. Some of the warnings can be individually disabled by other flags, @@ -1456,7 +1461,7 @@ the correct number of ARGS must be provided." "Compilation produced %s syntax errors.") (js2-msg "msg.var.redecl" - "TypeError: redeclaration of var %s.") + "Redeclaration of var %s.") (js2-msg "msg.const.redecl" "TypeError: redeclaration of const %s.") @@ -7456,22 +7461,23 @@ We do a depth-first traversal of NODE. For any functions we find, we append the property name to QNAME, then call `js2-record-imenu-entry'." (let (right) (dolist (e (js2-object-node-elems node)) ; e is a `js2-object-prop-node' - (let ((left (js2-infix-node-left e)) - ;; Element positions are relative to the parent position. - (pos (+ pos (js2-node-pos e)))) - (cond - ;; foo: function() {...} - ((js2-function-node-p (setq right (js2-infix-node-right e))) - (when (js2-prop-node-name left) - ;; As a policy decision, we record the position of the property, - ;; not the position of the `function' keyword, since the property - ;; is effectively the name of the function. - (js2-record-imenu-entry right (append qname (list left)) pos))) - ;; foo: {object-literal} -- add foo to qname, offset position, and recurse - ((js2-object-node-p right) - (js2-record-object-literal right - (append qname (list (js2-infix-node-left e))) - (+ pos (js2-node-pos right))))))))) + (when (js2-infix-node-p e) + (let ((left (js2-infix-node-left e)) + ;; Element positions are relative to the parent position. + (pos (+ pos (js2-node-pos e)))) + (cond + ;; foo: function() {...} + ((js2-function-node-p (setq right (js2-infix-node-right e))) + (when (js2-prop-node-name left) + ;; As a policy decision, we record the position of the property, + ;; not the position of the `function' keyword, since the property + ;; is effectively the name of the function. + (js2-record-imenu-entry right (append qname (list left)) pos))) + ;; foo: {object-literal} -- add foo to qname, offset position, and recurse + ((js2-object-node-p right) + (js2-record-object-literal right + (append qname (list (js2-infix-node-left e))) + (+ pos (js2-node-pos right)))))))))) (defun js2-node-top-level-decl-p (node) "Return t if NODE's name is defined in the top-level scope. @@ -7987,7 +7993,7 @@ Scanner should be initialized." js2-nesting-of-function 0 js2-labeled-stmt nil js2-recorded-identifiers nil ; for js2-highlight - js2-in-use-strict-directive nil) + js2-in-use-strict-directive js2-mode-assume-strict) (while (/= (setq tt (js2-get-token)) js2-EOF) (if (= tt js2-FUNCTION) (progn @@ -8098,21 +8104,25 @@ declared; probably to check them for errors." (list node))) ((js2-object-node-p node) (dolist (elem (js2-object-node-elems node)) - ;; js2-infix-node-p catches both object prop node and initialized - ;; binding element (which is directly an infix node). - (cond - ((js2-object-prop-node-p elem) - (push (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)) - ;; Destructuring with default argument. - ((js2-infix-node-p elem) - (push (js2-define-destruct-symbols - (js2-infix-node-left elem) - decl-type face ignore-not-in-block) - name-nodes)))) + (let ((subexpr (cond + ((and (js2-infix-node-p elem) + (= js2-ASSIGN (js2-infix-node-type elem))) + ;; Destructuring with default argument. + (js2-infix-node-left elem)) + ((and (js2-infix-node-p elem) + (= js2-COLON (js2-infix-node-type elem))) + ;; In regular destructuring {a: aa, b: bb}, + ;; the var is on the right. In abbreviated + ;; destructuring {a, b}, right == left. + (js2-infix-node-right elem)) + ((and (js2-unary-node-p elem) + (= js2-TRIPLEDOT (js2-unary-node-type elem))) + ;; Destructuring with spread. + (js2-unary-node-operand elem))))) + (when subexpr + (push (js2-define-destruct-symbols + subexpr decl-type face ignore-not-in-block) + name-nodes)))) (apply #'append (nreverse name-nodes))) ((js2-array-node-p node) (dolist (elem (js2-array-node-elems node)) @@ -9600,16 +9610,10 @@ If NODE is non-nil, it is the AST node associated with the symbol." (pos (if node (js2-node-abs-pos node))) (len (if node (js2-node-len node)))) (cond - ((and symbol ; already defined - (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)))) + ((and symbol ; already defined in this block + (or (= sdt js2-LET) + (= sdt js2-CONST)) + (eq defining-scope js2-current-scope)) (js2-report-error (cond ((= sdt js2-CONST) "msg.const.redecl") @@ -9619,9 +9623,7 @@ 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) - ;; strict mode const is scoped to the current LexicalEnvironment - (and js2-in-use-strict-directive - (= decl-type js2-CONST))) + (= decl-type js2-CONST)) (if (and (= decl-type js2-LET) (not ignore-not-in-block) (or (= (js2-node-type js2-current-scope) js2-IF) @@ -9629,10 +9631,7 @@ 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) - ;; sloppy mode const is scoped to the current VariableEnvironment - (and (not js2-in-use-strict-directive) - (= decl-type js2-CONST))) + (= decl-type js2-FUNCTION)) (if symbol (if (and js2-strict-var-redeclaration-warning (= sdt js2-VAR)) (js2-add-strict-warning "msg.var.redecl" name) @@ -10738,16 +10737,19 @@ If ONLY-OF-P is non-nil, only the 'for (foo of bar)' form is allowed." `js2-method-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))) - (when (js2-computed-prop-name-node-p key) - (setq key (js2-computed-prop-name-node-expr key))) - (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))))) + (cond + ((js2-unary-node-p property-node) nil) ;; {...foo} + (t + (let ((key (js2-infix-node-left property-node))) + (when (js2-computed-prop-name-node-p key) + (setq key (js2-computed-prop-name-node-expr key))) + (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)) @@ -10782,7 +10784,13 @@ expression)." (setq previous-token (js2-current-token) tt (js2-get-prop-name-token)))) (cond - ;; Found a property (of any sort) + ;; Rest/spread (...expr) + ((and (>= js2-language-version 200) + (not class-p) (not static) (not previous-token) + (= js2-TRIPLEDOT tt)) + (setq after-comma nil + elem (js2-make-unary js2-TRIPLEDOT 'js2-parse-assign-expr))) + ;; Found a key/value 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 previous-token))