Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dox does not support async function from ES2017 #198

Open
hasezoey opened this issue Apr 1, 2023 · 1 comment
Open

dox does not support async function from ES2017 #198

hasezoey opened this issue Apr 1, 2023 · 1 comment

Comments

@hasezoey
Copy link
Contributor

hasezoey commented Apr 1, 2023

i have noticed that dox does not support async functions, examples:

when used as a static function:

/**
 * test1
 */
Class.test = async function() {
  // test
}

it is recognized as a property instead of method:

{
  tags: [],
  description: { full: 'test1', summary: 'test1', body: '' },
  isPrivate: false,
  isConstructor: false,
  isClass: false,
  isEvent: false,
  ignore: false,
  line: 4670,
  codeStart: 4673,
  code: 'Class.test = async function() {\n  // test\n}',
  ctx: {
    type: 'property',
    name: 'test',
    value: 'async function() {',
    string: 'Class.test',
    constructor: 'Class'
  }
}

and when used as a normal function:

/**
 * test2
 */
async function test2() {
  // test
}

it does not have a ctx:

{
  tags: [],
  description: { full: 'test2', summary: 'test2', body: '' },
  isPrivate: false,
  isConstructor: false,
  isClass: false,
  isEvent: false,
  ignore: false,
  line: 4684,
  codeStart: 4687,
  code: 'async function test2() {\n' +
    '  // test\n' +
    '}\n' +
    '\n' +
    'if (util.inspect.custom) {\n' +
    '  // Avoid Node deprecation warning DEP0079\n' +
    '  Model[util.inspect.custom] = Model.inspect;\n' +
    '}',
  ctx: false
}
the functions without async for comparison

when used as a static function:

/**
 * test1
 */
Class.test = function() {
  // test
}

is recognized as a method properly:

{
  tags: [],
  description: { full: 'test1', summary: 'test1', body: '' },
  isPrivate: false,
  isConstructor: false,
  isClass: false,
  isEvent: false,
  ignore: false,
  line: 4670,
  codeStart: 4673,
  code: 'Class.test = function() {\n  // test\n}',
  ctx: {
    type: 'method',
    name: 'test',
    string: 'Class.test()',
    constructor: 'Class'
  }
}

and when used as a normal function:

/**
 * test2
 */
function test2() {
  // test
}

it properly has a ctx:

{
  tags: [],
  description: { full: 'test2', summary: 'test2', body: '' },
  isPrivate: false,
  isConstructor: false,
  isClass: false,
  isEvent: false,
  ignore: false,
  line: 4677,
  codeStart: 4680,
  code: 'function test2() {\n  // test\n}',
  ctx: { type: 'function', name: 'test2', string: 'test2()' }
}
@hasezoey
Copy link
Contributor Author

hasezoey commented Apr 1, 2023

for anyone wanting a quick fix, put the following code before any dox.parse* function executes:

Workaround code
// add custom matchers to dox, to recognize things it does not know about
// see https://github.com/tj/dox/issues/198
{
  // Some matchers need to be in a specific order, like the "prototype" matcher must be before the static matcher (and inverted because "unshift")

  // "unshift" is used, because the first function to return a object from "contextPatternMatchers" is used (and we need to "overwrite" those specific functions)

  // push a matcher to recognize "Class.fn = async function" as a method
  dox.contextPatternMatchers.unshift(function(str) {
    const match = /^\s*([\w$.]+)\s*\.\s*([\w$]+)\s*=\s*(?:async\s+)?function/.exec(str);
    if (match) {
      return {
        type: 'method',
        receiver: match[1],
        name: match[2],
        string: match[1] + '.' + match[2] + '()'
      };
    }
  });

  // push a matcher to recognize "Class.prototype.fn = async function" as a method
  dox.contextPatternMatchers.unshift(function(str) {
    const match = /^\s*([\w$.]+)\s*\.\s*prototype\s*\.\s*([\w$]+)\s*=\s*(?:async\s+)?function/.exec(str);
    if (match) {
      return {
        type: 'method',
        constructor: match[1],
        cons: match[1],
        name: match[2],
        string: match[1] + '.prototype.' + match[2] + '()'
      };
    }
  });

  // push a matcher to recognize "async function" as a function
  dox.contextPatternMatchers.unshift(function(str) {
    const match = /^\s*(export(\s+default)?\s+)?(?:async\s+)?function\s+([\w$]+)\s*\(/.exec(str);
    if (match) {
      return {
        type: 'function',
        name: match[3],
        string: match[3] + '()'
      };
    }
  });
}

Note: the base code & regex is basically copied from the existing matcher functions, the code may also not cover all function types

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant