summaryrefslogtreecommitdiff
path: root/tools/eslint/node_modules/doctrine
diff options
context:
space:
mode:
Diffstat (limited to 'tools/eslint/node_modules/doctrine')
-rw-r--r--tools/eslint/node_modules/doctrine/.jshintrc28
-rw-r--r--tools/eslint/node_modules/doctrine/.npmignore3
-rw-r--r--tools/eslint/node_modules/doctrine/.scripted6
-rw-r--r--tools/eslint/node_modules/doctrine/.travis.yml7
-rw-r--r--tools/eslint/node_modules/doctrine/CONTRIBUTING.md5
-rw-r--r--tools/eslint/node_modules/doctrine/LICENSE.BSD19
-rw-r--r--tools/eslint/node_modules/doctrine/LICENSE.closure-compiler202
-rw-r--r--tools/eslint/node_modules/doctrine/LICENSE.esprima19
-rw-r--r--tools/eslint/node_modules/doctrine/README.md176
-rw-r--r--tools/eslint/node_modules/doctrine/coverage/coverage-final.json2
-rw-r--r--tools/eslint/node_modules/doctrine/coverage/lcov-report/base.css182
-rw-r--r--tools/eslint/node_modules/doctrine/coverage/lcov-report/index.html72
-rw-r--r--tools/eslint/node_modules/doctrine/coverage/lcov-report/prettify.css1
-rw-r--r--tools/eslint/node_modules/doctrine/coverage/lcov-report/prettify.js1
-rw-r--r--tools/eslint/node_modules/doctrine/coverage/lcov-report/sort-arrow-sprite.pngbin0 -> 209 bytes
-rw-r--r--tools/eslint/node_modules/doctrine/coverage/lcov-report/sorter.js156
-rw-r--r--tools/eslint/node_modules/doctrine/coverage/lcov.info0
-rw-r--r--tools/eslint/node_modules/doctrine/eslint.json22
-rw-r--r--tools/eslint/node_modules/doctrine/gulpfile.js120
-rw-r--r--tools/eslint/node_modules/doctrine/lib/doctrine.js809
-rw-r--r--tools/eslint/node_modules/doctrine/lib/typed.js1261
-rw-r--r--tools/eslint/node_modules/doctrine/lib/utility.js54
-rw-r--r--tools/eslint/node_modules/doctrine/node_modules/esutils/LICENSE.BSD19
-rw-r--r--tools/eslint/node_modules/doctrine/node_modules/esutils/README.md169
-rw-r--r--tools/eslint/node_modules/doctrine/node_modules/esutils/lib/ast.js144
-rw-r--r--tools/eslint/node_modules/doctrine/node_modules/esutils/lib/code.js101
-rw-r--r--tools/eslint/node_modules/doctrine/node_modules/esutils/lib/keyword.js137
-rw-r--r--tools/eslint/node_modules/doctrine/node_modules/esutils/lib/utils.js33
-rw-r--r--tools/eslint/node_modules/doctrine/node_modules/esutils/package.json66
-rw-r--r--tools/eslint/node_modules/doctrine/node_modules/isarray/README.md54
-rw-r--r--tools/eslint/node_modules/doctrine/node_modules/isarray/build/build.js209
-rw-r--r--tools/eslint/node_modules/doctrine/node_modules/isarray/component.json19
-rw-r--r--tools/eslint/node_modules/doctrine/node_modules/isarray/index.js3
-rw-r--r--tools/eslint/node_modules/doctrine/node_modules/isarray/package.json54
-rw-r--r--tools/eslint/node_modules/doctrine/package.json71
-rw-r--r--tools/eslint/node_modules/doctrine/test/midstream.js61
-rw-r--r--tools/eslint/node_modules/doctrine/test/parse.js2219
-rw-r--r--tools/eslint/node_modules/doctrine/test/strict.js168
-rw-r--r--tools/eslint/node_modules/doctrine/test/stringify.js413
-rw-r--r--tools/eslint/node_modules/doctrine/test/test.html31
-rw-r--r--tools/eslint/node_modules/doctrine/test/unwrap.js60
41 files changed, 7176 insertions, 0 deletions
diff --git a/tools/eslint/node_modules/doctrine/.jshintrc b/tools/eslint/node_modules/doctrine/.jshintrc
new file mode 100644
index 0000000000..3ecc7bcde6
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/.jshintrc
@@ -0,0 +1,28 @@
+{
+ "curly": true,
+ "eqeqeq": true,
+ "immed": true,
+ "indent": 4,
+ "eqnull": true,
+ "latedef": true,
+ "noarg": true,
+ "noempty": true,
+ "quotmark": "single",
+ "undef": true,
+ "unused": "vars",
+ "strict": true,
+ "trailing": true,
+ "validthis": true,
+ "bitwise": true,
+ "plusplus": false,
+ "nomen": true,
+
+ "onevar": true,
+
+ "node": true,
+ "predef": [
+ "doctrine",
+ "parseTypeExpression",
+ "parseTop"
+ ]
+}
diff --git a/tools/eslint/node_modules/doctrine/.npmignore b/tools/eslint/node_modules/doctrine/.npmignore
new file mode 100644
index 0000000000..ba73eea154
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/.npmignore
@@ -0,0 +1,3 @@
+node_modules
+
+*.iml \ No newline at end of file
diff --git a/tools/eslint/node_modules/doctrine/.scripted b/tools/eslint/node_modules/doctrine/.scripted
new file mode 100644
index 0000000000..89683cd30f
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/.scripted
@@ -0,0 +1,6 @@
+{
+ "editor": {
+ "expandtab": true,
+ "tabsize": 4
+ }
+} \ No newline at end of file
diff --git a/tools/eslint/node_modules/doctrine/.travis.yml b/tools/eslint/node_modules/doctrine/.travis.yml
new file mode 100644
index 0000000000..93b0f3ee42
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/.travis.yml
@@ -0,0 +1,7 @@
+language: node_js
+node_js:
+ - 0.10
+after_script:
+ - npm run coveralls
+git:
+ depth: 10
diff --git a/tools/eslint/node_modules/doctrine/CONTRIBUTING.md b/tools/eslint/node_modules/doctrine/CONTRIBUTING.md
new file mode 100644
index 0000000000..6e0978475e
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/CONTRIBUTING.md
@@ -0,0 +1,5 @@
+Project license(s): 2-clause BSD license
+
+* You will only Submit Contributions where You have authored 100% of the content.
+* You will only Submit Contributions to which You have the necessary rights. This means that if You are employed You have received the necessary permissions from Your employer to make the Contributions.
+* Whatever content You Contribute will be provided under the Project License(s).
diff --git a/tools/eslint/node_modules/doctrine/LICENSE.BSD b/tools/eslint/node_modules/doctrine/LICENSE.BSD
new file mode 100644
index 0000000000..3e580c355a
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/LICENSE.BSD
@@ -0,0 +1,19 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tools/eslint/node_modules/doctrine/LICENSE.closure-compiler b/tools/eslint/node_modules/doctrine/LICENSE.closure-compiler
new file mode 100644
index 0000000000..d645695673
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/LICENSE.closure-compiler
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/tools/eslint/node_modules/doctrine/LICENSE.esprima b/tools/eslint/node_modules/doctrine/LICENSE.esprima
new file mode 100644
index 0000000000..3e580c355a
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/LICENSE.esprima
@@ -0,0 +1,19 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tools/eslint/node_modules/doctrine/README.md b/tools/eslint/node_modules/doctrine/README.md
new file mode 100644
index 0000000000..bade0907b6
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/README.md
@@ -0,0 +1,176 @@
+doctrine ([doctrine](http://github.com/Constellation/doctrine)) is JSDoc parser.
+
+[![Build Status](https://travis-ci.org/Constellation/doctrine.svg?branch=master)](https://travis-ci.org/Constellation/doctrine)
+[![Coverage Status](https://img.shields.io/coveralls/Constellation/doctrine.svg)](https://coveralls.io/r/Constellation/doctrine?branch=master)
+[![Dependency Status](https://david-dm.org/Constellation/doctrine.svg)](https://david-dm.org/Constellation/doctrine)
+[![devDependency Status](https://david-dm.org/Constellation/doctrine/dev-status.svg)](https://david-dm.org/Constellation/doctrine#info=devDependencies)
+[![Gitter chat](https://badges.gitter.im/Constellation/doctrine.png)](https://gitter.im/Constellation/doctrine)
+
+It is now used by content assist system of [Eclipse Orion](http://www.eclipse.org/orion/) ([detail](http://planetorion.org/news/2012/10/orion-1-0-release/)). And used as JSDoc validator in [ESLint](http://eslint.org/).
+
+Doctrine can be used in a web browser with using browserify.
+or in a Node.js application via the package manager:
+
+ npm install doctrine
+
+simple example:
+
+ doctrine.parse(
+ [
+ "/**",
+ " * This function comment is parsed by doctrine",
+ " * @param {{ok:String}} userName",
+ "*/"
+ ].join('\n'), { unwrap: true });
+
+and gets following information
+
+ {
+ "description": "This function comment is parsed by doctrine",
+ "tags": [
+ {
+ "title": "param",
+ "description": null,
+ "type": {
+ "type": "RecordType",
+ "fields": [
+ {
+ "type": "FieldType",
+ "key": "ok",
+ "value": {
+ "type": "NameExpression",
+ "name": "String"
+ }
+ }
+ ]
+ },
+ "name": "userName"
+ }
+ ]
+ }
+
+see [demo page](http://constellation.github.com/doctrine/demo/index.html) more detail.
+
+### Options
+
+#### doctrine.parse
+We can pass options to `doctrine.parse(comment, options)`.
+```js
+{
+ unwrap: boolean, // default: false
+ tags: [ string ] | null, // default: null
+ recoverable: boolean, // default: false
+ sloppy: boolean, // default: false
+ lineNumbers: boolean // default: false
+}
+```
+
+##### unwrap
+
+When `unwrap` is `true`, doctrine attempt to unwrap comment specific string from a provided comment text. (removes `/**`, `*/` and `*`)
+For example, `unwrap` transforms
+```
+/**
+ * @param use
+ */
+```
+to
+```
+@param use
+```
+If a provided comment has these comment specific strings, you need to specify this `unwrap` option to `true`.
+
+##### tags
+
+When `tags` array is specified, doctrine only produce tags that is specified in this array.
+For example, if you specify `[ 'param' ]`, doctrine only produces `param` tags.
+If null is specified, doctrine produces all tags that doctrine can recognize.
+
+##### recoverable
+
+When `recoverable` is `true`, doctrine becomes `recoverable` - When failing to parse jsdoc comment, doctrine recovers its state and attempt to continue parsing.
+
+##### sloppy
+
+When `sloppy` is `true`,
+```
+@param String [foo]
+```
+'s `[foo]` is interpreted as a optional parameter, not interpreted as a name of this `@param`.
+
+##### lineNumbers
+
+When `lineNumbers` is `true`, parsed tags will include a `lineNumber` property indicating the line (relative to the start of the comment block) where each tag is located in the source. So, given the following comment:
+```
+/**
+ * @param {String} foo
+ * @return {number}
+ */
+```
+The `@param` tag will have `lineNumber: 1`, and the `@return` tag will have `lineNumber: 2`.
+
+
+### License
+
+#### doctrine
+
+Copyright (C) 2012 [Yusuke Suzuki](http://github.com/Constellation)
+ (twitter: [@Constellation](http://twitter.com/Constellation)) and other contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#### esprima
+
+some of functions is derived from esprima
+
+Copyright (C) 2012, 2011 [Ariya Hidayat](http://ariya.ofilabs.com/about)
+ (twitter: [@ariyahidayat](http://twitter.com/ariyahidayat)) and other contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+#### closure-compiler
+
+some of extensions is derived from closure-compiler
+
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
diff --git a/tools/eslint/node_modules/doctrine/coverage/coverage-final.json b/tools/eslint/node_modules/doctrine/coverage/coverage-final.json
new file mode 100644
index 0000000000..2c63c08510
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/coverage/coverage-final.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/tools/eslint/node_modules/doctrine/coverage/lcov-report/base.css b/tools/eslint/node_modules/doctrine/coverage/lcov-report/base.css
new file mode 100644
index 0000000000..7fb8827220
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/coverage/lcov-report/base.css
@@ -0,0 +1,182 @@
+body, html {
+ margin:0; padding: 0;
+}
+body {
+ font-family: Helvetica Neue, Helvetica,Arial;
+ font-size: 10pt;
+}
+div.header, div.footer {
+ background: #eee;
+ padding: 1em;
+}
+div.header {
+ z-index: 100;
+ position: fixed;
+ top: 0;
+ border-bottom: 1px solid #666;
+ width: 100%;
+}
+div.footer {
+ border-top: 1px solid #666;
+}
+div.body {
+ margin-top: 10em;
+}
+div.meta {
+ font-size: 90%;
+ text-align: center;
+}
+h1, h2, h3 {
+ font-weight: normal;
+}
+h1 {
+ font-size: 12pt;
+}
+h2 {
+ font-size: 10pt;
+}
+pre {
+ font-family: Consolas, Menlo, Monaco, monospace;
+ margin: 0;
+ padding: 0;
+ line-height: 14px;
+ font-size: 14px;
+ -moz-tab-size: 2;
+ -o-tab-size: 2;
+ tab-size: 2;
+}
+
+div.path { font-size: 110%; }
+div.path a:link, div.path a:visited { color: #000; }
+table.coverage { border-collapse: collapse; margin:0; padding: 0 }
+
+table.coverage td {
+ margin: 0;
+ padding: 0;
+ color: #111;
+ vertical-align: top;
+}
+table.coverage td.line-count {
+ width: 50px;
+ text-align: right;
+ padding-right: 5px;
+}
+table.coverage td.line-coverage {
+ color: #777 !important;
+ text-align: right;
+ border-left: 1px solid #666;
+ border-right: 1px solid #666;
+}
+
+table.coverage td.text {
+}
+
+table.coverage td span.cline-any {
+ display: inline-block;
+ padding: 0 5px;
+ width: 40px;
+}
+table.coverage td span.cline-neutral {
+ background: #eee;
+}
+table.coverage td span.cline-yes {
+ background: #b5d592;
+ color: #999;
+}
+table.coverage td span.cline-no {
+ background: #fc8c84;
+}
+
+.cstat-yes { color: #111; }
+.cstat-no { background: #fc8c84; color: #111; }
+.fstat-no { background: #ffc520; color: #111 !important; }
+.cbranch-no { background: yellow !important; color: #111; }
+
+.cstat-skip { background: #ddd; color: #111; }
+.fstat-skip { background: #ddd; color: #111 !important; }
+.cbranch-skip { background: #ddd !important; color: #111; }
+
+.missing-if-branch {
+ display: inline-block;
+ margin-right: 10px;
+ position: relative;
+ padding: 0 4px;
+ background: black;
+ color: yellow;
+}
+
+.skip-if-branch {
+ display: none;
+ margin-right: 10px;
+ position: relative;
+ padding: 0 4px;
+ background: #ccc;
+ color: white;
+}
+
+.missing-if-branch .typ, .skip-if-branch .typ {
+ color: inherit !important;
+}
+
+.entity, .metric { font-weight: bold; }
+.metric { display: inline-block; border: 1px solid #333; padding: 0.3em; background: white; }
+.metric small { font-size: 80%; font-weight: normal; color: #666; }
+
+div.coverage-summary table { border-collapse: collapse; margin: 3em; font-size: 110%; }
+div.coverage-summary td, div.coverage-summary table th { margin: 0; padding: 0.25em 1em; border-top: 1px solid #666; border-bottom: 1px solid #666; }
+div.coverage-summary th { text-align: left; border: 1px solid #666; background: #eee; font-weight: normal; }
+div.coverage-summary th.file { border-right: none !important; }
+div.coverage-summary th.pic { border-left: none !important; text-align: right; }
+div.coverage-summary th.pct { border-right: none !important; }
+div.coverage-summary th.abs { border-left: none !important; text-align: right; }
+div.coverage-summary td.pct { text-align: right; border-left: 1px solid #666; }
+div.coverage-summary td.abs { text-align: right; font-size: 90%; color: #444; border-right: 1px solid #666; }
+div.coverage-summary td.file { text-align: right; border-left: 1px solid #666; white-space: nowrap; }
+div.coverage-summary td.pic { min-width: 120px !important; }
+div.coverage-summary a:link { text-decoration: none; color: #000; }
+div.coverage-summary a:visited { text-decoration: none; color: #333; }
+div.coverage-summary a:hover { text-decoration: underline; }
+div.coverage-summary tfoot td { border-top: 1px solid #666; }
+
+div.coverage-summary .sorter {
+ height: 10px;
+ width: 7px;
+ display: inline-block;
+ margin-left: 0.5em;
+ background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
+}
+div.coverage-summary .sorted .sorter {
+ background-position: 0 -20px;
+}
+div.coverage-summary .sorted-desc .sorter {
+ background-position: 0 -10px;
+}
+
+.high { background: #b5d592 !important; }
+.medium { background: #ffe87c !important; }
+.low { background: #fc8c84 !important; }
+
+span.cover-fill, span.cover-empty {
+ display:inline-block;
+ border:1px solid #444;
+ background: white;
+ height: 12px;
+}
+span.cover-fill {
+ background: #ccc;
+ border-right: 1px solid #444;
+}
+span.cover-empty {
+ background: white;
+ border-left: none;
+}
+span.cover-full {
+ border-right: none !important;
+}
+pre.prettyprint {
+ border: none !important;
+ padding: 0 !important;
+ margin: 0 !important;
+}
+.com { color: #999 !important; }
+.ignore-none { color: #999; font-weight: normal; } \ No newline at end of file
diff --git a/tools/eslint/node_modules/doctrine/coverage/lcov-report/index.html b/tools/eslint/node_modules/doctrine/coverage/lcov-report/index.html
new file mode 100644
index 0000000000..d998817068
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/coverage/lcov-report/index.html
@@ -0,0 +1,72 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>Code coverage report for All files</title>
+ <meta charset="utf-8">
+
+ <link rel="stylesheet" href="prettify.css">
+
+ <link rel="stylesheet" href="base.css">
+ <style type='text/css'>
+ div.coverage-summary .sorter {
+ background-image: url(sort-arrow-sprite.png);
+ }
+ </style>
+</head>
+<body>
+<div class="header high">
+ <h1>Code coverage report for <span class="entity">All files</span></h1>
+ <h2>
+
+ Statements: <span class="metric">100% <small>(0 / 0)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
+
+
+ Branches: <span class="metric">100% <small>(0 / 0)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
+
+
+ Functions: <span class="metric">100% <small>(0 / 0)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
+
+
+ Lines: <span class="metric">100% <small>(0 / 0)</small></span> &nbsp;&nbsp;&nbsp;&nbsp;
+
+ Ignored: <span class="metric"><span class="ignore-none">none</span></span> &nbsp;&nbsp;&nbsp;&nbsp;
+ </h2>
+ <div class="path"></div>
+</div>
+<div class="body">
+<div class="coverage-summary">
+<table>
+<thead>
+<tr>
+ <th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
+ <th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
+ <th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
+ <th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
+ <th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
+ <th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
+ <th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
+ <th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
+ <th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
+ <th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
+</tr>
+</thead>
+<tbody></tbody>
+</table>
+</div>
+</div>
+<div class="footer">
+ <div class="meta">Generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Tue Feb 24 2015 02:28:53 GMT+0900 (JST)</div>
+</div>
+
+<script src="prettify.js"></script>
+<script>
+window.onload = function () {
+ if (typeof prettyPrint === 'function') {
+ prettyPrint();
+ }
+};
+</script>
+
+<script src="sorter.js"></script>
+</body>
+</html>
diff --git a/tools/eslint/node_modules/doctrine/coverage/lcov-report/prettify.css b/tools/eslint/node_modules/doctrine/coverage/lcov-report/prettify.css
new file mode 100644
index 0000000000..b317a7cda3
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/coverage/lcov-report/prettify.css
@@ -0,0 +1 @@
+.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
diff --git a/tools/eslint/node_modules/doctrine/coverage/lcov-report/prettify.js b/tools/eslint/node_modules/doctrine/coverage/lcov-report/prettify.js
new file mode 100644
index 0000000000..ef51e03866
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/coverage/lcov-report/prettify.js
@@ -0,0 +1 @@
+window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V<U;++V){var ae=Z[V];if(ae.ignoreCase){ac=true}else{if(/[a-z]/i.test(ae.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,""))){S=true;ac=false;break}}}var Y={b:8,t:9,n:10,v:11,f:12,r:13};function ab(ah){var ag=ah.charCodeAt(0);if(ag!==92){return ag}var af=ah.charAt(1);ag=Y[af];if(ag){return ag}else{if("0"<=af&&af<="7"){return parseInt(ah.substring(1),8)}else{if(af==="u"||af==="x"){return parseInt(ah.substring(2),16)}else{return ah.charCodeAt(1)}}}}function T(af){if(af<32){return(af<16?"\\x0":"\\x")+af.toString(16)}var ag=String.fromCharCode(af);if(ag==="\\"||ag==="-"||ag==="["||ag==="]"){ag="\\"+ag}return ag}function X(am){var aq=am.substring(1,am.length-1).match(new RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));var ak=[];var af=[];var ao=aq[0]==="^";for(var ar=ao?1:0,aj=aq.length;ar<aj;++ar){var ah=aq[ar];if(/\\[bdsw]/i.test(ah)){ak.push(ah)}else{var ag=ab(ah);var al;if(ar+2<aj&&"-"===aq[ar+1]){al=ab(aq[ar+2]);ar+=2}else{al=ag}af.push([ag,al]);if(!(al<65||ag>122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;ar<af.length;++ar){var at=af[ar];if(at[0]<=ap[1]+1){ap[1]=Math.max(ap[1],at[1])}else{ai.push(ap=at)}}var an=["["];if(ao){an.push("^")}an.push.apply(an,ak);for(var ar=0;ar<ai.length;++ar){var at=ai[ar];an.push(T(at[0]));if(at[1]>at[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak<ah;++ak){var ag=aj[ak];if(ag==="("){++am}else{if("\\"===ag.charAt(0)){var af=+ag.substring(1);if(af&&af<=am){an[af]=-1}}}}for(var ak=1;ak<an.length;++ak){if(-1===an[ak]){an[ak]=++ad}}for(var ak=0,am=0;ak<ah;++ak){var ag=aj[ak];if(ag==="("){++am;if(an[am]===undefined){aj[ak]="(?:"}}else{if("\\"===ag.charAt(0)){var af=+ag.substring(1);if(af&&af<=am){aj[ak]="\\"+an[am]}}}}for(var ak=0,am=0;ak<ah;++ak){if("^"===aj[ak]&&"^"!==aj[ak+1]){aj[ak]=""}}if(al.ignoreCase&&S){for(var ak=0;ak<ah;++ak){var ag=aj[ak];var ai=ag.charAt(0);if(ag.length>=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V<U;++V){var ae=Z[V];if(ae.global||ae.multiline){throw new Error(""+ae)}aa.push("(?:"+W(ae)+")")}return new RegExp(aa.join("|"),ac?"gi":"g")}function a(V){var U=/(?:^|\s)nocode(?:\s|$)/;var X=[];var T=0;var Z=[];var W=0;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=document.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Y=S&&"pre"===S.substring(0,3);function aa(ab){switch(ab.nodeType){case 1:if(U.test(ab.className)){return}for(var ae=ab.firstChild;ae;ae=ae.nextSibling){aa(ae)}var ad=ab.nodeName;if("BR"===ad||"LI"===ad){X[W]="\n";Z[W<<1]=T++;Z[(W++<<1)|1]=ab}break;case 3:case 4:var ac=ab.nodeValue;if(ac.length){if(!Y){ac=ac.replace(/[ \t\r\n]+/g," ")}else{ac=ac.replace(/\r\n?/g,"\n")}X[W]=ac;Z[W<<1]=T;T+=ac.length;Z[(W++<<1)|1]=ab}break}}aa(V);return{sourceCode:X.join("").replace(/\n$/,""),spans:Z}}function B(S,U,W,T){if(!U){return}var V={sourceCode:U,basePos:S};W(V);T.push.apply(T,V.decorations)}var v=/\S/;function o(S){var V=undefined;for(var U=S.firstChild;U;U=U.nextSibling){var T=U.nodeType;V=(T===1)?(V?S:U):(T===3)?(v.test(U.nodeValue)?S:V):V}return V===S?undefined:V}function g(U,T){var S={};var V;(function(){var ad=U.concat(T);var ah=[];var ag={};for(var ab=0,Z=ad.length;ab<Z;++ab){var Y=ad[ab];var ac=Y[3];if(ac){for(var ae=ac.length;--ae>=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae<aq;++ae){var ag=an[ae];var ap=aj[ag];var ai=void 0;var am;if(typeof ap==="string"){am=false}else{var aa=S[ag.charAt(0)];if(aa){ai=ag.match(aa[1]);ap=aa[0]}else{for(var ao=0;ao<X;++ao){aa=T[ao];ai=ag.match(aa[1]);if(ai){ap=aa[0];break}}if(!ai){ap=F}}am=ap.length>=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y<W.length;++Y){ae(W[Y])}if(ag===(ag|0)){W[0].setAttribute("value",ag)}var aa=ac.createElement("OL");aa.className="linenums";var X=Math.max(0,((ag-1))|0)||0;for(var Y=0,T=W.length;Y<T;++Y){af=W[Y];af.className="L"+((Y+X)%10);if(!af.firstChild){af.appendChild(ac.createTextNode("\xA0"))}aa.appendChild(af)}V.appendChild(aa)}function D(ac){var aj=/\bMSIE\b/.test(navigator.userAgent);var am=/\n/g;var al=ac.sourceCode;var an=al.length;var V=0;var aa=ac.spans;var T=aa.length;var ah=0;var X=ac.decorations;var Y=X.length;var Z=0;X[Y]=an;var ar,aq;for(aq=ar=0;aq<Y;){if(X[aq]!==X[aq+2]){X[ar++]=X[aq++];X[ar++]=X[aq++]}else{aq+=2}}Y=ar;for(aq=ar=0;aq<Y;){var at=X[aq];var ab=X[aq+1];var W=aq+2;while(W+2<=Y&&X[W+1]===ab){W+=2}X[ar++]=at;X[ar++]=ab;aq=W}Y=X.length=ar;var ae=null;while(ah<T){var af=aa[ah];var S=aa[ah+2]||an;var ag=X[Z];var ap=X[Z+2]||an;var W=Math.min(S,ap);var ak=aa[ah+1];var U;if(ak.nodeType!==1&&(U=al.substring(V,W))){if(aj){U=U.replace(am,"\r")}ak.nodeValue=U;var ai=ak.ownerDocument;var ao=ai.createElement("SPAN");ao.className=X[Z+1];var ad=ak.parentNode;ad.replaceChild(ao,ak);ao.appendChild(ak);if(V<S){aa[ah+1]=ak=ai.createTextNode(al.substring(W,S));ad.insertBefore(ak,ao.nextSibling)}}V=W;if(V>=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*</.test(S)?"default-markup":"default-code"}return t[T]}c(K,["default-code"]);c(g([],[[F,/^[^<?]+/],[E,/^<!\w[^>]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa<ac.length;++aa){for(var Z=0,V=ac[aa].length;Z<V;++Z){T.push(ac[aa][Z])}}ac=null;var W=Date;if(!W.now){W={now:function(){return +(new Date)}}}var X=0;var S;var ab=/\blang(?:uage)?-([\w.]+)(?!\S)/;var ae=/\bprettyprint\b/;function U(){var ag=(window.PR_SHOULD_USE_CONTINUATION?W.now()+250:Infinity);for(;X<T.length&&W.now()<ag;X++){var aj=T[X];var ai=aj.className;if(ai.indexOf("prettyprint")>=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X<T.length){setTimeout(U,250)}else{if(ad){ad()}}}U()}window.prettyPrintOne=y;window.prettyPrint=b;window.PR={createSimpleLexer:g,registerLangHandler:c,sourceDecorator:i,PR_ATTRIB_NAME:P,PR_ATTRIB_VALUE:n,PR_COMMENT:j,PR_DECLARATION:E,PR_KEYWORD:z,PR_LITERAL:G,PR_NOCODE:N,PR_PLAIN:F,PR_PUNCTUATION:L,PR_SOURCE:J,PR_STRING:C,PR_TAG:m,PR_TYPE:O}})();PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_DECLARATION,/^<!\w[^>]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^<script\b[^>]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:<!--|-->)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]);
diff --git a/tools/eslint/node_modules/doctrine/coverage/lcov-report/sort-arrow-sprite.png b/tools/eslint/node_modules/doctrine/coverage/lcov-report/sort-arrow-sprite.png
new file mode 100644
index 0000000000..03f704a609
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/coverage/lcov-report/sort-arrow-sprite.png
Binary files differ
diff --git a/tools/eslint/node_modules/doctrine/coverage/lcov-report/sorter.js b/tools/eslint/node_modules/doctrine/coverage/lcov-report/sorter.js
new file mode 100644
index 0000000000..6afb736c39
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/coverage/lcov-report/sorter.js
@@ -0,0 +1,156 @@
+var addSorting = (function () {
+ "use strict";
+ var cols,
+ currentSort = {
+ index: 0,
+ desc: false
+ };
+
+ // returns the summary table element
+ function getTable() { return document.querySelector('.coverage-summary table'); }
+ // returns the thead element of the summary table
+ function getTableHeader() { return getTable().querySelector('thead tr'); }
+ // returns the tbody element of the summary table
+ function getTableBody() { return getTable().querySelector('tbody'); }
+ // returns the th element for nth column
+ function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; }
+
+ // loads all columns
+ function loadColumns() {
+ var colNodes = getTableHeader().querySelectorAll('th'),
+ colNode,
+ cols = [],
+ col,
+ i;
+
+ for (i = 0; i < colNodes.length; i += 1) {
+ colNode = colNodes[i];
+ col = {
+ key: colNode.getAttribute('data-col'),
+ sortable: !colNode.getAttribute('data-nosort'),
+ type: colNode.getAttribute('data-type') || 'string'
+ };
+ cols.push(col);
+ if (col.sortable) {
+ col.defaultDescSort = col.type === 'number';
+ colNode.innerHTML = colNode.innerHTML + '<span class="sorter"></span>';
+ }
+ }
+ return cols;
+ }
+ // attaches a data attribute to every tr element with an object
+ // of data values keyed by column name
+ function loadRowData(tableRow) {
+ var tableCols = tableRow.querySelectorAll('td'),
+ colNode,
+ col,
+ data = {},
+ i,
+ val;
+ for (i = 0; i < tableCols.length; i += 1) {
+ colNode = tableCols[i];
+ col = cols[i];
+ val = colNode.getAttribute('data-value');
+ if (col.type === 'number') {
+ val = Number(val);
+ }
+ data[col.key] = val;
+ }
+ return data;
+ }
+ // loads all row data
+ function loadData() {
+ var rows = getTableBody().querySelectorAll('tr'),
+ i;
+
+ for (i = 0; i < rows.length; i += 1) {
+ rows[i].data = loadRowData(rows[i]);
+ }
+ }
+ // sorts the table using the data for the ith column
+ function sortByIndex(index, desc) {
+ var key = cols[index].key,
+ sorter = function (a, b) {
+ a = a.data[key];
+ b = b.data[key];
+ return a < b ? -1 : a > b ? 1 : 0;
+ },
+ finalSorter = sorter,
+ tableBody = document.querySelector('.coverage-summary tbody'),
+ rowNodes = tableBody.querySelectorAll('tr'),
+ rows = [],
+ i;
+
+ if (desc) {
+ finalSorter = function (a, b) {
+ return -1 * sorter(a, b);
+ };
+ }
+
+ for (i = 0; i < rowNodes.length; i += 1) {
+ rows.push(rowNodes[i]);
+ tableBody.removeChild(rowNodes[i]);
+ }
+
+ rows.sort(finalSorter);
+
+ for (i = 0; i < rows.length; i += 1) {
+ tableBody.appendChild(rows[i]);
+ }
+ }
+ // removes sort indicators for current column being sorted
+ function removeSortIndicators() {
+ var col = getNthColumn(currentSort.index),
+ cls = col.className;
+
+ cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
+ col.className = cls;
+ }
+ // adds sort indicators for current column being sorted
+ function addSortIndicators() {
+ getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted';
+ }
+ // adds event listeners for all sorter widgets
+ function enableUI() {
+ var i,
+ el,
+ ithSorter = function ithSorter(i) {
+ var col = cols[i];
+
+ return function () {
+ var desc = col.defaultDescSort;
+
+ if (currentSort.index === i) {
+ desc = !currentSort.desc;
+ }
+ sortByIndex(i, desc);
+ removeSortIndicators();
+ currentSort.index = i;
+ currentSort.desc = desc;
+ addSortIndicators();
+ };
+ };
+ for (i =0 ; i < cols.length; i += 1) {
+ if (cols[i].sortable) {
+ el = getNthColumn(i).querySelector('.sorter');
+ if (el.addEventListener) {
+ el.addEventListener('click', ithSorter(i));
+ } else {
+ el.attachEvent('onclick', ithSorter(i));
+ }
+ }
+ }
+ }
+ // adds sorting functionality to the UI
+ return function () {
+ if (!getTable()) {
+ return;
+ }
+ cols = loadColumns();
+ loadData(cols);
+ addSortIndicators();
+ enableUI();
+ };
+})();
+
+window.addEventListener('load', addSorting);
diff --git a/tools/eslint/node_modules/doctrine/coverage/lcov.info b/tools/eslint/node_modules/doctrine/coverage/lcov.info
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/coverage/lcov.info
diff --git a/tools/eslint/node_modules/doctrine/eslint.json b/tools/eslint/node_modules/doctrine/eslint.json
new file mode 100644
index 0000000000..330835b9bf
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/eslint.json
@@ -0,0 +1,22 @@
+{
+ "env": {
+ "node": true
+ },
+ "rules": {
+ "quotes": [2, "single"],
+ "valid-jsdoc": [2, true],
+ "brace-style": [2, true],
+ "semi": [2, true],
+ "no-bitwise": [2, true],
+ "camelcase": [2, true],
+ "curly": [2, true],
+ "eqeqeq": [2, "allow-null"],
+ "wrap-iife": [2, true],
+ "eqeqeq": [2, true],
+ "strict": [2, true],
+ "no-unused-vars": [2, true],
+ "no-underscore-dangle": [0, false],
+ "no-use-before-define": [0, false],
+ "no-constant-condition": [0, false]
+ }
+}
diff --git a/tools/eslint/node_modules/doctrine/gulpfile.js b/tools/eslint/node_modules/doctrine/gulpfile.js
new file mode 100644
index 0000000000..a68d0ff930
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/gulpfile.js
@@ -0,0 +1,120 @@
+/*
+ Copyright (C) 2014 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+'use strict';
+
+var gulp = require('gulp');
+var mocha = require('gulp-mocha');
+var jshint = require('gulp-jshint');
+var eslint = require('gulp-eslint');
+var istanbul = require('gulp-istanbul');
+var bump = require('gulp-bump');
+var filter = require('gulp-filter');
+var git = require('gulp-git');
+var tagVersion = require('gulp-tag-version');
+
+var SRC = [ 'lib/*.js' ];
+
+var TEST = [ 'test/*.js' ];
+
+var LINT = [
+ 'gulpfile.js'
+].concat(SRC);
+
+var ESLINT_OPTION = {
+ 'rules': {
+ 'quotes': 0,
+ 'eqeqeq': 0,
+ 'no-use-before-define': 0,
+ 'no-underscore-dangle': 0,
+ 'no-shadow': 0,
+ 'no-constant-condition': 0,
+ 'no-multi-spaces': 0,
+ 'dot-notation': [2, {'allowKeywords': false}]
+ },
+ 'env': {
+ 'node': true
+ }
+};
+
+gulp.task('test', function (cb) {
+ gulp.src(SRC)
+ .pipe(istanbul()) // Covering files
+ .on('finish', function () {
+ gulp.src(TEST)
+ .pipe(mocha({
+ reporter: 'spec',
+ timeout: 100000 // 100s
+ }))
+ .pipe(istanbul.writeReports()) // Creating the reports after tests runned
+ .on('end', cb);
+ });
+});
+
+gulp.task('lint', function () {
+ return gulp.src(LINT)
+ .pipe(jshint('.jshintrc'))
+ .pipe(jshint.reporter(require('jshint-stylish')))
+ .pipe(jshint.reporter('fail'))
+ .pipe(eslint(ESLINT_OPTION))
+ .pipe(eslint.formatEach('compact', process.stderr))
+ .pipe(eslint.failOnError());
+});
+
+
+/**
+ * Bumping version number and tagging the repository with it.
+ * Please read http://semver.org/
+ *
+ * You can use the commands
+ *
+ * gulp patch # makes v0.1.0 -> v0.1.1
+ * gulp feature # makes v0.1.1 -> v0.2.0
+ * gulp release # makes v0.2.1 -> v1.0.0
+ *
+ * To bump the version numbers accordingly after you did a patch,
+ * introduced a feature or made a backwards-incompatible release.
+ */
+
+function inc(importance) {
+ // get all the files to bump version in
+ return gulp.src(['./package.json'])
+ // bump the version number in those files
+ .pipe(bump({type: importance}))
+ // save it back to filesystem
+ .pipe(gulp.dest('./'))
+ // commit the changed version number
+ .pipe(git.commit('Bumps package version'))
+ // read only one file to get the version number
+ .pipe(filter('package.json'))
+ // **tag it in the repository**
+ .pipe(tagVersion({ prefix: '' }));
+}
+
+gulp.task('patch', [ 'travis' ], function () { return inc('patch'); });
+gulp.task('minor', [ 'travis' ], function () { return inc('minor'); });
+gulp.task('major', [ 'travis' ], function () { return inc('major'); });
+
+gulp.task('travis', [ 'lint', 'test' ]);
+gulp.task('default', [ 'travis' ]);
diff --git a/tools/eslint/node_modules/doctrine/lib/doctrine.js b/tools/eslint/node_modules/doctrine/lib/doctrine.js
new file mode 100644
index 0000000000..dd3cccb263
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/lib/doctrine.js
@@ -0,0 +1,809 @@
+/*
+ Copyright (C) 2012-2014 Yusuke Suzuki <utatane.tea@gmail.com>
+ Copyright (C) 2014 Dan Tao <daniel.tao@gmail.com>
+ Copyright (C) 2013 Andrew Eisenberg <andrew@eisenberg.as>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+(function () {
+ 'use strict';
+
+ var typed,
+ utility,
+ isArray,
+ jsdoc,
+ esutils,
+ hasOwnProperty;
+
+ esutils = require('esutils');
+ isArray = require('isarray');
+ typed = require('./typed');
+ utility = require('./utility');
+
+ function sliceSource(source, index, last) {
+ return source.slice(index, last);
+ }
+
+ hasOwnProperty = (function () {
+ var func = Object.prototype.hasOwnProperty;
+ return function hasOwnProperty(obj, name) {
+ return func.call(obj, name);
+ };
+ }());
+
+ function shallowCopy(obj) {
+ var ret = {}, key;
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ ret[key] = obj[key];
+ }
+ }
+ return ret;
+ }
+
+ function isASCIIAlphanumeric(ch) {
+ return (ch >= 0x61 /* 'a' */ && ch <= 0x7A /* 'z' */) ||
+ (ch >= 0x41 /* 'A' */ && ch <= 0x5A /* 'Z' */) ||
+ (ch >= 0x30 /* '0' */ && ch <= 0x39 /* '9' */);
+ }
+
+ function isParamTitle(title) {
+ return title === 'param' || title === 'argument' || title === 'arg';
+ }
+
+ function isProperty(title) {
+ return title === 'property' || title === 'prop';
+ }
+
+ function isNameParameterRequired(title) {
+ return isParamTitle(title) || isProperty(title) ||
+ title === 'alias' || title === 'this' || title === 'mixes' || title === 'requires';
+ }
+
+ function isAllowedName(title) {
+ return isNameParameterRequired(title) || title === 'const' || title === 'constant';
+ }
+
+ function isAllowedNested(title) {
+ return isProperty(title) || isParamTitle(title);
+ }
+
+ function isTypeParameterRequired(title) {
+ return isParamTitle(title) || title === 'define' || title === 'enum' ||
+ title === 'implements' || title === 'return' ||
+ title === 'this' || title === 'type' || title === 'typedef' ||
+ title === 'returns' || isProperty(title);
+ }
+
+ // Consider deprecation instead using 'isTypeParameterRequired' and 'Rules' declaration to pick when a type is optional/required
+ // This would require changes to 'parseType'
+ function isAllowedType(title) {
+ return isTypeParameterRequired(title) || title === 'throws' || title === 'const' || title === 'constant' ||
+ title === 'namespace' || title === 'member' || title === 'var' || title === 'module' ||
+ title === 'constructor' || title === 'class' || title === 'extends' || title === 'augments' ||
+ title === 'public' || title === 'private' || title === 'protected';
+ }
+
+ function trim(str) {
+ return str.replace(/^\s+/, '').replace(/\s+$/, '');
+ }
+
+ function unwrapComment(doc) {
+ // JSDoc comment is following form
+ // /**
+ // * .......
+ // */
+ // remove /**, */ and *
+ var BEFORE_STAR = 0,
+ STAR = 1,
+ AFTER_STAR = 2,
+ index,
+ len,
+ mode,
+ result,
+ ch;
+
+ doc = doc.replace(/^\/\*\*?/, '').replace(/\*\/$/, '');
+ index = 0;
+ len = doc.length;
+ mode = BEFORE_STAR;
+ result = '';
+
+ while (index < len) {
+ ch = doc.charCodeAt(index);
+ switch (mode) {
+ case BEFORE_STAR:
+ if (esutils.code.isLineTerminator(ch)) {
+ result += String.fromCharCode(ch);
+ } else if (ch === 0x2A /* '*' */) {
+ mode = STAR;
+ } else if (!esutils.code.isWhiteSpace(ch)) {
+ result += String.fromCharCode(ch);
+ mode = AFTER_STAR;
+ }
+ break;
+
+ case STAR:
+ if (!esutils.code.isWhiteSpace(ch)) {
+ result += String.fromCharCode(ch);
+ }
+ mode = esutils.code.isLineTerminator(ch) ? BEFORE_STAR : AFTER_STAR;
+ break;
+
+ case AFTER_STAR:
+ result += String.fromCharCode(ch);
+ if (esutils.code.isLineTerminator(ch)) {
+ mode = BEFORE_STAR;
+ }
+ break;
+ }
+ index += 1;
+ }
+
+ return result;
+ }
+
+ // JSDoc Tag Parser
+
+ (function (exports) {
+ var Rules,
+ index,
+ lineNumber,
+ length,
+ source,
+ recoverable,
+ sloppy,
+ strict;
+
+ function advance() {
+ var ch = source.charCodeAt(index);
+ index += 1;
+ if (esutils.code.isLineTerminator(ch) && !(ch === 0x0D /* '\r' */ && source.charCodeAt(index) === 0x0A /* '\n' */)) {
+ lineNumber += 1;
+ }
+ return String.fromCharCode(ch);
+ }
+
+ function scanTitle() {
+ var title = '';
+ // waste '@'
+ advance();
+
+ while (index < length && isASCIIAlphanumeric(source.charCodeAt(index))) {
+ title += advance();
+ }
+
+ return title;
+ }
+
+ function seekContent() {
+ var ch, waiting, last = index;
+
+ waiting = false;
+ while (last < length) {
+ ch = source.charCodeAt(last);
+ if (esutils.code.isLineTerminator(ch) && !(ch === 0x0D /* '\r' */ && source.charCodeAt(last + 1) === 0x0A /* '\n' */)) {
+ lineNumber += 1;
+ waiting = true;
+ } else if (waiting) {
+ if (ch === 0x40 /* '@' */) {
+ break;
+ }
+ if (!esutils.code.isWhiteSpace(ch)) {
+ waiting = false;
+ }
+ }
+ last += 1;
+ }
+ return last;
+ }
+
+ // type expression may have nest brace, such as,
+ // { { ok: string } }
+ //
+ // therefore, scanning type expression with balancing braces.
+ function parseType(title, last) {
+ var ch, brace, type, direct = false;
+
+
+ // search '{'
+ while (index < last) {
+ ch = source.charCodeAt(index);
+ if (esutils.code.isWhiteSpace(ch)) {
+ advance();
+ } else if (ch === 0x7B /* '{' */) {
+ advance();
+ break;
+ } else {
+ // this is direct pattern
+ direct = true;
+ break;
+ }
+ }
+
+
+ if (direct) {
+ return null;
+ }
+
+ // type expression { is found
+ brace = 1;
+ type = '';
+ while (index < last) {
+ ch = source.charCodeAt(index);
+ if (esutils.code.isLineTerminator(ch)) {
+ advance();
+ } else {
+ if (ch === 0x7D /* '}' */) {
+ brace -= 1;
+ if (brace === 0) {
+ advance();
+ break;
+ }
+ } else if (ch === 0x7B /* '{' */) {
+ brace += 1;
+ }
+ type += advance();
+ }
+ }
+
+ if (brace !== 0) {
+ // braces is not balanced
+ return utility.throwError('Braces are not balanced');
+ }
+
+ if (isParamTitle(title)) {
+ return typed.parseParamType(type);
+ }
+ return typed.parseType(type);
+ }
+
+ function scanIdentifier(last) {
+ var identifier;
+ if (!esutils.code.isIdentifierStart(source.charCodeAt(index))) {
+ return null;
+ }
+ identifier = advance();
+ while (index < last && esutils.code.isIdentifierPart(source.charCodeAt(index))) {
+ identifier += advance();
+ }
+ return identifier;
+ }
+
+ function skipWhiteSpace(last) {
+ while (index < last && (esutils.code.isWhiteSpace(source.charCodeAt(index)) || esutils.code.isLineTerminator(source.charCodeAt(index)))) {
+ advance();
+ }
+ }
+
+ function parseName(last, allowBrackets, allowNestedParams) {
+ var name = '', useBrackets;
+
+ skipWhiteSpace(last);
+
+ if (index >= last) {
+ return null;
+ }
+
+ if (allowBrackets && source.charCodeAt(index) === 0x5B /* '[' */) {
+ useBrackets = true;
+ name = advance();
+ }
+
+ if (!esutils.code.isIdentifierStart(source.charCodeAt(index))) {
+ return null;
+ }
+
+ name += scanIdentifier(last);
+
+ if (allowNestedParams) {
+ if (source.charCodeAt(index) === 0x3A /* ':' */ && (
+ name === 'module' ||
+ name === 'external' ||
+ name === 'event')) {
+ name += advance();
+ name += scanIdentifier(last);
+
+ }
+ while (source.charCodeAt(index) === 0x2E /* '.' */ ||
+ source.charCodeAt(index) === 0x23 /* '#' */ ||
+ source.charCodeAt(index) === 0x7E /* '~' */) {
+ name += advance();
+ name += scanIdentifier(last);
+ }
+ }
+
+ if (useBrackets) {
+ // do we have a default value for this?
+ if (source.charCodeAt(index) === 0x3D /* '=' */) {
+
+ // consume the '='' symbol
+ name += advance();
+ // scan in the default value
+ while (index < last && source.charCodeAt(index) !== 0x5D /* ']' */) {
+ name += advance();
+ }
+ }
+
+ if (index >= last || source.charCodeAt(index) !== 0x5D /* ']' */) {
+ // we never found a closing ']'
+ return null;
+ }
+
+ // collect the last ']'
+ name += advance();
+ }
+
+ return name;
+ }
+
+ function skipToTag() {
+ while (index < length && source.charCodeAt(index) !== 0x40 /* '@' */) {
+ advance();
+ }
+ if (index >= length) {
+ return false;
+ }
+ utility.assert(source.charCodeAt(index) === 0x40 /* '@' */);
+ return true;
+ }
+
+ function TagParser(options, title) {
+ this._options = options;
+ this._title = title;
+ this._tag = {
+ title: title,
+ description: null
+ };
+ if (this._options.lineNumbers) {
+ this._tag.lineNumber = lineNumber;
+ }
+ this._last = 0;
+ // space to save special information for title parsers.
+ this._extra = { };
+ }
+
+ // addError(err, ...)
+ TagParser.prototype.addError = function addError(errorText) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ msg = errorText.replace(
+ /%(\d)/g,
+ function (whole, index) {
+ utility.assert(index < args.length, 'Message reference must be in range');
+ return args[index];
+ }
+ );
+
+ if (!this._tag.errors) {
+ this._tag.errors = [];
+ }
+ if (strict) {
+ utility.throwError(msg);
+ }
+ this._tag.errors.push(msg);
+ return recoverable;
+ };
+
+ TagParser.prototype.parseType = function () {
+ // type required titles
+ if (isTypeParameterRequired(this._title)) {
+ try {
+ this._tag.type = parseType(this._title, this._last);
+ if (!this._tag.type) {
+ if (!isParamTitle(this._title)) {
+ if (!this.addError('Missing or invalid tag type')) {
+ return false;
+ }
+ }
+ }
+ } catch (error) {
+ this._tag.type = null;
+ if (!this.addError(error.message)) {
+ return false;
+ }
+ }
+ } else if (isAllowedType(this._title)) {
+ // optional types
+ try {
+ this._tag.type = parseType(this._title, this._last);
+ } catch (e) {
+ //For optional types, lets drop the thrown error when we hit the end of the file
+ }
+ }
+ return true;
+ };
+
+ TagParser.prototype._parseNamePath = function (optional) {
+ var name;
+ name = parseName(this._last, sloppy && isParamTitle(this._title), true);
+ if (!name) {
+ if (!optional) {
+ if (!this.addError('Missing or invalid tag name')) {
+ return false;
+ }
+ }
+ }
+ this._tag.name = name;
+ return true;
+ };
+
+ TagParser.prototype.parseNamePath = function () {
+ return this._parseNamePath(false);
+ };
+
+ TagParser.prototype.parseNamePathOptional = function () {
+ return this._parseNamePath(true);
+ };
+
+
+ TagParser.prototype.parseName = function () {
+ var assign, name;
+
+ // param, property requires name
+ if (isAllowedName(this._title)) {
+ this._tag.name = parseName(this._last, sloppy && isParamTitle(this._title), isAllowedNested(this._title));
+ if (!this._tag.name) {
+ if (!isNameParameterRequired(this._title)) {
+ return true;
+ }
+
+ // it's possible the name has already been parsed but interpreted as a type
+ // it's also possible this is a sloppy declaration, in which case it will be
+ // fixed at the end
+ if (isParamTitle(this._title) && this._tag.type && this._tag.type.name) {
+ this._extra.name = this._tag.type;
+ this._tag.name = this._tag.type.name;
+ this._tag.type = null;
+ } else {
+ if (!this.addError('Missing or invalid tag name')) {
+ return false;
+ }
+ }
+ } else {
+ name = this._tag.name;
+ if (name.charAt(0) === '[' && name.charAt(name.length - 1) === ']') {
+ // extract the default value if there is one
+ // example: @param {string} [somebody=John Doe] description
+ assign = name.substring(1, name.length - 1).split('=');
+ if (assign[1]) {
+ this._tag['default'] = assign[1];
+ }
+ this._tag.name = assign[0];
+
+ // convert to an optional type
+ if (this._tag.type && this._tag.type.type !== 'OptionalType') {
+ this._tag.type = {
+ type: 'OptionalType',
+ expression: this._tag.type
+ };
+ }
+ }
+ }
+ }
+
+ return true;
+ };
+
+ TagParser.prototype.parseDescription = function parseDescription() {
+ var description = trim(sliceSource(source, index, this._last));
+ if (description) {
+ if ((/^-\s+/).test(description)) {
+ description = description.substring(2);
+ }
+ this._tag.description = description;
+ }
+ return true;
+ };
+
+ TagParser.prototype.parseKind = function parseKind() {
+ var kind, kinds;
+ kinds = {
+ 'class': true,
+ 'constant': true,
+ 'event': true,
+ 'external': true,
+ 'file': true,
+ 'function': true,
+ 'member': true,
+ 'mixin': true,
+ 'module': true,
+ 'namespace': true,
+ 'typedef': true
+ };
+ kind = trim(sliceSource(source, index, this._last));
+ this._tag.kind = kind;
+ if (!hasOwnProperty(kinds, kind)) {
+ if (!this.addError('Invalid kind name \'%0\'', kind)) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ TagParser.prototype.parseAccess = function parseAccess() {
+ var access;
+ access = trim(sliceSource(source, index, this._last));
+ this._tag.access = access;
+ if (access !== 'private' && access !== 'protected' && access !== 'public') {
+ if (!this.addError('Invalid access name \'%0\'', access)) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ TagParser.prototype.parseVariation = function parseVariation() {
+ var variation, text;
+ text = trim(sliceSource(source, index, this._last));
+ variation = parseFloat(text, 10);
+ this._tag.variation = variation;
+ if (isNaN(variation)) {
+ if (!this.addError('Invalid variation \'%0\'', text)) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ TagParser.prototype.ensureEnd = function () {
+ var shouldBeEmpty = trim(sliceSource(source, index, this._last));
+ if (shouldBeEmpty) {
+ if (!this.addError('Unknown content \'%0\'', shouldBeEmpty)) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ TagParser.prototype.epilogue = function epilogue() {
+ var description;
+
+ description = this._tag.description;
+ // un-fix potentially sloppy declaration
+ if (isParamTitle(this._title) && !this._tag.type && description && description.charAt(0) === '[') {
+ this._tag.type = this._extra.name;
+ this._tag.name = undefined;
+
+ if (!sloppy) {
+ if (!this.addError('Missing or invalid tag name')) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ };
+
+ Rules = {
+ // http://usejsdoc.org/tags-access.html
+ 'access': ['parseAccess'],
+ // http://usejsdoc.org/tags-alias.html
+ 'alias': ['parseNamePath', 'ensureEnd'],
+ // http://usejsdoc.org/tags-augments.html
+ 'augments': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // http://usejsdoc.org/tags-constructor.html
+ 'constructor': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // Synonym: http://usejsdoc.org/tags-constructor.html
+ 'class': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // Synonym: http://usejsdoc.org/tags-extends.html
+ 'extends': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // http://usejsdoc.org/tags-deprecated.html
+ 'deprecated': ['parseDescription'],
+ // http://usejsdoc.org/tags-global.html
+ 'global': ['ensureEnd'],
+ // http://usejsdoc.org/tags-inner.html
+ 'inner': ['ensureEnd'],
+ // http://usejsdoc.org/tags-instance.html
+ 'instance': ['ensureEnd'],
+ // http://usejsdoc.org/tags-kind.html
+ 'kind': ['parseKind'],
+ // http://usejsdoc.org/tags-mixes.html
+ 'mixes': ['parseNamePath', 'ensureEnd'],
+ // http://usejsdoc.org/tags-mixin.html
+ 'mixin': ['parseNamePathOptional', 'ensureEnd'],
+ // http://usejsdoc.org/tags-member.html
+ 'member': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // http://usejsdoc.org/tags-method.html
+ 'method': ['parseNamePathOptional', 'ensureEnd'],
+ // http://usejsdoc.org/tags-module.html
+ 'module': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // Synonym: http://usejsdoc.org/tags-method.html
+ 'func': ['parseNamePathOptional', 'ensureEnd'],
+ // Synonym: http://usejsdoc.org/tags-method.html
+ 'function': ['parseNamePathOptional', 'ensureEnd'],
+ // Synonym: http://usejsdoc.org/tags-member.html
+ 'var': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // http://usejsdoc.org/tags-name.html
+ 'name': ['parseNamePath', 'ensureEnd'],
+ // http://usejsdoc.org/tags-namespace.html
+ 'namespace': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // http://usejsdoc.org/tags-private.html
+ 'private': ['parseType', 'parseDescription'],
+ // http://usejsdoc.org/tags-protected.html
+ 'protected': ['parseType', 'parseDescription'],
+ // http://usejsdoc.org/tags-public.html
+ 'public': ['parseType', 'parseDescription'],
+ // http://usejsdoc.org/tags-readonly.html
+ 'readonly': ['ensureEnd'],
+ // http://usejsdoc.org/tags-requires.html
+ 'requires': ['parseNamePath', 'ensureEnd'],
+ // http://usejsdoc.org/tags-since.html
+ 'since': ['parseDescription'],
+ // http://usejsdoc.org/tags-static.html
+ 'static': ['ensureEnd'],
+ // http://usejsdoc.org/tags-summary.html
+ 'summary': ['parseDescription'],
+ // http://usejsdoc.org/tags-this.html
+ 'this': ['parseNamePath', 'ensureEnd'],
+ // http://usejsdoc.org/tags-todo.html
+ 'todo': ['parseDescription'],
+ // http://usejsdoc.org/tags-variation.html
+ 'variation': ['parseVariation'],
+ // http://usejsdoc.org/tags-version.html
+ 'version': ['parseDescription']
+ };
+
+ TagParser.prototype.parse = function parse() {
+ var i, iz, sequences, method;
+
+ // empty title
+ if (!this._title) {
+ if (!this.addError('Missing or invalid title')) {
+ return null;
+ }
+ }
+
+ // Seek to content last index.
+ this._last = seekContent(this._title);
+
+ if (hasOwnProperty(Rules, this._title)) {
+ sequences = Rules[this._title];
+ } else {
+ // default sequences
+ sequences = ['parseType', 'parseName', 'parseDescription', 'epilogue'];
+ }
+
+ for (i = 0, iz = sequences.length; i < iz; ++i) {
+ method = sequences[i];
+ if (!this[method]()) {
+ return null;
+ }
+ }
+
+ // Seek global index to end of this tag.
+ index = this._last;
+ return this._tag;
+ };
+
+ function parseTag(options) {
+ var title, parser;
+
+ // skip to tag
+ if (!skipToTag()) {
+ return null;
+ }
+
+ // scan title
+ title = scanTitle();
+
+ // construct tag parser
+ parser = new TagParser(options, title);
+ return parser.parse();
+ }
+
+ //
+ // Parse JSDoc
+ //
+
+ function scanJSDocDescription() {
+ var description = '', ch, atAllowed;
+
+ atAllowed = true;
+ while (index < length) {
+ ch = source.charCodeAt(index);
+
+ if (atAllowed && ch === 0x40 /* '@' */) {
+ break;
+ }
+
+ if (esutils.code.isLineTerminator(ch)) {
+ atAllowed = true;
+ } else if (atAllowed && !esutils.code.isWhiteSpace(ch)) {
+ atAllowed = false;
+ }
+
+ description += advance();
+ }
+ return trim(description);
+ }
+
+ function parse(comment, options) {
+ var tags = [], tag, description, interestingTags, i, iz;
+
+ if (options === undefined) {
+ options = {};
+ }
+
+ if (typeof options.unwrap === 'boolean' && options.unwrap) {
+ source = unwrapComment(comment);
+ } else {
+ source = comment;
+ }
+
+ // array of relevant tags
+ if (options.tags) {
+ if (isArray(options.tags)) {
+ interestingTags = { };
+ for (i = 0, iz = options.tags.length; i < iz; i++) {
+ if (typeof options.tags[i] === 'string') {
+ interestingTags[options.tags[i]] = true;
+ } else {
+ utility.throwError('Invalid "tags" parameter: ' + options.tags);
+ }
+ }
+ } else {
+ utility.throwError('Invalid "tags" parameter: ' + options.tags);
+ }
+ }
+
+ length = source.length;
+ index = 0;
+ lineNumber = 0;
+ recoverable = options.recoverable;
+ sloppy = options.sloppy;
+ strict = options.strict;
+
+ description = scanJSDocDescription();
+
+ while (true) {
+ tag = parseTag(options);
+ if (!tag) {
+ break;
+ }
+ if (!interestingTags || interestingTags.hasOwnProperty(tag.title)) {
+ tags.push(tag);
+ }
+ }
+
+ return {
+ description: description,
+ tags: tags
+ };
+ }
+ exports.parse = parse;
+ }(jsdoc = {}));
+
+ exports.version = utility.VERSION;
+ exports.parse = jsdoc.parse;
+ exports.parseType = typed.parseType;
+ exports.parseParamType = typed.parseParamType;
+ exports.unwrapComment = unwrapComment;
+ exports.Syntax = shallowCopy(typed.Syntax);
+ exports.Error = utility.DoctrineError;
+ exports.type = {
+ Syntax: exports.Syntax,
+ parseType: typed.parseType,
+ parseParamType: typed.parseParamType,
+ stringify: typed.stringify
+ };
+}());
+/* vim: set sw=4 ts=4 et tw=80 : */
diff --git a/tools/eslint/node_modules/doctrine/lib/typed.js b/tools/eslint/node_modules/doctrine/lib/typed.js
new file mode 100644
index 0000000000..2b02000e63
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/lib/typed.js
@@ -0,0 +1,1261 @@
+/*
+ Copyright (C) 2012-2014 Yusuke Suzuki <utatane.tea@gmail.com>
+ Copyright (C) 2014 Dan Tao <daniel.tao@gmail.com>
+ Copyright (C) 2013 Andrew Eisenberg <andrew@eisenberg.as>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// "typed", the Type Expression Parser for doctrine.
+
+(function () {
+ 'use strict';
+
+ var Syntax,
+ Token,
+ source,
+ length,
+ index,
+ previous,
+ token,
+ value,
+ esutils,
+ utility;
+
+ esutils = require('esutils');
+ utility = require('./utility');
+
+ Syntax = {
+ NullableLiteral: 'NullableLiteral',
+ AllLiteral: 'AllLiteral',
+ NullLiteral: 'NullLiteral',
+ UndefinedLiteral: 'UndefinedLiteral',
+ VoidLiteral: 'VoidLiteral',
+ UnionType: 'UnionType',
+ ArrayType: 'ArrayType',
+ RecordType: 'RecordType',
+ FieldType: 'FieldType',
+ FunctionType: 'FunctionType',
+ ParameterType: 'ParameterType',
+ RestType: 'RestType',
+ NonNullableType: 'NonNullableType',
+ OptionalType: 'OptionalType',
+ NullableType: 'NullableType',
+ NameExpression: 'NameExpression',
+ TypeApplication: 'TypeApplication'
+ };
+
+ Token = {
+ ILLEGAL: 0, // ILLEGAL
+ DOT_LT: 1, // .<
+ REST: 2, // ...
+ LT: 3, // <
+ GT: 4, // >
+ LPAREN: 5, // (
+ RPAREN: 6, // )
+ LBRACE: 7, // {
+ RBRACE: 8, // }
+ LBRACK: 9, // [
+ RBRACK: 10, // ]
+ COMMA: 11, // ,
+ COLON: 12, // :
+ STAR: 13, // *
+ PIPE: 14, // |
+ QUESTION: 15, // ?
+ BANG: 16, // !
+ EQUAL: 17, // =
+ NAME: 18, // name token
+ STRING: 19, // string
+ NUMBER: 20, // number
+ EOF: 21
+ };
+
+ function isTypeName(ch) {
+ return '><(){}[],:*|?!='.indexOf(String.fromCharCode(ch)) === -1 && !esutils.code.isWhiteSpace(ch) && !esutils.code.isLineTerminator(ch);
+ }
+
+ function Context(previous, index, token, value) {
+ this._previous = previous;
+ this._index = index;
+ this._token = token;
+ this._value = value;
+ }
+
+ Context.prototype.restore = function () {
+ previous = this._previous;
+ index = this._index;
+ token = this._token;
+ value = this._value;
+ };
+
+ Context.save = function () {
+ return new Context(previous, index, token, value);
+ };
+
+ function advance() {
+ var ch = source.charAt(index);
+ index += 1;
+ return ch;
+ }
+
+ function scanHexEscape(prefix) {
+ var i, len, ch, code = 0;
+
+ len = (prefix === 'u') ? 4 : 2;
+ for (i = 0; i < len; ++i) {
+ if (index < length && esutils.code.isHexDigit(source.charCodeAt(index))) {
+ ch = advance();
+ code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
+ } else {
+ return '';
+ }
+ }
+ return String.fromCharCode(code);
+ }
+
+ function scanString() {
+ var str = '', quote, ch, code, unescaped, restore; //TODO review removal octal = false
+ quote = source.charAt(index);
+ ++index;
+
+ while (index < length) {
+ ch = advance();
+
+ if (ch === quote) {
+ quote = '';
+ break;
+ } else if (ch === '\\') {
+ ch = advance();
+ if (!esutils.code.isLineTerminator(ch.charCodeAt(0))) {
+ switch (ch) {
+ case 'n':
+ str += '\n';
+ break;
+ case 'r':
+ str += '\r';
+ break;
+ case 't':
+ str += '\t';
+ break;
+ case 'u':
+ case 'x':
+ restore = index;
+ unescaped = scanHexEscape(ch);
+ if (unescaped) {
+ str += unescaped;
+ } else {
+ index = restore;
+ str += ch;
+ }
+ break;
+ case 'b':
+ str += '\b';
+ break;
+ case 'f':
+ str += '\f';
+ break;
+ case 'v':
+ str += '\v';
+ break;
+
+ default:
+ if (esutils.code.isOctalDigit(ch.charCodeAt(0))) {
+ code = '01234567'.indexOf(ch);
+
+ // \0 is not octal escape sequence
+ // Deprecating unused code. TODO review removal
+ //if (code !== 0) {
+ // octal = true;
+ //}
+
+ if (index < length && esutils.code.isOctalDigit(source.charCodeAt(index))) {
+ //TODO Review Removal octal = true;
+ code = code * 8 + '01234567'.indexOf(advance());
+
+ // 3 digits are only allowed when string starts
+ // with 0, 1, 2, 3
+ if ('0123'.indexOf(ch) >= 0 &&
+ index < length &&
+ esutils.code.isOctalDigit(source.charCodeAt(index))) {
+ code = code * 8 + '01234567'.indexOf(advance());
+ }
+ }
+ str += String.fromCharCode(code);
+ } else {
+ str += ch;
+ }
+ break;
+ }
+ } else {
+ if (ch === '\r' && source.charCodeAt(index) === 0x0A /* '\n' */) {
+ ++index;
+ }
+ }
+ } else if (esutils.code.isLineTerminator(ch.charCodeAt(0))) {
+ break;
+ } else {
+ str += ch;
+ }
+ }
+
+ if (quote !== '') {
+ utility.throwError('unexpected quote');
+ }
+
+ value = str;
+ return Token.STRING;
+ }
+
+ function scanNumber() {
+ var number, ch;
+
+ number = '';
+ ch = source.charCodeAt(index);
+
+ if (ch !== 0x2E /* '.' */) {
+ number = advance();
+ ch = source.charCodeAt(index);
+
+ if (number === '0') {
+ if (ch === 0x78 /* 'x' */ || ch === 0x58 /* 'X' */) {
+ number += advance();
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (!esutils.code.isHexDigit(ch)) {
+ break;
+ }
+ number += advance();
+ }
+
+ if (number.length <= 2) {
+ // only 0x
+ utility.throwError('unexpected token');
+ }
+
+ if (index < length) {
+ ch = source.charCodeAt(index);
+ if (esutils.code.isIdentifierStart(ch)) {
+ utility.throwError('unexpected token');
+ }
+ }
+ value = parseInt(number, 16);
+ return Token.NUMBER;
+ }
+
+ if (esutils.code.isOctalDigit(ch)) {
+ number += advance();
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (!esutils.code.isOctalDigit(ch)) {
+ break;
+ }
+ number += advance();
+ }
+
+ if (index < length) {
+ ch = source.charCodeAt(index);
+ if (esutils.code.isIdentifierStart(ch) || esutils.code.isDecimalDigit(ch)) {
+ utility.throwError('unexpected token');
+ }
+ }
+ value = parseInt(number, 8);
+ return Token.NUMBER;
+ }
+
+ if (esutils.code.isDecimalDigit(ch)) {
+ utility.throwError('unexpected token');
+ }
+ }
+
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (!esutils.code.isDecimalDigit(ch)) {
+ break;
+ }
+ number += advance();
+ }
+ }
+
+ if (ch === 0x2E /* '.' */) {
+ number += advance();
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (!esutils.code.isDecimalDigit(ch)) {
+ break;
+ }
+ number += advance();
+ }
+ }
+
+ if (ch === 0x65 /* 'e' */ || ch === 0x45 /* 'E' */) {
+ number += advance();
+
+ ch = source.charCodeAt(index);
+ if (ch === 0x2B /* '+' */ || ch === 0x2D /* '-' */) {
+ number += advance();
+ }
+
+ ch = source.charCodeAt(index);
+ if (esutils.code.isDecimalDigit(ch)) {
+ number += advance();
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (!esutils.code.isDecimalDigit(ch)) {
+ break;
+ }
+ number += advance();
+ }
+ } else {
+ utility.throwError('unexpected token');
+ }
+ }
+
+ if (index < length) {
+ ch = source.charCodeAt(index);
+ if (esutils.code.isIdentifierStart(ch)) {
+ utility.throwError('unexpected token');
+ }
+ }
+
+ value = parseFloat(number);
+ return Token.NUMBER;
+ }
+
+
+ function scanTypeName() {
+ var ch, ch2;
+
+ value = advance();
+ while (index < length && isTypeName(source.charCodeAt(index))) {
+ ch = source.charCodeAt(index);
+ if (ch === 0x2E /* '.' */) {
+ if ((index + 1) >= length) {
+ return Token.ILLEGAL;
+ }
+ ch2 = source.charCodeAt(index + 1);
+ if (ch2 === 0x3C /* '<' */) {
+ break;
+ }
+ }
+ value += advance();
+ }
+ return Token.NAME;
+ }
+
+ function next() {
+ var ch;
+
+ previous = index;
+
+ while (index < length && esutils.code.isWhiteSpace(source.charCodeAt(index))) {
+ advance();
+ }
+ if (index >= length) {
+ token = Token.EOF;
+ return token;
+ }
+
+ ch = source.charCodeAt(index);
+ switch (ch) {
+ case 0x27: /* ''' */
+ case 0x22: /* '"' */
+ token = scanString();
+ return token;
+
+ case 0x3A: /* ':' */
+ advance();
+ token = Token.COLON;
+ return token;
+
+ case 0x2C: /* ',' */
+ advance();
+ token = Token.COMMA;
+ return token;
+
+ case 0x28: /* '(' */
+ advance();
+ token = Token.LPAREN;
+ return token;
+
+ case 0x29: /* ')' */
+ advance();
+ token = Token.RPAREN;
+ return token;
+
+ case 0x5B: /* '[' */
+ advance();
+ token = Token.LBRACK;
+ return token;
+
+ case 0x5D: /* ']' */
+ advance();
+ token = Token.RBRACK;
+ return token;
+
+ case 0x7B: /* '{' */
+ advance();
+ token = Token.LBRACE;
+ return token;
+
+ case 0x7D: /* '}' */
+ advance();
+ token = Token.RBRACE;
+ return token;
+
+ case 0x2E: /* '.' */
+ if (index + 1 < length) {
+ ch = source.charCodeAt(index + 1);
+ if (ch === 0x3C /* '<' */) {
+ advance(); // '.'
+ advance(); // '<'
+ token = Token.DOT_LT;
+ return token;
+ }
+
+ if (ch === 0x2E /* '.' */ && index + 2 < length && source.charCodeAt(index + 2) === 0x2E /* '.' */) {
+ advance(); // '.'
+ advance(); // '.'
+ advance(); // '.'
+ token = Token.REST;
+ return token;
+ }
+
+ if (esutils.code.isDecimalDigit(ch)) {
+ token = scanNumber();
+ return token;
+ }
+ }
+ token = Token.ILLEGAL;
+ return token;
+
+ case 0x3C: /* '<' */
+ advance();
+ token = Token.LT;
+ return token;
+
+ case 0x3E: /* '>' */
+ advance();
+ token = Token.GT;
+ return token;
+
+ case 0x2A: /* '*' */
+ advance();
+ token = Token.STAR;
+ return token;
+
+ case 0x7C: /* '|' */
+ advance();
+ token = Token.PIPE;
+ return token;
+
+ case 0x3F: /* '?' */
+ advance();
+ token = Token.QUESTION;
+ return token;
+
+ case 0x21: /* '!' */
+ advance();
+ token = Token.BANG;
+ return token;
+
+ case 0x3D: /* '=' */
+ advance();
+ token = Token.EQUAL;
+ return token;
+
+ default:
+ if (esutils.code.isDecimalDigit(ch)) {
+ token = scanNumber();
+ return token;
+ }
+
+ // type string permits following case,
+ //
+ // namespace.module.MyClass
+ //
+ // this reduced 1 token TK_NAME
+ utility.assert(isTypeName(ch));
+ token = scanTypeName();
+ return token;
+ }
+ }
+
+ function consume(target, text) {
+ utility.assert(token === target, text || 'consumed token not matched');
+ next();
+ }
+
+ function expect(target, message) {
+ if (token !== target) {
+ utility.throwError(message || 'unexpected token');
+ }
+ next();
+ }
+
+ // UnionType := '(' TypeUnionList ')'
+ //
+ // TypeUnionList :=
+ // <<empty>>
+ // | NonemptyTypeUnionList
+ //
+ // NonemptyTypeUnionList :=
+ // TypeExpression
+ // | TypeExpression '|' NonemptyTypeUnionList
+ function parseUnionType() {
+ var elements;
+ consume(Token.LPAREN, 'UnionType should start with (');
+ elements = [];
+ if (token !== Token.RPAREN) {
+ while (true) {
+ elements.push(parseTypeExpression());
+ if (token === Token.RPAREN) {
+ break;
+ }
+ expect(Token.PIPE);
+ }
+ }
+ consume(Token.RPAREN, 'UnionType should end with )');
+ return {
+ type: Syntax.UnionType,
+ elements: elements
+ };
+ }
+
+ // ArrayType := '[' ElementTypeList ']'
+ //
+ // ElementTypeList :=
+ // <<empty>>
+ // | TypeExpression
+ // | '...' TypeExpression
+ // | TypeExpression ',' ElementTypeList
+ function parseArrayType() {
+ var elements;
+ consume(Token.LBRACK, 'ArrayType should start with [');
+ elements = [];
+ while (token !== Token.RBRACK) {
+ if (token === Token.REST) {
+ consume(Token.REST);
+ elements.push({
+ type: Syntax.RestType,
+ expression: parseTypeExpression()
+ });
+ break;
+ } else {
+ elements.push(parseTypeExpression());
+ }
+ if (token !== Token.RBRACK) {
+ expect(Token.COMMA);
+ }
+ }
+ expect(Token.RBRACK);
+ return {
+ type: Syntax.ArrayType,
+ elements: elements
+ };
+ }
+
+ function parseFieldName() {
+ var v = value;
+ if (token === Token.NAME || token === Token.STRING) {
+ next();
+ return v;
+ }
+
+ if (token === Token.NUMBER) {
+ consume(Token.NUMBER);
+ return String(v);
+ }
+
+ utility.throwError('unexpected token');
+ }
+
+ // FieldType :=
+ // FieldName
+ // | FieldName ':' TypeExpression
+ //
+ // FieldName :=
+ // NameExpression
+ // | StringLiteral
+ // | NumberLiteral
+ // | ReservedIdentifier
+ function parseFieldType() {
+ var key;
+
+ key = parseFieldName();
+ if (token === Token.COLON) {
+ consume(Token.COLON);
+ return {
+ type: Syntax.FieldType,
+ key: key,
+ value: parseTypeExpression()
+ };
+ }
+ return {
+ type: Syntax.FieldType,
+ key: key,
+ value: null
+ };
+ }
+
+ // RecordType := '{' FieldTypeList '}'
+ //
+ // FieldTypeList :=
+ // <<empty>>
+ // | FieldType
+ // | FieldType ',' FieldTypeList
+ function parseRecordType() {
+ var fields;
+
+ consume(Token.LBRACE, 'RecordType should start with {');
+ fields = [];
+ if (token === Token.COMMA) {
+ consume(Token.COMMA);
+ } else {
+ while (token !== Token.RBRACE) {
+ fields.push(parseFieldType());
+ if (token !== Token.RBRACE) {
+ expect(Token.COMMA);
+ }
+ }
+ }
+ expect(Token.RBRACE);
+ return {
+ type: Syntax.RecordType,
+ fields: fields
+ };
+ }
+
+ // NameExpression :=
+ // Identifier
+ // | TagIdentifier ':' Identifier
+ //
+ // Tag identifier is one of "module", "external" or "event"
+ // Identifier is the same as Token.NAME, including any dots, something like
+ // namespace.module.MyClass
+ function parseNameExpression() {
+ var name = value;
+ expect(Token.NAME);
+
+ if (token === Token.COLON && (
+ name === 'module' ||
+ name === 'external' ||
+ name === 'event')) {
+ consume(Token.COLON);
+ name += ':' + value;
+ expect(Token.NAME);
+ }
+
+ return {
+ type: Syntax.NameExpression,
+ name: name
+ };
+ }
+
+ // TypeExpressionList :=
+ // TopLevelTypeExpression
+ // | TopLevelTypeExpression ',' TypeExpressionList
+ function parseTypeExpressionList() {
+ var elements = [];
+
+ elements.push(parseTop());
+ while (token === Token.COMMA) {
+ consume(Token.COMMA);
+ elements.push(parseTop());
+ }
+ return elements;
+ }
+
+ // TypeName :=
+ // NameExpression
+ // | NameExpression TypeApplication
+ //
+ // TypeApplication :=
+ // '.<' TypeExpressionList '>'
+ // | '<' TypeExpressionList '>' // this is extension of doctrine
+ function parseTypeName() {
+ var expr, applications;
+
+ expr = parseNameExpression();
+ if (token === Token.DOT_LT || token === Token.LT) {
+ next();
+ applications = parseTypeExpressionList();
+ expect(Token.GT);
+ return {
+ type: Syntax.TypeApplication,
+ expression: expr,
+ applications: applications
+ };
+ }
+ return expr;
+ }
+
+ // ResultType :=
+ // <<empty>>
+ // | ':' void
+ // | ':' TypeExpression
+ //
+ // BNF is above
+ // but, we remove <<empty>> pattern, so token is always TypeToken::COLON
+ function parseResultType() {
+ consume(Token.COLON, 'ResultType should start with :');
+ if (token === Token.NAME && value === 'void') {
+ consume(Token.NAME);
+ return {
+ type: Syntax.VoidLiteral
+ };
+ }
+ return parseTypeExpression();
+ }
+
+ // ParametersType :=
+ // RestParameterType
+ // | NonRestParametersType
+ // | NonRestParametersType ',' RestParameterType
+ //
+ // RestParameterType :=
+ // '...'
+ // '...' Identifier
+ //
+ // NonRestParametersType :=
+ // ParameterType ',' NonRestParametersType
+ // | ParameterType
+ // | OptionalParametersType
+ //
+ // OptionalParametersType :=
+ // OptionalParameterType
+ // | OptionalParameterType, OptionalParametersType
+ //
+ // OptionalParameterType := ParameterType=
+ //
+ // ParameterType := TypeExpression | Identifier ':' TypeExpression
+ //
+ // Identifier is "new" or "this"
+ function parseParametersType() {
+ var params = [], optionalSequence = false, expr, rest = false;
+
+ while (token !== Token.RPAREN) {
+ if (token === Token.REST) {
+ // RestParameterType
+ consume(Token.REST);
+ rest = true;
+ }
+
+ expr = parseTypeExpression();
+ if (expr.type === Syntax.NameExpression && token === Token.COLON) {
+ // Identifier ':' TypeExpression
+ consume(Token.COLON);
+ expr = {
+ type: Syntax.ParameterType,
+ name: expr.name,
+ expression: parseTypeExpression()
+ };
+ }
+ if (token === Token.EQUAL) {
+ consume(Token.EQUAL);
+ expr = {
+ type: Syntax.OptionalType,
+ expression: expr
+ };
+ optionalSequence = true;
+ } else {
+ if (optionalSequence) {
+ utility.throwError('unexpected token');
+ }
+ }
+ if (rest) {
+ expr = {
+ type: Syntax.RestType,
+ expression: expr
+ };
+ }
+ params.push(expr);
+ if (token !== Token.RPAREN) {
+ expect(Token.COMMA);
+ }
+ }
+ return params;
+ }
+
+ // FunctionType := 'function' FunctionSignatureType
+ //
+ // FunctionSignatureType :=
+ // | TypeParameters '(' ')' ResultType
+ // | TypeParameters '(' ParametersType ')' ResultType
+ // | TypeParameters '(' 'this' ':' TypeName ')' ResultType
+ // | TypeParameters '(' 'this' ':' TypeName ',' ParametersType ')' ResultType
+ function parseFunctionType() {
+ var isNew, thisBinding, params, result, fnType;
+ utility.assert(token === Token.NAME && value === 'function', 'FunctionType should start with \'function\'');
+ consume(Token.NAME);
+
+ // Google Closure Compiler is not implementing TypeParameters.
+ // So we do not. if we don't get '(', we see it as error.
+ expect(Token.LPAREN);
+
+ isNew = false;
+ params = [];
+ thisBinding = null;
+ if (token !== Token.RPAREN) {
+ // ParametersType or 'this'
+ if (token === Token.NAME &&
+ (value === 'this' || value === 'new')) {
+ // 'this' or 'new'
+ // 'new' is Closure Compiler extension
+ isNew = value === 'new';
+ consume(Token.NAME);
+ expect(Token.COLON);
+ thisBinding = parseTypeName();
+ if (token === Token.COMMA) {
+ consume(Token.COMMA);
+ params = parseParametersType();
+ }
+ } else {
+ params = parseParametersType();
+ }
+ }
+
+ expect(Token.RPAREN);
+
+ result = null;
+ if (token === Token.COLON) {
+ result = parseResultType();
+ }
+
+ fnType = {
+ type: Syntax.FunctionType,
+ params: params,
+ result: result
+ };
+ if (thisBinding) {
+ // avoid adding null 'new' and 'this' properties
+ fnType['this'] = thisBinding;
+ if (isNew) {
+ fnType['new'] = true;
+ }
+ }
+ return fnType;
+ }
+
+ // BasicTypeExpression :=
+ // '*'
+ // | 'null'
+ // | 'undefined'
+ // | TypeName
+ // | FunctionType
+ // | UnionType
+ // | RecordType
+ // | ArrayType
+ function parseBasicTypeExpression() {
+ var context;
+ switch (token) {
+ case Token.STAR:
+ consume(Token.STAR);
+ return {
+ type: Syntax.AllLiteral
+ };
+
+ case Token.LPAREN:
+ return parseUnionType();
+
+ case Token.LBRACK:
+ return parseArrayType();
+
+ case Token.LBRACE:
+ return parseRecordType();
+
+ case Token.NAME:
+ if (value === 'null') {
+ consume(Token.NAME);
+ return {
+ type: Syntax.NullLiteral
+ };
+ }
+
+ if (value === 'undefined') {
+ consume(Token.NAME);
+ return {
+ type: Syntax.UndefinedLiteral
+ };
+ }
+
+ context = Context.save();
+ if (value === 'function') {
+ try {
+ return parseFunctionType();
+ } catch (e) {
+ context.restore();
+ }
+ }
+
+ return parseTypeName();
+
+ default:
+ utility.throwError('unexpected token');
+ }
+ }
+
+ // TypeExpression :=
+ // BasicTypeExpression
+ // | '?' BasicTypeExpression
+ // | '!' BasicTypeExpression
+ // | BasicTypeExpression '?'
+ // | BasicTypeExpression '!'
+ // | '?'
+ // | BasicTypeExpression '[]'
+ function parseTypeExpression() {
+ var expr;
+
+ if (token === Token.QUESTION) {
+ consume(Token.QUESTION);
+ if (token === Token.COMMA || token === Token.EQUAL || token === Token.RBRACE ||
+ token === Token.RPAREN || token === Token.PIPE || token === Token.EOF ||
+ token === Token.RBRACK || token === Token.GT) {
+ return {
+ type: Syntax.NullableLiteral
+ };
+ }
+ return {
+ type: Syntax.NullableType,
+ expression: parseBasicTypeExpression(),
+ prefix: true
+ };
+ }
+
+ if (token === Token.BANG) {
+ consume(Token.BANG);
+ return {
+ type: Syntax.NonNullableType,
+ expression: parseBasicTypeExpression(),
+ prefix: true
+ };
+ }
+
+ expr = parseBasicTypeExpression();
+ if (token === Token.BANG) {
+ consume(Token.BANG);
+ return {
+ type: Syntax.NonNullableType,
+ expression: expr,
+ prefix: false
+ };
+ }
+
+ if (token === Token.QUESTION) {
+ consume(Token.QUESTION);
+ return {
+ type: Syntax.NullableType,
+ expression: expr,
+ prefix: false
+ };
+ }
+
+ if (token === Token.LBRACK) {
+ consume(Token.LBRACK);
+ expect(Token.RBRACK, 'expected an array-style type declaration (' + value + '[])');
+ return {
+ type: Syntax.TypeApplication,
+ expression: {
+ type: Syntax.NameExpression,
+ name: 'Array'
+ },
+ applications: [expr]
+ };
+ }
+
+ return expr;
+ }
+
+ // TopLevelTypeExpression :=
+ // TypeExpression
+ // | TypeUnionList
+ //
+ // This rule is Google Closure Compiler extension, not ES4
+ // like,
+ // { number | string }
+ // If strict to ES4, we should write it as
+ // { (number|string) }
+ function parseTop() {
+ var expr, elements;
+
+ expr = parseTypeExpression();
+ if (token !== Token.PIPE) {
+ return expr;
+ }
+
+ elements = [ expr ];
+ consume(Token.PIPE);
+ while (true) {
+ elements.push(parseTypeExpression());
+ if (token !== Token.PIPE) {
+ break;
+ }
+ consume(Token.PIPE);
+ }
+
+ return {
+ type: Syntax.UnionType,
+ elements: elements
+ };
+ }
+
+ function parseTopParamType() {
+ var expr;
+
+ if (token === Token.REST) {
+ consume(Token.REST);
+ return {
+ type: Syntax.RestType,
+ expression: parseTop()
+ };
+ }
+
+ expr = parseTop();
+ if (token === Token.EQUAL) {
+ consume(Token.EQUAL);
+ return {
+ type: Syntax.OptionalType,
+ expression: expr
+ };
+ }
+
+ return expr;
+ }
+
+ function parseType(src, opt) {
+ var expr;
+
+ source = src;
+ length = source.length;
+ index = 0;
+ previous = 0;
+
+ next();
+ expr = parseTop();
+
+ if (opt && opt.midstream) {
+ return {
+ expression: expr,
+ index: previous
+ };
+ }
+
+ if (token !== Token.EOF) {
+ utility.throwError('not reach to EOF');
+ }
+
+ return expr;
+ }
+
+ function parseParamType(src, opt) {
+ var expr;
+
+ source = src;
+ length = source.length;
+ index = 0;
+ previous = 0;
+
+ next();
+ expr = parseTopParamType();
+
+ if (opt && opt.midstream) {
+ return {
+ expression: expr,
+ index: previous
+ };
+ }
+
+ if (token !== Token.EOF) {
+ utility.throwError('not reach to EOF');
+ }
+
+ return expr;
+ }
+
+ function stringifyImpl(node, compact, topLevel) {
+ var result, i, iz;
+
+ switch (node.type) {
+ case Syntax.NullableLiteral:
+ result = '?';
+ break;
+
+ case Syntax.AllLiteral:
+ result = '*';
+ break;
+
+ case Syntax.NullLiteral:
+ result = 'null';
+ break;
+
+ case Syntax.UndefinedLiteral:
+ result = 'undefined';
+ break;
+
+ case Syntax.VoidLiteral:
+ result = 'void';
+ break;
+
+ case Syntax.UnionType:
+ if (!topLevel) {
+ result = '(';
+ } else {
+ result = '';
+ }
+
+ for (i = 0, iz = node.elements.length; i < iz; ++i) {
+ result += stringifyImpl(node.elements[i], compact);
+ if ((i + 1) !== iz) {
+ result += '|';
+ }
+ }
+
+ if (!topLevel) {
+ result += ')';
+ }
+ break;
+
+ case Syntax.ArrayType:
+ result = '[';
+ for (i = 0, iz = node.elements.length; i < iz; ++i) {
+ result += stringifyImpl(node.elements[i], compact);
+ if ((i + 1) !== iz) {
+ result += compact ? ',' : ', ';
+ }
+ }
+ result += ']';
+ break;
+
+ case Syntax.RecordType:
+ result = '{';
+ for (i = 0, iz = node.fields.length; i < iz; ++i) {
+ result += stringifyImpl(node.fields[i], compact);
+ if ((i + 1) !== iz) {
+ result += compact ? ',' : ', ';
+ }
+ }
+ result += '}';
+ break;
+
+ case Syntax.FieldType:
+ if (node.value) {
+ result = node.key + (compact ? ':' : ': ') + stringifyImpl(node.value, compact);
+ } else {
+ result = node.key;
+ }
+ break;
+
+ case Syntax.FunctionType:
+ result = compact ? 'function(' : 'function (';
+
+ if (node['this']) {
+ if (node['new']) {
+ result += (compact ? 'new:' : 'new: ');
+ } else {
+ result += (compact ? 'this:' : 'this: ');
+ }
+
+ result += stringifyImpl(node['this'], compact);
+
+ if (node.params.length !== 0) {
+ result += compact ? ',' : ', ';
+ }
+ }
+
+ for (i = 0, iz = node.params.length; i < iz; ++i) {
+ result += stringifyImpl(node.params[i], compact);
+ if ((i + 1) !== iz) {
+ result += compact ? ',' : ', ';
+ }
+ }
+
+ result += ')';
+
+ if (node.result) {
+ result += (compact ? ':' : ': ') + stringifyImpl(node.result, compact);
+ }
+ break;
+
+ case Syntax.ParameterType:
+ result = node.name + (compact ? ':' : ': ') + stringifyImpl(node.expression, compact);
+ break;
+
+ case Syntax.RestType:
+ result = '...';
+ if (node.expression) {
+ result += stringifyImpl(node.expression, compact);
+ }
+ break;
+
+ case Syntax.NonNullableType:
+ if (node.prefix) {
+ result = '!' + stringifyImpl(node.expression, compact);
+ } else {
+ result = stringifyImpl(node.expression, compact) + '!';
+ }
+ break;
+
+ case Syntax.OptionalType:
+ result = stringifyImpl(node.expression, compact) + '=';
+ break;
+
+ case Syntax.NullableType:
+ if (node.prefix) {
+ result = '?' + stringifyImpl(node.expression, compact);
+ } else {
+ result = stringifyImpl(node.expression, compact) + '?';
+ }
+ break;
+
+ case Syntax.NameExpression:
+ result = node.name;
+ break;
+
+ case Syntax.TypeApplication:
+ result = stringifyImpl(node.expression, compact) + '.<';
+ for (i = 0, iz = node.applications.length; i < iz; ++i) {
+ result += stringifyImpl(node.applications[i], compact);
+ if ((i + 1) !== iz) {
+ result += compact ? ',' : ', ';
+ }
+ }
+ result += '>';
+ break;
+
+ default:
+ utility.throwError('Unknown type ' + node.type);
+ }
+
+ return result;
+ }
+
+ function stringify(node, options) {
+ if (options == null) {
+ options = {};
+ }
+ return stringifyImpl(node, options.compact, options.topLevel);
+ }
+
+ exports.parseType = parseType;
+ exports.parseParamType = parseParamType;
+ exports.stringify = stringify;
+ exports.Syntax = Syntax;
+}());
+/* vim: set sw=4 ts=4 et tw=80 : */
diff --git a/tools/eslint/node_modules/doctrine/lib/utility.js b/tools/eslint/node_modules/doctrine/lib/utility.js
new file mode 100644
index 0000000000..bb44125846
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/lib/utility.js
@@ -0,0 +1,54 @@
+/*
+ Copyright (C) 2014 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+(function () {
+ 'use strict';
+
+ var VERSION;
+
+ VERSION = require('../package.json').version;
+ exports.VERSION = VERSION;
+
+ function DoctrineError(message) {
+ this.name = 'DoctrineError';
+ this.message = message;
+ }
+ DoctrineError.prototype = (function () {
+ var Middle = function () { };
+ Middle.prototype = Error.prototype;
+ return new Middle();
+ }());
+ DoctrineError.prototype.constructor = DoctrineError;
+ exports.DoctrineError = DoctrineError;
+
+ function throwError(message) {
+ throw new DoctrineError(message);
+ }
+ exports.throwError = throwError;
+
+ exports.assert = require('assert');
+}());
+
+/* vim: set sw=4 ts=4 et tw=80 : */
diff --git a/tools/eslint/node_modules/doctrine/node_modules/esutils/LICENSE.BSD b/tools/eslint/node_modules/doctrine/node_modules/esutils/LICENSE.BSD
new file mode 100644
index 0000000000..3e580c355a
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/node_modules/esutils/LICENSE.BSD
@@ -0,0 +1,19 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tools/eslint/node_modules/doctrine/node_modules/esutils/README.md b/tools/eslint/node_modules/doctrine/node_modules/esutils/README.md
new file mode 100644
index 0000000000..494fac5eda
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/node_modules/esutils/README.md
@@ -0,0 +1,169 @@
+### esutils [![Build Status](https://secure.travis-ci.org/Constellation/esutils.svg)](http://travis-ci.org/Constellation/esutils)
+esutils ([esutils](http://github.com/Constellation/esutils)) is
+utility box for ECMAScript language tools.
+
+### API
+
+### ast
+
+#### ast.isExpression(node)
+
+Returns true if `node` is an Expression as defined in ECMA262 edition 5.1 section
+[11](https://es5.github.io/#x11).
+
+#### ast.isStatement(node)
+
+Returns true if `node` is a Statement as defined in ECMA262 edition 5.1 section
+[12](https://es5.github.io/#x12).
+
+#### ast.isIterationStatement(node)
+
+Returns true if `node` is an IterationStatement as defined in ECMA262 edition
+5.1 section [12.6](https://es5.github.io/#x12.6).
+
+#### ast.isSourceElement(node)
+
+Returns true if `node` is a SourceElement as defined in ECMA262 edition 5.1
+section [14](https://es5.github.io/#x14).
+
+#### ast.trailingStatement(node)
+
+Returns `Statement?` if `node` has trailing `Statement`.
+```js
+if (cond)
+ consequent;
+```
+When taking this `IfStatement`, returns `consequent;` statement.
+
+#### ast.isProblematicIfStatement(node)
+
+Returns true if `node` is a problematic IfStatement. If `node` is a problematic `IfStatement`, `node` cannot be represented as an one on one JavaScript code.
+```js
+{
+ type: 'IfStatement',
+ consequent: {
+ type: 'WithStatement',
+ body: {
+ type: 'IfStatement',
+ consequent: {type: 'EmptyStatement'}
+ }
+ },
+ alternate: {type: 'EmptyStatement'}
+}
+```
+The above node cannot be represented as a JavaScript code, since the top level `else` alternate belongs to an inner `IfStatement`.
+
+
+### code
+
+#### code.isDecimalDigit(code)
+
+Return true if provided code is decimal digit.
+
+#### code.isHexDigit(code)
+
+Return true if provided code is hexadecimal digit.
+
+#### code.isOctalDigit(code)
+
+Return true if provided code is octal digit.
+
+#### code.isWhiteSpace(code)
+
+Return true if provided code is white space. White space characters are formally defined in ECMA262.
+
+#### code.isLineTerminator(code)
+
+Return true if provided code is line terminator. Line terminator characters are formally defined in ECMA262.
+
+#### code.isIdentifierStart(code)
+
+Return true if provided code can be the first character of ECMA262 Identifier. They are formally defined in ECMA262.
+
+#### code.isIdentifierPart(code)
+
+Return true if provided code can be the trailing character of ECMA262 Identifier. They are formally defined in ECMA262.
+
+### keyword
+
+#### keyword.isKeywordES5(id, strict)
+
+Returns `true` if provided identifier string is a Keyword or Future Reserved Word
+in ECMA262 edition 5.1. They are formally defined in ECMA262 sections
+[7.6.1.1](http://es5.github.io/#x7.6.1.1) and [7.6.1.2](http://es5.github.io/#x7.6.1.2),
+respectively. If the `strict` flag is truthy, this function additionally checks whether
+`id` is a Keyword or Future Reserved Word under strict mode.
+
+#### keyword.isKeywordES6(id, strict)
+
+Returns `true` if provided identifier string is a Keyword or Future Reserved Word
+in ECMA262 edition 6. They are formally defined in ECMA262 sections
+[11.6.2.1](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-keywords) and
+[11.6.2.2](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-future-reserved-words),
+respectively. If the `strict` flag is truthy, this function additionally checks whether
+`id` is a Keyword or Future Reserved Word under strict mode.
+
+#### keyword.isReservedWordES5(id, strict)
+
+Returns `true` if provided identifier string is a Reserved Word in ECMA262 edition 5.1.
+They are formally defined in ECMA262 section [7.6.1](http://es5.github.io/#x7.6.1).
+If the `strict` flag is truthy, this function additionally checks whether `id`
+is a Reserved Word under strict mode.
+
+#### keyword.isReservedWordES6(id, strict)
+
+Returns `true` if provided identifier string is a Reserved Word in ECMA262 edition 6.
+They are formally defined in ECMA262 section [11.6.2](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-reserved-words).
+If the `strict` flag is truthy, this function additionally checks whether `id`
+is a Reserved Word under strict mode.
+
+#### keyword.isRestrictedWord(id)
+
+Returns `true` if provided identifier string is one of `eval` or `arguments`.
+They are restricted in strict mode code throughout ECMA262 edition 5.1 and
+in ECMA262 edition 6 section [12.1.1](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-identifiers-static-semantics-early-errors).
+
+#### keyword.isIdentifierName(id)
+
+Return true if provided identifier string is an IdentifierName as specified in
+ECMA262 edition 5.1 section [7.6](https://es5.github.io/#x7.6).
+
+#### keyword.isIdentifierES5(id, strict)
+
+Return true if provided identifier string is an Identifier as specified in
+ECMA262 edition 5.1 section [7.6](https://es5.github.io/#x7.6). If the `strict`
+flag is truthy, this function additionally checks whether `id` is an Identifier
+under strict mode.
+
+#### keyword.isIdentifierES6(id, strict)
+
+Return true if provided identifier string is an Identifier as specified in
+ECMA262 edition 6 section [12.1](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-identifiers).
+If the `strict` flag is truthy, this function additionally checks whether `id`
+is an Identifier under strict mode.
+
+### License
+
+Copyright (C) 2013 [Yusuke Suzuki](http://github.com/Constellation)
+ (twitter: [@Constellation](http://twitter.com/Constellation)) and other contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tools/eslint/node_modules/doctrine/node_modules/esutils/lib/ast.js b/tools/eslint/node_modules/doctrine/node_modules/esutils/lib/ast.js
new file mode 100644
index 0000000000..8faadae1ce
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/node_modules/esutils/lib/ast.js
@@ -0,0 +1,144 @@
+/*
+ Copyright (C) 2013 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+(function () {
+ 'use strict';
+
+ function isExpression(node) {
+ if (node == null) { return false; }
+ switch (node.type) {
+ case 'ArrayExpression':
+ case 'AssignmentExpression':
+ case 'BinaryExpression':
+ case 'CallExpression':
+ case 'ConditionalExpression':
+ case 'FunctionExpression':
+ case 'Identifier':
+ case 'Literal':
+ case 'LogicalExpression':
+ case 'MemberExpression':
+ case 'NewExpression':
+ case 'ObjectExpression':
+ case 'SequenceExpression':
+ case 'ThisExpression':
+ case 'UnaryExpression':
+ case 'UpdateExpression':
+ return true;
+ }
+ return false;
+ }
+
+ function isIterationStatement(node) {
+ if (node == null) { return false; }
+ switch (node.type) {
+ case 'DoWhileStatement':
+ case 'ForInStatement':
+ case 'ForStatement':
+ case 'WhileStatement':
+ return true;
+ }
+ return false;
+ }
+
+ function isStatement(node) {
+ if (node == null) { return false; }
+ switch (node.type) {
+ case 'BlockStatement':
+ case 'BreakStatement':
+ case 'ContinueStatement':
+ case 'DebuggerStatement':
+ case 'DoWhileStatement':
+ case 'EmptyStatement':
+ case 'ExpressionStatement':
+ case 'ForInStatement':
+ case 'ForStatement':
+ case 'IfStatement':
+ case 'LabeledStatement':
+ case 'ReturnStatement':
+ case 'SwitchStatement':
+ case 'ThrowStatement':
+ case 'TryStatement':
+ case 'VariableDeclaration':
+ case 'WhileStatement':
+ case 'WithStatement':
+ return true;
+ }
+ return false;
+ }
+
+ function isSourceElement(node) {
+ return isStatement(node) || node != null && node.type === 'FunctionDeclaration';
+ }
+
+ function trailingStatement(node) {
+ switch (node.type) {
+ case 'IfStatement':
+ if (node.alternate != null) {
+ return node.alternate;
+ }
+ return node.consequent;
+
+ case 'LabeledStatement':
+ case 'ForStatement':
+ case 'ForInStatement':
+ case 'WhileStatement':
+ case 'WithStatement':
+ return node.body;
+ }
+ return null;
+ }
+
+ function isProblematicIfStatement(node) {
+ var current;
+
+ if (node.type !== 'IfStatement') {
+ return false;
+ }
+ if (node.alternate == null) {
+ return false;
+ }
+ current = node.consequent;
+ do {
+ if (current.type === 'IfStatement') {
+ if (current.alternate == null) {
+ return true;
+ }
+ }
+ current = trailingStatement(current);
+ } while (current);
+
+ return false;
+ }
+
+ module.exports = {
+ isExpression: isExpression,
+ isStatement: isStatement,
+ isIterationStatement: isIterationStatement,
+ isSourceElement: isSourceElement,
+ isProblematicIfStatement: isProblematicIfStatement,
+
+ trailingStatement: trailingStatement
+ };
+}());
+/* vim: set sw=4 ts=4 et tw=80 : */
diff --git a/tools/eslint/node_modules/doctrine/node_modules/esutils/lib/code.js b/tools/eslint/node_modules/doctrine/node_modules/esutils/lib/code.js
new file mode 100644
index 0000000000..730292a347
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/node_modules/esutils/lib/code.js
@@ -0,0 +1,101 @@
+/*
+ Copyright (C) 2013-2014 Yusuke Suzuki <utatane.tea@gmail.com>
+ Copyright (C) 2014 Ivan Nikulin <ifaaan@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+(function () {
+ 'use strict';
+
+ var Regex, NON_ASCII_WHITESPACES;
+
+ // See `tools/generate-identifier-regex.js`.
+ Regex = {
+ NonAsciiIdentifierStart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'),
+ NonAsciiIdentifierPart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0\u08A2-\u08AC\u08E4-\u08FE\u0900-\u0963\u0966-\u096F\u0971-\u0977\u0979-\u097F\u0981-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C82\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D02\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191C\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1D00-\u1DE6\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA697\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7B\uAA80-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE26\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]')
+ };
+
+ function isDecimalDigit(ch) {
+ return (ch >= 48 && ch <= 57); // 0..9
+ }
+
+ function isHexDigit(ch) {
+ return isDecimalDigit(ch) || // 0..9
+ (97 <= ch && ch <= 102) || // a..f
+ (65 <= ch && ch <= 70); // A..F
+ }
+
+ function isOctalDigit(ch) {
+ return (ch >= 48 && ch <= 55); // 0..7
+ }
+
+ // 7.2 White Space
+
+ NON_ASCII_WHITESPACES = [
+ 0x1680, 0x180E,
+ 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A,
+ 0x202F, 0x205F,
+ 0x3000,
+ 0xFEFF
+ ];
+
+ function isWhiteSpace(ch) {
+ return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
+ (ch >= 0x1680 && NON_ASCII_WHITESPACES.indexOf(ch) >= 0);
+ }
+
+ // 7.3 Line Terminators
+
+ function isLineTerminator(ch) {
+ return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029);
+ }
+
+ // 7.6 Identifier Names and Identifiers
+
+ function isIdentifierStart(ch) {
+ return (ch >= 97 && ch <= 122) || // a..z
+ (ch >= 65 && ch <= 90) || // A..Z
+ (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore)
+ (ch === 92) || // \ (backslash)
+ ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
+ }
+
+ function isIdentifierPart(ch) {
+ return (ch >= 97 && ch <= 122) || // a..z
+ (ch >= 65 && ch <= 90) || // A..Z
+ (ch >= 48 && ch <= 57) || // 0..9
+ (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore)
+ (ch === 92) || // \ (backslash)
+ ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
+ }
+
+ module.exports = {
+ isDecimalDigit: isDecimalDigit,
+ isHexDigit: isHexDigit,
+ isOctalDigit: isOctalDigit,
+ isWhiteSpace: isWhiteSpace,
+ isLineTerminator: isLineTerminator,
+ isIdentifierStart: isIdentifierStart,
+ isIdentifierPart: isIdentifierPart
+ };
+}());
+/* vim: set sw=4 ts=4 et tw=80 : */
diff --git a/tools/eslint/node_modules/doctrine/node_modules/esutils/lib/keyword.js b/tools/eslint/node_modules/doctrine/node_modules/esutils/lib/keyword.js
new file mode 100644
index 0000000000..884be72fbe
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/node_modules/esutils/lib/keyword.js
@@ -0,0 +1,137 @@
+/*
+ Copyright (C) 2013 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+(function () {
+ 'use strict';
+
+ var code = require('./code');
+
+ function isStrictModeReservedWordES6(id) {
+ switch (id) {
+ case 'implements':
+ case 'interface':
+ case 'package':
+ case 'private':
+ case 'protected':
+ case 'public':
+ case 'static':
+ case 'let':
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ function isKeywordES5(id, strict) {
+ // yield should not be treated as keyword under non-strict mode.
+ if (!strict && id === 'yield') {
+ return false;
+ }
+ return isKeywordES6(id, strict);
+ }
+
+ function isKeywordES6(id, strict) {
+ if (strict && isStrictModeReservedWordES6(id)) {
+ return true;
+ }
+
+ switch (id.length) {
+ case 2:
+ return (id === 'if') || (id === 'in') || (id === 'do');
+ case 3:
+ return (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try');
+ case 4:
+ return (id === 'this') || (id === 'else') || (id === 'case') ||
+ (id === 'void') || (id === 'with') || (id === 'enum');
+ case 5:
+ return (id === 'while') || (id === 'break') || (id === 'catch') ||
+ (id === 'throw') || (id === 'const') || (id === 'yield') ||
+ (id === 'class') || (id === 'super');
+ case 6:
+ return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
+ (id === 'switch') || (id === 'export') || (id === 'import');
+ case 7:
+ return (id === 'default') || (id === 'finally') || (id === 'extends');
+ case 8:
+ return (id === 'function') || (id === 'continue') || (id === 'debugger');
+ case 10:
+ return (id === 'instanceof');
+ default:
+ return false;
+ }
+ }
+
+ function isReservedWordES5(id, strict) {
+ return id === 'null' || id === 'true' || id === 'false' || isKeywordES5(id, strict);
+ }
+
+ function isReservedWordES6(id, strict) {
+ return id === 'null' || id === 'true' || id === 'false' || isKeywordES6(id, strict);
+ }
+
+ function isRestrictedWord(id) {
+ return id === 'eval' || id === 'arguments';
+ }
+
+ function isIdentifierName(id) {
+ var i, iz, ch;
+
+ if (id.length === 0) {
+ return false;
+ }
+
+ ch = id.charCodeAt(0);
+ if (!code.isIdentifierStart(ch) || ch === 92) { // \ (backslash)
+ return false;
+ }
+
+ for (i = 1, iz = id.length; i < iz; ++i) {
+ ch = id.charCodeAt(i);
+ if (!code.isIdentifierPart(ch) || ch === 92) { // \ (backslash)
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function isIdentifierES5(id, strict) {
+ return isIdentifierName(id) && !isReservedWordES5(id, strict);
+ }
+
+ function isIdentifierES6(id, strict) {
+ return isIdentifierName(id) && !isReservedWordES6(id, strict);
+ }
+
+ module.exports = {
+ isKeywordES5: isKeywordES5,
+ isKeywordES6: isKeywordES6,
+ isReservedWordES5: isReservedWordES5,
+ isReservedWordES6: isReservedWordES6,
+ isRestrictedWord: isRestrictedWord,
+ isIdentifierName: isIdentifierName,
+ isIdentifierES5: isIdentifierES5,
+ isIdentifierES6: isIdentifierES6
+ };
+}());
+/* vim: set sw=4 ts=4 et tw=80 : */
diff --git a/tools/eslint/node_modules/doctrine/node_modules/esutils/lib/utils.js b/tools/eslint/node_modules/doctrine/node_modules/esutils/lib/utils.js
new file mode 100644
index 0000000000..ce18faa6bc
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/node_modules/esutils/lib/utils.js
@@ -0,0 +1,33 @@
+/*
+ Copyright (C) 2013 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+(function () {
+ 'use strict';
+
+ exports.ast = require('./ast');
+ exports.code = require('./code');
+ exports.keyword = require('./keyword');
+}());
+/* vim: set sw=4 ts=4 et tw=80 : */
diff --git a/tools/eslint/node_modules/doctrine/node_modules/esutils/package.json b/tools/eslint/node_modules/doctrine/node_modules/esutils/package.json
new file mode 100644
index 0000000000..b01fe6004b
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/node_modules/esutils/package.json
@@ -0,0 +1,66 @@
+{
+ "name": "esutils",
+ "description": "utility box for ECMAScript language tools",
+ "homepage": "https://github.com/Constellation/esutils",
+ "main": "lib/utils.js",
+ "version": "1.1.6",
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "directories": {
+ "lib": "./lib"
+ },
+ "files": [
+ "LICENSE.BSD",
+ "README.md",
+ "lib"
+ ],
+ "maintainers": [
+ {
+ "name": "constellation",
+ "email": "utatane.tea@gmail.com"
+ }
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git+ssh://git@github.com/Constellation/esutils.git"
+ },
+ "devDependencies": {
+ "mocha": "~1.12.0",
+ "chai": "~1.7.2",
+ "jshint": "2.1.5",
+ "coffee-script": "~1.6.3",
+ "unicode-6.3.0": "~0.1.1",
+ "regenerate": "~0.5.4"
+ },
+ "licenses": [
+ {
+ "type": "BSD",
+ "url": "http://github.com/Constellation/esutils/raw/master/LICENSE.BSD"
+ }
+ ],
+ "scripts": {
+ "test": "npm run-script lint && npm run-script unit-test",
+ "lint": "jshint lib/*.js",
+ "unit-test": "mocha --compilers coffee:coffee-script -R spec",
+ "generate-regex": "node tools/generate-identifier-regex.js"
+ },
+ "gitHead": "a91c5ed6199d1019ef071f610848fcd5103ef153",
+ "bugs": {
+ "url": "https://github.com/Constellation/esutils/issues"
+ },
+ "_id": "esutils@1.1.6",
+ "_shasum": "c01ccaa9ae4b897c6d0c3e210ae52f3c7a844375",
+ "_from": "esutils@>=1.1.6 <2.0.0",
+ "_npmVersion": "2.0.0-alpha-5",
+ "_npmUser": {
+ "name": "constellation",
+ "email": "utatane.tea@gmail.com"
+ },
+ "dist": {
+ "shasum": "c01ccaa9ae4b897c6d0c3e210ae52f3c7a844375",
+ "tarball": "http://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz"
+ },
+ "_resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz",
+ "readme": "ERROR: No README data found!"
+}
diff --git a/tools/eslint/node_modules/doctrine/node_modules/isarray/README.md b/tools/eslint/node_modules/doctrine/node_modules/isarray/README.md
new file mode 100644
index 0000000000..052a62b8d7
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/node_modules/isarray/README.md
@@ -0,0 +1,54 @@
+
+# isarray
+
+`Array#isArray` for older browsers.
+
+## Usage
+
+```js
+var isArray = require('isarray');
+
+console.log(isArray([])); // => true
+console.log(isArray({})); // => false
+```
+
+## Installation
+
+With [npm](http://npmjs.org) do
+
+```bash
+$ npm install isarray
+```
+
+Then bundle for the browser with
+[browserify](https://github.com/substack/browserify).
+
+With [component](http://component.io) do
+
+```bash
+$ component install juliangruber/isarray
+```
+
+## License
+
+(MIT)
+
+Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/tools/eslint/node_modules/doctrine/node_modules/isarray/build/build.js b/tools/eslint/node_modules/doctrine/node_modules/isarray/build/build.js
new file mode 100644
index 0000000000..ec58596aee
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/node_modules/isarray/build/build.js
@@ -0,0 +1,209 @@
+
+/**
+ * Require the given path.
+ *
+ * @param {String} path
+ * @return {Object} exports
+ * @api public
+ */
+
+function require(path, parent, orig) {
+ var resolved = require.resolve(path);
+
+ // lookup failed
+ if (null == resolved) {
+ orig = orig || path;
+ parent = parent || 'root';
+ var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
+ err.path = orig;
+ err.parent = parent;
+ err.require = true;
+ throw err;
+ }
+
+ var module = require.modules[resolved];
+
+ // perform real require()
+ // by invoking the module's
+ // registered function
+ if (!module.exports) {
+ module.exports = {};
+ module.client = module.component = true;
+ module.call(this, module.exports, require.relative(resolved), module);
+ }
+
+ return module.exports;
+}
+
+/**
+ * Registered modules.
+ */
+
+require.modules = {};
+
+/**
+ * Registered aliases.
+ */
+
+require.aliases = {};
+
+/**
+ * Resolve `path`.
+ *
+ * Lookup:
+ *
+ * - PATH/index.js
+ * - PATH.js
+ * - PATH
+ *
+ * @param {String} path
+ * @return {String} path or null
+ * @api private
+ */
+
+require.resolve = function(path) {
+ if (path.charAt(0) === '/') path = path.slice(1);
+ var index = path + '/index.js';
+
+ var paths = [
+ path,
+ path + '.js',
+ path + '.json',
+ path + '/index.js',
+ path + '/index.json'
+ ];
+
+ for (var i = 0; i < paths.length; i++) {
+ var path = paths[i];
+ if (require.modules.hasOwnProperty(path)) return path;
+ }
+
+ if (require.aliases.hasOwnProperty(index)) {
+ return require.aliases[index];
+ }
+};
+
+/**
+ * Normalize `path` relative to the current path.
+ *
+ * @param {String} curr
+ * @param {String} path
+ * @return {String}
+ * @api private
+ */
+
+require.normalize = function(curr, path) {
+ var segs = [];
+
+ if ('.' != path.charAt(0)) return path;
+
+ curr = curr.split('/');
+ path = path.split('/');
+
+ for (var i = 0; i < path.length; ++i) {
+ if ('..' == path[i]) {
+ curr.pop();
+ } else if ('.' != path[i] && '' != path[i]) {
+ segs.push(path[i]);
+ }
+ }
+
+ return curr.concat(segs).join('/');
+};
+
+/**
+ * Register module at `path` with callback `definition`.
+ *
+ * @param {String} path
+ * @param {Function} definition
+ * @api private
+ */
+
+require.register = function(path, definition) {
+ require.modules[path] = definition;
+};
+
+/**
+ * Alias a module definition.
+ *
+ * @param {String} from
+ * @param {String} to
+ * @api private
+ */
+
+require.alias = function(from, to) {
+ if (!require.modules.hasOwnProperty(from)) {
+ throw new Error('Failed to alias "' + from + '", it does not exist');
+ }
+ require.aliases[to] = from;
+};
+
+/**
+ * Return a require function relative to the `parent` path.
+ *
+ * @param {String} parent
+ * @return {Function}
+ * @api private
+ */
+
+require.relative = function(parent) {
+ var p = require.normalize(parent, '..');
+
+ /**
+ * lastIndexOf helper.
+ */
+
+ function lastIndexOf(arr, obj) {
+ var i = arr.length;
+ while (i--) {
+ if (arr[i] === obj) return i;
+ }
+ return -1;
+ }
+
+ /**
+ * The relative require() itself.
+ */
+
+ function localRequire(path) {
+ var resolved = localRequire.resolve(path);
+ return require(resolved, parent, path);
+ }
+
+ /**
+ * Resolve relative to the parent.
+ */
+
+ localRequire.resolve = function(path) {
+ var c = path.charAt(0);
+ if ('/' == c) return path.slice(1);
+ if ('.' == c) return require.normalize(p, path);
+
+ // resolve deps by returning
+ // the dep in the nearest "deps"
+ // directory
+ var segs = parent.split('/');
+ var i = lastIndexOf(segs, 'deps') + 1;
+ if (!i) i = 0;
+ path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
+ return path;
+ };
+
+ /**
+ * Check if module is defined at `path`.
+ */
+
+ localRequire.exists = function(path) {
+ return require.modules.hasOwnProperty(localRequire.resolve(path));
+ };
+
+ return localRequire;
+};
+require.register("isarray/index.js", function(exports, require, module){
+module.exports = Array.isArray || function (arr) {
+ return Object.prototype.toString.call(arr) == '[object Array]';
+};
+
+});
+require.alias("isarray/index.js", "isarray/index.js");
+
diff --git a/tools/eslint/node_modules/doctrine/node_modules/isarray/component.json b/tools/eslint/node_modules/doctrine/node_modules/isarray/component.json
new file mode 100644
index 0000000000..9e31b68388
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/node_modules/isarray/component.json
@@ -0,0 +1,19 @@
+{
+ "name" : "isarray",
+ "description" : "Array#isArray for older browsers",
+ "version" : "0.0.1",
+ "repository" : "juliangruber/isarray",
+ "homepage": "https://github.com/juliangruber/isarray",
+ "main" : "index.js",
+ "scripts" : [
+ "index.js"
+ ],
+ "dependencies" : {},
+ "keywords": ["browser","isarray","array"],
+ "author": {
+ "name": "Julian Gruber",
+ "email": "mail@juliangruber.com",
+ "url": "http://juliangruber.com"
+ },
+ "license": "MIT"
+}
diff --git a/tools/eslint/node_modules/doctrine/node_modules/isarray/index.js b/tools/eslint/node_modules/doctrine/node_modules/isarray/index.js
new file mode 100644
index 0000000000..5f5ad45d46
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/node_modules/isarray/index.js
@@ -0,0 +1,3 @@
+module.exports = Array.isArray || function (arr) {
+ return Object.prototype.toString.call(arr) == '[object Array]';
+};
diff --git a/tools/eslint/node_modules/doctrine/node_modules/isarray/package.json b/tools/eslint/node_modules/doctrine/node_modules/isarray/package.json
new file mode 100644
index 0000000000..25c8581bee
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/node_modules/isarray/package.json
@@ -0,0 +1,54 @@
+{
+ "name": "isarray",
+ "description": "Array#isArray for older browsers",
+ "version": "0.0.1",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/juliangruber/isarray.git"
+ },
+ "homepage": "https://github.com/juliangruber/isarray",
+ "main": "index.js",
+ "scripts": {
+ "test": "tap test/*.js"
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "tap": "*"
+ },
+ "keywords": [
+ "browser",
+ "isarray",
+ "array"
+ ],
+ "author": {
+ "name": "Julian Gruber",
+ "email": "mail@juliangruber.com",
+ "url": "http://juliangruber.com"
+ },
+ "license": "MIT",
+ "_id": "isarray@0.0.1",
+ "dist": {
+ "shasum": "8a18acfca9a8f4177e09abfc6038939b05d1eedf",
+ "tarball": "http://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
+ },
+ "_from": "isarray@0.0.1",
+ "_npmVersion": "1.2.18",
+ "_npmUser": {
+ "name": "juliangruber",
+ "email": "julian@juliangruber.com"
+ },
+ "maintainers": [
+ {
+ "name": "juliangruber",
+ "email": "julian@juliangruber.com"
+ }
+ ],
+ "directories": {},
+ "_shasum": "8a18acfca9a8f4177e09abfc6038939b05d1eedf",
+ "_resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "readme": "\n# isarray\n\n`Array#isArray` for older browsers.\n\n## Usage\n\n```js\nvar isArray = require('isarray');\n\nconsole.log(isArray([])); // => true\nconsole.log(isArray({})); // => false\n```\n\n## Installation\n\nWith [npm](http://npmjs.org) do\n\n```bash\n$ npm install isarray\n```\n\nThen bundle for the browser with\n[browserify](https://github.com/substack/browserify).\n\nWith [component](http://component.io) do\n\n```bash\n$ component install juliangruber/isarray\n```\n\n## License\n\n(MIT)\n\nCopyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n",
+ "readmeFilename": "README.md",
+ "bugs": {
+ "url": "https://github.com/juliangruber/isarray/issues"
+ }
+}
diff --git a/tools/eslint/node_modules/doctrine/package.json b/tools/eslint/node_modules/doctrine/package.json
new file mode 100644
index 0000000000..7de168c4ea
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/package.json
@@ -0,0 +1,71 @@
+{
+ "name": "doctrine",
+ "description": "JSDoc parser",
+ "homepage": "http://github.com/Constellation/doctrine.html",
+ "main": "lib/doctrine.js",
+ "version": "0.6.4",
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "directories": {
+ "lib": "./lib"
+ },
+ "maintainers": [
+ {
+ "name": "constellation",
+ "email": "utatane.tea@gmail.com"
+ }
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git+ssh://git@github.com/Constellation/doctrine.git"
+ },
+ "devDependencies": {
+ "coveralls": "^2.11.2",
+ "gulp": "^3.8.10",
+ "gulp-bump": "^0.1.13",
+ "gulp-eslint": "^0.5.0",
+ "gulp-filter": "^2.0.2",
+ "gulp-git": "^1.0.0",
+ "gulp-istanbul": "^0.6.0",
+ "gulp-jshint": "^1.9.0",
+ "gulp-mocha": "^2.0.0",
+ "gulp-tag-version": "^1.2.1",
+ "jshint-stylish": "^1.0.0",
+ "should": "^5.0.1"
+ },
+ "licenses": [
+ {
+ "type": "BSD",
+ "url": "http://github.com/Constellation/doctrine/raw/master/LICENSE.BSD"
+ }
+ ],
+ "scripts": {
+ "test": "gulp",
+ "unit-test": "gulp test",
+ "lint": "gulp lint",
+ "coveralls": "cat ./coverage/lcov.info | coveralls && rm -rf ./coverage"
+ },
+ "dependencies": {
+ "esutils": "^1.1.6",
+ "isarray": "0.0.1"
+ },
+ "gitHead": "0835299b485ecdfa908d20628d6c8900144590ff",
+ "bugs": {
+ "url": "https://github.com/Constellation/doctrine/issues"
+ },
+ "_id": "doctrine@0.6.4",
+ "_shasum": "81428491a942ef18b0492056eda3800eee57d61d",
+ "_from": "doctrine@>=0.6.2 <0.7.0",
+ "_npmVersion": "1.4.28",
+ "_npmUser": {
+ "name": "constellation",
+ "email": "utatane.tea@gmail.com"
+ },
+ "dist": {
+ "shasum": "81428491a942ef18b0492056eda3800eee57d61d",
+ "tarball": "http://registry.npmjs.org/doctrine/-/doctrine-0.6.4.tgz"
+ },
+ "_resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.6.4.tgz",
+ "readme": "ERROR: No README data found!"
+}
diff --git a/tools/eslint/node_modules/doctrine/test/midstream.js b/tools/eslint/node_modules/doctrine/test/midstream.js
new file mode 100644
index 0000000000..2e71bd14e1
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/test/midstream.js
@@ -0,0 +1,61 @@
+/*
+ Copyright (C) 2014 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*global require describe it*/
+/*jslint node:true */
+'use strict';
+
+var fs = require('fs'),
+ path = require('path'),
+ root = path.join(path.dirname(fs.realpathSync(__filename)), '..'),
+ doctrine = require(root);
+require('should');
+
+describe('midstream', function () {
+ it('parseType', function () {
+ var res = doctrine.parseType('string name', { midstream: true });
+ res.should.eql({
+ "expression": {
+ "name": "string",
+ "type": "NameExpression"
+ },
+ "index": 6
+ });
+ });
+
+ it('parseParamType', function () {
+ var res = doctrine.parseParamType('...test ok', { midstream: true });
+ res.should.eql({
+ "expression": {
+ "expression": {
+ "name": "test",
+ "type": "NameExpression"
+ },
+ "type": "RestType"
+ },
+ "index": 7
+ });
+ });
+});
+
+/* vim: set sw=4 ts=4 et tw=80 : */
diff --git a/tools/eslint/node_modules/doctrine/test/parse.js b/tools/eslint/node_modules/doctrine/test/parse.js
new file mode 100644
index 0000000000..851e67c0d9
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/test/parse.js
@@ -0,0 +1,2219 @@
+/*
+ Copyright (C) 2013 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*global require describe it*/
+/*jslint node:true */
+'use strict';
+
+var fs = require('fs'),
+ path = require('path'),
+ root = path.join(path.dirname(fs.realpathSync(__filename)), '..'),
+ doctrine = require(root);
+require('should');
+
+describe('parse', function () {
+ it('alias', function () {
+ var res = doctrine.parse('/** @alias */', { unwrap: true });
+ res.tags.should.have.length(0);
+ });
+
+ it('alias with name', function () {
+ var res = doctrine.parse('/** @alias aliasName */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'alias');
+ res.tags[0].should.have.property('name', 'aliasName');
+ });
+
+ it('alias with namepath', function () {
+ var res = doctrine.parse('/** @alias aliasName.OK */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'alias');
+ res.tags[0].should.have.property('name', 'aliasName.OK');
+ });
+
+ it('const', function () {
+ var res = doctrine.parse('/** @const */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'const');
+ });
+
+ it('const with name', function () {
+ var res = doctrine.parse('/** @const constname */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'const');
+ res.tags[0].should.have.property('name', 'constname');
+ });
+
+ it('constant with name', function () {
+ var res = doctrine.parse('/** @constant constname */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'constant');
+ res.tags[0].should.have.property('name', 'constname');
+ });
+
+ it('const with type and name', function () {
+ var res = doctrine.parse('/** @const {String} constname */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'const');
+ res.tags[0].should.have.property('name', 'constname');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'String'
+ });
+ });
+
+ it('constant with type and name', function () {
+ var res = doctrine.parse('/** @constant {String} constname */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'constant');
+ res.tags[0].should.have.property('name', 'constname');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'String'
+ });
+ });
+
+ it('const multiple', function () {
+ var res = doctrine.parse("/**@const\n @const*/", { unwrap: true });
+ res.tags.should.have.length(2);
+ res.tags[0].should.have.property('title', 'const');
+ res.tags[1].should.have.property('title', 'const');
+ });
+
+ it('const double', function () {
+ var res = doctrine.parse("/**@const\n @const*/", { unwrap: true });
+ res.tags.should.have.length(2);
+ res.tags[0].should.have.property('title', 'const');
+ res.tags[1].should.have.property('title', 'const');
+ });
+
+ it('const triple', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @const @const",
+ " * @const @const",
+ " * @const @const",
+ " */"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(3);
+ res.tags[0].should.have.property('title', 'const');
+ res.tags[1].should.have.property('title', 'const');
+ res.tags[2].should.have.property('title', 'const');
+ });
+
+ it('constructor', function () {
+ var res = doctrine.parse('/** @constructor */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'constructor');
+ });
+
+ it('constructor with type', function () {
+ var res = doctrine.parse('/** @constructor {Object} */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'constructor');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'Object'
+ });
+ });
+
+ it('constructor with type and name', function () {
+ var res = doctrine.parse('/** @constructor {Object} objName */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'constructor');
+ res.tags[0].should.have.property('name', 'objName');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'Object'
+ });
+ });
+
+ it('class', function () {
+ var res = doctrine.parse('/** @class */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'class');
+ });
+
+ it('class with type', function () {
+ var res = doctrine.parse('/** @class {Object} */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'class');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'Object'
+ });
+ });
+
+ it('class with type and name', function () {
+ var res = doctrine.parse('/** @class {Object} objName */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'class');
+ res.tags[0].should.have.property('name', 'objName');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'Object'
+ });
+ });
+
+ it('deprecated', function () {
+ var res = doctrine.parse('/** @deprecated */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'deprecated');
+ });
+
+ it('deprecated', function () {
+ var res = doctrine.parse('/** @deprecated some text here describing why it is deprecated */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'deprecated');
+ res.tags[0].should.have.property('description', 'some text here describing why it is deprecated');
+ });
+
+ it('func', function () {
+ var res = doctrine.parse('/** @func */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'func');
+ });
+
+ it('func with name', function () {
+ var res = doctrine.parse('/** @func thingName.func */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'func');
+ res.tags[0].should.have.property('name', 'thingName.func');
+ });
+
+ it('func with type', function () {
+ var res = doctrine.parse('/** @func {Object} thingName.func */', { unwrap: true });
+ res.tags.should.have.length(0);
+ // func does not accept type
+ });
+
+ it('function', function () {
+ var res = doctrine.parse('/** @function */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'function');
+ });
+
+ it('function with name', function () {
+ var res = doctrine.parse('/** @function thingName.function */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'function');
+ res.tags[0].should.have.property('name', 'thingName.function');
+ });
+
+ it('function with type', function () {
+ var res = doctrine.parse('/** @function {Object} thingName.function */', { unwrap: true });
+ res.tags.should.have.length(0);
+ // function does not accept type
+ });
+
+ it('member', function () {
+ var res = doctrine.parse('/** @member */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'member');
+ });
+
+ it('member with name', function () {
+ var res = doctrine.parse('/** @member thingName.name */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'member');
+ res.tags[0].should.have.property('name', 'thingName.name');
+ });
+
+ it('member with type', function () {
+ var res = doctrine.parse('/** @member {Object} thingName.name */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'member');
+ res.tags[0].should.have.property('name', 'thingName.name');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'Object'
+ });
+ });
+
+ it('method', function () {
+ var res = doctrine.parse('/** @method */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'method');
+ });
+
+ it('method with name', function () {
+ var res = doctrine.parse('/** @method thingName.function */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'method');
+ res.tags[0].should.have.property('name', 'thingName.function');
+ });
+
+ it('method with type', function () {
+ var res = doctrine.parse('/** @method {Object} thingName.function */', { unwrap: true });
+ res.tags.should.have.length(0);
+ // method does not accept type
+ });
+
+ it('mixes', function () {
+ var res = doctrine.parse('/** @mixes */', { unwrap: true });
+ res.tags.should.have.length(0);
+ });
+
+ it('mixes with name', function () {
+ var res = doctrine.parse('/** @mixes thingName */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'mixes');
+ res.tags[0].should.have.property('name', 'thingName');
+ });
+
+ it('mixes with namepath', function () {
+ var res = doctrine.parse('/** @mixes thingName.name */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'mixes');
+ res.tags[0].should.have.property('name', 'thingName.name');
+ });
+
+ it('mixin', function () {
+ var res = doctrine.parse('/** @mixin */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'mixin');
+ });
+
+ it('mixin with name', function () {
+ var res = doctrine.parse('/** @mixin thingName */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'mixin');
+ res.tags[0].should.have.property('name', 'thingName');
+ });
+
+ it('mixin with namepath', function () {
+ var res = doctrine.parse('/** @mixin thingName.name */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'mixin');
+ res.tags[0].should.have.property('name', 'thingName.name');
+ });
+
+ it('module', function () {
+ var res = doctrine.parse('/** @module */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'module');
+ });
+
+ it('module with name', function () {
+ var res = doctrine.parse('/** @module thingName.name */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'module');
+ res.tags[0].should.have.property('name', 'thingName.name');
+ });
+
+ it('module with type', function () {
+ var res = doctrine.parse('/** @module {Object} thingName.name */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'module');
+ res.tags[0].should.have.property('name', 'thingName.name');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'Object'
+ });
+ });
+
+ it('name', function () {
+ var res = doctrine.parse('/** @name thingName.name */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'name');
+ res.tags[0].should.have.property('name', 'thingName.name');
+ });
+
+ it('name', function () {
+ var res = doctrine.parse('/** @name thingName#name */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'name');
+ res.tags[0].should.have.property('name', 'thingName#name');
+ });
+
+ it('name', function () {
+ var res = doctrine.parse('/** @name thingName~name */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'name');
+ res.tags[0].should.have.property('name', 'thingName~name');
+ });
+
+ it('name', function () {
+ var res = doctrine.parse('/** @name {thing} thingName.name */', { unwrap: true });
+ // name does not accept type
+ res.tags.should.have.length(0);
+ });
+
+ it('namespace', function () {
+ var res = doctrine.parse('/** @namespace */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'namespace');
+ });
+
+ it('namespace with name', function () {
+ var res = doctrine.parse('/** @namespace thingName.name */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'namespace');
+ res.tags[0].should.have.property('name', 'thingName.name');
+ });
+
+ it('namespace with type', function () {
+ var res = doctrine.parse('/** @namespace {Object} thingName.name */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'namespace');
+ res.tags[0].should.have.property('name', 'thingName.name');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'Object'
+ });
+ });
+
+ it('param', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @param {String} userName",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'param');
+ res.tags[0].should.have.property('name', 'userName');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'String'
+ });
+ });
+
+ it('param with properties', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @param {String} user.name",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'param');
+ res.tags[0].should.have.property('name', 'user.name');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'String'
+ });
+ });
+
+ it('arg with properties', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @arg {String} user.name",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'arg');
+ res.tags[0].should.have.property('name', 'user.name');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'String'
+ });
+ });
+
+ it('argument with properties', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @argument {String} user.name",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'argument');
+ res.tags[0].should.have.property('name', 'user.name');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'String'
+ });
+ });
+
+ it('param typeless', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @param userName",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.eql({
+ title: 'param',
+ type: null,
+ name: 'userName',
+ description: null
+ });
+
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @param userName Something descriptive",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.eql({
+ title: 'param',
+ type: null,
+ name: 'userName',
+ description: 'Something descriptive'
+ });
+
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @param user.name Something descriptive",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.eql({
+ title: 'param',
+ type: null,
+ name: 'user.name',
+ description: 'Something descriptive'
+ });
+ });
+
+ it('param broken', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @param {String} userName",
+ " * @param {String userName",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'param');
+ res.tags[0].should.have.property('name', 'userName');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'String'
+ });
+ });
+
+ it('param record', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @param {{ok:String}} userName",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'param');
+ res.tags[0].should.have.property('name', 'userName');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'RecordType',
+ fields: [{
+ type: 'FieldType',
+ key: 'ok',
+ value: {
+ type: 'NameExpression',
+ name: 'String'
+ }
+ }]
+ });
+ });
+
+ it('param record broken', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @param {{ok:String} userName",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.be.empty;
+ });
+
+ it('param multiple lines', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @param {string|",
+ " * number} userName",
+ " * }}",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'param');
+ res.tags[0].should.have.property('name', 'userName');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'UnionType',
+ elements: [{
+ type: 'NameExpression',
+ name: 'string'
+ }, {
+ type: 'NameExpression',
+ name: 'number'
+ }]
+ });
+ });
+
+ it('param without braces', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @param string name description",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'param');
+ res.tags[0].should.have.property('name', 'string');
+ res.tags[0].should.have.property('type', null);
+ res.tags[0].should.have.property('description', 'name description');
+ });
+
+ it('param w/ hyphen before description', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @param {string} name - description",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.eql({
+ title: 'param',
+ type: {
+ type: 'NameExpression',
+ name: 'string'
+ },
+ name: 'name',
+ description: 'description'
+ });
+ });
+
+ it('param w/ hyphen + leading space before description', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @param {string} name - description",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.eql({
+ title: 'param',
+ type: {
+ type: 'NameExpression',
+ name: 'string'
+ },
+ name: 'name',
+ description: ' description'
+ });
+ });
+
+ it('description and param separated by blank line', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * Description",
+ " * blah blah blah",
+ " *",
+ " * @param {string} name description",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.description.should.eql('Description\nblah blah blah');
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'param');
+ res.tags[0].should.have.property('name', 'name');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'string'
+ });
+ res.tags[0].should.have.property('description', 'description');
+ });
+
+ it('regular block comment instead of jsdoc-style block comment', function () {
+ var res = doctrine.parse(
+ [
+ "/*",
+ " * Description",
+ " * blah blah blah",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.description.should.eql("Description\nblah blah blah");
+ });
+
+ it('augments', function () {
+ var res = doctrine.parse('/** @augments */', { unwrap: true });
+ res.tags.should.have.length(1);
+ });
+
+ it('augments with name', function () {
+ var res = doctrine.parse('/** @augments ClassName */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'augments');
+ res.tags[0].should.have.property('name', 'ClassName');
+ });
+
+ it('augments with type', function () {
+ var res = doctrine.parse('/** @augments {ClassName} */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'augments');
+ res.tags[0].should.have.property('type', {
+ type: 'NameExpression',
+ name: 'ClassName'
+ });
+ });
+
+ it('augments with name', function () {
+ var res = doctrine.parse('/** @augments ClassName.OK */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'augments');
+ res.tags[0].should.have.property('name', 'ClassName.OK');
+ });
+
+ it('extends', function () {
+ var res = doctrine.parse('/** @extends */', { unwrap: true });
+ res.tags.should.have.length(1);
+ });
+
+ it('extends with name', function () {
+ var res = doctrine.parse('/** @extends ClassName */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'extends');
+ res.tags[0].should.have.property('name', 'ClassName');
+ });
+
+ it('extends with type', function () {
+ var res = doctrine.parse('/** @extends {ClassName} */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'extends');
+ res.tags[0].should.have.property('type', {
+ type: 'NameExpression',
+ name: 'ClassName'
+ });
+ });
+
+ it('extends with namepath', function () {
+ var res = doctrine.parse('/** @extends ClassName.OK */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'extends');
+ res.tags[0].should.have.property('name', 'ClassName.OK');
+ });
+
+ it('prop', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @prop {string} thingName - does some stuff",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'prop');
+ res.tags[0].should.have.property('description', 'does some stuff');
+ res.tags[0].type.should.have.property('name', 'string');
+ res.tags[0].should.have.property('name', 'thingName');
+ });
+
+ it('prop without type', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @prop thingName - does some stuff",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(0);
+ });
+
+
+ it('property', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @property {string} thingName - does some stuff",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'property');
+ res.tags[0].should.have.property('description', 'does some stuff');
+ res.tags[0].type.should.have.property('name', 'string');
+ res.tags[0].should.have.property('name', 'thingName');
+ });
+
+ it('property without type', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @property thingName - does some stuff",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(0);
+ });
+
+ it('property with nested name', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @property {string} thingName.name - does some stuff",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'property');
+ res.tags[0].should.have.property('description', 'does some stuff');
+ res.tags[0].type.should.have.property('name', 'string');
+ res.tags[0].should.have.property('name', 'thingName.name');
+ });
+
+ it('throws', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @throws {Error} if something goes wrong",
+ " */"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'throws');
+ res.tags[0].should.have.property('description', 'if something goes wrong');
+ res.tags[0].type.should.have.property('name', 'Error');
+ });
+
+ it('throws without type', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @throws if something goes wrong",
+ " */"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'throws');
+ res.tags[0].should.have.property('description', 'if something goes wrong');
+ });
+
+ it('kind', function () {
+ var res = doctrine.parse('/** @kind class */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'kind');
+ res.tags[0].should.have.property('kind', 'class');
+ });
+
+ it('kind error', function () {
+ var res = doctrine.parse('/** @kind ng */', { unwrap: true, recoverable: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('errors');
+ res.tags[0].errors.should.have.length(1);
+ res.tags[0].errors[0].should.equal('Invalid kind name \'ng\'');
+ });
+
+ it('todo', function () {
+ var res = doctrine.parse('/** @todo Write the documentation */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'todo');
+ res.tags[0].should.have.property('description', 'Write the documentation');
+ });
+
+ it('summary', function () {
+ // japanese lang
+ var res = doctrine.parse('/** @summary ゆるゆり3期おめでとー */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'summary');
+ res.tags[0].should.have.property('description', 'ゆるゆり3期おめでとー');
+ });
+
+ it('variation', function () {
+ // japanese lang
+ var res = doctrine.parse('/** @variation 42 */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'variation');
+ res.tags[0].should.have.property('variation', 42);
+ });
+
+ it('variation error', function () {
+ // japanese lang
+ var res = doctrine.parse('/** @variation Animation */', { unwrap: true, recoverable: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('errors');
+ res.tags[0].errors.should.have.length(1);
+ res.tags[0].errors[0].should.equal('Invalid variation \'Animation\'');
+ });
+
+ it('access', function () {
+ var res = doctrine.parse('/** @access public */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'access');
+ res.tags[0].should.have.property('access', 'public');
+ });
+
+ it('access error', function () {
+ var res = doctrine.parse('/** @access ng */', { unwrap: true, recoverable: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('errors');
+ res.tags[0].errors.should.have.length(1);
+ res.tags[0].errors[0].should.equal('Invalid access name \'ng\'');
+ });
+
+ it('public', function () {
+ var res = doctrine.parse('/** @public */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'public');
+ });
+
+ it('public type and description', function () {
+ var res = doctrine.parse('/** @public {number} ok */', { unwrap: true, recoverable: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'public');
+ res.tags[0].should.have.property('description', 'ok');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'number'
+ });
+ });
+
+ it('protected', function () {
+ var res = doctrine.parse('/** @protected */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'protected');
+ });
+
+ it('protected type and description', function () {
+ var res = doctrine.parse('/** @protected {number} ok */', { unwrap: true, recoverable: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'protected');
+ res.tags[0].should.have.property('description', 'ok');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'number'
+ });
+ });
+
+ it('private', function () {
+ var res = doctrine.parse('/** @private */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'private');
+ });
+
+ it('private type and description', function () {
+ var res = doctrine.parse('/** @private {number} ok */', { unwrap: true, recoverable: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'private');
+ res.tags[0].should.have.property('description', 'ok');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'number'
+ });
+ });
+
+ it('readonly', function () {
+ var res = doctrine.parse('/** @readonly */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'readonly');
+ });
+
+ it('readonly error', function () {
+ var res = doctrine.parse('/** @readonly ng */', { unwrap: true, recoverable: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('errors');
+ res.tags[0].errors.should.have.length(1);
+ res.tags[0].errors[0].should.equal('Unknown content \'ng\'');
+ });
+
+ it('requires', function () {
+ var res = doctrine.parse('/** @requires */', { unwrap: true });
+ res.tags.should.have.length(0);
+ });
+
+ it('requires with module name', function () {
+ var res = doctrine.parse('/** @requires name.path */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'requires');
+ res.tags[0].should.have.property('name', 'name.path');
+ });
+
+ it('global', function () {
+ var res = doctrine.parse('/** @global */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'global');
+ });
+
+ it('global error', function () {
+ var res = doctrine.parse('/** @global ng */', { unwrap: true, recoverable: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('errors');
+ res.tags[0].errors.should.have.length(1);
+ res.tags[0].errors[0].should.equal('Unknown content \'ng\'');
+ });
+
+ it('inner', function () {
+ var res = doctrine.parse('/** @inner */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'inner');
+ });
+
+ it('inner error', function () {
+ var res = doctrine.parse('/** @inner ng */', { unwrap: true, recoverable: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('errors');
+ res.tags[0].errors.should.have.length(1);
+ res.tags[0].errors[0].should.equal('Unknown content \'ng\'');
+ });
+
+ it('instance', function () {
+ var res = doctrine.parse('/** @instance */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'instance');
+ });
+
+ it('instance error', function () {
+ var res = doctrine.parse('/** @instance ng */', { unwrap: true, recoverable: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('errors');
+ res.tags[0].errors.should.have.length(1);
+ res.tags[0].errors[0].should.equal('Unknown content \'ng\'');
+ });
+
+ it('since', function () {
+ var res = doctrine.parse('/** @since 1.2.1 */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'since');
+ res.tags[0].should.have.property('description', '1.2.1');
+ });
+
+ it('static', function () {
+ var res = doctrine.parse('/** @static */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'static');
+ });
+
+ it('static error', function () {
+ var res = doctrine.parse('/** @static ng */', { unwrap: true, recoverable: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('errors');
+ res.tags[0].errors.should.have.length(1);
+ res.tags[0].errors[0].should.equal('Unknown content \'ng\'');
+ });
+
+ it('this', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @this thingName",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'this');
+ res.tags[0].should.have.property('name', 'thingName');
+ });
+
+ it('this with namepath', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @this thingName.name",
+ "*/"
+ ].join('\n'), { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'this');
+ res.tags[0].should.have.property('name', 'thingName.name');
+ });
+
+ it('this error', function () {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @this",
+ "*/"
+ ].join('\n'), { unwrap: true, recoverable: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'this');
+ res.tags[0].should.have.property('errors');
+ res.tags[0].errors.should.have.length(1);
+ res.tags[0].errors[0].should.equal('Missing or invalid tag name');
+ });
+
+ it('var', function () {
+ var res = doctrine.parse('/** @var */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'var');
+ });
+
+ it('var with name', function () {
+ var res = doctrine.parse('/** @var thingName.name */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'var');
+ res.tags[0].should.have.property('name', 'thingName.name');
+ });
+
+ it('var with type', function () {
+ var res = doctrine.parse('/** @var {Object} thingName.name */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'var');
+ res.tags[0].should.have.property('name', 'thingName.name');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ type: 'NameExpression',
+ name: 'Object'
+ });
+ });
+
+ it('version', function () {
+ var res = doctrine.parse('/** @version 1.2.1 */', { unwrap: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'version');
+ res.tags[0].should.have.property('description', '1.2.1');
+ });
+
+ it('incorrect name', function () {
+ var res = doctrine.parse('/** @name thingName#%name */', { unwrap: true });
+ // name does not accept type
+ res.tags.should.have.length(0);
+ res.should.eql({
+ "description": "",
+ "tags": [
+ ]
+ });
+ });
+});
+
+describe('parseType', function () {
+ it('union type closure-compiler extended', function () {
+ var type = doctrine.parseType("string|number");
+ type.should.eql({
+ type: 'UnionType',
+ elements: [{
+ type: 'NameExpression',
+ name: 'string'
+ }, {
+ type: 'NameExpression',
+ name: 'number'
+ }]
+ });
+ });
+
+ it('empty union type', function () {
+ var type = doctrine.parseType("()");
+ type.should.eql({
+ type: 'UnionType',
+ elements: []
+ });
+ });
+
+ it('comma last array type', function () {
+ var type = doctrine.parseType("[string,]");
+ type.should.eql({
+ type: 'ArrayType',
+ elements: [{
+ type: 'NameExpression',
+ name: 'string'
+ }]
+ });
+ });
+
+ it('array type of all literal', function () {
+ var type = doctrine.parseType("[*]");
+ type.should.eql({
+ type: 'ArrayType',
+ elements: [{
+ type: 'AllLiteral'
+ }]
+ });
+ });
+
+ it('array type of nullable literal', function () {
+ var type = doctrine.parseType("[?]");
+ type.should.eql({
+ type: 'ArrayType',
+ elements: [{
+ type: 'NullableLiteral'
+ }]
+ });
+ });
+
+ it('comma last record type', function () {
+ var type = doctrine.parseType("{,}");
+ type.should.eql({
+ type: 'RecordType',
+ fields: []
+ });
+ });
+
+ it('type application', function () {
+ var type = doctrine.parseType("Array.<String>");
+ type.should.eql({
+ type: 'TypeApplication',
+ expression: {
+ type: 'NameExpression',
+ name: 'Array'
+ },
+ applications: [{
+ type: 'NameExpression',
+ name: 'String'
+ }]
+ });
+ });
+
+ it('type application with NullableLiteral', function () {
+ var type = doctrine.parseType("Array<?>");
+ type.should.eql({
+ type: 'TypeApplication',
+ expression: {
+ type: 'NameExpression',
+ name: 'Array'
+ },
+ applications: [{
+ type: 'NullableLiteral'
+ }]
+ });
+ });
+
+ it('type application with multiple patterns', function () {
+ var type = doctrine.parseType("Array.<String, Number>");
+ type.should.eql({
+ type: 'TypeApplication',
+ expression: {
+ type: 'NameExpression',
+ name: 'Array'
+ },
+ applications: [{
+ type: 'NameExpression',
+ name: 'String'
+ }, {
+ type: 'NameExpression',
+ name: 'Number'
+ }]
+ });
+ });
+
+ it('type application without dot', function () {
+ var type = doctrine.parseType("Array<String>");
+ type.should.eql({
+ type: 'TypeApplication',
+ expression: {
+ type: 'NameExpression',
+ name: 'Array'
+ },
+ applications: [{
+ type: 'NameExpression',
+ name: 'String'
+ }]
+ });
+ });
+
+ it('array-style type application', function () {
+ var type = doctrine.parseType("String[]");
+ type.should.eql({
+ type: 'TypeApplication',
+ expression: {
+ type: 'NameExpression',
+ name: 'Array'
+ },
+ applications: [{
+ type: 'NameExpression',
+ name: 'String'
+ }]
+ });
+ });
+
+ it('function type simple', function () {
+ var type = doctrine.parseType("function()");
+ type.should.eql({
+ "type": "FunctionType",
+ "params": [],
+ "result": null
+ });
+ });
+
+ it('function type with name', function () {
+ var type = doctrine.parseType("function(a)");
+ type.should.eql({
+ "type": "FunctionType",
+ "params": [
+ {
+ "type": "NameExpression",
+ "name": "a"
+ }
+ ],
+ "result": null
+ });
+ });
+ it('function type with name and type', function () {
+ var type = doctrine.parseType("function(a:b)");
+ type.should.eql({
+ "type": "FunctionType",
+ "params": [
+ {
+ "type": "ParameterType",
+ "name": "a",
+ "expression": {
+ "type": "NameExpression",
+ "name": "b"
+ }
+ }
+ ],
+ "result": null
+ });
+ });
+ it('function type with optional param', function () {
+ var type = doctrine.parseType("function(a=)");
+ type.should.eql({
+ "type": "FunctionType",
+ "params": [
+ {
+ "type": "OptionalType",
+ "expression": {
+ "type": "NameExpression",
+ "name": "a"
+ }
+ }
+ ],
+ "result": null
+ });
+ });
+ it('function type with optional param name and type', function () {
+ var type = doctrine.parseType("function(a:b=)");
+ type.should.eql({
+ "type": "FunctionType",
+ "params": [
+ {
+ "type": "OptionalType",
+ "expression": {
+ "type": "ParameterType",
+ "name": "a",
+ "expression": {
+ "type": "NameExpression",
+ "name": "b"
+ }
+ }
+ }
+ ],
+ "result": null
+ });
+ });
+ it('function type with rest param', function () {
+ var type = doctrine.parseType("function(...a)");
+ type.should.eql({
+ "type": "FunctionType",
+ "params": [
+ {
+ "type": "RestType",
+ "expression": {
+ "type": "NameExpression",
+ "name": "a"
+ }
+ }
+ ],
+ "result": null
+ });
+ });
+ it('function type with rest param name and type', function () {
+ var type = doctrine.parseType("function(...a:b)");
+ type.should.eql({
+ "type": "FunctionType",
+ "params": [
+ {
+ "type": "RestType",
+ "expression": {
+ "type": "ParameterType",
+ "name": "a",
+ "expression": {
+ "type": "NameExpression",
+ "name": "b"
+ }
+ }
+ }
+ ],
+ "result": null
+ });
+ });
+
+ it('function type with optional rest param', function () {
+ var type = doctrine.parseType("function(...a=)");
+ type.should.eql({
+ "type": "FunctionType",
+ "params": [
+ {
+ "type": "RestType",
+ "expression": {
+ "type": "OptionalType",
+ "expression": {
+ "type": "NameExpression",
+ "name": "a"
+ }
+ }
+ }
+ ],
+ "result": null
+ });
+ });
+ it('function type with optional rest param name and type', function () {
+ var type = doctrine.parseType("function(...a:b=)");
+ type.should.eql({
+ "type": "FunctionType",
+ "params": [
+ {
+ "type": "RestType",
+ "expression": {
+ "type": "OptionalType",
+ "expression": {
+ "type": "ParameterType",
+ "name": "a",
+ "expression": {
+ "type": "NameExpression",
+ "name": "b"
+ }
+ }
+ }
+ }],
+ "result": null
+ });
+ });
+
+ it('string value in type', function () {
+ var type;
+
+ type = doctrine.parseType("{'ok':String}");
+ type.should.eql({
+ "fields": [
+ {
+ "key": "ok",
+ "type": "FieldType",
+ "value": {
+ "name": "String",
+ "type": "NameExpression"
+ }
+ }
+ ],
+ "type": "RecordType"
+ });
+
+ type = doctrine.parseType('{"\\r\\n\\t\\u2028\\x20\\u20\\b\\f\\v\\\r\n\\\n\\0\\07\\012\\o":String}');
+ type.should.eql({
+ "fields": [
+ {
+ "key": "\r\n\t\u2028\x20u20\b\f\v\0\u0007\u000ao",
+ "type": "FieldType",
+ "value": {
+ "name": "String",
+ "type": "NameExpression"
+ }
+ }
+ ],
+ "type": "RecordType"
+ });
+
+ doctrine.parseType.bind(doctrine, "{'ok\":String}").should.throw('unexpected quote');
+ doctrine.parseType.bind(doctrine, "{'o\n':String}").should.throw('unexpected quote');
+ });
+
+ it('number value in type', function () {
+ var type;
+
+ type = doctrine.parseType("{20:String}");
+ type.should.eql({
+ "fields": [
+ {
+ "key": "20",
+ "type": "FieldType",
+ "value": {
+ "name": "String",
+ "type": "NameExpression"
+ }
+ }
+ ],
+ "type": "RecordType"
+ });
+
+ type = doctrine.parseType("{.2:String, 30:Number, 0x20:String}");
+ type.should.eql({
+ "fields": [
+ {
+ "key": "0.2",
+ "type": "FieldType",
+ "value": {
+ "name": "String",
+ "type": "NameExpression"
+ }
+ },
+ {
+ "key": "30",
+ "type": "FieldType",
+ "value": {
+ "name": "Number",
+ "type": "NameExpression"
+ }
+ },
+ {
+ "key": "32",
+ "type": "FieldType",
+ "value": {
+ "name": "String",
+ "type": "NameExpression"
+ }
+ }
+ ],
+ "type": "RecordType"
+ });
+
+
+ type = doctrine.parseType("{0X2:String, 0:Number, 100e200:String, 10e-20:Number}");
+ type.should.eql({
+ "fields": [
+ {
+ "key": "2",
+ "type": "FieldType",
+ "value": {
+ "name": "String",
+ "type": "NameExpression"
+ }
+ },
+ {
+ "key": "0",
+ "type": "FieldType",
+ "value": {
+ "name": "Number",
+ "type": "NameExpression"
+ }
+ },
+ {
+ "key": "1e+202",
+ "type": "FieldType",
+ "value": {
+ "name": "String",
+ "type": "NameExpression"
+ }
+ },
+ {
+ "key": "1e-19",
+ "type": "FieldType",
+ "value": {
+ "name": "Number",
+ "type": "NameExpression"
+ }
+ }
+ ],
+ "type": "RecordType"
+ });
+
+
+ doctrine.parseType.bind(doctrine, "{0x:String}").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "{0x").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "{0xd").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "{0x2_:").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "{021:").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "{021_:").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "{021").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "{08").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "{0y").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "{0").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "{100e2").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "{100e-2").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "{100e-200:").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "{100e:").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "function(number=, string)").should.throw('not reach to EOF');
+ });
+
+ it('dotted type', function () {
+ var type;
+ type = doctrine.parseType("Cocoa.Cappuccino");
+ type.should.eql({
+ "name": "Cocoa.Cappuccino",
+ "type": "NameExpression"
+ });
+ });
+
+ it('rest array type', function () {
+ var type;
+ type = doctrine.parseType("[string,...string]");
+ type.should.eql({
+ "elements": [
+ {
+ "name": "string",
+ "type": "NameExpression"
+ },
+ {
+ "expression": {
+ "name": "string",
+ "type": "NameExpression"
+ },
+ "type": "RestType"
+ }
+ ],
+ "type": "ArrayType"
+ });
+ });
+
+ it ('nullable type', function () {
+ var type;
+ type = doctrine.parseType("string?");
+ type.should.eql({
+ "expression": {
+ "name": "string",
+ "type": "NameExpression"
+ },
+ "prefix": false,
+ "type": "NullableType"
+ });
+ });
+
+ it ('non-nullable type', function () {
+ var type;
+ type = doctrine.parseType("string!");
+ type.should.eql({
+ "expression": {
+ "name": "string",
+ "type": "NameExpression"
+ },
+ "prefix": false,
+ "type": "NonNullableType"
+ });
+ });
+
+ it ('toplevel multiple pipe type', function () {
+ var type;
+ type = doctrine.parseType("string|number|Test");
+ type.should.eql({
+ "elements": [
+ {
+ "name": "string",
+ "type": "NameExpression"
+ },
+ {
+ "name": "number",
+ "type": "NameExpression"
+ },
+ {
+ "name": "Test",
+ "type": "NameExpression"
+ }
+ ],
+ "type": "UnionType"
+ });
+ });
+
+ it('illegal tokens', function () {
+ doctrine.parseType.bind(doctrine, ".").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, ".d").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "(").should.throw('unexpected token');
+ doctrine.parseType.bind(doctrine, "Test.").should.throw('unexpected token');
+ });
+});
+
+describe('parseParamType', function () {
+ it('question', function () {
+ var type = doctrine.parseParamType("?");
+ type.should.eql({
+ type: 'NullableLiteral'
+ });
+ });
+
+ it('question option', function () {
+ var type = doctrine.parseParamType("?=");
+ type.should.eql({
+ type: 'OptionalType',
+ expression: {
+ type: 'NullableLiteral'
+ }
+ });
+ });
+
+ it('function option parameters former', function () {
+ var type = doctrine.parseParamType("function(?, number)");
+ type.should.eql({
+ type: 'FunctionType',
+ params: [{
+ type: 'NullableLiteral'
+ }, {
+ type: 'NameExpression',
+ name: 'number'
+ }],
+ result: null
+ });
+ });
+
+ it('function option parameters latter', function () {
+ var type = doctrine.parseParamType("function(number, ?)");
+ type.should.eql({
+ type: 'FunctionType',
+ params: [{
+ type: 'NameExpression',
+ name: 'number'
+ }, {
+ type: 'NullableLiteral'
+ }],
+ result: null
+ });
+ });
+
+ it('function type union', function () {
+ var type = doctrine.parseParamType("function(): ?|number");
+ type.should.eql({
+ type: 'UnionType',
+ elements: [{
+ type: 'FunctionType',
+ params: [],
+ result: {
+ type: 'NullableLiteral'
+ }
+ }, {
+ type: 'NameExpression',
+ name: 'number'
+ }]
+ });
+ });
+});
+
+describe('invalid', function () {
+ it('empty union pipe', function () {
+ doctrine.parseType.bind(doctrine, "(|)").should.throw();
+ doctrine.parseType.bind(doctrine, "(string|)").should.throw();
+ doctrine.parseType.bind(doctrine, "(string||)").should.throw();
+ });
+
+ it('comma only array type', function () {
+ doctrine.parseType.bind(doctrine, "[,]").should.throw();
+ });
+
+ it('comma only record type', function () {
+ doctrine.parseType.bind(doctrine, "{,,}").should.throw();
+ });
+
+ it('incorrect bracket', function () {
+ doctrine.parseParamType.bind(doctrine, "int[").should.throw();
+ });
+});
+
+describe('tags option', function() {
+ it ('only param', function() {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @const @const",
+ " * @param {String} y",
+ " */"
+ ].join('\n'), { tags: ['param'], unwrap:true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'param');
+ res.tags[0].should.have.property('name', 'y');
+ });
+
+ it ('param and type', function() {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @const x",
+ " * @param {String} y",
+ " * @type {String} ",
+ " */"
+ ].join('\n'), { tags: ['param', 'type'], unwrap:true });
+ res.tags.should.have.length(2);
+ res.tags[0].should.have.property('title', 'param');
+ res.tags[0].should.have.property('name', 'y');
+ res.tags[1].should.have.property('title', 'type');
+ res.tags[1].should.have.property('type');
+ res.tags[1].type.should.have.property('name', 'String');
+ });
+
+});
+
+describe('invalid tags', function() {
+ it ('bad tag 1', function() {
+ doctrine.parse.bind(doctrine,
+ [
+ "/**",
+ " * @param {String} hucairz",
+ " */"
+ ].join('\n'), { tags: 1, unwrap:true }).should.throw();
+ });
+
+ it ('bad tag 2', function() {
+ doctrine.parse.bind(doctrine,
+ [
+ "/**",
+ " * @param {String} hucairz",
+ " */"
+ ].join('\n'), { tags: ['a', 1], unwrap:true }).should.throw();
+ });
+});
+
+describe('optional params', function() {
+
+ // should fail since sloppy option not set
+ it('failure 0', function() {
+ doctrine.parse(
+ ["/**", " * @param {String} [val]", " */"].join('\n'), {
+ unwrap: true
+ }).should.eql({
+ "description": "",
+ "tags": []
+ });
+ });
+
+ it('failure 1', function() {
+ doctrine.parse(
+ ["/**", " * @param [val", " */"].join('\n'), {
+ unwrap: true, sloppy: true
+ }).should.eql({
+ "description": "",
+ "tags": []
+ });
+ });
+
+ it('success 1', function() {
+ doctrine.parse(
+ ["/**", " * @param {String} [val]", " */"].join('\n'), {
+ unwrap: true, sloppy: true
+ }).should.eql({
+ "description": "",
+ "tags": [{
+ "title": "param",
+ "description": null,
+ "type": {
+ "type": "OptionalType",
+ "expression": {
+ "type": "NameExpression",
+ "name": "String"
+ }
+ },
+ "name": "val"
+ }]
+ });
+ });
+ it('success 2', function() {
+ doctrine.parse(
+ ["/**", " * @param {String=} val", " */"].join('\n'), {
+ unwrap: true, sloppy: true
+ }).should.eql({
+ "description": "",
+ "tags": [{
+ "title": "param",
+ "description": null,
+ "type": {
+ "type": "OptionalType",
+ "expression": {
+ "type": "NameExpression",
+ "name": "String"
+ }
+ },
+ "name": "val"
+ }]
+ });
+ });
+
+ it('success 3', function() {
+ doctrine.parse(
+ ["/**", " * @param {String=} [val=abc] some description", " */"].join('\n'),
+ { unwrap: true, sloppy: true}
+ ).should.eql({
+ "description": "",
+ "tags": [{
+ "title": "param",
+ "description": "some description",
+ "type": {
+ "type": "OptionalType",
+ "expression": {
+ "type": "NameExpression",
+ "name": "String"
+ }
+ },
+ "name": "val",
+ "default": "abc"
+ }]
+ });
+ });
+
+ it('line numbers', function() {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @param {string} foo",
+ " * @returns {string}",
+ " *",
+ " * @example",
+ " * f('blah'); // => undefined",
+ " */"
+ ].join('\n'),
+ { unwrap: true, lineNumbers: true }
+ );
+
+ res.tags[0].should.have.property('lineNumber', 1);
+ res.tags[1].should.have.property('lineNumber', 2);
+ res.tags[2].should.have.property('lineNumber', 4);
+ });
+
+ it('should handle \\r\\n line endings correctly', function() {
+ var res = doctrine.parse(
+ [
+ "/**",
+ " * @param {string} foo",
+ " * @returns {string}",
+ " *",
+ " * @example",
+ " * f('blah'); // => undefined",
+ " */"
+ ].join('\r\n'),
+ { unwrap: true, lineNumbers: true }
+ );
+
+ res.tags[0].should.have.property('lineNumber', 1);
+ res.tags[1].should.have.property('lineNumber', 2);
+ res.tags[2].should.have.property('lineNumber', 4);
+ });
+});
+
+describe('recovery tests', function() {
+ it ('params 2', function () {
+ var res = doctrine.parse(
+ [
+ "@param f",
+ "@param {string} f2"
+ ].join('\n'), { recoverable: true });
+
+ // ensure both parameters are OK
+ res.tags.should.have.length(2);
+ res.tags[0].should.have.property('title', 'param');
+ res.tags[0].should.have.property('type', null);
+ res.tags[0].should.have.property('name', 'f');
+
+ res.tags[1].should.have.property('title', 'param');
+ res.tags[1].should.have.property('type');
+ res.tags[1].type.should.have.property('name', 'string');
+ res.tags[1].type.should.have.property('type', 'NameExpression');
+ res.tags[1].should.have.property('name', 'f2');
+ });
+
+ it ('params 2', function () {
+ var res = doctrine.parse(
+ [
+ "@param string f",
+ "@param {string} f2"
+ ].join('\n'), { recoverable: true });
+
+ // ensure first parameter is OK even with invalid type name
+ res.tags.should.have.length(2);
+ res.tags[0].should.have.property('title', 'param');
+ res.tags[0].should.have.property('type', null);
+ res.tags[0].should.have.property('name', 'string');
+ res.tags[0].should.have.property('description', 'f');
+
+ res.tags[1].should.have.property('title', 'param');
+ res.tags[1].should.have.property('type');
+ res.tags[1].type.should.have.property('name', 'string');
+ res.tags[1].type.should.have.property('type', 'NameExpression');
+ res.tags[1].should.have.property('name', 'f2');
+ });
+
+ it ('return 1', function() {
+ var res = doctrine.parse(
+ [
+ "@returns"
+ ].join('\n'), { recoverable: true });
+
+ // return tag should exist
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'returns');
+ res.tags[0].should.have.property('type', null);
+ });
+ it ('return 2', function() {
+ var res = doctrine.parse(
+ [
+ "@returns",
+ "@param {string} f2"
+ ].join('\n'), { recoverable: true });
+
+ // return tag should exist as well as next tag
+ res.tags.should.have.length(2);
+ res.tags[0].should.have.property('title', 'returns');
+ res.tags[0].should.have.property('type', null);
+
+ res.tags[1].should.have.property('title', 'param');
+ res.tags[1].should.have.property('type');
+ res.tags[1].type.should.have.property('name', 'string');
+ res.tags[1].type.should.have.property('type', 'NameExpression');
+ res.tags[1].should.have.property('name', 'f2');
+ });
+
+ it ('extra @ 1', function() {
+ var res = doctrine.parse(
+ [
+ "@",
+ "@returns",
+ "@param {string} f2"
+ ].join('\n'), { recoverable: true });
+
+ // empty tag name shouldn't affect subsequent tags
+ res.tags.should.have.length(3);
+ res.tags[0].should.have.property('title', '');
+ res.tags[0].should.not.have.property('type');
+
+ res.tags[1].should.have.property('title', 'returns');
+ res.tags[1].should.have.property('type', null);
+
+ res.tags[2].should.have.property('title', 'param');
+ res.tags[2].should.have.property('type');
+ res.tags[2].type.should.have.property('name', 'string');
+ res.tags[2].type.should.have.property('type', 'NameExpression');
+ res.tags[2].should.have.property('name', 'f2');
+ });
+
+ it ('extra @ 2', function() {
+ var res = doctrine.parse(
+ [
+ "@ invalid name",
+ "@param {string} f2"
+ ].join('\n'), { recoverable: true });
+
+ // empty tag name shouldn't affect subsequent tags
+ res.tags.should.have.length(2);
+ res.tags[0].should.have.property('title', '');
+ res.tags[0].should.not.have.property('type');
+ res.tags[0].should.not.have.property('name');
+ res.tags[0].should.have.property('description', 'invalid name');
+
+ res.tags[1].should.have.property('title', 'param');
+ res.tags[1].should.have.property('type');
+ res.tags[1].type.should.have.property('name', 'string');
+ res.tags[1].type.should.have.property('type', 'NameExpression');
+ res.tags[1].should.have.property('name', 'f2');
+ });
+
+ it ('invalid tag 1', function() {
+ var res = doctrine.parse(
+ [
+ "@111 invalid name",
+ "@param {string} f2"
+ ].join('\n'), { recoverable: true });
+
+ // invalid tag name shouldn't affect subsequent tags
+ res.tags.should.have.length(2);
+ res.tags[0].should.have.property('title', '111');
+ res.tags[0].should.not.have.property('type');
+ res.tags[0].should.not.have.property('name');
+ res.tags[0].should.have.property('description', 'invalid name');
+
+ res.tags[1].should.have.property('title', 'param');
+ res.tags[1].should.have.property('type');
+ res.tags[1].type.should.have.property('name', 'string');
+ res.tags[1].type.should.have.property('type', 'NameExpression');
+ res.tags[1].should.have.property('name', 'f2');
+ });
+
+ it ('invalid tag 1', function() {
+ var res = doctrine.parse(
+ [
+ "@111",
+ "@param {string} f2"
+ ].join('\n'), { recoverable: true });
+
+ // invalid tag name shouldn't affect subsequent tags
+ res.tags.should.have.length(2);
+ res.tags[0].should.have.property('title', '111');
+ res.tags[0].should.not.have.property('type');
+ res.tags[0].should.not.have.property('name');
+ res.tags[0].should.have.property('description', null);
+
+ res.tags[1].should.have.property('title', 'param');
+ res.tags[1].should.have.property('type');
+ res.tags[1].type.should.have.property('name', 'string');
+ res.tags[1].type.should.have.property('type', 'NameExpression');
+ res.tags[1].should.have.property('name', 'f2');
+ });
+
+ it ('should not crash on bad type in @param without name', function() {
+ var res = doctrine.parse("@param {Function(DOMNode)}", { recoverable: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.eql({
+ "description": null,
+ "errors": [
+ "not reach to EOF",
+ "Missing or invalid tag name"
+ ],
+ "name": null,
+ "title": "param",
+ "type": null
+ });
+ });
+
+ it ('should not crash on bad type in @param in sloppy mode', function() {
+ var res = doctrine.parse("@param {int[} [x]", { sloppy: true, recoverable: true });
+ res.tags.should.have.length(1);
+ res.tags[0].should.eql({
+ "description": null,
+ "errors": [
+ "expected an array-style type declaration (int[])"
+ ],
+ "name": "x",
+ "title": "param",
+ "type": null
+ });
+ });
+});
+
+describe('exported Syntax', function() {
+ it ('members', function () {
+ doctrine.Syntax.should.eql({
+ NullableLiteral: 'NullableLiteral',
+ AllLiteral: 'AllLiteral',
+ NullLiteral: 'NullLiteral',
+ UndefinedLiteral: 'UndefinedLiteral',
+ VoidLiteral: 'VoidLiteral',
+ UnionType: 'UnionType',
+ ArrayType: 'ArrayType',
+ RecordType: 'RecordType',
+ FieldType: 'FieldType',
+ FunctionType: 'FunctionType',
+ ParameterType: 'ParameterType',
+ RestType: 'RestType',
+ NonNullableType: 'NonNullableType',
+ OptionalType: 'OptionalType',
+ NullableType: 'NullableType',
+ NameExpression: 'NameExpression',
+ TypeApplication: 'TypeApplication'
+ });
+ });
+});
+
+describe('@ mark contained descriptions', function () {
+ it ('comment description #10', function () {
+ doctrine.parse(
+ [
+ '/**',
+ ' * Prevents the default action. It is equivalent to',
+ ' * {@code e.preventDefault()}, but can be used as the callback argument of',
+ ' * {@link goog.events.listen} without declaring another function.',
+ ' * @param {!goog.events.Event} e An event.',
+ ' */'
+ ].join('\n'),
+ { unwrap: true, sloppy: true }).should.eql({
+ 'description': 'Prevents the default action. It is equivalent to\n{@code e.preventDefault()}, but can be used as the callback argument of\n{@link goog.events.listen} without declaring another function.',
+ 'tags': [{
+ 'title': 'param',
+ 'description': 'An event.',
+ 'type': {
+ 'type': 'NonNullableType',
+ 'expression': {
+ 'type': 'NameExpression',
+ 'name': 'goog.events.Event'
+ },
+ 'prefix': true
+ },
+ 'name': 'e'
+ }]
+ });
+ });
+
+ it ('tag description', function () {
+ doctrine.parse(
+ [
+ '/**',
+ ' * Prevents the default action. It is equivalent to',
+ ' * @param {!goog.events.Event} e An event.',
+ ' * {@code e.preventDefault()}, but can be used as the callback argument of',
+ ' * {@link goog.events.listen} without declaring another function.',
+ ' */'
+ ].join('\n'),
+ { unwrap: true, sloppy: true }).should.eql({
+ 'description': 'Prevents the default action. It is equivalent to',
+ 'tags': [{
+ 'title': 'param',
+ 'description': 'An event.\n{@code e.preventDefault()}, but can be used as the callback argument of\n{@link goog.events.listen} without declaring another function.',
+ 'type': {
+ 'type': 'NonNullableType',
+ 'expression': {
+ 'type': 'NameExpression',
+ 'name': 'goog.events.Event'
+ },
+ 'prefix': true
+ },
+ 'name': 'e'
+ }]
+ });
+ });
+});
+
+describe('function', function () {
+ it ('recognize "function" type', function () {
+ var res = doctrine.parse(
+ [
+ "@param {function} foo description",
+ ].join('\n'), {});
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'param');
+ res.tags[0].should.have.property('type');
+ res.tags[0].type.should.eql({
+ "name": "function",
+ "type": "NameExpression"
+ });
+ res.tags[0].should.have.property('name', 'foo');
+ res.tags[0].should.have.property('description', 'description');
+ });
+});
+
+describe('tagged namepaths', function () {
+ it ('recognize module:', function () {
+ var res = doctrine.parse(
+ [
+ "@alias module:Foo.bar"
+ ].join('\n'), {});
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'alias');
+ res.tags[0].should.have.property('name', 'module:Foo.bar');
+ res.tags[0].should.have.property('description', null);
+ });
+
+ it ('recognize external:', function () {
+ var res = doctrine.parse(
+ [
+ "@param {external:Foo.bar} baz description"
+ ].join('\n'), {});
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'param');
+ res.tags[0].type.should.eql({
+ "name": "external:Foo.bar",
+ "type": "NameExpression"
+ });
+ res.tags[0].should.have.property('name', 'baz');
+ res.tags[0].should.have.property('description', 'description');
+ });
+
+ it ('recognize event:', function () {
+ var res = doctrine.parse(
+ [
+ "@function event:Foo.bar"
+ ].join('\n'), {});
+ res.tags.should.have.length(1);
+ res.tags[0].should.have.property('title', 'function');
+ res.tags[0].should.have.property('name', 'event:Foo.bar');
+ res.tags[0].should.have.property('description', null);
+ });
+
+ it ('invalid bogus:', function () {
+ var res = doctrine.parse(
+ [
+ "@method bogus:Foo.bar"
+ ].join('\n'), {});
+ res.tags.should.have.length(0);
+ });
+});
+
+/* vim: set sw=4 ts=4 et tw=80 : */
diff --git a/tools/eslint/node_modules/doctrine/test/strict.js b/tools/eslint/node_modules/doctrine/test/strict.js
new file mode 100644
index 0000000000..f6008d52f9
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/test/strict.js
@@ -0,0 +1,168 @@
+/*
+ Copyright (C) 2014 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*global require describe it*/
+/*jslint node:true */
+'use strict';
+
+var fs = require('fs'),
+ path = require('path'),
+ root = path.join(path.dirname(fs.realpathSync(__filename)), '..'),
+ doctrine = require(root);
+require('should');
+
+describe('strict parse', function () {
+ // https://github.com/Constellation/doctrine/issues/21
+ it('unbalanced braces', function () {
+ (function () {
+ doctrine.parse(
+ [
+ "/**",
+ " * @param {const",
+ " */"
+ ].join('\n'), { unwrap: true, strict: true });
+ }).should.throw('Braces are not balanced');
+
+ (function () {
+ doctrine.parse(
+ [
+ "/**",
+ " * @param {const",
+ " */"
+ ].join('\n'), { unwrap: true });
+ }).should.not.throw();
+
+ (function () {
+ doctrine.parse(
+ [
+ "/**",
+ " * Description",
+ " * @param {string name Param description",
+ " * @param {int} foo Bar",
+ " */"
+ ].join('\n'), { unwrap: true, strict: true });
+ }).should.throw('Braces are not balanced');
+
+ (function () {
+ doctrine.parse(
+ [
+ "/**",
+ " * Description",
+ " * @param {string name Param description",
+ " * @param {int} foo Bar",
+ " */"
+ ].join('\n'), { unwrap: true });
+ }).should.not.throw();
+
+ (function () {
+ doctrine.parse(
+ [
+ "/**",
+ " * Description",
+ " * @returns {int",
+ " */"
+ ].join('\n'), { unwrap: true, strict: true });
+ }).should.throw('Braces are not balanced');
+
+ (function () {
+ doctrine.parse(
+ [
+ "/**",
+ " * Description",
+ " * @returns {int",
+ " */"
+ ].join('\n'), { unwrap: true });
+ }).should.not.throw();
+ });
+
+ // https://github.com/Constellation/doctrine/issues/21
+ it('incorrect tag starting with @@', function () {
+ (function () {
+ doctrine.parse(
+ [
+ "/**",
+ " * @@version",
+ " */"
+ ].join('\n'), { unwrap: true, strict: true });
+ }).should.throw('Missing or invalid title');
+
+ (function () {
+ doctrine.parse(
+ [
+ "/**",
+ " * @@version",
+ " */"
+ ].join('\n'), { unwrap: true });
+ }).should.not.throw();
+
+ (function () {
+ doctrine.parse(
+ [
+ "/**",
+ " * Description",
+ " * @@param {string} name Param description",
+ " */"
+ ].join('\n'), { unwrap: true, strict: true });
+ }).should.throw('Missing or invalid title');
+
+ (function () {
+ doctrine.parse(
+ [
+ "/**",
+ " * Description",
+ " * @@param {string} name Param description",
+ " */"
+ ].join('\n'), { unwrap: true });
+ }).should.not.throw();
+
+ (function () {
+ doctrine.parse(
+ [
+ "/**",
+ " * Description",
+ " * @kind ng",
+ " */"
+ ].join('\n'), { unwrap: true, strict: true });
+ }).should.throw('Invalid kind name \'ng\'');
+
+ (function () {
+ doctrine.parse(
+ [
+ "/**",
+ " * Description",
+ " * @variation Animation",
+ " */"
+ ].join('\n'), { unwrap: true, strict: true });
+ }).should.throw('Invalid variation \'Animation\'');
+
+ (function () {
+ doctrine.parse(
+ [
+ "/**",
+ " * Description",
+ " * @access ng",
+ " */"
+ ].join('\n'), { unwrap: true, strict: true });
+ }).should.throw('Invalid access name \'ng\'');
+ });
+});
diff --git a/tools/eslint/node_modules/doctrine/test/stringify.js b/tools/eslint/node_modules/doctrine/test/stringify.js
new file mode 100644
index 0000000000..0f3a43ed83
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/test/stringify.js
@@ -0,0 +1,413 @@
+/*
+ Copyright (C) 2013 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*global require describe it*/
+/*jslint node:true */
+'use strict';
+
+var fs = require('fs'),
+ path = require('path'),
+ root = path.join(path.dirname(fs.realpathSync(__filename)), '..'),
+ doctrine = require(root),
+ assert = require('assert');
+require('should');
+
+// tests for the stringify function.
+// ensure that we can parse and then stringify and the results are identical
+describe('stringify', function () {
+
+ function testStringify(text) {
+ it (text, function() {
+ var result = doctrine.parse("@param {" + text + "} name");
+ // console.log("Parse Tree: " + JSON.stringify(result, null, " "));
+ var stringed = doctrine.type.stringify(result.tags[0].type, {compact:true});
+ stringed.should.equal(text);
+ });
+ }
+
+ // simple
+ testStringify("String");
+ testStringify("*");
+ testStringify("null");
+ testStringify("undefined");
+ testStringify("void");
+ //testStringify("?="); // Failing
+
+ // rest
+ testStringify("...string");
+ testStringify("...[string]");
+ testStringify("...[[string]]");
+
+ // optional, nullable, nonnullable
+ testStringify("string=");
+ testStringify("?string");
+ testStringify("!string");
+ testStringify("!string=");
+
+ // type applications
+ testStringify("Array.<String>");
+ testStringify("Array.<String,Number>");
+
+ // union types
+ testStringify("()");
+ testStringify("(String|Number)");
+
+ // Arrays
+ testStringify("[String]");
+ testStringify("[String,Number]");
+ testStringify("[(String|Number)]");
+
+ // Record types
+ testStringify("{a}");
+ testStringify("{a:String}");
+ testStringify("{a:String,b}");
+ testStringify("{a:String,b:object}");
+ testStringify("{a:String,b:foo.bar.baz}");
+ testStringify("{a:(String|Number),b,c:Array.<String>}");
+ testStringify("...{a:(String|Number),b,c:Array.<String>}");
+ testStringify("{a:(String|Number),b,c:Array.<String>}=");
+
+ // fn types
+ testStringify("function(a)");
+ testStringify("function(a):String");
+ testStringify("function(a:number):String");
+ testStringify("function(a:number,b:Array.<(String|Number|Object)>):String");
+ testStringify("function(a:number,callback:function(a:Array.<(String|Number|Object)>):boolean):String");
+ testStringify("function(a:(string|number),this:string,new:true):function():number");
+ testStringify("function(a:(string|number),this:string,new:true):function(a:function(val):result):number");
+});
+
+describe('literals', function() {
+ it('NullableLiteral', function () {
+ doctrine.type.stringify({
+ type: doctrine.Syntax.NullableLiteral
+ }).should.equal('?');
+ });
+
+ it('AllLiteral', function () {
+ doctrine.type.stringify({
+ type: doctrine.Syntax.AllLiteral
+ }).should.equal('*');
+ });
+
+ it('NullLiteral', function () {
+ doctrine.type.stringify({
+ type: doctrine.Syntax.NullLiteral
+ }).should.equal('null');
+ });
+
+ it('UndefinedLiteral', function () {
+ doctrine.type.stringify({
+ type: doctrine.Syntax.UndefinedLiteral
+ }).should.equal('undefined');
+ });
+});
+
+describe('Expression', function () {
+ it('NameExpression', function () {
+ doctrine.type.stringify({
+ type: doctrine.Syntax.NameExpression,
+ name: 'this.is.valid'
+ }).should.equal('this.is.valid');
+
+ doctrine.type.stringify({
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ }).should.equal('String');
+ });
+
+ it('ArrayType', function () {
+ doctrine.type.stringify({
+ type: doctrine.Syntax.ArrayType,
+ elements: [{
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ }]
+ }).should.equal('[String]');
+
+ doctrine.type.stringify({
+ type: doctrine.Syntax.ArrayType,
+ elements: [{
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ }, {
+ type: doctrine.Syntax.NameExpression,
+ name: 'Number'
+ }]
+ }).should.equal('[String, Number]');
+
+ doctrine.type.stringify({
+ type: doctrine.Syntax.ArrayType,
+ elements: []
+ }).should.equal('[]');
+ });
+
+ it('RecordType', function () {
+ doctrine.type.stringify({
+ type: doctrine.Syntax.RecordType,
+ fields: [{
+ type: doctrine.Syntax.FieldType,
+ key: 'name',
+ value: null
+ }]
+ }).should.equal('{name}');
+
+ doctrine.type.stringify({
+ type: doctrine.Syntax.RecordType,
+ fields: [{
+ type: doctrine.Syntax.FieldType,
+ key: 'name',
+ value: {
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ }
+ }]
+ }).should.equal('{name: String}');
+
+ doctrine.type.stringify({
+ type: doctrine.Syntax.RecordType,
+ fields: [{
+ type: doctrine.Syntax.FieldType,
+ key: 'string',
+ value: {
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ }
+ }, {
+ type: doctrine.Syntax.FieldType,
+ key: 'number',
+ value: {
+ type: doctrine.Syntax.NameExpression,
+ name: 'Number'
+ }
+ }]
+ }).should.equal('{string: String, number: Number}');
+
+ doctrine.type.stringify({
+ type: doctrine.Syntax.RecordType,
+ fields: []
+ }).should.equal('{}');
+ });
+
+ it('UnionType', function () {
+ doctrine.type.stringify({
+ type: doctrine.Syntax.UnionType,
+ elements: [{
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ }]
+ }).should.equal('(String)');
+
+ doctrine.type.stringify({
+ type: doctrine.Syntax.UnionType,
+ elements: [{
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ }, {
+ type: doctrine.Syntax.NameExpression,
+ name: 'Number'
+ }]
+ }).should.equal('(String|Number)');
+
+ doctrine.type.stringify({
+ type: doctrine.Syntax.UnionType,
+ elements: [{
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ }, {
+ type: doctrine.Syntax.NameExpression,
+ name: 'Number'
+ }]
+ }, { topLevel: true }).should.equal('String|Number');
+ });
+
+ it('RestType', function () {
+ doctrine.type.stringify({
+ type: doctrine.Syntax.RestType,
+ expression: {
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ }
+ }).should.equal('...String');
+ });
+
+ it('NonNullableType', function () {
+ doctrine.type.stringify({
+ type: doctrine.Syntax.NonNullableType,
+ expression: {
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ },
+ prefix: true
+ }).should.equal('!String');
+
+ doctrine.type.stringify({
+ type: doctrine.Syntax.NonNullableType,
+ expression: {
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ },
+ prefix: false
+ }).should.equal('String!');
+ });
+
+ it('OptionalType', function () {
+ doctrine.type.stringify({
+ type: doctrine.Syntax.OptionalType,
+ expression: {
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ }
+ }).should.equal('String=');
+ });
+
+ it('NullableType', function () {
+ doctrine.type.stringify({
+ type: doctrine.Syntax.NullableType,
+ expression: {
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ },
+ prefix: true
+ }).should.equal('?String');
+
+ doctrine.type.stringify({
+ type: doctrine.Syntax.NullableType,
+ expression: {
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ },
+ prefix: false
+ }).should.equal('String?');
+ });
+
+ it('TypeApplication', function () {
+ doctrine.type.stringify({
+ type: doctrine.Syntax.TypeApplication,
+ expression: {
+ type: doctrine.Syntax.NameExpression,
+ name: 'Array'
+ },
+ applications: [
+ {
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ }
+ ]
+ }).should.equal('Array.<String>');
+
+ doctrine.type.stringify({
+ type: doctrine.Syntax.TypeApplication,
+ expression: {
+ type: doctrine.Syntax.NameExpression,
+ name: 'Array'
+ },
+ applications: [
+ {
+ type: doctrine.Syntax.NameExpression,
+ name: 'String'
+ },
+ {
+ type: doctrine.Syntax.AllLiteral
+ }
+ ]
+ }).should.equal('Array.<String, *>');
+ });
+});
+
+describe('Complex identity', function () {
+ it('Functions', function () {
+ var data01 = 'function (): void';
+ doctrine.type.stringify(
+ doctrine.type.parseType(data01)
+ ).should.equal(data01);
+
+ var data02 = 'function (): String';
+ doctrine.type.stringify(
+ doctrine.type.parseType(data02)
+ ).should.equal(data02);
+
+ var data03 = 'function (test: string): String';
+ doctrine.type.stringify(
+ doctrine.type.parseType(data03)
+ ).should.equal(data03);
+
+ var data04 = 'function (this: Date, test: String): String';
+ doctrine.type.stringify(
+ doctrine.type.parseType(data04)
+ ).should.equal(data04);
+
+ var data05 = 'function (this: Date, a: String, b: Number): String';
+ doctrine.type.stringify(
+ doctrine.type.parseType(data05)
+ ).should.equal(data05);
+
+ var data06 = 'function (this: Date, a: Array.<String, Number>, b: Number): String';
+ doctrine.type.stringify(
+ doctrine.type.parseType(data06)
+ ).should.equal(data06);
+
+ var data07 = 'function (new: Date, a: Array.<String, Number>, b: Number): HashMap.<String, Number>';
+ doctrine.type.stringify(
+ doctrine.type.parseType(data07)
+ ).should.equal(data07);
+
+ var data08 = 'function (new: Date, a: Array.<String, Number>, b: (Number|String|Date)): HashMap.<String, Number>';
+ doctrine.type.stringify(
+ doctrine.type.parseType(data08)
+ ).should.equal(data08);
+
+ var data09 = 'function (new: Date)';
+ doctrine.type.stringify(
+ doctrine.type.parseType(data09)
+ ).should.equal(data09);
+
+ var data10 = 'function (this: Date)';
+ doctrine.type.stringify(
+ doctrine.type.parseType(data10)
+ ).should.equal(data10);
+
+ var data11 = 'function (this: Date, ...list)';
+ doctrine.type.stringify(
+ doctrine.type.parseType(data11)
+ ).should.equal(data11);
+
+ var data11a = 'function (this: Date, test: String=)';
+ doctrine.type.stringify(
+ doctrine.type.parseType(data11a)
+ ).should.equal(data11a);
+
+ // raw ... are not supported
+// var data12 = 'function (this: Date, ...)';
+// doctrine.type.stringify(
+// doctrine.type.parseType(data12)
+// ).should.equal(data12);
+
+ var data12a = 'function (this: Date, ?=)';
+ doctrine.type.stringify(
+ doctrine.type.parseType(data12a)
+ ).should.equal(data12a);
+ });
+});
+
+/* vim: set sw=4 ts=4 et tw=80 : */
diff --git a/tools/eslint/node_modules/doctrine/test/test.html b/tools/eslint/node_modules/doctrine/test/test.html
new file mode 100644
index 0000000000..3784c2e5e4
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/test/test.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Doctrine trying</title>
+<script src="../doctrine.js"></script>
+<script type="text/javascript">
+ window.onload = function() {
+ document.getElementById("doit").onclick = function() {
+ var res = doctrine.parseParamType(document.getElementById("commenttext").value,
+ {unwrap:true, recoverable:true} );
+
+ document.getElementById("parse_tree_res").innerHTML = JSON.stringify(res, null, ' ');
+ document.getElementById("stringify_res").textContent = doctrine.stringify(res);
+ };
+ };
+</script>
+</head>
+<body>
+ <textarea id="commenttext">Add a jsdoc comment here</textarea>
+ <br/>
+ <br/>
+ <button id="doit">Click to parse</button>
+ <br/>
+ <br/>
+ <h3>Parse Tree</h3>
+ <pre id="parse_tree_res" ></pre>
+ <h3>Stringified</h3>
+ <pre id="stringify_res" ></pre>
+</body>
+</html> \ No newline at end of file
diff --git a/tools/eslint/node_modules/doctrine/test/unwrap.js b/tools/eslint/node_modules/doctrine/test/unwrap.js
new file mode 100644
index 0000000000..03d6f6dfe5
--- /dev/null
+++ b/tools/eslint/node_modules/doctrine/test/unwrap.js
@@ -0,0 +1,60 @@
+/*
+ Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*jslint node:true */
+'use strict';
+
+var fs = require('fs'),
+ path = require('path'),
+ root = path.join(path.dirname(fs.realpathSync(__filename)), '..'),
+ doctrine = require(root);
+require('should');
+
+describe('unwrapComment', function () {
+ it('normal', function () {
+ doctrine.unwrapComment('/**\n * @const\n * @const\n */').should.equal('\n@const\n@const\n');
+ });
+
+ it('single', function () {
+ doctrine.unwrapComment('/**x*/').should.equal('x');
+ });
+
+ it('more stars', function () {
+ doctrine.unwrapComment('/***x*/').should.equal('x');
+ doctrine.unwrapComment('/****x*/').should.equal('*x');
+ });
+
+ it('2 lines', function () {
+ doctrine.unwrapComment('/**x\n * y\n*/').should.equal('x\ny\n');
+ });
+
+ it('2 lines with space', function () {
+ doctrine.unwrapComment('/**x\n * y\n*/').should.equal('x\n y\n');
+ });
+
+ it('3 lines with blank line', function () {
+ doctrine.unwrapComment('/**x\n *\n \* y\n*/').should.equal('x\n\ny\n');
+ });
+});
+/* vim: set sw=4 ts=4 et tw=80 : */