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

Commit

Permalink
feat: add docs to metadata & codegen types (#1140)
Browse files Browse the repository at this point in the history
  • Loading branch information
tjjfvi authored Jul 6, 2023
1 parent be30235 commit 05d2e7d
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 15 deletions.
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/smoldot2@light-js-deno-v1.0.6/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

0 comments on commit 05d2e7d

Please sign in to comment.