Repository: eslint/doctrine (js)

Issue:
Support nested brackets in default values
Intent is to support the following code:

```js
/**
 * @param {Array} [foo=[1]] this is a param
 */
```

Currently the default parsing ends at the first `]` regardless if other opening `[`s are encountered. JSDoc handles this syntax properly, and usejsdoc doesn't mention it but also doesn't forbid it in its discussion of default values.

Pull request description:
Parse array default syntax
Fixes #133

this allows the code

    @param {Array} [foo=[1]] to properly be parsed

It does this by keeping track of bracket depth in the name parsing.

Patch:
diff --git a/lib/doctrine.js b/lib/doctrine.js
index 78f3ff0..c38830a 100644
--- a/lib/doctrine.js
+++ b/lib/doctrine.js
@@ -337,13 +337,21 @@
             }
 
             if (useBrackets) {
+
+
                 // do we have a default value for this?
                 if (source.charCodeAt(index) === 0x3D  /* '=' */) {
-
                     // consume the '='' symbol
                     name += advance();
+                    var bracketDepth = 1;
                     // scan in the default value
-                    while (index < last && source.charCodeAt(index) !== 0x5D  /* ']' */) {
+                    while (index < last) {
+                        if (source.charCodeAt(index) === 0x5B /* '[' */) {
+                            bracketDepth++;
+                        } else if (source.charCodeAt(index) === 0x5D  /* ']' */ &&
+                            --bracketDepth === 0) {
+                            break;
+                        }
                         name += advance();
                     }
                 }


Test patch:
diff --git a/test/parse.js b/test/parse.js
index c2311e7..7220af1 100644
--- a/test/parse.js
+++ b/test/parse.js
@@ -1921,6 +1921,28 @@ describe('optional params', function() {
         });
     });
 
+    it('default array', function() {
+        doctrine.parse(
+            ["/**", " * @param {String} [val=['foo']] 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": "['foo']"
+            }]
+        });
+    });
+
     it('line numbers', function() {
         var res = doctrine.parse(
             [