Skip to content

Commit

Permalink
Merge pull request #3 from markwpearce/fix/missing_semicolon
Browse files Browse the repository at this point in the history
Fixes issue with generating documentation with namespaces
  • Loading branch information
markwpearce authored Sep 9, 2021
2 parents eeacca4 + 03ec477 commit f6872b6
Show file tree
Hide file tree
Showing 7 changed files with 342 additions and 2,299 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"program": "${workspaceFolder}/node_modules/.bin/jsdoc",
"request": "launch",
"cwd": "${workspaceFolder}",
"args": ["-c", "jsdoc.json", "-t", "node_modules/minami", "-d", "docs"],
"args": ["-c", "jsdoc.json", "-d", "docs"],
"skipFiles": ["<node_internals>/**"],
"type": "node",
"sourceMaps": true
Expand Down
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,39 @@ Example:
"includePattern": ".+\\.br?s$"
},
"opts": {
"recurse": true
"recurse": true,
"template": "node_modules/clean-jsdoc-theme", // or whatever template you've chosen - see below
"brighterscript-jsdocs-plugin": {
"addModule": true // true by default - should we generate module names based on the file names?
}
}
}
```

Note: You may want to set configuration value `opts.brighterscript-jsdocs-plugin.addModule` to `false` if you are using Brighterscript namespaces and you want your code grouped by namespace.

3. Add a script to `package.json` like:

```json
"scripts": {
"docs": "./node_modules/.bin/jsdoc -c jsdoc.json -d docs -t ./node_modules/braintree-jsdoc-template"
"docs": "./node_modules/.bin/jsdoc -c jsdoc.json -d docs"
}
```

# Generating Documentation

Run the script to generate documentation! (Documentation is put in the `./docs/` folder)

```
npm run docs
```

# Templates

The default JSDocs template may not meet your needs. Here's a good list of templates that are available:

https://cancerberosgx.github.io/jsdoc-templates-demo/demo/

# Brightscript and Brighterscript

Internally, this plugin uses the [Brighterscript](https://github.com/rokucommunity/brighterscript) parser. Brighterscript is a superset of Roku's Brightscript language, so plain old .brs files should be parsed properly.
Expand All @@ -83,7 +97,7 @@ It is not necessary to wrap BrightScript comments in javascript style comments,

These comments will be parsed the same:

```bs
```
' Give the maximum of two numbers
' @param {integer} x - the first number
' @param {integer} y - the second number
Expand Down Expand Up @@ -111,7 +125,7 @@ end function

## Example

```bs
```
' Namespace for testing
namespace TestBsDoc
Expand Down
134 changes: 92 additions & 42 deletions convert-brighterscript-docs.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
'use strict';
const bs = require('brighterscript');
const path = require('path');

const jsCommentStartRegex = /^[\s]*(?:\/\*+)?[\s]*(.*)/g
const bsMeaningfulCommentRegex = /^[\s]*(?:'|REM)[\s]*\**[\s]*(.*)/g
const paramRegex = /@param\s+(?:{([^}]*)})?\s+(?:\[(\w+).*\]|(\w+))[\s-\s|\s]*(.*)/
const returnRegex = /@returns?\s*({(?:[^}]*)})?\s*(.*)/
const extendsRegex = /@extends/
const moduleRegex = /@module ([^\*\s]+)/
const opts = env && env.opts || {}
const pluginOpts = opts['brighterscript-jsdocs-plugin'] || {};

if (pluginOpts.addModule === undefined || pluginOpts.addModule === null) {
pluginOpts.addModule = true
}



/** @type {string[]} */
const namespacesCreated = []

/** @type {string[]} */
const modulesCreated = []

/** @type {string[]} */
let parserLines = []

Expand Down Expand Up @@ -109,14 +120,28 @@ function getCommentForStatement(comments, stmt) {
}

function getMemberOf(moduleName = "", namespaceName = "") {
const memberOf = namespaceName || moduleName;

const memberOf = namespaceName || moduleName.replace(/\./g, '/');
const memberType = /*namespaceName ? "" : */ "module:"
if (memberOf) {
return (` * @memberof module:${memberOf}`);
return ` * @memberof! ${memberType}${memberOf.replace(/\./g, '/')}`;
}
return ""
}

/**
*
* @param {string} moduleName
* @returns
*/
function getModuleLineComment(moduleName = "") {
const modifiedModuleName = moduleName.replace(/\./g, '/')
if (!modifiedModuleName || modulesCreated.includes(modifiedModuleName)) {
return ""
}
modulesCreated.push(modifiedModuleName);
return [`/**`, ` * @module ${modifiedModuleName}`, ` */`].join('\n');
}

/**
* Convert a comment statement text to Js Doc Lines
* This will return a string[] with each line of a block comment
Expand All @@ -134,13 +159,16 @@ function convertCommentTextToJsDocLines(comment) {
// * Comment here
commentLines.push(...comment.text.split('\n').map((line, i) => {
return line.replace(bsMeaningfulCommentRegex, '$1');
}).map(line => line.trim()).map((line, i, lines) => {
if (i === 0) {
line = line.replace(jsCommentStartRegex, '$1');
}
line = line.replace(/\**\/\s*/g, "")
return " * " + line;
}))
}).map(line => line.trim())
.filter((line) => {
return !line.includes('@module')
}).map((line, i, lines) => {
if (i === 0) {
line = line.replace(jsCommentStartRegex, '$1');
}
line = line.replace(/\**\/\s*/g, "")
return " * " + line;
}))
}
return commentLines
}
Expand Down Expand Up @@ -333,7 +361,7 @@ function processClass(comment, klass, moduleName = "", namespaceName = "") {
let parentClassName = "", extendsLine = ""
if (klass.parentClassName) {
parentClassName = klass.parentClassName.getName()
extendsLine = ` * @extends ${klass.parentClassName.getName()} `
extendsLine = ` * @extends ${klass.parentClassName.getName(bs.ParseMode.BrighterScript)} `
}

for (var i = 0; i < commentLines.length; i++) {
Expand Down Expand Up @@ -371,6 +399,7 @@ function processClass(comment, klass, moduleName = "", namespaceName = "") {

output.push('}\n')
if (namespaceName) {
// output.push(...['/**', ' * @class', ' */']);
output.push(`${namespaceName}.${klassName} = ${klassName}; `)
}
return output.join('\n')
Expand All @@ -389,32 +418,52 @@ function processClass(comment, klass, moduleName = "", namespaceName = "") {
function processNamespace(comment, namespace, moduleName = "", parentNamespaceName) {

const output = [];
let namespaceName = namespace.name;

if (parentNamespaceName) {
namespaceName = parentNamespaceName + "." + namespaceName
const namespaceParts = namespace.name.split('.');
const namespaceNames = []
let namespaceNameChain = ""
for (const namespacePart of namespaceParts) {
if (namespaceNameChain.length > 0) {
namespaceNameChain += '.'
}
namespaceNameChain += namespacePart;
namespaceNames.push(namespaceNameChain)
}
if (!namespacesCreated.includes(namespaceName)) {
// have not created this namespace yet
let commentLines = convertCommentTextToJsDocLines(comment);

// if (namespaceName !== moduleName) {
commentLines.push(getMemberOf(moduleName, parentNamespaceName));
// }
commentLines.push(` * @namespace ${namespaceName} `)
commentLines.push(' */');

output.push(commentLines.join('\n'));
let index = 0
let previousNamespace = ""
for (const namespaceName of namespaceNames) {
let subNamespace = namespaceName
if (parentNamespaceName) {
output.push(`${parentNamespaceName}.namespaceName = {}`)
subNamespace = parentNamespaceName + "." + namespaceName
}
else {
output.push(`var ${namespaceName} = {}; `);
if (!namespacesCreated.includes(subNamespace)) {
// have not created this namespace yet

output.push(getModuleLineComment(subNamespace));
let commentLines = convertCommentTextToJsDocLines(comment);
if (subNamespace != moduleName) {
commentLines.push(getMemberOf(previousNamespace));
}
//commentLines.push(` * @namespace {object} ${subNamespace} `)
commentLines.push(' */');

output.push(commentLines.join('\n'));
/*
if (parentNamespaceName || index > 0) {
output.push(`${subNamespace} = {}`)
}
else {
output.push(`var ${subNamespace} = {}; `);
}*/
namespacesCreated.push(subNamespace)
}
namespacesCreated.push(namespaceName)
previousNamespace = subNamespace
index++
}

output.push(processStatements(namespace.body.statements, moduleName, namespaceName))
let totalNamespace = namespace.name
if (parentNamespaceName) {
totalNamespace = parentNamespaceName + "." + totalNamespace
}
output.push(processStatements(namespace.body.statements, moduleName, totalNamespace))
return output.join('\n');
}

Expand Down Expand Up @@ -472,19 +521,20 @@ exports.handlers = {
const statements = parseResult.statements

// Add our module to the top of the file if it doesn't exist. If it does find out the name
const moduleMatch = e.source.match(/@module ([^\*\s]+)/);
let moduleName = "";
const moduleMatch = e.source.match(moduleRegex);
const output = [];
if (moduleMatch) {
moduleName = moduleMatch[1];
} else {
moduleName = path.parse(e.filename).name.replace(/\./g, '_');
let moduleName = "";
if (pluginOpts.addModule) {
if (moduleMatch) {
moduleName = moduleMatch[1];
} else {
moduleName = path.parse(e.filename).name.split('.')[0].replace(/\./g, '_');
}
output.push(getModuleLineComment(moduleName));
}
output.push(`/** @module ${moduleName} */`);

output.push(processStatements(statements, moduleName))

e.source = output.join('\n');
//console.log(e.source)
// console.log(e.source)
}
};
17 changes: 17 additions & 0 deletions examples/source/DebugWindow.bs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
' @module BGE
namespace BGE.Debug.Alpha.Beta

class DebugWindow extends BGE.UI.UiContainer

function new(game as BGE.Game) as void
super(game)
m.backgroundRGBA = BGE.RGBAtoRGBA(128, 128, 128, 0.5)
m.padding.set(10)
end function




end class

end namespace
7 changes: 5 additions & 2 deletions jsdoc.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
"include": [
"examples"
],
"includePattern": ".+\\.br?s$"
"includePattern": ".+\\DebugWindow.br?s$"
},
"extendedConfig": {},
"opts": {
"recurse": true,
"template": "node_modules/braintree-jsdoc-template"
"readme": "README.md",
"template": "node_modules/braintree-jsdoc-template",
"brighterscript-jsdocs-plugin": {}
}
}
Loading

0 comments on commit f6872b6

Please sign in to comment.