@hypermode/modus-sdk-as
Advanced tools
Comparing version 0.13.5 to 0.14.0
{ | ||
"name": "@hypermode/modus-sdk-as", | ||
"version": "0.13.5", | ||
"version": "0.14.0", | ||
"repository": "github:hypermodeinc/modus", | ||
@@ -31,3 +31,3 @@ "description": "Modus SDK for AssemblyScript", | ||
"@types/eslint__js": "^8.42.3", | ||
"@types/node": "^22.9.0", | ||
"@types/node": "^22.9.1", | ||
"as-test": "^0.3.5", | ||
@@ -34,0 +34,0 @@ "assemblyscript": "^0.27.31", |
import binaryen from "assemblyscript/lib/binaryen.js"; | ||
import { FunctionSignature, TypeDefinition, typeMap, } from "./types.js"; | ||
import { CommentNode, Range, } from "assemblyscript/dist/assemblyscript.js"; | ||
import { Docs, FunctionSignature, TypeDefinition, typeMap, } from "./types.js"; | ||
export class Extractor { | ||
@@ -8,5 +9,9 @@ binaryen; | ||
transform; | ||
constructor(transform, module) { | ||
this.program = transform.program; | ||
constructor(transform) { | ||
this.binaryen = transform.binaryen; | ||
} | ||
initHook(program) { | ||
this.program = program; | ||
} | ||
compileHook(module) { | ||
this.module = module; | ||
@@ -44,3 +49,3 @@ } | ||
importFns: importedFunctions, | ||
types, | ||
types: types.map((v) => this.getTypeDocs(v)), | ||
}; | ||
@@ -139,6 +144,134 @@ } | ||
} | ||
return new FunctionSignature(e.name, params, [ | ||
const signature = new FunctionSignature(e.name, params, [ | ||
{ type: f.signature.returnType.toString() }, | ||
]); | ||
signature.docs = this.getDocsFromFunction(signature); | ||
return signature; | ||
} | ||
getDocsFromFunction(signature) { | ||
let docs = null; | ||
for (const source of this.program.sources.filter((v) => v.sourceKind == 1)) { | ||
for (const node of source.statements.filter((v) => v.kind == 55 && | ||
v.flags >= 2)) { | ||
const source = node.range.source; | ||
if (node.flags <= 1) | ||
continue; | ||
if (node.name.text == signature.name) { | ||
const nodeIndex = source.statements.indexOf(node); | ||
const prevNode = source.statements[Math.max(nodeIndex - 1, 0)]; | ||
const start = nodeIndex > 0 ? prevNode.range.end : 0; | ||
const end = node.range.start; | ||
const newRange = new Range(start, end); | ||
newRange.source = source; | ||
const commentNodes = this.parseComments(newRange); | ||
if (!commentNodes.length) | ||
return; | ||
docs = Docs.from(commentNodes); | ||
} | ||
} | ||
} | ||
return docs; | ||
} | ||
getTypeDocs(type) { | ||
const name = (() => { | ||
if (type.name.startsWith("~lib/")) | ||
return null; | ||
return type.name.slice(Math.max(type.name.lastIndexOf("<"), type.name.lastIndexOf("/") + 1), Math.max(type.name.indexOf(">"), type.name.length)); | ||
})(); | ||
if (!name) | ||
return type; | ||
for (const _node of Array.from(this.program.managedClasses.values())) { | ||
if (_node.name != name) | ||
continue; | ||
const node = _node.declaration; | ||
const source = node.range.source; | ||
const nodeIndex = source.statements.indexOf(node); | ||
const prevNode = source.statements[Math.max(nodeIndex - 1, 0)]; | ||
const start = nodeIndex > 0 ? prevNode.range.end : 0; | ||
const end = node.range.start; | ||
const newRange = new Range(start, end); | ||
newRange.source = source; | ||
const commentNodes = this.parseComments(newRange); | ||
if (!commentNodes.length) | ||
break; | ||
type.docs = Docs.from(commentNodes); | ||
if (node.members.length) { | ||
const memberDocs = this.getFieldsDocs(node.members.filter((v) => v.kind == 54), node); | ||
if (!memberDocs) | ||
continue; | ||
for (let i = 0; i < memberDocs.length; i++) { | ||
const docs = memberDocs[i]; | ||
if (docs) { | ||
const index = type.fields.findIndex((v) => v.name == node.members[i].name.text); | ||
if (index < 0) | ||
continue; | ||
type.fields[index].docs = docs; | ||
} | ||
} | ||
} | ||
} | ||
return type; | ||
} | ||
getFieldsDocs(nodes, parent) { | ||
const docs = new Array(nodes.length).fill(null); | ||
for (let i = 0; i < nodes.length; i++) { | ||
const node = nodes[i]; | ||
const source = node.range.source; | ||
const start = i == 0 ? parent.range.start : nodes[i - 1].range.end; | ||
const end = node.range.start; | ||
const newRange = new Range(start, end); | ||
newRange.source = source; | ||
const commentNodes = this.parseComments(newRange); | ||
if (!commentNodes.length) | ||
continue; | ||
docs[i] = Docs.from(commentNodes); | ||
} | ||
return docs; | ||
} | ||
parseComments(range) { | ||
const nodes = []; | ||
let text = range.source.text.slice(range.start, range.end).trim(); | ||
const start = Math.min(text.indexOf("/*") === -1 ? Infinity : text.indexOf("/*"), text.indexOf("//") === -1 ? Infinity : text.indexOf("//")); | ||
if (start !== Infinity) | ||
text = text.slice(start); | ||
let commentKind; | ||
if (text.startsWith("//")) { | ||
commentKind = text.startsWith("///") | ||
? 1 | ||
: 0; | ||
const end = range.source.text.indexOf("\n", range.start + 1); | ||
if (end === -1) | ||
return []; | ||
range.start = range.source.text.indexOf("//", range.start); | ||
const newRange = new Range(range.start, end); | ||
newRange.source = range.source; | ||
const node = new CommentNode(commentKind, newRange.source.text.slice(newRange.start, newRange.end), newRange); | ||
nodes.push(node); | ||
if (end < range.end) { | ||
const newRange = new Range(end, range.end); | ||
newRange.source = range.source; | ||
nodes.push(...this.parseComments(newRange)); | ||
} | ||
} | ||
else if (text.startsWith("/*")) { | ||
commentKind = 2; | ||
const end = range.source.text.indexOf("*/", range.start) + 2; | ||
if (end === 1) | ||
return []; | ||
range.start = range.source.text.indexOf("/**", range.start); | ||
const newRange = new Range(range.start, end); | ||
newRange.source = range.source; | ||
const node = new CommentNode(commentKind, newRange.source.text.slice(newRange.start, newRange.end), newRange); | ||
nodes.push(node); | ||
if (end < range.end) { | ||
const newRange = new Range(end, range.end); | ||
newRange.source = range.source; | ||
nodes.push(...this.parseComments(newRange)); | ||
} | ||
} | ||
else { | ||
return []; | ||
} | ||
return nodes; | ||
} | ||
} | ||
@@ -145,0 +278,0 @@ export function getTypeName(path) { |
@@ -5,5 +5,9 @@ import { Transform } from "assemblyscript/dist/transform.js"; | ||
export default class ModusTransform extends Transform { | ||
extractor = new Extractor(this); | ||
afterInitialize(program) { | ||
this.extractor.initHook(program); | ||
} | ||
afterCompile(module) { | ||
const extractor = new Extractor(this, module); | ||
const info = extractor.getProgramInfo(); | ||
this.extractor.compileHook(module); | ||
const info = this.extractor.getProgramInfo(); | ||
const m = Metadata.generate(); | ||
@@ -10,0 +14,0 @@ m.addExportFn(info.exportFns); |
@@ -11,2 +11,20 @@ import { getTypeName } from "./extractor.js"; | ||
} | ||
export class Docs { | ||
lines; | ||
constructor(lines) { | ||
this.lines = lines; | ||
} | ||
static from(nodes) { | ||
for (const node of nodes.reverse()) { | ||
if (node.commentKind != 2 || !node.text.startsWith("/**")) | ||
continue; | ||
const lines = node.text | ||
.split("\n") | ||
.filter((v) => v.trim().startsWith("* ")) | ||
.map((v) => v.trim().slice(2)); | ||
return new Docs(lines); | ||
} | ||
return null; | ||
} | ||
} | ||
export class FunctionSignature { | ||
@@ -16,6 +34,8 @@ name; | ||
results; | ||
constructor(name, parameters, results) { | ||
docs; | ||
constructor(name, parameters, results, docs = undefined) { | ||
this.name = name; | ||
this.parameters = parameters; | ||
this.results = results; | ||
this.docs = docs; | ||
} | ||
@@ -44,2 +64,5 @@ toString() { | ||
} | ||
if (this.docs) { | ||
output["docs"] = this.docs; | ||
} | ||
return output; | ||
@@ -52,6 +75,8 @@ } | ||
fields; | ||
constructor(name, id, fields) { | ||
docs; | ||
constructor(name, id, fields, docs = undefined) { | ||
this.name = name; | ||
this.id = id; | ||
this.fields = fields; | ||
this.docs = docs; | ||
} | ||
@@ -72,2 +97,3 @@ toString() { | ||
fields: this.fields, | ||
docs: this.docs, | ||
}; | ||
@@ -79,2 +105,19 @@ } | ||
} | ||
export class Field { | ||
name; | ||
type; | ||
docs; | ||
constructor(name, type, docs = undefined) { | ||
this.name = name; | ||
this.type = type; | ||
this.docs = docs; | ||
} | ||
toJSON() { | ||
return { | ||
name: this.name, | ||
type: this.type, | ||
docs: this.docs, | ||
}; | ||
} | ||
} | ||
export const typeMap = new Map([ | ||
@@ -81,0 +124,0 @@ ["~lib/string/String", "string"], |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
160527
5156