Skip to content
This repository has been archived by the owner on Sep 14, 2023. It is now read-only.

feat: add docs to metadata & codegen types #1140

Merged
merged 2 commits into from
Jul 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions _tasks/dnt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ await Promise.all([
name: "wat-the-crypto",
version: "0.0.3",
},
"https://deno.land/x/scale@v0.12.2/mod.ts#=": {
"https://deno.land/x/scale@v0.13.0/mod.ts#=": {
name: "scale-codec",
version: "0.12.2",
version: "0.13.0",
},
"https://deno.land/x/[email protected]/index-deno.js": {
name: "smoldot",
Expand Down
8 changes: 2 additions & 6 deletions codegen/CodecCodegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ export class CodecCodegen {
if (existing === null) {
this.codecIds.set(value, this.nextCodecId++)
} else if (existing === undefined) {
const meta = value._metadata.find((x): x is typeof x & { type: "atomic" | "factory" } =>
x.type === "atomic" || x.type === "factory"
)
const meta = value._metadata[0]
if (!meta || meta.type === "atomic") return
if (meta.factory === $.deferred) {
this.codecIds.set(value, this.nextCodecId++)
Expand Down Expand Up @@ -86,9 +84,7 @@ export class CodecCodegen {
}
if (value === null) return "null"
if (value instanceof $.Codec) {
const meta = value._metadata.find((x): x is typeof x & { type: "atomic" | "factory" } =>
x.type === "atomic" || x.type === "factory"
)
const meta = value._metadata[0]
if (!meta) throw new Error("Cannot serialize metadata-less codec")
if (meta.type === "atomic") return `C.${meta.name}`
const id = this.codecIds.get(value)
Expand Down
29 changes: 28 additions & 1 deletion codegen/TypeCodegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export class TypeCodegen {
)

isTuple = new $.CodecVisitor<boolean>().add($.tuple, () => true).fallback(() => false)
isField = new $.CodecVisitor<boolean>()
.add($.field<any, any, any>, () => true).fallback(() => false)

nativeVisitor = new $.CodecVisitor<string>()
.add($.int, (_codec, _signed, size) => size > 32 ? "bigint" : "number")
Expand Down Expand Up @@ -93,10 +95,28 @@ export class TypeCodegen {
(_codec, variants) =>
Object.values(variants).map((v) => this.codecCodegen.print(v)).join(" | "),
)
.add(
$.documented,
(_codec, docs, inner) => {
if (this.isField.visit(inner)) {
return `{\n${formatDocComment(docs)}\n${this.native(inner).slice(1)}`
}
return `${formatDocComment(docs)}\n` + this.native(inner)
},
)
.add($.never, () => "never")
.add($null, () => "null")

declVisitor = new $.CodecVisitor<(name: string, isTypes: boolean) => string>()
.generic((visitor) =>
visitor.add(
$.documented,
(_codec, docs, inner) => (name, isTypes) =>
(isTypes
? formatDocComment(docs) + "\n"
: "") + visitor.visit(inner)(name, isTypes).trim(),
)
)
.add($.literalUnion, (_codec, _variants) => (name, isTypes) => {
const variants = Object.values(_variants) as string[]
return isTypes
Expand Down Expand Up @@ -243,7 +263,8 @@ export ${isTypes ? `namespace ${name}` : `const ${name} =`} {
const trailing = isTypes ? `: C.$.Codec<${name}>` : `= ${this.codecCodegen.print(codec)}`
return `
export const $${name.replace(/^./, (x) => x.toLowerCase())}${trailing}
${this.declVisitor.visit(codec)(name, isTypes)}

${this.declVisitor.visit(codec)(name, isTypes).trim()}
`
}).join("\n")
files.set(
Expand All @@ -270,3 +291,9 @@ export ${isTypes ? `namespace ${name}` : `const ${name} =`} {
)
}
}

function formatDocComment(docs: string) {
if (!docs) return ""
if (!docs.includes("\n")) return `/** ${docs} */`
return `/**\n${docs.replace(/^/gm, " * ")}\n*/`
}
2 changes: 1 addition & 1 deletion deps/scale.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from "https://deno.land/x/scale@v0.12.2/mod.ts#="
export * from "https://deno.land/x/scale@v0.13.0/mod.ts#="
11 changes: 8 additions & 3 deletions scale_info/transformTys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ export function transformTys(tys: Ty[]): ScaleInfo {
}
} else {
return $.object(
...ty.fields.map((x) => maybeOptionalField(normalizeIdent(x.name!), visit(x.ty))),
...ty.fields.map((x) =>
withDocs(x.docs, maybeOptionalField(normalizeIdent(x.name!), visit(x.ty)))
),
)
}
} else if (ty.type === "Tuple") {
Expand Down Expand Up @@ -128,7 +130,10 @@ export function transformTys(tys: Ty[]): ScaleInfo {
} else {
// Object variant
const memberFields = fields.map((field) => {
return maybeOptionalField(normalizeIdent(field.name!), visit(field.ty))
return withDocs(
field.docs,
maybeOptionalField(normalizeIdent(field.name!), visit(field.ty)),
)
})
member = $.variant(type, ...memberFields)
}
Expand Down Expand Up @@ -165,7 +170,7 @@ export function transformTys(tys: Ty[]): ScaleInfo {

function withDocs<I, O>(_docs: string[], codec: Codec<I, O>): Codec<I, O> {
const docs = normalizeDocs(_docs)
if (docs) return $.withMetadata($.docs(docs), codec)
if (docs) return $.documented(docs, codec)
return codec
}

Expand Down
3 changes: 2 additions & 1 deletion server/factories.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { escapeHtml } from "../deps/escape.ts"
import { Status } from "../deps/std/http.ts"
import { CacheBase } from "../util/cache/base.ts"

Expand Down Expand Up @@ -57,7 +58,7 @@ export function acceptsHtml(request: Request): boolean {
export async function renderCode(code: string) {
return `
<body>
<pre>${code}</pre>
<pre>${escapeHtml(code)}</pre>
</body>
`
}
12 changes: 11 additions & 1 deletion util/normalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,17 @@ export function normalizeIdent(ident: string) {
}

export function normalizeDocs(docs: string[] | undefined): string {
return docs?.join("\n") ?? ""
let str = docs?.join("\n") ?? ""
str = str
.replace(/[^\S\n]+$/gm, "") // strip trailing whitespace
.replace(/^\n+|\n+$/g, "") // strip leading and trailing newlines
const match = /^([^\S\n]+).*(?:\n\1.*)*$/.exec(str) // find a common indent
if (match) {
const { 1: prefix } = match
str = str.replace(new RegExp(`^${prefix}`, "gm"), "") // strip the common indent
// this `new RegExp` is safe because `prefix` must be whitespace
}
return str
}

export function normalizePackageName(name: string) {
Expand Down