(defun js2-print-function-node (n i)
(let* ((pad (js2-make-pad i))
- (getter (js2-node-get-prop n 'GETTER_SETTER))
+ (method (js2-node-get-prop n 'METHOD_TYPE))
(name (or (js2-function-node-name n)
(js2-function-node-member-expr n)))
(params (js2-function-node-params n))
(rest-p (js2-function-node-rest-p n))
(body (js2-function-node-body n))
(expr (not (eq (js2-function-node-form n) 'FUNCTION_STATEMENT))))
- (unless (or getter arrow)
+ (unless (or method arrow)
(insert pad "function")
(when (eq (js2-function-node-generator-type n) 'STAR)
(insert "*")))
(insert ": ")
(js2-print-ast right 0)))))
-(cl-defstruct (js2-getter-setter-node
+(cl-defstruct (js2-method-node
(:include js2-infix-node)
(:constructor nil)
- (:constructor make-js2-getter-setter-node (&key type ; GET, SET, or FUNCTION
- (pos js2-ts-cursor)
- len left right)))
- "AST node for a getter/setter property in an object literal.
-The `left' field is the `js2-name-node' naming the getter/setter prop.
+ (:constructor make-js2-method-node (&key type ; GET, SET, or FUNCTION
+ (pos js2-ts-cursor)
+ len left right)))
+ "AST node for a method in an object literal or a class body.
+The `left' field is the `js2-name-node' naming the method.
The `right' field is always an anonymous `js2-function-node' with a node
-property `GETTER_SETTER' set to js2-GET, js2-SET, or js2-FUNCTION. ")
+property `METHOD_TYPE' set to js2-GET, js2-SET, or js2-FUNCTION. ")
-(put 'cl-struct-js2-getter-setter-node 'js2-visitor 'js2-visit-infix-node)
-(put 'cl-struct-js2-getter-setter-node 'js2-printer 'js2-print-getter-setter)
+(put 'cl-struct-js2-method-node 'js2-visitor 'js2-visit-infix-node)
+(put 'cl-struct-js2-method-node 'js2-printer 'js2-print-method)
-(defun js2-print-getter-setter (n i)
+(defun js2-print-method (n i)
(let* ((pad (js2-make-pad i))
- (left (js2-getter-setter-node-left n))
- (right (js2-getter-setter-node-right n)))
+ (left (js2-method-node-left n))
+ (right (js2-method-node-right n)))
(insert pad)
(if (/= (js2-node-type n) js2-FUNCTION)
(insert (if (= (js2-node-type n) js2-GET) "get " "set ")))
(list node)))
((js2-object-node-p node)
(dolist (elem (js2-object-node-elems node))
- (when (js2-object-prop-node-p elem)
+ ;; js2-infix-node-p catches both object prop node and initialized
+ ;; binding element (which is directly an infix node).
+ (when (js2-infix-node-p elem)
(push (js2-define-destruct-symbols
- ;; In abbreviated destructuring {a, b}, right == left.
- (js2-object-prop-node-right elem)
+ (js2-infix-node-left elem)
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))
(when elem
+ (if (js2-infix-node-p elem) (setq elem (js2-infix-node-left elem)))
(push (js2-define-destruct-symbols
elem decl-type face ignore-not-in-block)
name-nodes)))
(js2-node-add-children pn test-expr if-true if-false))
pn))
-(defun js2-make-binary (type left parser)
+(defun js2-make-binary (type left parser &optional no-get)
"Helper for constructing a binary-operator AST node.
LEFT is the left-side-expression, already parsed, and the
binary operator should have just been matched.
(op-pos (- (js2-current-token-beg) pos))
(right (if (js2-node-p parser)
parser
- (js2-get-token)
+ (unless no-get (js2-get-token))
(funcall parser)))
(pn (make-js2-infix-node :type type
:pos pos
(apply #'js2-node-add-children pn (js2-array-node-elems pn)))
;; destructuring binding
(js2-is-in-destructuring
- (push (if (or (= tt js2-LC)
- (= tt js2-LB)
- (= tt js2-NAME))
- ;; [a, b, c] | {a, b, c} | {a:x, b:y, c:z} | a
- (js2-parse-destruct-primary-expr)
- ;; invalid pattern
+ (push (cond
+ ((and (= tt js2-NAME)
+ (= js2-ASSIGN (js2-peek-token)))
+ ;; a=defaultValue
+ (js2-parse-initialized-binding (js2-parse-name js2-NAME)))
+ ((or (= tt js2-LC)
+ (= tt js2-LB)
+ (= tt js2-NAME))
+ ;; [a, b, c] | {a, b, c} | {a:x, b:y, c:z} | a
+ (js2-parse-destruct-primary-expr))
+ ;; invalid pattern
+ (t
(js2-report-error "msg.bad.var")
- (make-js2-error-node))
+ (make-js2-error-node)))
elems)
(setq after-lb-or-comma nil
after-comma nil))
(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
+`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)))
(if after-comma
(js2-parse-warn-trailing-comma "msg.extra.trailing.comma"
pos elems after-comma)))
+ ;; Skip semicolons in a class body
+ ((and class-p
+ (= tt js2-SEMI))
+ nil)
(t
(js2-report-error "msg.bad.prop")
(unless js2-recover-from-parse-errors
;; Check if the property is a duplicate.
(string= previous-elem-key-string elem-key-string)
;; But make an exception for getter / setter pairs.
- (not (and (js2-getter-setter-node-p elem)
- (js2-getter-setter-node-p previous-elem)
- (/= (js2-getter-setter-node-type elem)
- (js2-getter-setter-node-type previous-elem))))))
+ (not (and (js2-method-node-p elem)
+ (js2-method-node-p previous-elem)
+ (/= (js2-method-node-type elem)
+ (js2-method-node-type previous-elem))))))
elems))
(js2-report-error "msg.dup.obj.lit.prop.strict"
elem-key-string
(>= js2-language-version 200))
(when (js2-name-node-p key) ; highlight function name properties
(js2-record-face 'font-lock-function-name-face))
- (js2-parse-getter-setter-prop pos key property-type))
+ (js2-parse-method-prop pos key property-type))
+ ;; binding element with initializer
+ ((and (= (js2-peek-token) js2-ASSIGN)
+ (>= js2-language-version 200))
+ (js2-parse-initialized-binding key))
;; regular prop
(t
(let ((beg (js2-current-token-beg))
'record)
expr)))))
+(defun js2-parse-initialized-binding (name)
+ "Parse a `SingleNameBinding' with initializer.
+
+`name' is the `BindingIdentifier'."
+ (when (js2-match-token js2-ASSIGN)
+ (js2-make-binary js2-ASSIGN name 'js2-parse-assign-expr t)))
+
(defun js2-parse-prop-name (tt)
(cond
;; Literal string keys: {'foo': 'bar'}
(js2-node-add-children result prop expr)
result))))
-(defun js2-parse-getter-setter-prop (pos prop type-string)
- "Parse getter or setter property in an object literal.
+(defun js2-parse-method-prop (pos prop type-string)
+ "Parse method property in an object literal or a class body.
JavaScript syntax is:
- { get foo() {...}, set foo(x) {...} }
+ { foo(...) {...}, get foo() {...}, set foo(x) {...}, *foo(...) {...} }
and expression closure style is also supported
(js2-report-error "msg.bad.prop")
(if (cl-plusp (length (js2-function-name fn)))
(js2-report-error "msg.bad.prop")))
- (js2-node-set-prop fn 'GETTER_SETTER type) ; for codegen
+ (js2-node-set-prop fn 'METHOD_TYPE type) ; for codegen
(when (string= type-string "*")
(setf (js2-function-node-generator-type fn) 'STAR))
(setq end (js2-node-end fn)
- result (make-js2-getter-setter-node :type type
- :pos pos
- :len (- end pos)
- :left prop
- :right fn))
+ result (make-js2-method-node :type type
+ :pos pos
+ :len (- end pos)
+ :left prop
+ :right fn))
(js2-node-add-children result prop fn)
result))