[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master ec7932d 047/110: Merge pull request #283 from XeCycle/mast
From: |
Dmitry Gutov |
Subject: |
[elpa] master ec7932d 047/110: Merge pull request #283 from XeCycle/master-with-async |
Date: |
Thu, 23 Jun 2016 01:12:56 +0000 (UTC) |
branch: master
commit ec7932da4ca5aaff8b8ab26ad27b361fa18d5d54
Merge: f652d17 d0e4323
Author: Dmitry Gutov <address@hidden>
Commit: Dmitry Gutov <address@hidden>
Merge pull request #283 from XeCycle/master-with-async
Adapt old async to master & async methods
---
NEWS.md | 9 +--
js2-mode.el | 175 ++++++++++++++++++++++++++++++++++++++++---------------
tests/parser.el | 61 +++++++++++++++++++
3 files changed, 195 insertions(+), 50 deletions(-)
diff --git a/NEWS.md b/NEWS.md
index 33ba376..a916356 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -4,15 +4,16 @@
* Object properties are highlighted using a different face:
`js2-object-property`, which has no color by default.
-* `js2-getter-setter-node` is renamed to `js2-method-node`, together
- with its related functions. It already handles generator methods,
- and will in the future add support for async methods, so the old
- name will get more confusing.
+* `js2-getter-setter-node` is renamed to `js2-method-node`, together with
+ its related functions. It already handles generator methods, and we
+ added support for async methods (see below), so the old name will get
+ more confusing.
* Support for default parameters in destructuring. It should work for both
objects and arrays, in both literals and function arguments.
* New mode: `js2-jsx-mode`, deriving from `js2-mode`. Supports indentation of
JSXElement expressions wrapped within parentheses or as function arguments.
Indentation is customizable via `sgml-attribute-offset`.
+* Experimental support for ES7 stage 3 async/await.
## 20150909
diff --git a/js2-mode.el b/js2-mode.el
index 1cf19b8..c7af462 100644
--- a/js2-mode.el
+++ b/js2-mode.el
@@ -617,7 +617,9 @@ which doesn't seem particularly useful, but Rhino permits
it."
(defvar js2-NO_SUBS_TEMPLATE 167) ; template literal without substitutions
(defvar js2-TAGGED_TEMPLATE 168) ; tagged template literal
-(defconst js2-num-tokens (1+ js2-TAGGED_TEMPLATE))
+(defvar js2-AWAIT 169) ; await (pseudo keyword)
+
+(defconst js2-num-tokens (1+ js2-AWAIT))
(defconst js2-debug-print-trees nil)
@@ -1363,6 +1365,9 @@ the correct number of ARGS must be provided."
(js2-msg "msg.yield.parenthesized"
"yield expression must be parenthesized.")
+(js2-msg "msg.bad.await"
+ "await must be in async functions.")
+
;; NativeGlobal
(js2-msg "msg.cant.call.indirect"
"Function '%s' must be called directly, and not by way of a "
@@ -3257,6 +3262,7 @@ a `js2-label-node' or the innermost enclosing loop.")
params rest-p
body
generator-type
+ async
lp rp)))
"AST node for a function declaration.
The `params' field is a Lisp list of nodes. Each node is either a simple
@@ -3273,6 +3279,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
+ async ; t if the function is defined as `async function`
member-expr) ; nonstandard Ecma extension from Rhino
(put 'cl-struct-js2-function-node 'js2-visitor 'js2-visit-function-node)
@@ -3294,8 +3301,10 @@ The `params' field is a Lisp list of nodes. Each node
is either a simple
(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 method arrow)
- (insert pad "function")
+ (unless method
+ (insert pad)
+ (when (js2-function-node-async n) (insert "async "))
+ (unless arrow (insert "function"))
(when (eq (js2-function-node-generator-type n) 'STAR)
(insert "*")))
(when name
@@ -3466,6 +3475,7 @@ The type field inherited from `js2-node' holds the
operator."
(cons js2-TYPEOF "typeof")
(cons js2-INSTANCEOF "instanceof")
(cons js2-DELPROP "delete")
+ (cons js2-AWAIT "await")
(cons js2-COMMA ",")
(cons js2-COLON ":")
(cons js2-OR "||")
@@ -3546,7 +3556,7 @@ The type field holds the actual assignment operator.")
len operand)))
"AST node type for unary operator nodes.
The type field can be NOT, BITNOT, POS, NEG, INC, DEC,
-TYPEOF, DELPROP or TRIPLEDOT. For INC or DEC, a 'postfix node
+TYPEOF, DELPROP, TRIPLEDOT or AWAIT. For INC or DEC, a 'postfix node
property is added if the operator follows the operand."
operand) ; a `js2-node' expression
@@ -3566,7 +3576,8 @@ property is added if the operator follows the operand."
(unless postfix
(insert op))
(if (or (= tt js2-TYPEOF)
- (= tt js2-DELPROP))
+ (= tt js2-DELPROP)
+ (= tt js2-AWAIT))
(insert " "))
(js2-print-ast (js2-unary-node-operand n) 0)
(when postfix
@@ -3951,13 +3962,12 @@ both fields have the same value.")
(cl-defstruct (js2-method-node
(:include js2-infix-node)
(:constructor nil)
- (:constructor make-js2-method-node (&key type ; GET, SET, or
FUNCTION
- (pos js2-ts-cursor)
+ (:constructor make-js2-method-node (&key (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 `METHOD_TYPE' set to js2-GET, js2-SET, or js2-FUNCTION. ")
+property `METHOD_TYPE' set to 'GET or 'SET. ")
(put 'cl-struct-js2-method-node 'js2-visitor 'js2-visit-infix-node)
(put 'cl-struct-js2-method-node 'js2-printer 'js2-print-method)
@@ -3965,10 +3975,14 @@ property `METHOD_TYPE' set to js2-GET, js2-SET, or
js2-FUNCTION. ")
(defun js2-print-method (n i)
(let* ((pad (js2-make-pad i))
(left (js2-method-node-left n))
- (right (js2-method-node-right n)))
+ (right (js2-method-node-right n))
+ (type (js2-node-get-prop right 'METHOD_TYPE)))
(insert pad)
- (if (/= (js2-node-type n) js2-FUNCTION)
- (insert (if (= (js2-node-type n) js2-GET) "get " "set ")))
+ (when type
+ (insert (cdr (assoc type '((GET . "get ")
+ (SET . "set ")
+ (ASYNC . "async ")
+ (FUNCTION . ""))))))
(when (and (js2-function-node-p right)
(eq 'STAR (js2-function-node-generator-type right)))
(insert "*"))
@@ -5134,6 +5148,8 @@ You should use `js2-print-tree' instead of this function."
(or (js2-node-has-side-effects expr)
(when (js2-string-node-p expr)
(member (js2-string-node-value expr) '("use strict" "use
asm"))))))
+ ((= tt js2-AWAIT)
+ (js2-node-has-side-effects (js2-unary-node-operand node)))
((= tt js2-COMMA)
(js2-node-has-side-effects (js2-infix-node-right node)))
((or (= tt js2-AND)
@@ -7709,12 +7725,43 @@ Returns nil and consumes nothing if MATCH is not the
next token."
(defun js2-match-contextual-kwd (name)
"Consume and return t if next token is `js2-NAME', and its
string is NAME. Returns nil and keeps current token otherwise."
- (if (or (/= (js2-get-token) js2-NAME)
- (not (string= (js2-current-token-string) name)))
- (progn
- (js2-unget-token)
- nil)
+ (if (js2-contextual-kwd-p (progn (js2-get-token)
+ (js2-current-token))
+ name)
+ (progn (js2-record-face 'font-lock-keyword-face) t)
+ (js2-unget-token)
+ nil))
+
+(defun js2-contextual-kwd-p (token name)
+ "Return t if TOKEN is `js2-NAME', and its string is NAME."
+ (and (= (js2-token-type token) js2-NAME)
+ (string= (js2-token-string token) name)))
+
+(defun js2-match-async-function ()
+ (when (and (js2-contextual-kwd-p (js2-current-token) "async")
+ (= (js2-peek-token) js2-FUNCTION))
(js2-record-face 'font-lock-keyword-face)
+ (js2-get-token)
+ t))
+
+(defun js2-match-async-arrow-function ()
+ (when (and (js2-contextual-kwd-p (js2-current-token) "async")
+ (/= (js2-peek-token) js2-FUNCTION))
+ (js2-record-face 'font-lock-keyword-face)
+ (js2-get-token)
+ t))
+
+(defun js2-match-await ()
+ (when (and (= tt js2-NAME)
+ (js2-contextual-kwd-p (js2-current-token) "await"))
+ (js2-record-face 'font-lock-keyword-face)
+ (let ((beg (js2-current-token-beg))
+ (end (js2-current-token-end)))
+ (js2-get-token)
+ (unless (and (js2-inside-function)
+ (js2-function-node-async js2-current-script-or-fn))
+ (js2-report-error "msg.bad.await" nil
+ beg (- end beg))))
t))
(defun js2-get-prop-name-token ()
@@ -8151,7 +8198,7 @@ Last token scanned is the close-curly for the function
body."
(js2-name-node-name name) pos end)
(js2-add-strict-warning "msg.anon.no.return.value" nil pos end)))))
-(defun js2-parse-function-stmt ()
+(defun js2-parse-function-stmt (&optional async-p)
(let ((pos (js2-current-token-beg))
(star-p (js2-match-token js2-MUL)))
(js2-must-match-name "msg.unnamed.function.stmt")
@@ -8159,28 +8206,31 @@ Last token scanned is the close-curly for the function
body."
pn member-expr)
(cond
((js2-match-token js2-LP)
- (js2-parse-function 'FUNCTION_STATEMENT pos star-p name))
+ (js2-parse-function 'FUNCTION_STATEMENT pos star-p async-p name))
(js2-allow-member-expr-as-function-name
(setq member-expr (js2-parse-member-expr-tail nil name))
(js2-parse-highlight-member-expr-fn-name member-expr)
(js2-must-match js2-LP "msg.no.paren.parms")
- (setf pn (js2-parse-function 'FUNCTION_STATEMENT pos star-p)
+ (setf pn (js2-parse-function 'FUNCTION_STATEMENT pos star-p async-p)
(js2-function-node-member-expr pn) member-expr)
pn)
(t
(js2-report-error "msg.no.paren.parms")
(make-js2-error-node))))))
-(defun js2-parse-function-expr ()
+(defun js2-parse-async-function-stmt ()
+ (js2-parse-function-stmt t))
+
+(defun js2-parse-function-expr (&optional async-p)
(let ((pos (js2-current-token-beg))
(star-p (js2-match-token js2-MUL))
name)
(when (js2-match-token js2-NAME)
(setq name (js2-create-name-node t)))
(js2-must-match js2-LP "msg.no.paren.parms")
- (js2-parse-function 'FUNCTION_EXPRESSION pos star-p name)))
+ (js2-parse-function 'FUNCTION_EXPRESSION pos star-p async-p name)))
-(defun js2-parse-function-internal (function-type pos star-p &optional name)
+(defun js2-parse-function-internal (function-type pos star-p &optional async-p
name)
(let (fn-node lp)
(if (= (js2-current-token-type) js2-LP) ; eventually matched LP?
(setq lp (js2-current-token-beg)))
@@ -8188,7 +8238,8 @@ Last token scanned is the close-curly for the function
body."
:name name
:form function-type
:lp (if lp (- lp pos))
- :generator-type (and star-p 'STAR)))
+ :generator-type (and star-p 'STAR)
+ :async async-p))
(when name
(js2-set-face (js2-node-pos name) (js2-node-end name)
'font-lock-function-name-face 'record)
@@ -8243,7 +8294,7 @@ Last token scanned is the close-curly for the function
body."
(setf (js2-scope-parent-scope fn-node) js2-current-scope)
fn-node))
-(defun js2-parse-function (function-type pos star-p &optional name)
+(defun js2-parse-function (function-type pos star-p &optional async-p name)
"Function parser. FUNCTION-TYPE is a symbol, POS is the
beginning of the first token (function keyword, unless it's an
arrow function), NAME is js2-name-node."
@@ -8259,7 +8310,7 @@ arrow function), NAME is js2-name-node."
(setq ts-state (make-js2-ts-state))
(setq continue (catch 'reparse
(setq fn-node (js2-parse-function-internal
- function-type pos star-p name))
+ function-type pos star-p async-p name))
;; Don't continue.
nil))
(when continue
@@ -8369,9 +8420,12 @@ node are given relative start positions and correct
lengths."
(defun js2-statement-helper ()
(let* ((tt (js2-get-token))
(first-tt tt)
+ (async-stmt (js2-match-async-function))
(parser (if (= tt js2-ERROR)
#'js2-parse-semi
- (aref js2-parsers tt)))
+ (if async-stmt
+ #'js2-parse-async-function-stmt
+ (aref js2-parsers tt))))
pn)
;; If the statement is set, then it's been told its label by now.
(and js2-labeled-stmt
@@ -8380,7 +8434,8 @@ node are given relative start positions and correct
lengths."
(setq pn (funcall parser))
;; Don't do auto semi insertion for certain statement types.
(unless (or (memq first-tt js2-no-semi-insertion)
- (js2-labeled-stmt-node-p pn))
+ (js2-labeled-stmt-node-p pn)
+ async-stmt)
(js2-auto-insert-semicolon pn))
pn))
@@ -9583,9 +9638,20 @@ If NODE is non-nil, it is the AST node associated with
the symbol."
(let ((tt (js2-get-token))
(pos (js2-current-token-beg))
pn left right op-pos
- ts-state recorded-identifiers parsed-errors)
+ ts-state recorded-identifiers parsed-errors
+ async-p)
(if (= tt js2-YIELD)
(js2-parse-return-or-yield tt t)
+ ;; TODO(mooz): Bit confusing.
+ ;; If we meet `async` token and it's not part of `async
+ ;; function`, then this `async` is for a succeeding async arrow
+ ;; function.
+ ;; Since arrow function parsing doesn't rely on neither
+ ;; `js2-parse-function-stmt' nor `js2-parse-function-expr' that
+ ;; interpret `async` token, we trash `async` and just remember
+ ;; we met `async` keyword to `async-p'.
+ (when (js2-match-async-arrow-function)
+ (setq async-p t))
;; Save the tokenizer state in case we find an arrow function
;; and have to rewind.
(setq ts-state (make-js2-ts-state)
@@ -9621,7 +9687,7 @@ If NODE is non-nil, it is the AST node associated with
the symbol."
(js2-ts-seek ts-state)
(setq js2-recorded-identifiers recorded-identifiers
js2-parsed-errors parsed-errors)
- (setq pn (js2-parse-function 'FUNCTION_ARROW (js2-current-token-beg)
nil)))
+ (setq pn (js2-parse-function 'FUNCTION_ARROW (js2-current-token-beg)
nil async-p)))
(t
(js2-unget-token)))
pn)))
@@ -9810,6 +9876,18 @@ to parse the operand (for prefix operators)."
(js2-node-add-children pn expr)
pn))
+(defun js2-make-await ()
+ "Make an await node."
+ (let* ((pos (js2-current-token-beg))
+ (expr (js2-parse-unary-expr))
+ (end (js2-node-end expr))
+ pn)
+ (setq pn (make-js2-await-node :pos pos
+ :len (- end pos)
+ :operand expr))
+ (js2-node-add-children pn expr)
+ pn))
+
(defconst js2-incrementable-node-types
(list js2-NAME js2-GETPROP js2-GETELEM js2-GET_REF js2-CALL)
"Node types that can be the operand of a ++ or -- operator.")
@@ -9851,6 +9929,8 @@ to parse the operand (for prefix operators)."
((= tt js2-DELPROP)
(js2-get-token)
(js2-make-unary js2-DELPROP 'js2-parse-unary-expr))
+ ((js2-match-await)
+ (js2-make-unary js2-AWAIT 'js2-parse-unary-expr))
((= tt js2-ERROR)
(js2-get-token)
(make-js2-error-node)) ; try to continue
@@ -10240,6 +10320,8 @@ array-literals, array comprehensions and regular
expressions."
(js2-parse-class-expr))
((= tt js2-FUNCTION)
(js2-parse-function-expr))
+ ((js2-match-async-function)
+ (js2-parse-function-expr t))
((= tt js2-LB)
(js2-parse-array-comp-or-literal))
((= tt js2-LC)
@@ -10649,12 +10731,11 @@ expression)."
(= js2-MUL tt))
(setq previous-token (js2-current-token)
tt (js2-get-prop-name-token)))
- ;; Handle 'get' or 'set' keywords
+ ;; Handle getter, setter and async methods
(let ((prop (js2-current-token-string)))
(when (and (>= js2-language-version 200)
(= js2-NAME tt)
- (or (string= prop "get")
- (string= prop "set"))
+ (member prop '("get" "set" "async"))
(member (js2-peek-token)
(list js2-NAME js2-STRING js2-NUMBER js2-LB)))
(setq previous-token (js2-current-token)
@@ -10707,8 +10788,11 @@ expression)."
;; But make an exception for getter / setter pairs.
(not (and (js2-method-node-p elem)
(js2-method-node-p previous-elem)
- (/= (js2-method-node-type elem)
- (js2-method-node-type
previous-elem))))))
+ (let ((type (js2-node-get-prop
(js2-method-node-right elem) 'METHOD_TYPE))
+ (previous-type (js2-node-get-prop
(js2-method-node-right previous-elem) 'METHOD_TYPE)))
+ (and (member type '(GET SET))
+ (member previous-type '(GET SET))
+ (not (eq type previous-type))))))))
elems))
(js2-report-error "msg.dup.obj.lit.prop.strict"
elem-key-string
@@ -10728,11 +10812,10 @@ When `js2-is-in-destructuring' is t, forms like {a,
b, c} will be permitted."
(if (= (js2-token-type previous-token) js2-MUL)
"*"
(js2-token-string previous-token)))))
- (when (or (string= prop "get")
- (string= prop "set"))
+ (when (member prop '("get" "set" "async"))
(js2-set-face (js2-token-beg previous-token)
(js2-token-end previous-token)
- 'font-lock-keyword-face 'record)) ; get/set
+ 'font-lock-keyword-face 'record)) ; get/set/async
(cond
;; method definition: {f() {...}}
((and (= (js2-peek-token) js2-LP)
@@ -10837,7 +10920,8 @@ string or expression."
"Parse method property in an object literal or a class body.
JavaScript syntax is:
- { foo(...) {...}, get foo() {...}, set foo(x) {...}, *foo(...) {...} }
+ { foo(...) {...}, get foo() {...}, set foo(x) {...}, *foo(...) {...},
+ async foo(...) {...} }
and expression closure style is also supported
@@ -10846,12 +10930,12 @@ and expression closure style is also supported
POS is the start position of the `get' or `set' keyword.
PROP is the `js2-name-node' representing the property name.
TYPE-STRING is a string `get', `set', `*', or nil, indicating a found keyword."
- (let ((type (cond
- ((string= "get" type-string) js2-GET)
- ((string= "set" type-string) js2-SET)
- (t js2-FUNCTION)))
- result end
- (fn (js2-parse-function-expr)))
+ (let* ((type (or (cdr (assoc type-string '(("get" . GET)
+ ("set" . SET)
+ ("async" . ASYNC))))
+ 'FUNCTION))
+ result end
+ (fn (js2-parse-function-expr (eq type 'ASYNC))))
;; it has to be an anonymous function, as we already parsed the name
(if (/= (js2-node-type fn) js2-FUNCTION)
(js2-report-error "msg.bad.prop")
@@ -10861,8 +10945,7 @@ TYPE-STRING is a string `get', `set', `*', or nil,
indicating a found keyword."
(when (string= type-string "*")
(setf (js2-function-node-generator-type fn) 'STAR))
(setq end (js2-node-end fn)
- result (make-js2-method-node :type type
- :pos pos
+ result (make-js2-method-node :pos pos
:len (- end pos)
:left prop
:right fn))
diff --git a/tests/parser.el b/tests/parser.el
index e97000d..7c4daa8 100644
--- a/tests/parser.el
+++ b/tests/parser.el
@@ -435,6 +435,67 @@ the test."
(js2-deftest-parse parse-generator-comp-with-yield-inside-function-is-ok
"(for (x of []) function*() { yield x;\n});")
+;;; Async
+
+(js2-deftest-parse async-function-statement
+ "async function foo() {\n}")
+
+(js2-deftest-parse async-function-statement-inside-block
+ "if (true) {\n async function foo() {\n }\n}")
+
+(js2-deftest-parse async-function-expression-statements-are-verboten
+ "async function() {}" :syntax-error "(")
+
+(js2-deftest-parse async-named-function-expression
+ "a = async function b() {};")
+
+(js2-deftest-parse async-arrow-function-expression
+ "a = async (b) => { b;\n};")
+
+(js2-deftest-parse async-method-in-object-literal
+ "({async f() {}});")
+
+(js2-deftest-parse async-method-in-class-body
+ "class C {\n async foo() {}\n}")
+
+(js2-deftest-parse static-async-method-in-class-body
+ "class C {\n static async foo() {}\n}")
+
+(js2-deftest-parse async-method-allow-await
+ "({async f() { await x;\n}});")
+
+;;; Await
+
+(js2-deftest-parse await-is-ok "async function foo() {\n await bar();\n}")
+
+(js2-deftest-parse await-inside-assignment-is-ok
+ "async function foo() {\n var result = await bar();\n}")
+
+(js2-deftest-parse await-inside-array-is-ok
+ "async function foo() {\n var results = [await bar(),
await baz()];\n}")
+
+(js2-deftest-parse await-inside-non-async-function-is-not-ok
+ "function foo() {\n await bar();\n}"
+ :syntax-error "await")
+
+(js2-deftest-parse await-inside-non-async-arrow-function-is-not-ok
+ "a = () => { await bar();\n}"
+ :syntax-error "await")
+
+;;; 'async' and 'await' are contextual keywords
+
+(js2-deftest-parse async-can-be-var-name
+ "var async = 3;")
+
+(js2-deftest-parse async-can-be-function-name
+ "function async() {\n}")
+
+(js2-deftest-parse await-can-be-var-name
+ "var await = 3;")
+
+(js2-deftest-parse await-can-be-function-name
+ "function await() {\n}")
+
;;; Numbers
(js2-deftest-parse decimal-starting-with-zero "081;" :reference "81;")
- [elpa] master 57dca37 073/110: Refactor await parsing to only parse once, (continued)
- [elpa] master 57dca37 073/110: Refactor await parsing to only parse once, Dmitry Gutov, 2016/06/22
- [elpa] master 60f7a2b 080/110: Fix computed property generator methods indentation, Dmitry Gutov, 2016/06/22
- [elpa] master de6df33 049/110: Fix semicolons and scoping in exported decls, Dmitry Gutov, 2016/06/22
- [elpa] master dbf4fe9 038/110: Adapt async/await changes to latest master, Dmitry Gutov, 2016/06/22
- [elpa] master 7fe7165 053/110: Fix array destructuring including triple-dot, Dmitry Gutov, 2016/06/22
- [elpa] master d1bf11f 068/110: Fix void parsing, Dmitry Gutov, 2016/06/22
- [elpa] master 7b430a3 079/110: Merge pull request #308 from zmwangx/jsdoc-callback-func-method, Dmitry Gutov, 2016/06/22
- [elpa] master c988876 086/110: Fix the straggler, Dmitry Gutov, 2016/06/22
- [elpa] master 6399bec 001/110: Support ES(7) async/await syntax; Closes #185, Dmitry Gutov, 2016/06/22
- [elpa] master fa0aa09 060/110: Merge pull request #294 from lunaryorn/patch-1, Dmitry Gutov, 2016/06/22
- [elpa] master ec7932d 047/110: Merge pull request #283 from XeCycle/master-with-async,
Dmitry Gutov <=
- [elpa] master e44d9e1 088/110: Merge pull request #325 from phst/all-tests, Dmitry Gutov, 2016/06/22
- [elpa] master 812df51 091/110: Merge pull request #326 from phst/compiler-warning-25, Dmitry Gutov, 2016/06/22
- [elpa] master de5b31c 085/110: Fix the tests broken in the previous commit, Dmitry Gutov, 2016/06/22
- [elpa] master f130121 095/110: Merge pull request #328 from XeCycle/iname-color, Dmitry Gutov, 2016/06/22
- [elpa] master 9586f45 096/110: Add :warnings-count keyword argument, Dmitry Gutov, 2016/06/22
- [elpa] master e5e4fa4 105/110: Add js2-mode-assume-strict custom variable, Dmitry Gutov, 2016/06/22
- [elpa] master bb0acf5 106/110: Merge pull request #342 from shicks/strict, Dmitry Gutov, 2016/06/22
- [elpa] master 173d1c8 101/110: Merge pull request #332 from bolivier/master, Dmitry Gutov, 2016/06/22
- [elpa] master c162f35 092/110: Colorize contextual keywords as & from in import & export, Dmitry Gutov, 2016/06/22
- [elpa] master 66fe8de 107/110: js2-define-symbol: Treat const same as let, Dmitry Gutov, 2016/06/22