summaryrefslogtreecommitdiff
path: root/tools/doc
diff options
context:
space:
mode:
authorSam Ruby <rubys@intertwingly.net>2018-08-30 10:37:04 -0400
committerSam Ruby <rubys@intertwingly.net>2018-09-02 10:14:03 -0400
commit5da155398ef8645c76872c6db3114a3e796a80da (patch)
tree34be30e547da9ad823ef5a8e23490c094f81fbd5 /tools/doc
parenta55c57b8c48d4d09d3fb74ffddab6e87d10f2030 (diff)
downloadandroid-node-v8-5da155398ef8645c76872c6db3114a3e796a80da.tar.gz
android-node-v8-5da155398ef8645c76872c6db3114a3e796a80da.tar.bz2
android-node-v8-5da155398ef8645c76872c6db3114a3e796a80da.zip
tools: add [src] links to assert.html
Parse `const assert = module.exports = ok;` as exporting a constructor named `assert`. PR-URL: https://github.com/nodejs/node/pull/22601 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Diffstat (limited to 'tools/doc')
-rw-r--r--tools/doc/apilinks.js85
1 files changed, 58 insertions, 27 deletions
diff --git a/tools/doc/apilinks.js b/tools/doc/apilinks.js
index 98dd7827d6..35183912d3 100644
--- a/tools/doc/apilinks.js
+++ b/tools/doc/apilinks.js
@@ -55,35 +55,50 @@ process.argv.slice(2).forEach((file) => {
const ast = acorn.parse(source, { ecmaVersion: 10, locations: true });
const program = ast.body;
+ // Build link
+ const link = `https://github.com/${repo}/blob/${tag}/` +
+ path.relative('.', file).replace(/\\/g, '/');
+
// Scan for exports.
const exported = { constructors: [], identifiers: [] };
program.forEach((statement) => {
- if (statement.type !== 'ExpressionStatement') return;
- const expr = statement.expression;
- if (expr.type !== 'AssignmentExpression') return;
-
- let lhs = expr.left;
- if (expr.left.object.type === 'MemberExpression') lhs = lhs.object;
- if (lhs.type !== 'MemberExpression') return;
- if (lhs.object.name !== 'module') return;
- if (lhs.property.name !== 'exports') return;
-
- let rhs = expr.right;
- while (rhs.type === 'AssignmentExpression') rhs = rhs.right;
-
- if (rhs.type === 'NewExpression') {
- exported.constructors.push(rhs.callee.name);
- } else if (rhs.type === 'ObjectExpression') {
- rhs.properties.forEach((property) => {
- if (property.value.type === 'Identifier') {
- exported.identifiers.push(property.value.name);
- if (/^[A-Z]/.test(property.value.name[0])) {
- exported.constructors.push(property.value.name);
+ if (statement.type === 'ExpressionStatement') {
+ const expr = statement.expression;
+ if (expr.type !== 'AssignmentExpression') return;
+
+ let lhs = expr.left;
+ if (expr.left.object.type === 'MemberExpression') lhs = lhs.object;
+ if (lhs.type !== 'MemberExpression') return;
+ if (lhs.object.name !== 'module') return;
+ if (lhs.property.name !== 'exports') return;
+
+ let rhs = expr.right;
+ while (rhs.type === 'AssignmentExpression') rhs = rhs.right;
+
+ if (rhs.type === 'NewExpression') {
+ exported.constructors.push(rhs.callee.name);
+ } else if (rhs.type === 'ObjectExpression') {
+ rhs.properties.forEach((property) => {
+ if (property.value.type === 'Identifier') {
+ exported.identifiers.push(property.value.name);
+ if (/^[A-Z]/.test(property.value.name[0])) {
+ exported.constructors.push(property.value.name);
+ }
}
- }
- });
- } else if (rhs.type === 'Identifier') {
- exported.identifiers.push(rhs.name);
+ });
+ } else if (rhs.type === 'Identifier') {
+ exported.identifiers.push(rhs.name);
+ }
+ } else if (statement.type === 'VariableDeclaration') {
+ for (const decl of statement.declarations) {
+ let init = decl.init;
+ while (init && init.type === 'AssignmentExpression') init = init.left;
+ if (!init || init.type !== 'MemberExpression') continue;
+ if (init.object.name !== 'module') continue;
+ if (init.property.name !== 'exports') continue;
+ exported.constructors.push(decl.id.name);
+ definition[decl.id.name] = `${link}#L${statement.loc.start.line}`;
+ }
}
});
@@ -93,8 +108,7 @@ process.argv.slice(2).forEach((file) => {
// ClassName.prototype.foo = ...;
// function Identifier(...) {...};
//
- const link = `https://github.com/${repo}/blob/${tag}/` +
- path.relative('.', file).replace(/\\/g, '/');
+ const indirect = {};
program.forEach((statement) => {
if (statement.type === 'ExpressionStatement') {
@@ -128,6 +142,11 @@ process.argv.slice(2).forEach((file) => {
}
definition[name] = `${link}#L${statement.loc.start.line}`;
+
+ if (expr.left.property.name === expr.right.name) {
+ indirect[expr.right.name] = name;
+ }
+
} else if (statement.type === 'FunctionDeclaration') {
const name = statement.id.name;
if (!exported.identifiers.includes(name)) return;
@@ -136,6 +155,18 @@ process.argv.slice(2).forEach((file) => {
`${link}#L${statement.loc.start.line}`;
}
});
+
+ // Search for indirect references of the form ClassName.foo = foo;
+ if (Object.keys(indirect).length > 0) {
+ program.forEach((statement) => {
+ if (statement.type === 'FunctionDeclaration') {
+ const name = statement.id.name;
+ if (indirect[name]) {
+ definition[indirect[name]] = `${link}#L${statement.loc.start.line}`;
+ }
+ }
+ });
+ }
});
console.log(JSON.stringify(definition, null, 2));