Skip to content

Commit

Permalink
#13, ConstructorDeclarationImpl.fromSignature()
Browse files Browse the repository at this point in the history
  • Loading branch information
ajvincent committed Jan 14, 2024
1 parent 7b7e667 commit 7a5557a
Show file tree
Hide file tree
Showing 6 changed files with 285 additions and 2 deletions.
2 changes: 2 additions & 0 deletions stage_1_bootstrap/build/BuildClassesDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import createStructureParts from "./hooks/structure/createParts.js";
import defineKindProperty from "./hooks/structure/defineKind.js";
import addConstructor from "./hooks/structure/addConstructor.js";
import addStaticClone from "./hooks/structure/addStaticClone.js";
import addDeclarationFromSignature from "./hooks/structure/addDeclarationFromSignature.js";
import saveStructureFile from "./hooks/structure/save.js";
import removeUselessCopyFields from "./hooks/structure/removeUselessCopyFields.js";
import structureSpecialCases from "./hooks/structure/specialCases.js";
Expand Down Expand Up @@ -52,6 +53,7 @@ async function BuildClassesDriver(distDir: string): Promise<void>
dictionary.addStructureHook("define structure kind", defineKindProperty);
dictionary.addStructureHook("add constructor", addConstructor);
dictionary.addStructureHook("add static clone method", addStaticClone);
dictionary.addStructureHook("add static fromSignature method", addDeclarationFromSignature);
dictionary.addStructureHook("remove useless copy-fields method", removeUselessCopyFields);
dictionary.addStructureHook("add .toJSON()", add_toJSON);
dictionary.addStructureHook("add type structures", addTypeStructures);
Expand Down
165 changes: 165 additions & 0 deletions stage_1_bootstrap/build/hooks/structure/addDeclarationFromSignature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
import {
StructureKind,
VariableDeclarationKind,
} from "ts-morph";
*/

import StructureDictionaries, {
type StructureParts
} from "#stage_one/build/StructureDictionaries.js";

import {
StructureImplMeta
} from "#stage_one/build/structureMeta/DataClasses.js";

import {
LiteralTypedStructureImpl,
MethodDeclarationImpl,
ParameterDeclarationImpl,
/*
UnionTypedStructureImpl,
VariableDeclarationImpl,
VariableStatementImpl,
*/
} from "#stage_one/prototype-snapshot/exports.js";

import ClassFieldStatementsMap from "#stage_one/build/utilities/public/ClassFieldStatementsMap.js";
import ClassMembersMap from "#stage_one/build/utilities/public/ClassMembersMap.js";
import { Scope } from "ts-morph";
//import ConstantTypeStructures from "#stage_one/build/utilities/ConstantTypeStructures.js";

export default function addDeclarationFromSignature(
name: string,
meta: StructureImplMeta,
dictionaries: StructureDictionaries
): Promise<void>
{
const parts = dictionaries.structureParts.get(meta)!;
switch (parts.classDecl.name) {
case "ConstructorDeclarationImpl":
convertConstructor(parts, dictionaries);
break;
case "MethodDeclarationImpl":
/*
declarationFromSignature(
parts,
dictionaries.structureParts.get("MethodSignatureImpl"),
dictionaries
);
*/
break;
case "PropertyDeclarationImpl":
/*
declarationFromSignature(
parts,
dictionaries.structureParts.get("PropertySignatureImpl");
dictionaries
);
*/
break;
}
return Promise.resolve();
}

function convertConstructor(
parts: StructureParts,
dictionaries: StructureDictionaries
): void
{
addImport(parts, dictionaries, false, false, "cloneStructureOrStringArray");
addImport(parts, dictionaries, true, true, "JSDocImpl");
addImport(parts, dictionaries, true, true, "ParameterDeclarationImpl");
addImport(parts, dictionaries, true, true, "TypeParameterDeclarationImpl");
addImport(parts, dictionaries, false, false, "TypeStructureClassesMap");
const signatureImplClass = "ConstructSignatureDeclarationImpl";

const groupName = createFromSignatureMethod(signatureImplClass, parts, dictionaries);
parts.classFieldsStatements.set(
ClassFieldStatementsMap.FIELD_HEAD_SUPER_CALL, groupName, [
`const declaration = new ${parts.classDecl.name};`
]
);
parts.classFieldsStatements.set(
ClassFieldStatementsMap.FIELD_TAIL_FINAL_RETURN, groupName, [
`return declaration;`
]
);

parts.classFieldsStatements.set("docs", groupName, [
`declaration.docs.push(...cloneStructureOrStringArray<
JSDocImpl,
StructureKind.JSDoc,
JSDocImpl
>(
signature.docs as (string | JSDocImpl)[],
StructureKind.JSDoc
) as JSDocImpl[]);`,
]);

parts.classFieldsStatements.set("leadingTrivia", groupName, [
`declaration.leadingTrivia.push(...signature.leadingTrivia);`,
]);
parts.classFieldsStatements.set("trailingTrivia", groupName, [
`declaration.trailingTrivia.push(...signature.trailingTrivia);`,
]);

parts.classFieldsStatements.set("typeParameters", groupName, [
`declaration.typeParameters.push(
...StructuresClassesMap.cloneArray(
signature.typeParameters as TypeParameterDeclarationImpl[]
) as TypeParameterDeclarationImpl[],
);`
]);
parts.classFieldsStatements.set("parameters", groupName, [
`declaration.parameters.push(
...StructuresClassesMap.cloneArray(
signature.parameters as ParameterDeclarationImpl[]
) as ParameterDeclarationImpl[]
);`,
]);
parts.classFieldsStatements.set("returnType", groupName, [
`if (signature.returnTypeStructure) {
declaration.returnTypeStructure = TypeStructureClassesMap.clone(signature.returnTypeStructure);
}`,
]);
}

function createFromSignatureMethod(
sourceType: string,
parts: StructureParts,
dictionaries: StructureDictionaries
): string
{
addImport(parts, dictionaries, true, true, sourceType);

const method = new MethodDeclarationImpl("fromSignature");
method.isStatic = true;
method.scope = Scope.Public;
{
const param = new ParameterDeclarationImpl("signature");
param.typeStructure = new LiteralTypedStructureImpl(sourceType);
method.parameters.push(param);
}
method.returnType = parts.classDecl.name;
parts.classMembersMap.addMembers([method]);
return ClassMembersMap.keyFromMember(method);
}

function addImport(
parts: StructureParts,
dictionaries: StructureDictionaries,
isPublic: boolean,
isTypeOnly: boolean,
name: string
): void
{
const exportManager = isPublic ? dictionaries.publicExports : dictionaries.internalExports;
parts.importsManager.addImports({
pathToImportedModule: exportManager.absolutePathToExportFile,
isPackageImport: false,
isDefaultImport: false,
importNames: [name],
isTypeOnly
});
}
2 changes: 1 addition & 1 deletion stage_1_bootstrap/build/hooks/structure/specialCases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
} from "ts-morph";

import StructureDictionaries, {
StructureParts
type StructureParts
} from "#stage_one/build/StructureDictionaries.js";

import {
Expand Down
1 change: 1 addition & 0 deletions stage_1_bootstrap/build/structureMeta/DataClasses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ export class StructureImplMeta extends BaseMetadata implements MetaImplementatio
}
}
}

export class StructureUnionMeta implements MetaImplementation
{
readonly metaType = MetaType.StructureUnion;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
//#region preamble
import { ConstructorDeclarationOverloadImpl } from "../exports.js";
import {
ConstructorDeclarationOverloadImpl,
type ConstructSignatureDeclarationImpl,
type JSDocImpl,
type ParameterDeclarationImpl,
type TypeParameterDeclarationImpl,
} from "../exports.js";
import {
type CloneableStructure,
cloneStructureArray,
cloneStructureOrStringArray,
COPY_FIELDS,
type ExtractStructure,
type JSDocableNodeStructureFields,
Expand All @@ -24,6 +31,7 @@ import {
StructuresClassesMap,
type TypeParameteredNodeStructureFields,
TypeParameteredNodeStructureMixin,
TypeStructureClassesMap,
} from "../internal-exports.js";
import MultiMixinBuilder from "mixin-decorators";
import {
Expand Down Expand Up @@ -93,6 +101,41 @@ export default class ConstructorDeclarationImpl
return target;
}

public static fromSignature(
signature: ConstructSignatureDeclarationImpl,
): ConstructorDeclarationImpl {
const declaration = new ConstructorDeclarationImpl();
declaration.docs.push(
...(cloneStructureOrStringArray<
JSDocImpl,
StructureKind.JSDoc,
JSDocImpl
>(
signature.docs as (string | JSDocImpl)[],
StructureKind.JSDoc,
) as JSDocImpl[]),
);
declaration.leadingTrivia.push(...signature.leadingTrivia);
declaration.parameters.push(
...(StructuresClassesMap.cloneArray(
signature.parameters as ParameterDeclarationImpl[],
) as ParameterDeclarationImpl[]),
);
if (signature.returnTypeStructure) {
declaration.returnTypeStructure = TypeStructureClassesMap.clone(
signature.returnTypeStructure,
);
}

declaration.trailingTrivia.push(...signature.trailingTrivia);
declaration.typeParameters.push(
...(StructuresClassesMap.cloneArray(
signature.typeParameters as TypeParameterDeclarationImpl[],
) as TypeParameterDeclarationImpl[]),
);
return declaration;
}

public toJSON(): StructureClassToJSON<ConstructorDeclarationImpl> {
const rv =
super.toJSON() as StructureClassToJSON<ConstructorDeclarationImpl>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import {
//MethodSignatureImpl
ConstructorDeclarationImpl,
ConstructSignatureDeclarationImpl,
JSDocImpl,
JSDocTagImpl,
ParameterDeclarationImpl,
TypeParameterDeclarationImpl,
} from "#stage_two/snapshot/source/exports.js";

describe("static fromSignature() methods generally work", () => {
const tag = new JSDocTagImpl("param");
tag.text = "Hi Mom";
const baseDoc = new JSDocImpl;
baseDoc.description = "Hello World";
baseDoc.tags.push(tag);

let doc: JSDocImpl;
beforeEach(() => {
doc = JSDocImpl.clone(baseDoc);
});

function checkDoc(clonedDoc: JSDocImpl): void {
expect(clonedDoc).not.toBe(doc);
expect(clonedDoc.description).toBe("Hello World");
expect(clonedDoc.tags.length).toBe(1);
expect(clonedDoc.tags[0]).not.toBe(tag);
expect(clonedDoc.tags[0].tagName).toBe(tag.tagName);
expect(clonedDoc.tags[0].text).toBe(tag.text);
}

it("on ConstructorDeclarationImpl", () => {
const signature = new ConstructSignatureDeclarationImpl;
signature.docs.push(doc);
signature.leadingTrivia.push("// leading signature");
signature.trailingTrivia.push("// trailing signature");

signature.typeParameters.push(new TypeParameterDeclarationImpl("SignatureType"));
{
const param = new ParameterDeclarationImpl("mySignature");
param.typeStructure = "SignatureType";
signature.parameters.push(param);
}

signature.returnTypeStructure = "symbol";

const decl: ConstructorDeclarationImpl = ConstructorDeclarationImpl.fromSignature(signature);
checkDoc(decl.docs[0] as JSDocImpl);
expect(decl.leadingTrivia).toEqual(signature.leadingTrivia);
expect(decl.leadingTrivia).not.toBe(signature.leadingTrivia);
expect(decl.trailingTrivia).toEqual(signature.trailingTrivia);
expect(decl.trailingTrivia).not.toBe(signature.trailingTrivia);

expect(decl.typeParameters.length).toBe(1);
if (decl.typeParameters.length > 0) {
const typeParam = decl.typeParameters[0];
expect(typeof typeParam).toBe("object");
if (typeof typeParam === "object") {
expect(typeParam.name).toBe("SignatureType");
}
expect(typeParam).not.toBe(signature.typeParameters[0]);
}

expect(decl.parameters.length).toBe(1);
if (decl.parameters.length > 0) {
const param = decl.parameters[0] as ParameterDeclarationImpl;
expect(param.name).toBe("mySignature");
expect(param.typeStructure).toBe("SignatureType");
expect(param).not.toBe(signature.parameters[0] as ParameterDeclarationImpl);
}
});
});

0 comments on commit 7a5557a

Please sign in to comment.