add script that finds all undocumented exports

This commit is contained in:
Felix Roos 2023-01-12 12:35:04 +01:00
parent 62af12f3b9
commit 48d0ffe868
5 changed files with 1691 additions and 44 deletions

17
index.mjs Normal file
View File

@ -0,0 +1,17 @@
// this barrel export is currently only used to find undocumented exports
export * from './packages/core/index.mjs';
export * from './packages/csound/index.mjs';
export * from './packages/embed/index.mjs';
export * from './packages/eval/index.mjs';
export * from './packages/midi/index.mjs';
export * from './packages/mini/index.mjs';
export * from './packages/osc/index.mjs';
export * from './packages/react/index.mjs';
export * from './packages/serial/index.mjs';
export * from './packages/soundfonts/index.mjs';
export * from './packages/tonal/index.mjs';
export * from './packages/tone/index.mjs';
export * from './packages/transpiler/index.mjs';
export * from './packages/webaudio/index.mjs';
export * from './packages/webdirt/index.mjs';
export * from './packages/xen/index.mjs';

1347
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
"lint": "eslint . --ext mjs,js --quiet",
"codeformat": "prettier --write .",
"format-check": "prettier --check .",
"report-undocumented": "node undocumented.mjs > undocumented.json",
"check": "npm run format-check && npm run lint && npm run test",
"iclc": "cd paper && pandoc --template=pandoc/iclc.html --citeproc --number-sections iclc2023.md -o iclc2023.html && pandoc --template=pandoc/iclc.latex --citeproc --number-sections iclc2023.md -o iclc2023.pdf"
},
@ -47,8 +48,10 @@
"homepage": "https://strudel.tidalcycles.org",
"devDependencies": {
"@vitest/ui": "^0.25.7",
"acorn-static-class-features": "^1.0.0",
"c8": "^7.12.0",
"canvas": "^2.11.0",
"dependency-tree": "^9.0.0",
"eslint": "^8.28.0",
"events": "^3.3.0",
"gh-pages": "^4.0.0",

286
undocumented.json Normal file
View File

@ -0,0 +1,286 @@
{
"/home/felix/projects/strudel/packages/core/fraction.mjs": [
"gcd"
],
"/home/felix/projects/strudel/packages/core/timespan.mjs": [
"TimeSpan"
],
"/home/felix/projects/strudel/packages/core/hap.mjs": [
"Hap"
],
"/home/felix/projects/strudel/packages/core/state.mjs": [
"State"
],
"/home/felix/projects/strudel/packages/core/util.mjs": [
"isNoteWithOctave",
"isNote",
"tokenizeNote",
"toMidi",
"fromMidi",
"freqToMidi",
"valueToMidi",
"_mod",
"getPlayableNoteValue",
"getFrequency",
"rotate",
"pipe",
"compose",
"flatten",
"id",
"constant",
"listRange",
"curry",
"parseNumeral",
"mapArgs",
"numeralArgs",
"parseFractional",
"fractionalArgs"
],
"/home/felix/projects/strudel/packages/core/value.mjs": [
"unionWithObj",
"valued",
"Value",
"map"
],
"/home/felix/projects/strudel/packages/core/drawLine.mjs": [],
"/home/felix/projects/strudel/packages/core/logger.mjs": [
"logKey",
"logger"
],
"/home/felix/projects/strudel/packages/core/pattern.mjs": [
"setStringParser",
"isPattern",
"reify",
"polymeter",
"set",
"keep",
"keepif",
"mod",
"pow",
"band",
"bor",
"bxor",
"blshift",
"brshift",
"lt",
"gt",
"lte",
"gte",
"eq",
"eqt",
"ne",
"net",
"and",
"or",
"func",
"register",
"compressSpan",
"compressspan",
"focusSpan",
"focusspan",
"zoomArc",
"zoomarc",
"linger",
"segment",
"invert",
"inv",
"hush",
"palindrome",
"juxBy",
"juxby",
"jux",
"stutWith",
"stutwith",
"stut",
"echowith",
"iterback",
"chunkback",
"bypass",
"duration",
"color",
"colour",
"striate"
],
"/home/felix/projects/strudel/packages/core/controls.mjs": [],
"/home/felix/projects/strudel/packages/core/euclid.mjs": [
"euclidrot",
"euclidLegatoRot"
],
"/home/felix/projects/strudel/packages/core/signal.mjs": [
"steady",
"signal",
"isaw",
"isaw2",
"saw2",
"sine2",
"cosine2",
"square2",
"tri2",
"time",
"_brandBy",
"brandBy",
"brand",
"_irand",
"__chooseWith",
"randcat",
"wchoose",
"wchooseCycles",
"perlinWith",
"degradeByWith",
"undegrade"
],
"/home/felix/projects/strudel/packages/core/speak.mjs": [
"speak"
],
"/home/felix/projects/strudel/packages/core/evaluate.mjs": [
"evalScope",
"evaluate"
],
"/home/felix/projects/strudel/packages/core/zyklus.mjs": [],
"/home/felix/projects/strudel/packages/core/cyclist.mjs": [
"Cyclist"
],
"/home/felix/projects/strudel/packages/core/time.mjs": [
"getTime",
"setTime"
],
"/home/felix/projects/strudel/packages/core/repl.mjs": [
"repl"
],
"/home/felix/projects/strudel/packages/core/draw.mjs": [
"getDrawContext",
"cleanupDraw"
],
"/home/felix/projects/strudel/packages/core/animate.mjs": [
"x",
"y",
"w",
"h",
"a",
"r",
"fill",
"smear",
"rescale",
"moveXY",
"zoomIn"
],
"/home/felix/projects/strudel/packages/core/pianoroll.mjs": [
"pianoroll"
],
"/home/felix/projects/strudel/packages/core/ui.mjs": [
"backgroundImage",
"cleanupUi"
],
"/home/felix/projects/strudel/packages/core/gist.js": [],
"/home/felix/projects/strudel/packages/core/index.mjs": [],
"/home/felix/projects/strudel/packages/eval/shift-traverser/index.js": [],
"/home/felix/projects/strudel/packages/eval/shapeshifter.mjs": [
"addMiniLocations",
"minifyStrings",
"wrappedAsync",
"shouldAddReturn"
],
"/home/felix/projects/strudel/packages/eval/evaluate.mjs": [
"evaluate"
],
"/home/felix/projects/strudel/packages/eval/index.mjs": [],
"/home/felix/projects/strudel/packages/midi/midi.mjs": [
"WebMidi",
"enableWebMidi"
],
"/home/felix/projects/strudel/packages/midi/index.mjs": [],
"/home/felix/projects/strudel/packages/mini/krill-parser.js": [],
"/home/felix/projects/strudel/packages/mini/mini.mjs": [
"patternifyAST",
"mini",
"h",
"minify"
],
"/home/felix/projects/strudel/packages/mini/index.mjs": [],
"/home/felix/projects/strudel/packages/soundfonts/fontloader.mjs": [
"getFontBufferSource",
"getFontPitch"
],
"/home/felix/projects/strudel/packages/soundfonts/list.mjs": [
"instruments",
"drums",
"instrumentNames"
],
"/home/felix/projects/strudel/packages/soundfonts/sfumato.mjs": [
"loadSoundfont"
],
"/home/felix/projects/strudel/packages/soundfonts/index.mjs": [],
"/home/felix/projects/strudel/packages/tonal/tonal.mjs": [],
"/home/felix/projects/strudel/packages/tonal/voicings.mjs": [
"voicingRegistry",
"setVoicingRange"
],
"/home/felix/projects/strudel/packages/tonal/index.mjs": [],
"/home/felix/projects/strudel/packages/tone/tone.mjs": [
"Tone",
"getDefaultSynth",
"tone",
"amsynth",
"duosynth",
"fmsynth",
"membrane",
"metal",
"monosynth",
"noise",
"pluck",
"polysynth",
"sampler",
"players",
"synth",
"vol",
"lowpass",
"highpass",
"adsr",
"out"
],
"/home/felix/projects/strudel/packages/tone/index.mjs": [],
"/home/felix/projects/strudel/packages/transpiler/transpiler.mjs": [
"transpiler"
],
"/home/felix/projects/strudel/packages/transpiler/index.mjs": [
"evaluate"
],
"/home/felix/projects/strudel/packages/webaudio/feedbackdelay.mjs": [],
"/home/felix/projects/strudel/packages/webaudio/reverb.mjs": [],
"/home/felix/projects/strudel/packages/webaudio/sampler.mjs": [
"getCachedBuffer",
"getSampleBufferSource",
"loadBuffer",
"reverseBuffer",
"getLoadedBuffer",
"resetLoadedSamples",
"getLoadedSamples"
],
"/home/felix/projects/strudel/packages/webaudio/vowel.mjs": [
"vowelFormant"
],
"/home/felix/projects/strudel/packages/webaudio/webaudio.mjs": [
"getAudioContext",
"panic",
"initAudio",
"initAudioOnFirstClick",
"webaudioOutput",
"webaudioOutputTrigger"
],
"/home/felix/projects/strudel/packages/webaudio/index.mjs": [],
"/home/felix/projects/strudel/packages/webdirt/webdirt.mjs": [
"loadWebDirt"
],
"/home/felix/projects/strudel/packages/webdirt/index.mjs": [],
"/home/felix/projects/strudel/packages/xen/xen.mjs": [
"edo",
"xen",
"tuning"
],
"/home/felix/projects/strudel/packages/xen/tunejs.js": [],
"/home/felix/projects/strudel/packages/xen/tune.mjs": [
"tune"
],
"/home/felix/projects/strudel/packages/xen/index.mjs": [],
"/home/felix/projects/strudel/index.mjs": []
}

82
undocumented.mjs Normal file
View File

@ -0,0 +1,82 @@
import { readFile } from 'node:fs/promises';
import { dirname, resolve } from 'path';
import { fileURLToPath } from 'url';
import { parse } from 'acorn';
import dependencyTree from 'dependency-tree';
const __dirname = dirname(fileURLToPath(import.meta.url));
function getExports(code) {
// parse it with acorn
let ast;
try {
ast = parse(code, {
ecmaVersion: 11,
sourceType: 'module',
});
} catch (err) {
return [`acorn parse error: ${err.name}: ${err.messsage}`];
}
// find all names exported in the file
return ast.body
.filter((node) => node?.type === 'ExportNamedDeclaration')
.map((node) => {
const { declaration } = node;
if (!declaration) {
// e.g. "export { Fraction, controls }"
return [];
}
switch (declaration.type) {
case 'VariableDeclaration':
return declaration.declarations
.map((d) => {
switch (d.id.type) {
case 'Identifier':
return d.id.name;
case 'ObjectPattern':
return d.id.properties.map((p) => p.value.name);
default:
return 'unknown declaration: ' + declaration;
}
})
.flat();
default:
// FunctionDeclaration, ClassDeclaration
return declaration.id.name;
}
})
.flat();
}
function isDocumented(name, docs) {
return docs.find(
(d) => d.name === name || d.tags?.find((t) => t.title === 'synonyms' && t.value.split(', ').includes(name)),
);
}
async function getUndocumented(path, docs) {
try {
// load the code of pattern.mjs as a string
const code = await readFile(path, 'utf8');
return getExports(code).filter((name) => !isDocumented(name, docs));
} catch (err) {
return [`parse error: ${err.name}: ${err.message}`];
}
}
// read doc.json file
const { docs } = JSON.parse(await readFile(resolve(__dirname, 'doc.json'), 'utf8'));
const paths = dependencyTree.toList({
filename: 'index.mjs',
// filename: 'packages/core/index.mjs',
directory: resolve(__dirname),
filter: (path) => !path.includes('node_modules'),
});
// const paths = ['../packages/core/pattern.mjs', '../packages/core/hap.mjs'].map((rel) => resolve(__dirname, rel));
const undocumented = Object.fromEntries(
await Promise.all(paths.map(async (path) => [path, await getUndocumented(path, docs)])),
);
console.log(JSON.stringify(undocumented, null, 2));