Loading codegen/class.ts +2 −1 Original line number Diff line number Diff line import { generateDecoder, generateEncoder } from "./codec.ts"; import { generateConstructor } from "./constructor.ts"; import { generateCloner, generateConstructor } from "./constructor.ts"; import { generateFields } from "./field.ts"; import { generateInspector } from "./inspector.ts"; import { generateProperties } from "./property.ts"; Loading Loading @@ -50,6 +50,7 @@ async function* generateClass( } for await (const code of generateFields(typeUri, types)) yield code; for await (const code of generateConstructor(typeUri, types)) yield code; for await (const code of generateCloner(typeUri, types)) yield code; for await (const code of generateProperties(typeUri, types)) yield code; for await (const code of generateEncoder(typeUri, types)) yield code; for await (const code of generateDecoder(typeUri, types)) yield code; Loading codegen/constructor.ts +61 −7 Original line number Diff line number Diff line Loading @@ -60,7 +60,13 @@ export async function* generateConstructor( types: Record<string, TypeSchema>, ): AsyncIterable<string> { const type = types[typeUri]; yield `constructor(values: `; yield ` /** * Constructs a new instance of ${type.name} with the given values. * @param values The values to initialize the instance with. */ constructor(values: `; for await (const code of generateParametersType(typeUri, types)) yield code; yield ") {\n"; if (type.extends == null) { Loading @@ -69,12 +75,12 @@ export async function* generateConstructor( yield "super(values);"; } for (const property of type.properties) { const fieldName = await getFieldName(property.uri); if (property.functional || property.singularAccessor) { yield ` if ("${property.singularName}" in values && \ values.${property.singularName} != null) { this.${await getFieldName(property.uri)} = [values.${property.singularName}]; this.${fieldName} = [values.${property.singularName}]; } `; } Loading @@ -82,11 +88,59 @@ export async function* generateConstructor( yield ` if ("${property.pluralName}" in values && \ values.${property.pluralName} != null) { this.${await getFieldName(property.uri)} = values.${property.pluralName}; this.${fieldName} = values.${property.pluralName}; } `; } } yield "}\n"; } export async function* generateCloner( typeUri: string, types: Record<string, TypeSchema>, ): AsyncIterable<string> { const type = types[typeUri]; yield ` /** * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @returns The cloned instance. */ clone(values: `; for await (const code of generateParametersType(typeUri, types)) yield code; yield ` = {}): ${type.name} {\n`; if (type.extends == null) { yield ` // @ts-ignore const clone: ${type.name} = new this.constructor(values); `; } else { yield `const clone = super.clone(values) as unknown as ${type.name};`; } for (const property of type.properties) { const fieldName = await getFieldName(property.uri); yield `clone.${fieldName} = this.${fieldName};`; if (property.functional || property.singularAccessor) { yield ` if ("${property.singularName}" in values && \ values.${property.singularName} != null) { clone.${fieldName} = [values.${property.singularName}]; } `; } if (!property.functional) { yield ` if ("${property.pluralName}" in values && \ values.${property.pluralName} != null) { clone.${fieldName} = values.${property.pluralName}; } `; } } yield ` return clone; } `; } vocab/mod.test.ts +27 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,33 @@ Deno.test("Activity.getObjects()", async () => { assertEquals(objects[1].name, "Second object"); }); Deno.test("Activity.clone()", async () => { const activity = new Activity({ actor: new Person({ name: "John Doe", }), object: new Object({ name: "Test", }), name: "Test", summary: "Test", }); const clone = activity.clone({ object: new Object({ name: "Modified", }), summary: "Modified", }); assertEquals((await activity.getActor())?.name, "John Doe"); assertEquals((await clone.getActor())?.name, "John Doe"); assertEquals((await activity.getObject())?.name, "Test"); assertEquals((await clone.getObject())?.name, "Modified"); assertEquals(activity.name, "Test"); assertEquals(clone.name, "Test"); assertEquals(activity.summary, "Test"); assertEquals(clone.summary, "Modified"); }); Deno.test("Deno.inspect(Object)", () => { const obj = new Object({ id: new URL("https://example.com/"), Loading Loading
codegen/class.ts +2 −1 Original line number Diff line number Diff line import { generateDecoder, generateEncoder } from "./codec.ts"; import { generateConstructor } from "./constructor.ts"; import { generateCloner, generateConstructor } from "./constructor.ts"; import { generateFields } from "./field.ts"; import { generateInspector } from "./inspector.ts"; import { generateProperties } from "./property.ts"; Loading Loading @@ -50,6 +50,7 @@ async function* generateClass( } for await (const code of generateFields(typeUri, types)) yield code; for await (const code of generateConstructor(typeUri, types)) yield code; for await (const code of generateCloner(typeUri, types)) yield code; for await (const code of generateProperties(typeUri, types)) yield code; for await (const code of generateEncoder(typeUri, types)) yield code; for await (const code of generateDecoder(typeUri, types)) yield code; Loading
codegen/constructor.ts +61 −7 Original line number Diff line number Diff line Loading @@ -60,7 +60,13 @@ export async function* generateConstructor( types: Record<string, TypeSchema>, ): AsyncIterable<string> { const type = types[typeUri]; yield `constructor(values: `; yield ` /** * Constructs a new instance of ${type.name} with the given values. * @param values The values to initialize the instance with. */ constructor(values: `; for await (const code of generateParametersType(typeUri, types)) yield code; yield ") {\n"; if (type.extends == null) { Loading @@ -69,12 +75,12 @@ export async function* generateConstructor( yield "super(values);"; } for (const property of type.properties) { const fieldName = await getFieldName(property.uri); if (property.functional || property.singularAccessor) { yield ` if ("${property.singularName}" in values && \ values.${property.singularName} != null) { this.${await getFieldName(property.uri)} = [values.${property.singularName}]; this.${fieldName} = [values.${property.singularName}]; } `; } Loading @@ -82,11 +88,59 @@ export async function* generateConstructor( yield ` if ("${property.pluralName}" in values && \ values.${property.pluralName} != null) { this.${await getFieldName(property.uri)} = values.${property.pluralName}; this.${fieldName} = values.${property.pluralName}; } `; } } yield "}\n"; } export async function* generateCloner( typeUri: string, types: Record<string, TypeSchema>, ): AsyncIterable<string> { const type = types[typeUri]; yield ` /** * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @returns The cloned instance. */ clone(values: `; for await (const code of generateParametersType(typeUri, types)) yield code; yield ` = {}): ${type.name} {\n`; if (type.extends == null) { yield ` // @ts-ignore const clone: ${type.name} = new this.constructor(values); `; } else { yield `const clone = super.clone(values) as unknown as ${type.name};`; } for (const property of type.properties) { const fieldName = await getFieldName(property.uri); yield `clone.${fieldName} = this.${fieldName};`; if (property.functional || property.singularAccessor) { yield ` if ("${property.singularName}" in values && \ values.${property.singularName} != null) { clone.${fieldName} = [values.${property.singularName}]; } `; } if (!property.functional) { yield ` if ("${property.pluralName}" in values && \ values.${property.pluralName} != null) { clone.${fieldName} = values.${property.pluralName}; } `; } } yield ` return clone; } `; }
vocab/mod.test.ts +27 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,33 @@ Deno.test("Activity.getObjects()", async () => { assertEquals(objects[1].name, "Second object"); }); Deno.test("Activity.clone()", async () => { const activity = new Activity({ actor: new Person({ name: "John Doe", }), object: new Object({ name: "Test", }), name: "Test", summary: "Test", }); const clone = activity.clone({ object: new Object({ name: "Modified", }), summary: "Modified", }); assertEquals((await activity.getActor())?.name, "John Doe"); assertEquals((await clone.getActor())?.name, "John Doe"); assertEquals((await activity.getObject())?.name, "Test"); assertEquals((await clone.getObject())?.name, "Modified"); assertEquals(activity.name, "Test"); assertEquals(clone.name, "Test"); assertEquals(activity.summary, "Test"); assertEquals(clone.summary, "Modified"); }); Deno.test("Deno.inspect(Object)", () => { const obj = new Object({ id: new URL("https://example.com/"), Loading