mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-20 17:26:01 +08:00
127 lines
3.5 KiB
JavaScript
Executable File
127 lines
3.5 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const { execSync } = require('child_process');
|
|
|
|
// Generate LSP symbols if not already present
|
|
const symbolsFile = path.join(__dirname, 'spine-libgdx-symbols.json');
|
|
if (!fs.existsSync(symbolsFile)) {
|
|
console.log('Generating LSP symbols for spine-libgdx...');
|
|
execSync(`npx lsp-cli ../spine-libgdx/spine-libgdx/src java ${symbolsFile}`, {
|
|
stdio: 'inherit',
|
|
cwd: __dirname
|
|
});
|
|
}
|
|
|
|
// Read and parse symbols
|
|
const data = JSON.parse(fs.readFileSync(symbolsFile, 'utf8'));
|
|
const allTypes = [];
|
|
|
|
// Recursively collect all types (including inner types)
|
|
function collectTypes(symbols, parentName = '') {
|
|
symbols.forEach(symbol => {
|
|
if (['class', 'interface', 'enum'].includes(symbol.kind)) {
|
|
// Skip utils package
|
|
if (symbol.file && symbol.file.includes('/utils/')) {
|
|
return;
|
|
}
|
|
|
|
// Skip SkeletonRenderer classes
|
|
if (symbol.name === 'SkeletonRenderer' || symbol.name === 'SkeletonRendererDebug') {
|
|
return;
|
|
}
|
|
|
|
const fullName = parentName ? `${parentName}.${symbol.name}` : symbol.name;
|
|
allTypes.push({
|
|
name: fullName,
|
|
kind: symbol.kind,
|
|
supertypes: symbol.supertypes || [],
|
|
documentation: symbol.documentation || null
|
|
});
|
|
|
|
// Recursively process children
|
|
if (symbol.children) {
|
|
collectTypes(symbol.children, fullName);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Collect all types
|
|
collectTypes(data.symbols);
|
|
|
|
// Sort types alphabetically
|
|
allTypes.sort((a, b) => a.name.localeCompare(b.name));
|
|
|
|
// Generate markdown
|
|
let markdown = `# Spine Runtime Types
|
|
|
|
Generated from spine-libgdx (reference implementation)
|
|
Total types: ${allTypes.length}
|
|
|
|
## Type Hierarchy
|
|
|
|
`;
|
|
|
|
// Build hierarchy map
|
|
const childrenMap = new Map();
|
|
allTypes.forEach(type => {
|
|
type.supertypes.forEach(supertype => {
|
|
if (!childrenMap.has(supertype)) {
|
|
childrenMap.set(supertype, []);
|
|
}
|
|
childrenMap.get(supertype).push(type.name);
|
|
});
|
|
});
|
|
|
|
// Helper to print hierarchy
|
|
function printHierarchy(typeName, indent = '') {
|
|
const children = childrenMap.get(typeName);
|
|
if (children && children.length > 0) {
|
|
children.sort().forEach(child => {
|
|
markdown += `${indent}- ${child}\n`;
|
|
printHierarchy(child, indent + ' ');
|
|
});
|
|
}
|
|
}
|
|
|
|
// Only show types that have subclasses
|
|
const typesWithChildren = [];
|
|
allTypes.forEach(type => {
|
|
if (childrenMap.has(type.name)) {
|
|
typesWithChildren.push(type.name);
|
|
}
|
|
});
|
|
|
|
// Sort and print hierarchy for types with children
|
|
typesWithChildren.sort().forEach(typeName => {
|
|
markdown += `\n**${typeName}**\n`;
|
|
printHierarchy(typeName, '');
|
|
});
|
|
|
|
// Add complete type list
|
|
markdown += `\n## All Types\n\n`;
|
|
|
|
allTypes.forEach(type => {
|
|
markdown += `- **${type.name}** (${type.kind})`;
|
|
|
|
if (type.supertypes.length > 0) {
|
|
markdown += ` extends ${type.supertypes.join(', ')}`;
|
|
}
|
|
|
|
if (type.documentation) {
|
|
const firstLine = type.documentation.split('\n')[0].trim();
|
|
if (firstLine) {
|
|
markdown += ` - ${firstLine}`;
|
|
}
|
|
}
|
|
|
|
markdown += '\n';
|
|
});
|
|
|
|
// Write output
|
|
const outputFile = path.join(__dirname, 'spine-runtimes-types.md');
|
|
fs.writeFileSync(outputFile, markdown);
|
|
console.log(`Generated: ${outputFile}`);
|
|
console.log(`Total types: ${allTypes.length}`); |