denoland/deno_doc

Erroneous parsing of decorators in JSDoc code blocks

Opened this issue · 1 comments

When using deno doc --json, example code blocks that contain decorators prove to be problematic for the parser. I'm not sure if this problem persists in --html or in the pretty-printed format in the CLI, but I would assume so since they all use the same parser under the hood AFAIK.

It stems from the @ prefix, which has also been a long running problem with the built-in JSDoc parser used by VSCode's intellisense, and a lot of other projects that incorporate JSDoc comment parsing in their logic. The parser gets confused and thinks the decorator is actually a malformed JSDoc tag, leading to unexpected (and usually terribly formatted) results.

Here's an example from the module doc comment in a JSR package of mine. Note the "unsupported" tags, particularly the last one. You can see it's parsing tags from inside an example code block.

{
  "version": 1,
  "nodes": [
    // ...
    {
      "name": "",
      "location": {
        "filename": "file:///workspaces/decorators/packages/types/mod.ts",
        "line": 1,
        "col": 0,
        "byteIndex": 0
      },
      "declarationKind": "export",
      "jsDoc": {
        "tags": [
          {
            "kind": "module"
          },
          {
            "kind": "unsupported",
            "value": "@log(\"class\") class Example {\n// ...\n"
          },
          {
            "kind": "unsupported",
            "value": "@log(\"method\") method() { return \"foo\" }\n"
          },
          {
            "kind": "unsupported",
            "value": "@log(\"getter\") get field() { return 42 }\n}\n```"
            // ---- the tell-tale sign its in an example code block  ^^^
          }
        ]
      },
      "kind": "moduleDoc"
    }
  ]
}

Just checked the output of deno doc --html and it is indeed affected by this issue. However, since the HTML doesn't render unsupported tags, the problem manifests itself as broken example code blocks. Notice in the screenshot below that the example cuts off before the class body for Config - that's because the very first line in the example class has a decorator on it.

image