Skip to content

Build docs update#350

Open
edwardalee wants to merge 3 commits intomasterfrom
build-docs-update
Open

Build docs update#350
edwardalee wants to merge 3 commits intomasterfrom
build-docs-update

Conversation

@edwardalee
Copy link
Copy Markdown
Contributor

This fixes #348, enabling documentation to build. This includes removing dependencies on 1. sun.security.util -- Internal JDK API that's no longer accessible due to the module system (JPMS)-- and com.sun.javadoc -- The old Doclet API, removed entirely in JDK 13 (replaced by jdk.javadoc.doclet).

A major part of the problem seems to have been related to accessors and the fact that https://accessors.org no longer has the information that these scripts assume a @terraswarm/jsdoc module at https://npmjs.org.

This results in a large number of errors reported when generating the docs, but the process completes and generates docs for all the local actors.

Dialog with Claude Code leading to these changes:

Cursor

Let me look at how configure processes build.xml.in and check what jsdoc-related configure logic exists.

Now I can see the problem clearly. Let me look at how configure substitutions work in build.xml.in.

Now the picture is clear. Here's the diagnosis:

The problem: build.xml.in (line 58) hardcodes jsdoc.home to node_modules/@terraswarm/jsdoc, but jsdoc is actually installed at vendors/jsdoc (cloned by the Makefile's git clone step). The node_modules/@terraswarm/jsdoc npm package is never successfully installed because:

  1. The ant jsdoc-install target checks if npmjs.org is reachable, and if that check fails, the install is silently skipped.
  2. Even if it were reachable, the @terraswarm/jsdoc npm package may no longer exist or be maintained.

Meanwhile, the doc/Makefile correctly clones jsdoc from GitHub into vendors/jsdoc/, and the file vendors/jsdoc/jsdoc.js does exist on your system. But build.xml never looks there -- it tries to run node_modules/@terraswarm/jsdoc/jsdoc.js which doesn't exist.

The fix: Change jsdoc.home in build.xml.in from node_modules/@terraswarm/jsdoc to vendors/jsdoc, and apply the same change to the already-generated build.xml so you don't need to re-run configure.

Summary of the issue and fix:

  • build.xml.in line 58 had jsdoc.home set to node_modules/@terraswarm/jsdoc, expecting jsdoc to be installed via npm install @terraswarm/jsdoc.
  • But the doc/Makefile installs jsdoc via git clone into vendors/jsdoc/ -- and that's what's actually present on your system (vendors/jsdoc/jsdoc.js exists).
  • The npm-based install was silently failing (likely because the npmjs.org reachability check failed or the package is no longer available), so node_modules/@terraswarm/jsdoc/jsdoc.js was never created.
  • This is not a configure substitution issue -- jsdoc.home was hardcoded (not a @VARIABLE@ placeholder), so configure never touched it.

I changed jsdoc.home from node_modules/@terraswarm/jsdoc to vendors/jsdoc in both build.xml.in (the template) and build.xml (the generated file). Try cd doc; make docs again to see if the jsdoc step now works.


User

OK, the next error is below. Suggestions?

jsdoc:
     [echo] Invoke jsdoc to generate documentation for .js files.
     [echo]     To set this up:
     [echo]        cd $PTII/vendors; git clone https://github.com/terraswarm/jsdoc.git    
     [echo] 
     [echo]     $PTII/doc/jsdoc/topREADME.md will be used as the basis of the first page.
     [echo] 
     [echo]     The output appears in doc/codeDoc/js/index.html
     [echo]     
     [exec] node:internal/modules/cjs/loader:1368
     [exec]   throw err;
     [exec]   ^
     [exec] 
     [exec] Error: Cannot find module 'requizzle'
     [exec] Require stack:
     [exec] - /Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/jsdoc.js
     [exec]     at Function._resolveFilename (node:internal/modules/cjs/loader:1365:15)
     [exec]     at defaultResolveImpl (node:internal/modules/cjs/loader:1021:19)
     [exec]     at resolveForCJSWithHooks (node:internal/modules/cjs/loader:1026:22)
     [exec]     at Function._load (node:internal/modules/cjs/loader:1175:37)
     [exec]     at TracingChannel.traceSync (node:diagnostics_channel:322:14)
     [exec]     at wrapModuleLoad (node:internal/modules/cjs/loader:235:24)
     [exec]     at Module.require (node:internal/modules/cjs/loader:1445:12)
     [exec]     at require (node:internal/modules/helpers:135:16)
     [exec]     at /Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/jsdoc.js:25:19
     [exec]     at Object.<anonymous> (/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/jsdoc.js:35:3) {
     [exec]   code: 'MODULE_NOT_FOUND',
     [exec]   requireStack: [ '/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/jsdoc.js' ]
     [exec] }
     [exec] 
     [exec] Node.js v22.18.0
     [exec] Result: 1


Cursor

The jsdoc path fix worked, but now jsdoc's npm dependencies aren't installed. The vendors/jsdoc directory was git-cloned but never had npm install run in it. Let me check what's there.

As expected -- node_modules is missing inside vendors/jsdoc. You just need to install the dependencies:

cd $PTII/vendors/jsdoc && npm install

That will fetch requizzle and all the other dependencies jsdoc needs. Then re-run cd doc; make docs.


User

Can this command somehow be added to the makefile?


Cursor

Good idea. Let me look at how the Makefile currently handles the jsdoc setup to find the right place to add it.

The right place is right after the git clone (line 820), before the ant invocation. If the clone just happened, or if node_modules is missing, we should run npm install.

Done. I added a step (lines 822-825) that checks if vendors/jsdoc/node_modules exists, and if not, runs npm install inside vendors/jsdoc. It follows the same pattern as the existing guards -- the leading - means make won't abort if the command fails, and it only runs when node_modules is missing, so it's a no-op on subsequent builds.


User

I now get the following message and am wondering why it is checking www.npmjs.org and whether we can remove this check.

-check-if-npmjs-org-is-up:
     [echo] Check to see if https://www.npmjs.org is up.

-jsdoc-no-network-message:
     [echo] The node binary was not found or does not work or npmjs.org was not reachable, so the network is probably down, so there is no point in trying npm.

Cursor

Let me trace through the dependency chain to understand what this check is guarding.

The whole npmjs.org check exists solely to support npm install @terraswarm/jsdoc and npm update @terraswarm/jsdoc into node_modules/ -- the old installation approach we've already replaced. The dependency chain is:

  • jsdocjsdoc-updatejsdoc-install-check-if-npmjs-org-is-up (which pings https://www.npmjs.org)

Since the Makefile now handles cloning into vendors/jsdoc and running npm install there, these ant targets are dead code. The fix is to remove the jsdoc-update dependency from the jsdoc target.

Done. I removed jsdoc-update from the jsdoc target's depends in both build.xml.in and build.xml. This eliminates the entire chain of npm/network checks (jsdoc-updatejsdoc-install-check-if-npmjs-org-is-up → npmjs.org ping). The jsdoc-install, jsdoc-update, and related check targets are now orphaned but harmless -- they won't run unless someone explicitly invokes them via ant jsdoc-install or ant jsdoc-update. You could clean them out later if you want, but they won't cause any trouble.


User

The next error:

jsdoc:
     [echo] Invoke jsdoc to generate documentation for .js files.
     [echo]     To set this up:
     [echo]        cd $PTII/vendors; git clone https://github.com/terraswarm/jsdoc.git    
     [echo] 
     [echo]     $PTII/doc/jsdoc/topREADME.md will be used as the basis of the first page.
     [echo] 
     [echo]     The output appears in doc/codeDoc/js/index.html
     [echo]     
     [exec] ERROR: Unable to find the plugin "node_modules/@terraswarm/jsdoc/plugins/markdown"
     [exec] ERROR: Unable to parse /Users/edwardlee/Ptolemy/ptII/ptolemy/actor/lib/jjs/modules/httpClient/httpClient.js: Unexpected token each
     [exec] ERROR: Unable to parse /Users/edwardlee/Ptolemy/ptII/ptolemy/actor/lib/jjs/modules/process/process.js: Unexpected token each
     [exec] ERROR: Unable to parse /Users/edwardlee/Ptolemy/ptII/org/terraswarm/accessor/accessors/web/userInterface/dashboard/src/components/FixedPlugin/FixedPlugin.jsx: Unexpected token =


Cursor

The first error is a plugin path issue -- doc/jsdoc/jsdoc.json likely references the old node_modules/@terraswarm/jsdoc path. Let me check.

There it is -- the plugin path on line 2 still references node_modules/@terraswarm/jsdoc. Let me check if the plugin exists in the vendors/jsdoc location.

That fixes the first error. The other three errors are different in nature -- they're JavaScript parse failures, not path issues:

  • Unexpected token each in httpClient.js and process.js -- These files likely use for each...in syntax, a SpiderMonkey/Nashorn extension that was never standard JavaScript. Modern jsdoc (using a modern JS parser) can't parse it.
  • Unexpected token = in FixedPlugin.jsx -- This is a JSX/React file with class property syntax that jsdoc doesn't understand without additional configuration.

These are pre-existing issues with old non-standard JS syntax in the codebase, not something caused by the configuration. They'll produce ERROR log lines but shouldn't prevent jsdoc from generating docs for the other files. Does the build actually fail on these, or does it continue past them?


User

No doc files are generated. The next error:

     [exec] Generating output files...
     [exec] node:fs:3085
     [exec]   binding.copyFile(
     [exec]           ^
     [exec] 
     [exec] Error: EISDIR: illegal operation on a directory, copyfile '/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/templates/default/static/fonts/OpenSans-Bold-webfont.eot' -> 'doc/codeDoc/js/fonts'
     [exec]     at Object.copyFileSync (node:fs:3085:11)
     [exec]     at /Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/templates/default/publish.js:472:12
     [exec]     at Array.forEach (<anonymous>)
     [exec]     at exports.publish (/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/templates/default/publish.js:469:17)
     [exec]     at module.exports.cli.generateDocs (/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/cli.js:430:39)
     [exec]     at module.exports.cli.processParseResults (/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/cli.js:383:20)
     [exec]     at module.exports.cli.main (/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/cli.js:227:14)
     [exec]     at module.exports.cli.runCommand (/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/cli.js:180:5)
     [exec]     at /Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/jsdoc.js:103:9
     [exec]     at Object.<anonymous> (/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/jsdoc.js:104:3)
     [exec]     at Module._compile (node:internal/modules/cjs/loader:1688:14)
     [exec]     at Object..js (node:internal/modules/cjs/loader:1820:10)
     [exec]     at Module.load (node:internal/modules/cjs/loader:1423:32)
     [exec]     at Function._load (node:internal/modules/cjs/loader:1246:12)
     [exec]     at TracingChannel.traceSync (node:diagnostics_channel:322:14)
     [exec]     at wrapModuleLoad (node:internal/modules/cjs/loader:235:24) {
     [exec]   errno: -21,
     [exec]   code: 'EISDIR',
     [exec]   syscall: 'copyfile',
     [exec]   path: '/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/templates/default/static/fonts/OpenSans-Bold-webfont.eot',
     [exec]   dest: 'doc/codeDoc/js/fonts'
     [exec] }


Cursor

This is a Node.js v22 compatibility issue with the old jsdoc code. Let me look at the relevant code in publish.js.

Found it. The bug is a Node.js version compatibility issue in vendors/jsdoc/lib/jsdoc/fs.js. Here's what happens:

  1. Line 98 defines a custom exports.copyFileSync(inFile, outDir, fileName) that correctly handles copying a file into a directory.
  2. Lines 123-125 then copy all properties from Node's built-in fs module onto exports -- which overwrites the custom copyFileSync with Node's fs.copyFileSync.
  3. Node's fs.copyFileSync(src, dest) expects dest to be a file path, not a directory, causing the EISDIR error.

In older Node.js versions fs.copyFileSync didn't exist, so the overwrite never happened. With Node v22, it does. The fix is to move the Node fs property copy to before the custom definitions, so the custom ones take precedence.

Now remove the old copy at the end of the file since it's been moved up.

Now the Node built-in fs members are copied first, and then the custom ls, toDir, mkPath, and copyFileSync definitions override any conflicting ones. This restores the intended behavior where jsdoc's copyFileSync(inFile, outDir) correctly constructs the output file path from the directory.

There's also a secondary issue: line 104 uses new Buffer(...) which is deprecated in modern Node. If you hit that next, it's a quick fix to Buffer.alloc(...), but let's see if this gets you past the current error first.


User

The next error:

     [exec] Generating output files...
     [exec] Error: unable to parse [ 'array' ].<{'horizontal': 'number', 'vertical': 'number'}>: Expected "!", "$", "'", "(", "*", ".", "...", "0", "?", "@", "Function", "\"", "\\", "_", "break", "case", "catch", "class", "const", "continue", "debugger", "default", "delete", "do", "else", "enum", "export", "extends", "false", "finally", "for", "function", "if", "implements", "import", "in", "instanceof", "interface", "let", "new", "null", "package", "private", "protected", "public", "return", "static", "super", "switch", "this", "throw", "true", "try", "typeof", "undefined", "var", "void", "while", "with", "yield", "{", Unicode letter number, Unicode lowercase letter, Unicode modifier letter, Unicode other letter, Unicode titlecase letter, Unicode uppercase letter, or [1-9] but "[" found.
     [exec]     at parseType (/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/lib/jsdoc/util/templateHelper.js:251:15)
     [exec]     at buildLink (/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/lib/jsdoc/util/templateHelper.js:328:22)
     [exec]     at exports.linkto (/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/lib/jsdoc/util/templateHelper.js:369:12)
     [exec]     at eval (eval at _.template (/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/node_modules/underscore/underscore.js:1454:20), <anonymous>:11:14)
     [exec]     at Array.forEach (<anonymous>)
     [exec]     at exports.Template.eval (eval at _.template (/Users/edwardlee/Ptolemy/ptII/vendors/jsdoc/node_modules/underscore/underscore.js:1454:20), <anonymous>:9:10)


Cursor

This is a bug in jsdoc's type expression parser -- it can't handle the complex type syntax [ 'array' ].<{'horizontal': 'number', 'vertical': 'number'}>. This is in the template rendering phase, so it crashes the entire output generation. Let me look at the code.

Now I understand the full chain:

  1. parseType catches the catharsis parse error, logs it via logger.error(), and continues
  2. But logger.error() triggers a one-time event that sets shouldExitWithError = true
  3. jsdoc finishes generating output, then exits with code 1
  4. Ant's <exec> sees the non-zero exit and reports BUILD FAILED

So docs are generated but the non-zero exit kills the build. The simplest fix is to add failonerror="false" to the jsdoc exec in the ant target, since jsdoc parse errors in individual files shouldn't prevent the rest of the docs from being built.

Added failonerror="false" to the jsdoc exec in both files. This way jsdoc will still log errors about unparseable type expressions or non-standard JavaScript syntax, but the build will continue past them. The docs for all successfully parsed files will still be generated in doc/codeDoc/js/index.html.


User

Next error:

./ptolemy/copernicus/applet/JarSigner.java:61: error: package sun.security.util is not visible
import sun.security.util.ManifestDigester;
                   ^
  (package sun.security.util is declared in module java.base, which does not export it to the unnamed module)
./doc/doclets/PtDoclet.java:36: error: package com.sun.javadoc does not exist
import com.sun.javadoc.ClassDoc;
                      ^
./doc/doclets/PtDoclet.java:37: error: package com.sun.javadoc does not exist
import com.sun.javadoc.FieldDoc;
                      ^
./doc/doclets/PtDoclet.java:38: error: package com.sun.javadoc does not exist
import com.sun.javadoc.ProgramElementDoc;
                      ^
./doc/doclets/PtDoclet.java:39: error: package com.sun.javadoc does not exist
import com.sun.javadoc.RootDoc;
                      ^
./doc/doclets/PtDoclet.java:40: error: package com.sun.javadoc does not exist
import com.sun.javadoc.SeeTag;
                      ^
./doc/doclets/PtDoclet.java:41: error: package com.sun.javadoc does not exist
import com.sun.javadoc.Tag;
                      ^
./doc/doclets/PtDoclet.java:84: error: cannot find symbol
    public static boolean start(RootDoc root)
                                ^
  symbol:   class RootDoc
  location: class PtDoclet
./doc/doclets/PtDoclet.java:159: error: cannot find symbol
            ProgramElementDoc programElementDoc) {
            ^


Cursor

These are two separate issues, both caused by running on a modern JDK (likely JDK 17+):

  1. sun.security.util -- Internal JDK API that's no longer accessible due to the module system (JPMS).
  2. com.sun.javadoc -- The old Doclet API, removed entirely in JDK 13 (replaced by jdk.javadoc.doclet).

These aren't doc-generation errors per se -- they're compilation errors triggered because the docs target depends on compiling these files first. The fix is to exclude them from the javadoc compilation path since they can't compile on modern JDKs.

Let me look at how the build handles this.

These are two JDK 17 compatibility issues. On JDK 17:

  1. sun.security.util is blocked by the Java module system (JPMS)
  2. com.sun.javadoc was entirely removed in JDK 13 -- PtDoclet is fundamentally broken on JDK 17

Let me check what configure sets for the doclets directory.

These are JDK 17 incompatibilities. Two fixes needed:

  1. ptolemy.copernicus.applet uses internal JDK APIs -- exclude it from the javadoc package list
  2. doc.doclets.PtDoclet uses the old com.sun.javadoc API (removed in JDK 13) -- PtDoclet fundamentally cannot work on JDK 17, so the PtDoclet-dependent targets need to be disabled

All the javadoc commands have - prefixes so make continues past errors, but the PtDoclet failure means codeDoc/ptolemy/actor/lib/Ramp.xml never gets created, which cascades to RampIdx.xml which does NOT have a - prefix and will halt the build.

Now for the critical fix -- the PtDoclet-dependent targets in FULL_DOCS will never produce output on JDK 17, and the RampIdx.xml target that depends on them will halt the build. I'll remove them from FULL_DOCS:

Here's a summary of the three changes to doc/makefile:

  1. Excluded ptolemy.copernicus.applet from COPERNICUSPACKAGES -- it uses sun.security.util.ManifestDigester, an internal API that's blocked by the Java module system on JDK 9+.

  2. Removed doc.doclets from ALLPACKAGES -- the PtDoclet and related classes use com.sun.javadoc.*, which was entirely removed in JDK 13.

  3. Removed codeDoc/ptolemy/actor/lib/Ramp.xml and RampIdx.xml from FULL_DOCS -- these targets depend on PtDoclet, which can't work on JDK 17. Without this change, the RampIdx.xml recipe (which lacks a - error-ignore prefix) would halt the build.

The codeDoc/tree.html (javadoc) and codeDoc/js/index.html (jsdoc) will still be generated. The PtDoclet-based actor documentation index (Ramp.xml, RampIdx.xml) is lost, but that's unavoidable without porting PtDoclet to the new jdk.javadoc.doclet API.


User

The build.xml file is generated by configure, so I think it's changes should go into @build.xml.in


Cursor

You're right. The changes I made earlier to build.xml (the jsdoc.home path, removing the jsdoc-update dependency, and adding failonerror="false") should be in build.xml.in -- which they already are. But build.xml should be regenerated from build.xml.in by re-running configure, rather than being edited directly. The direct edits to build.xml were just to avoid requiring you to re-run configure immediately, but you're correct that the canonical source is build.xml.in.

To make build.xml consistent, you can re-run configure:

cd $PTII && ./configure

That will regenerate build.xml from the updated build.xml.in, picking up all three changes (the vendors/jsdoc path, the removed jsdoc-update dependency, and the failonerror="false").


User

What would it take to port PtDoclet to the new jdk.javadoc.doclet API? Is this a big task?


Cursor

Let me look at the existing PtDoclet to assess the scope.

Now I have a complete picture. Here's the assessment:

It's a moderate task -- probably a few hours of work, not days. PtDoclet is a focused, single-purpose doclet (~485 lines) that does one thing: iterate over classes, extract javadoc comments/tags/fields, and write XML files. It doesn't do any complex rendering or cross-referencing.

Here's the mapping from the old API to the new jdk.javadoc.doclet API:

Old (com.sun.javadoc) New (jdk.javadoc.doclet / javax.lang.model)
Implement start(RootDoc) Implement Doclet interface with init(), run(), getSupportedOptions() etc.
RootDoc.classes() DocletEnvironment.getSpecifiedElements() + ElementFilter
ClassDoc TypeElement
FieldDoc VariableElement
ClassDoc.subclassOf(other) Types.isSubtype()
ClassDoc.fields() ElementFilter.fieldsIn(element.getEnclosedElements())
Tag / SeeTag DocCommentTree + DocTreeVisitor (this is the trickiest part)
ProgramElementDoc.tags("foo") DocTrees.getDocCommentTree() then walk the tree
Doc.inlineTags() Walk DocCommentTree.getBody() elements
SeeTag.referencedClass() etc. ReferenceTree + manual resolution
optionLength() getSupportedOptions() returning Set<Doclet.Option>
root.options() (raw string arrays) Typed Doclet.Option with process() callbacks

What makes it manageable:

  1. PtDoclet only uses ~6 types from the old API (RootDoc, ClassDoc, FieldDoc, ProgramElementDoc, Tag, SeeTag).
  2. PtIndexer has zero dependency on the old API -- it's pure Java I/O and data structures, so it needs no changes.
  3. The output logic (_writeDoc, _relativizePath, _getOutputDirectory) is all string manipulation that stays the same.
  4. The class is small with a simple linear flow: iterate classes → filter by superclass → extract fields → write XML.

The hardest part is the inline tag processing in _inlineTagCommentText() (lines 185-239). The old API gave you a flat array of Tag and SeeTag objects. The new API uses DocCommentTree which is a tree of DocTree nodes that you walk with a visitor. The {@link ...} handling in particular requires resolving references manually via DocTrees rather than getting pre-resolved referencedClass()/referencedMember() from SeeTag.

Rough estimate: 2-4 hours for someone familiar with the new Doclet API, maybe a full day if learning it from scratch. Would you like me to do the port?


User

Yes, please do the port.


Cursor

Let me first check how the doclet is invoked and what the build infrastructure looks like for compilation.

Now let me check what the new Doclet API looks like to make sure I get the imports right.

Now I have a thorough understanding of the old code. Let me write the ported version.

Now let me re-enable the PtDoclet targets in the Makefile and fix the build infrastructure.

Now update the javadoc.doclets target in build.xml.in -- on JDK 9+ there's no tools.jar (the doclet API is in jdk.javadoc module), so we remove that classpath entry and update the message.

Also update the javadoc.actor target which invokes PtDoclet -- the new API requires the doclet path to include the JDK modules, and we should remove the tools.jar reference there too.

Also fix the javadoc.base target which uses RatingTaglet -- let me check if that exists and also references tools.jar.

The remaining tools.jar references are in other targets (doccheck, ojdcheck, javadoc.base, actorIndex). Those are separate concerns -- they won't break the PtDoclet port. Let me now test that the new PtDoclet compiles.

Compiles cleanly -- only a pre-existing deprecation warning in PtIndexer.java (not our code). Let me also verify it can be loaded as a doclet by running a quick test.

Let me verify the XML output looks correct.

The port is complete and verified. Here's a summary:

PtDoclet ported successfully. It compiles, runs, and produces correct XML output on JDK 17.

What changed:

  1. doc/doclets/PtDoclet.java -- Complete rewrite from com.sun.javadoc to jdk.javadoc.doclet:

    • Implements the Doclet interface (init(), run(), getName(), getSupportedOptions(), getSupportedSourceVersion())
    • Uses javax.lang.model (TypeElement, VariableElement, Types.isSubtype()) instead of ClassDoc, FieldDoc, ClassDoc.subclassOf()
    • Uses com.sun.source.doctree (DocCommentTree, LinkTree, TextTree, UnknownBlockTagTree) instead of Tag/SeeTag
    • The -d option is handled via Doclet.Option instead of optionLength()
    • Instance methods instead of statics (the new API instantiates the doclet)
  2. build.xml.in -- Removed tools.jar from classpath in javadoc.doclets and javadoc.actor targets (not needed on JDK 9+)

  3. doc/makefile -- Re-enabled doc.doclets in ALLPACKAGES and restored Ramp.xml/RampIdx.xml in FULL_DOCS

Test output confirms the doclet correctly:

  • Identifies 10 NamedObj subclasses in ptolemy.kernel.util
  • Generates well-formed XML with description, author, version, since, ratings
  • Writes allNamedObjs.txt and PtIndexer.ser

User

This change seems to correctly build the Java class documentation, but it does not generate the XML Actor documentation file that used to get constructed and is used by the DocViewer class. The XML file uses the DocML schema, as defined in the DocManager class. Can we modify it to restore building the XML file?


Cursor

Let me look at the DocML schema and how the old PtDoclet generated actor documentation to understand what's expected.

Now let me look at the XML file that the old PtDoclet used to generate for a real actor, and compare it with what the new PtDoclet generates.

The XML actor documentation files are being generated correctly. The Ramp.xml file has the proper DocML format with <doc>, <description>, <author>, <version>, <since>, ratings, and <property> elements for ports/parameters.

Let me check what the user might be seeing differently. Perhaps the issue is with the make docs flow - maybe the Makefile invocation uses different flags.

The Makefile target doesn't pass -docletpath -- the old API loaded the doclet from the classpath automatically, but the new API needs it explicitly. Let me check if the CLASSPATH variable includes $PTII (i.e., .).

Let me test the exact flow that make docs would use to understand why it might fail.

That's the problem. On JDK 17, javadoc no longer searches the CLASSPATH environment variable for doclet classes -- it requires an explicit -docletpath. The Makefile sets CLASSPATH as an env var but that's not enough for the new javadoc.

Good -- the key fix is adding -docletpath to the Makefile's PTDOCLET variable. On JDK 17, the CLASSPATH env var isn't used to find doclet classes.

Let me verify this works end-to-end with the Makefile's actual invocation pattern.

The issue is argument ordering -- on JDK 17, -doclet must come before -d so javadoc knows to route -d to the custom doclet. The Makefile currently puts PTDOCFLAGS (containing -d) before PTDOCLET (containing -doclet). I need to swap the order in the Makefile, or merge the flags into PTDOCLET.

I need to swap PTDOCFLAGS and PTDOCLET in all the targets that use them, so -doclet comes before -d. Let me find all occurrences.

The fix is argument ordering. On JDK 17, -doclet must come before -d so javadoc knows to route the -d option to the custom doclet. I need to swap the order in all PtDoclet invocations.

Now fix the sub-targets (Bcvtb, CapeCode, HyVisual, Viptos, VisualSense) where -d is inline before $(PTDOCLET).

Now let me also make sure the PtDoclet is compiled before it's used. The Makefile doesn't have a dependency for compiling the doclet. Let me check whether the docs target compiles things first.

Good. FULL_DOCS includes codeDoc/ptolemy/actor/lib/Ramp.xml, which triggers the PtDoclet. But it doesn't ensure the doclet is compiled first. Let me add a compilation dependency.

I need to add a dependency to compile PtDoclet before the Ramp.xml target. Let me add a target for that.

Now let me verify the full flow works. First, let me clean out the previous test output and try the Makefile-style invocation.

The DocML XML files are generated correctly. Let me count how many XML files were generated.

155 actor documentation XML files generated. The fix involves two changes to doc/makefile:

  1. Added -docletpath $(ROOT) to PTDOCLET -- On JDK 9+, javadoc no longer searches the CLASSPATH environment variable for doclet classes; it requires an explicit -docletpath option.

  2. Swapped the order of $(PTDOCLET) and $(PTDOCFLAGS)/-d in all PtDoclet invocation targets -- On JDK 17, -doclet must appear before -d on the command line so javadoc knows to route the -d option to the custom doclet rather than trying to handle it as a standard doclet option (which doesn't exist with a custom doclet).

  3. Added a compilation dependency -- The codeDoc/ptolemy/actor/lib/Ramp.xml target now depends on $(ROOT)/doc/doclets/PtDoclet.class, which has a rule to compile the doclet from source, ensuring the doclet is built before it's invoked.

These changes were applied to all six PtDoclet targets (the main one plus Bcvtb, CapeCode, HyVisual, Viptos, and VisualSense variants).


User

I'm running make docs in the doc directory, and it still does not generate the XML files. I get a number of errors, the first few of which are:

     [exec] ERROR: Unable to parse /Users/edwardlee/Ptolemy/ptII/ptolemy/actor/lib/jjs/modules/httpClient/httpClient.js: Unexpected token each
     [exec] ERROR: Unable to parse /Users/edwardlee/Ptolemy/ptII/ptolemy/actor/lib/jjs/modules/process/process.js: Unexpected token each
     [exec] ERROR: Unable to parse /Users/edwardlee/Ptolemy/ptII/org/terraswarm/accessor/accessors/web/userInterface/dashboard/src/components/FixedPlugin/FixedPlugin.jsx: Unexpected token =
     [exec] ERROR: Unable to parse /Users/edwardlee/Ptolemy/ptII/org/terraswarm/accessor/accessors/web/userInterface/dashboard/src/components/Navbars/AdminNavbar.jsx: Unexpected token =
     [exec] ERROR: Unable to parse /Users/edwardlee/Ptolemy/ptII/org/terraswarm/accessor/accessors/web/userInterface/dashboard/src/components/Navbars/RTLNavbar.jsx: Unexpected token =
     [exec] ERROR: Unable to parse /Users/edwardlee/Ptolemy/ptII/org/terraswarm/accessor/accessors/web/userInterface/dashboard/src/components/Sidebar/Sidebar.jsx: Unexpected token =
     [exec] ERROR: Unable to parse /Users/edwardlee/Ptolemy/ptII/org/terraswarm/accessor/accessors/web/userInterface/dashboard/src/layouts/Admin/Admin.jsx: Unexpected token =


Cursor

Those errors are from the JSDoc (JavaScript documentation) step, not from the PtDoclet (Java XML documentation) step. The JSDoc errors are expected -- they come from old JavaScript files using non-standard syntax -- and were already handled by adding failonerror="false" to the JSDoc ant target in our earlier work.

The XML files not being generated is a separate issue. Let me check what's actually happening when make docs runs the PtDoclet target.

The Makefile target looks correct. Let me check if codeDoc/ptolemy/actor/lib/Ramp.xml already exists (from my earlier test), which would cause make to skip that target.

OK, so the file doesn't exist. Let me try running just the ptdoc target to see the actual error.

Found it. The issue is the -docletpath. The $(ROOT) variable in this Makefile is .. (relative to the doc directory), but the javadoc command already does cd .. before running. So -docletpath .. resolves to $PTII/.. which is the wrong directory. The docletpath needs to be . since javadoc runs from $PTII.

Good, the class file exists. The only problem is the path. Since the javadoc command runs inside (cd ..; ...), it's already in $PTII, so the docletpath should be . not $(ROOT) (which expands to ..).

Now let me test this.

The PtDoclet ran successfully (the ClassNotFoundException: antlr.CommonAST is just a classpath issue for one specific package, not a PtDoclet failure). Let me verify the XML files were generated.

It's working now. 1,772 DocML XML files were generated across all packages.

The problem was that the Makefile's PTDOCLET variable used -docletpath $(ROOT), where $(ROOT) expands to .. (relative to the doc directory). But the javadoc command runs inside (cd ..; ...), which puts it in $PTII. So -docletpath .. was looking for the doclet class one directory above $PTII -- the wrong location. Changing it to -docletpath . makes it find doc/doclets/PtDoclet.class correctly from $PTII.


User

Can you update the JavaScript files that use the non-standard syntax to use standard syntax instead?


Cursor

Let me start by examining the files with non-standard syntax.

Now let me look at the JSX files that have "Unexpected token =" errors.

Let me check if there are more files using the for each non-standard syntax.

Good. There are two categories of non-standard syntax:

  1. for each...in (Mozilla/Nashorn extension) in httpClient.js and process.js -- these can be fixed by replacing with standard for...of loops. The for each (var x in collection) iterates over values, which is equivalent to for (var x of collection) in standard JS.

  2. Class field declarations (method = () => {...}) in the 5 JSX files -- these use ES2022 class fields syntax. However, even if we fix this, JSDoc still can't parse JSX template syntax (<div>, <>, etc.), so these files will always fail JSDoc parsing regardless. I'll convert them anyway for consistency.

Let me start with the two .js files.

Now for the JSX files. The issue is class field arrow function syntax (methodName = () => {...}). I'll convert these to standard method declarations with constructor binding.

Starting with FixedPlugin.jsx:

Now AdminNavbar.jsx:

Now RTLNavbar.jsx (same structure):

Now Sidebar.jsx (only one class field: linkOnClick):

Finally, Admin.jsx (has toggleSidebar, getRoutes, handleBgClick, getBrandText):

All 7 files have been updated. Here's a summary of the changes:

JavaScript files (Nashorn for each...in → standard iterator pattern):

  • ptolemy/actor/lib/jjs/modules/httpClient/httpClient.js: Replaced for each (var name in headersMap.names()) with an explicit iterator()/hasNext()/next() loop. These files use Java interop via Nashorn, so the Java iterator API is the appropriate standard replacement (a plain for...of won't work on Java collections in Nashorn).

  • ptolemy/actor/lib/jjs/modules/process/process.js: Same pattern -- replaced for each(var javaVariable in System.env.entrySet()) with an explicit Java iterator loop.

JSX files (ES2022 class fields → constructor-bound methods):

  • FixedPlugin.jsx: Converted handleClick and activateMode from class field arrow functions to standard methods with bind(this) in the constructor.
  • AdminNavbar.jsx: Converted updateColor, toggleCollapse, and toggleModalSearch.
  • RTLNavbar.jsx: Converted updateColor, toggleCollapse, and toggleModalSearch.
  • Sidebar.jsx: Converted linkOnClick and also fixed the pre-existing this.activeRoute.bind(this) call (which wasn't assigning the result back).
  • Admin.jsx: Converted toggleSidebar, getRoutes, handleBgClick, and getBrandText.

Note that the JSX files will still produce JSDoc parse errors because JSDoc can't parse JSX template syntax (<div>, <>, etc.) -- that's a fundamental limitation. But the = token errors are now eliminated.


User

Where are these JSX files? I do not see them in the tree.


Cursor

Let me check if these files actually exist on disk.

The files do exist on disk. They're deep in the tree at:

org/terraswarm/accessor/accessors/web/userInterface/dashboard/src/
├── components/
│   ├── FixedPlugin/FixedPlugin.jsx
│   ├── Navbars/AdminNavbar.jsx
│   ├── Navbars/RTLNavbar.jsx
│   └── Sidebar/Sidebar.jsx
└── layouts/
    └── Admin/Admin.jsx

If you're not seeing them in the IDE file tree, it may be because that part of the tree is collapsed, or the org/terraswarm/accessor/accessors/ directory is quite deeply nested. Try expanding orgterraswarmaccessoraccessorswebuserInterfacedashboardsrc in the sidebar.


User

Are these generated files? git and cursor seem unaware of them. There are no diffs showing up from your changes.


Cursor

Yes, these are effectively external/generated files. The entire org/terraswarm/accessor/accessors/ directory is gitignored by org/terraswarm/accessor/.gitignore (which has /accessors as an ignore rule). That means these files are pulled in from somewhere else (likely cloned from a separate accessors repository) and are not tracked by this repo's git.

Since they're not under version control here, my edits to them are essentially throwaway -- they'll be overwritten the next time the accessors are fetched. The changes to those JSX files should instead be made in whatever upstream repository they come from, if the errors bother you.

The meaningful changes that are tracked by git are the two .js files:

  • ptolemy/actor/lib/jjs/modules/httpClient/httpClient.js
  • ptolemy/actor/lib/jjs/modules/process/process.js

Let me verify those diffs are visible.

Those two .js files are the only tracked changes. The JSX files under org/terraswarm/accessor/accessors/ are gitignored -- they come from an external accessors repository and aren't part of this repo. Any fixes to those would need to be made upstream.


User

Can you figure out how these files got here? I have not cloned any other repo into this one and they do not seem to be in a submodule.


Cursor

Let me check how this clone got triggered.

That explains it. The accessors directory is cloned automatically by the ./configure script. Here's what happens:

  1. When you ran ./configure, it checked for org/terraswarm/accessor/accessors/
  2. Since the directory didn't exist, it ran git clone https://github.com/icyphy/accessors inside org/terraswarm/accessor/ (see configure.in line 1346-1350)
  3. This created a nested, independent git repository at org/terraswarm/accessor/accessors/ with its own .git directory
  4. The parent ptII repo's .gitignore at org/terraswarm/accessor/.gitignore contains /accessors to exclude this entire clone from the ptII repo's tracking

So it's not a submodule -- it's just a separate git repo cloned into place by configure as a build dependency. The JSX files belong to the icyphy/accessors repository, and any fixes to them would need to be committed there. My edits to those files are local-only and won't persist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can't build the documentation.

2 participants