jsdoc / jsdoc/jsdoc

Static class properties incorrectly parsed with instance scope instead of static scope

Open
#2,144 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
15.5k
Forks
1.5k
Avg merge
10d 23h
Merged PRs (30d)
1

Description

Bug Description

JSDoc incorrectly parses static class properties with instance scope (#) instead of static scope (.), resulting in wrong longnames and scope classification.

Expected Behavior

Static class properties should be parsed with:

  • Longname: ClassName.propertyName (using . separator)
  • Scope: static

Actual Behavior

Static class properties are parsed with:

  • Longname: ClassName#propertyName (using # separator)
  • Scope: instance

Minimal Test Case

Input JavaScript:

/** Sample class with static and instance properties. */
class TestClass {
    /** Instance property. */
    instanceProp = 'instance';

    /** Static property. */
    static staticProp = 'static';

    /** Static method (works correctly). */
    static staticMethod() {
        return 'static method';
    }
}

Expected JSDoc Output:

  • TestClass#instanceProp with scope instance
  • TestClass.staticProp with scope static ❌ (currently fails)
  • TestClass.staticMethod with scope static

Actual JSDoc Output:

  • TestClass#instanceProp with scope instance
  • TestClass#staticProp with scope instance ❌ (incorrect)
  • TestClass.staticMethod with scope static

Environment

  • JSDoc version: 4.x (latest)
  • Node.js version: 23.1.0
  • Operating System: MacOS 15.6.1 (24G90)

Root Cause Analysis

The bug is located in packages/jsdoc-parse/lib/parser.js at lines 366-373 in the astnodeToMemberof() function:

} else if (isClassProperty(node)) {
  doclet = this._getDocletById(node.enclosingScope.nodeId);

  if (!doclet) {
    result.memberof = LONGNAMES.ANONYMOUS + SCOPE.PUNC.INSTANCE;
  } else {
    result.memberof = doclet.longname + SCOPE.PUNC.INSTANCE;  // ❌ Always uses INSTANCE
  }
}

This code always uses SCOPE.PUNC.INSTANCE (#) for class properties, regardless of whether they are static or not.

Proposed Fix

The fix should check the node.static property, similar to how static methods are handled in lines 384-390:

} else if (isClassProperty(node)) {
  doclet = this._getDocletById(node.enclosingScope.nodeId);

  if (!doclet) {
    result.memberof = LONGNAMES.ANONYMOUS + (node.static === true ? SCOPE.PUNC.STATIC : SCOPE.PUNC.INSTANCE);
  } else {
    result.memberof = doclet.longname + (node.static === true ? SCOPE.PUNC.STATIC : SCOPE.PUNC.INSTANCE);
  }
}

Test Case

I can provide a complete test case that demonstrates this bug:

Test fixture: test/fixtures/staticproperties.js fixtures-staticproperties.js
Test spec: test/specs/documentation/staticproperties.js specs-staticproperties.js

The test shows that:

  • Static methods are parsed correctly ✅
  • Static getters/setters are parsed correctly ✅
  • Static properties are parsed incorrectly ❌

Impact

This bug affects:

  • Documentation generation for classes with static properties
  • Template engines that rely on correct scope classification
  • Any tooling that processes JSDoc output and expects correct longnames

Additional Notes

  • Static methods and static getters/setters work correctly
  • Only static properties (field declarations) are affected
  • The bug has been confirmed with a minimal reproducible test case

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/jsdoc-parse/lib/parser.js, especially astnodeToMemberof() around lines 366-373, and compare it with the static-method handling around lines 384-390. Run test/specs/documentation/staticproperties.js with test/fixtures/staticproperties.js and verify that static properties produce the expected dot-separated longname and static scope while instance properties remain unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
documentation
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.