Skip to content

Commit

Permalink
#31, type accessors and structure sets, part 5.
Browse files Browse the repository at this point in the history
  • Loading branch information
ajvincent committed Nov 14, 2023
1 parent 1d5f8fb commit 7ffe3d5
Show file tree
Hide file tree
Showing 8 changed files with 285 additions and 6 deletions.
17 changes: 17 additions & 0 deletions stage_1_bootstrap/build/hooks/addTypeStructures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,23 @@ function addTypeAccessor(
[ `this.${typeAccessorProp.name}.typeStructure` ]
);

parts.importsManager.addImports({
pathToImportedModule: dictionaries.internalExports.absolutePathToExportFile,
isPackageImport: false,
importNames: ["TypeStructureClassesMap"],
isDefaultImport: false,
isTypeOnly: false
});

const existingStatements = parts.classFieldsStatements.get(
propertyKey,
COPY_FIELDS_NAME
)!;
existingStatements[0] = `if (${propertyKey}Structure) {\n` +
`target.${propertyKey}Structure = TypeStructureClassesMap.clone(${propertyKey}Structure);\n` +
`} else ${existingStatements[0] as string}`;
existingStatements.unshift(`const { ${propertyKey}Structure } = source as unknown as ${parts.classDecl.name!};`)

parts.classMembersMap.addMembers([
typeAccessorProp,
typeGetAccessor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
StructureBase,
type StructureClassToJSON,
TypeAccessors,
TypeStructureClassesMap,
} from "../internal-exports.js";
import type { stringOrWriterFunction } from "../types/stringOrWriterFunction.js";
import type {
Expand Down Expand Up @@ -65,7 +66,12 @@ export default function ReturnTypedNodeStructureMixin(
target: ReturnTypedNodeStructureMixin & Structures,
): void {
super[COPY_FIELDS](source, target);
if (source.returnType) {
const { returnTypeStructure } =
source as unknown as ReturnTypedNodeStructureMixin;
if (returnTypeStructure) {
target.returnTypeStructure =
TypeStructureClassesMap.clone(returnTypeStructure);
} else if (source.returnType) {
target.returnType = source.returnType;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
StructureBase,
type StructureClassToJSON,
TypeAccessors,
TypeStructureClassesMap,
} from "../internal-exports.js";
import type { stringOrWriterFunction } from "../types/stringOrWriterFunction.js";
import type {
Expand Down Expand Up @@ -62,7 +63,10 @@ export default function TypedNodeStructureMixin(
target: TypedNodeStructureMixin & Structures,
): void {
super[COPY_FIELDS](source, target);
if (source.type) {
const { typeStructure } = source as unknown as TypedNodeStructureMixin;
if (typeStructure) {
target.typeStructure = TypeStructureClassesMap.clone(typeStructure);
} else if (source.type) {
target.type = source.type;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
TypeAccessors,
type TypeParameteredNodeStructureFields,
TypeParameteredNodeStructureMixin,
TypeStructureClassesMap,
TypeStructureSet,
} from "../internal-exports.js";
import type { stringOrWriterFunction } from "../types/stringOrWriterFunction.js";
Expand Down Expand Up @@ -139,7 +140,10 @@ export default class ClassDeclarationImpl
);
}

if (source.extends) {
const { extendsStructure } = source as unknown as ClassDeclarationImpl;
if (extendsStructure) {
target.extendsStructure = TypeStructureClassesMap.clone(extendsStructure);
} else if (source.extends) {
target.extends = source.extends;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
StructureMixin,
StructuresClassesMap,
TypeAccessors,
TypeStructureClassesMap,
} from "../internal-exports.js";
import MultiMixinBuilder from "mixin-decorators";
import {
Expand Down Expand Up @@ -84,7 +85,11 @@ export default class IndexSignatureDeclarationImpl
target.keyName = source.keyName;
}

if (source.keyType) {
const { keyTypeStructure } =
source as unknown as IndexSignatureDeclarationImpl;
if (keyTypeStructure) {
target.keyTypeStructure = TypeStructureClassesMap.clone(keyTypeStructure);
} else if (source.keyType) {
target.keyType = source.keyType;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
StructureMixin,
StructuresClassesMap,
TypeAccessors,
TypeStructureClassesMap,
} from "../internal-exports.js";
import type { stringOrWriterFunction } from "../types/stringOrWriterFunction.js";
import MultiMixinBuilder from "mixin-decorators";
Expand Down Expand Up @@ -87,11 +88,20 @@ export default class TypeParameterDeclarationImpl
target: TypeParameterDeclarationImpl,
): void {
super[COPY_FIELDS](source, target);
if (source.constraint) {
const { constraintStructure } =
source as unknown as TypeParameterDeclarationImpl;
if (constraintStructure) {
target.constraintStructure =
TypeStructureClassesMap.clone(constraintStructure);
} else if (source.constraint) {
target.constraint = source.constraint;
}

if (source.default) {
const { defaultStructure } =
source as unknown as TypeParameterDeclarationImpl;
if (defaultStructure) {
target.defaultStructure = TypeStructureClassesMap.clone(defaultStructure);
} else if (source.default) {
target.default = source.default;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import {
CodeBlockWriter
} from "ts-morph";

import {
ClassDeclarationImpl,
TypeStructureKind,
WriterTypeStructureImpl,
} from "#stage_two/snapshot/source/exports.js";

import {
TypeStructuresBase
} from "#stage_two/snapshot/source/internal-exports.js";

describe("Type accessor properties work", () => {
let writerCount = 0;
function writerFunction(
writer: CodeBlockWriter
): void {
writerCount++;
writer.write("hello");
}

const writerTypeStructure = new WriterTypeStructureImpl(writerFunction);

let classDecl: ClassDeclarationImpl;
beforeEach(() => {
classDecl = new ClassDeclarationImpl;
writerCount = 0;
});

it("starting out undefined", () => {
expect(classDecl.extends).toBe(undefined);
expect(classDecl.extendsStructure).toBe(undefined);
});

describe("with direct type access", () => {
it("setting a literal", () => {
classDecl.extends = "boolean";
expect(classDecl.extendsStructure).toBe("boolean");
expect(classDecl.extends).toBe("boolean");
});

it("setting a writer function", () => {
classDecl.extends = writerFunction;
expect(classDecl.extendsStructure).toBe(writerTypeStructure);
expect(classDecl.extends).toBe(writerFunction);
expect(writerCount).toBe(0);
});

it("setting back to undefined after setting the type", () => {
classDecl.extends = "never";
classDecl.extends = undefined;
expect(classDecl.extends).toBe(undefined);
expect(classDecl.extendsStructure).toBe(undefined);

classDecl.extends = writerFunction;
classDecl.extends = undefined;
expect(classDecl.extends).toBe(undefined);
expect(classDecl.extendsStructure).toBe(undefined);
});

it("setting back to undefined after setting the type structure", () => {
classDecl.extendsStructure = "never";
classDecl.extends = undefined;
expect(classDecl.extends).toBe(undefined);
expect(classDecl.extendsStructure as unknown).toBe(undefined);

classDecl.extendsStructure = writerTypeStructure;
classDecl.extends = undefined;
expect(classDecl.extends).toBe(undefined);
expect(classDecl.extendsStructure as unknown).toBe(undefined);
});
});

describe("with type structure access", () => {
it("setting a literal", () => {
classDecl.extendsStructure = "boolean";
expect(classDecl.extends).toBe("boolean");
expect(classDecl.extendsStructure).toBe("boolean");
});

it("setting a type structure", () => {
classDecl.extendsStructure = writerTypeStructure;
expect(classDecl.extends).toBe(writerFunction);
expect(classDecl.extendsStructure).toBe(writerTypeStructure);
expect(writerCount).toBe(0);
});

it("setting back to undefined after setting the type", () => {
classDecl.extends = "never";
classDecl.extendsStructure = undefined;
expect(classDecl.extends as unknown).toBe(undefined);
expect(classDecl.extendsStructure).toBe(undefined);

classDecl.extends = writerFunction;
classDecl.extendsStructure = undefined;
expect(classDecl.extends as unknown).toBe(undefined);
expect(classDecl.extendsStructure).toBe(undefined);
});

it("setting back to undefined after setting the type structure", () => {
classDecl.extendsStructure = "never";
classDecl.extendsStructure = undefined;
expect(classDecl.extends).toBe(undefined);
expect(classDecl.extendsStructure).toBe(undefined);

classDecl.extendsStructure = writerTypeStructure;
classDecl.extendsStructure = undefined;
expect(classDecl.extends).toBe(undefined);
expect(classDecl.extendsStructure).toBe(undefined);
});
});

describe("with static clone()", () => {
let cloneDecl: ClassDeclarationImpl;
it("starting from undefined", () => {
cloneDecl = ClassDeclarationImpl.clone(classDecl);
expect(cloneDecl.extends).toBe(undefined);
expect(cloneDecl.extendsStructure).toBe(undefined);
});

it("with a string type", () => {
classDecl.extends = "boolean";
cloneDecl = ClassDeclarationImpl.clone(classDecl);
expect(cloneDecl.extends).toBe("boolean");
expect(cloneDecl.extendsStructure).toBe("boolean");
});

it("with a writer function", () => {
classDecl.extends = writerFunction;
cloneDecl = ClassDeclarationImpl.clone(classDecl);
expect(cloneDecl.extends).toBe(writerFunction);
expect(cloneDecl.extendsStructure).not.toBe(writerTypeStructure);
expect(typeof classDecl.extendsStructure).toBe("object");
if (typeof classDecl.extendsStructure === "object") {
expect(classDecl.extendsStructure.kind).toBe(TypeStructureKind.Writer);
expect(classDecl.extendsStructure.writerFunction).toBe(writerFunction);
}

expect(
TypeStructuresBase.getTypeStructureForCallback(writerFunction)
).toBe(writerTypeStructure);
expect(writerCount).toBe(0);
});

it("with a string type structure", () => {
classDecl.extendsStructure = "boolean";
cloneDecl = ClassDeclarationImpl.clone(classDecl);
expect(cloneDecl.extends).toBe("boolean");
expect(cloneDecl.extendsStructure).toBe("boolean");
});

it("with a writer type structure", () => {
classDecl.extendsStructure = writerTypeStructure;
cloneDecl = ClassDeclarationImpl.clone(classDecl);
expect(cloneDecl.extends).toBe(writerFunction);
expect(cloneDecl.extendsStructure).not.toBe(writerTypeStructure);
expect(typeof classDecl.extendsStructure).toBe("object");
if (typeof classDecl.extendsStructure === "object") {
expect(classDecl.extendsStructure.kind).toBe(TypeStructureKind.Writer);
expect(classDecl.extendsStructure.writerFunction).toBe(writerFunction);
}

expect(
TypeStructuresBase.getTypeStructureForCallback(writerFunction)
).toBe(writerTypeStructure);
expect(writerCount).toBe(0);
});
});

describe("with .toJSON()", () => {
it("starting out undefined", () => {
expect("extends" in classDecl.toJSON()).toBe(false);
});

it("and a string type field", () => {
classDecl.extends = "boolean";
expect(classDecl.toJSON().extends).toBe("boolean");
});

it("and a writer function type field", () => {
classDecl.extends = writerFunction;
expect(classDecl.toJSON().extends).toBe("hello");
expect(writerCount).toBe(1);
});

it("and a string typeStructure field", () => {
classDecl.extendsStructure = "boolean";
expect(classDecl.toJSON().extends).toBe("boolean");
});

it("and an object typeStructure field", () => {
classDecl.extendsStructure = writerTypeStructure;
expect(classDecl.toJSON().extends).toBe("hello");
expect(writerCount).toBe(1);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
import {
ClassDeclarationImpl,
StringTypeStructureImpl,
WriterTypeStructureImpl,
} from "#stage_two/snapshot/source/exports.js";
describe("Type structure set properties work", () => {
const stringTypeStructure = new StringTypeStructureImpl("NumberStringType");
const writerTypeStructure = new WriterTypeStructureImpl(writer => writer.write("NumberStringType"));
let classDecl: ClassDeclarationImpl;
beforeEach(() => classDecl = new ClassDeclarationImpl);
describe("with direct type access", () => {
});
describe("with type structure access", () => {
});
describe("with static clone()", () => {
});
describe("with .toJSON()", () => {
});
});
*/
xit("TypeStructureSet", () => {
expect(false).toBe(true);
});

0 comments on commit 7ffe3d5

Please sign in to comment.