Skip to content

Commit

Permalink
#13, ClassMembersMap.fromClassDeclaration()
Browse files Browse the repository at this point in the history
  • Loading branch information
ajvincent committed Jan 13, 2024
1 parent 69a34e2 commit 2c89649
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 87 deletions.
2 changes: 1 addition & 1 deletion stage_1_bootstrap/build/publicAndInternalExports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default async function defineExistingExports(

dictionaries.publicExports.addExports({
absolutePathToModule: path.join(distDir, "source/toolbox/ClassFieldStatementsMap.ts"),
exportNames: ["ClassFieldStatementsArray"],
exportNames: ["ClassFieldStatement"],
isDefaultExport: false,
isType: true,
});
Expand Down
26 changes: 13 additions & 13 deletions stage_1_integration/toolbox/ClassFieldStatementsMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type {
StatementStructureImpls
} from "../snapshot/source/exports.js";

export type ClassFieldStatementsArray = (string | WriterFunction | StatementStructureImpls)[];
export type ClassFieldStatement = string | WriterFunction | StatementStructureImpls;
type keyPair = {fieldName: string, statementGroup: string};

/**
Expand Down Expand Up @@ -80,11 +80,11 @@ export default class ClassFieldStatementsMap
return a.localeCompare(b);
}

readonly #map = new Map<string, ClassFieldStatementsArray>;
readonly #statementGroupMap = new Map<string, Map<string, ClassFieldStatementsArray>>;
readonly #map = new Map<string, ClassFieldStatement[]>;
readonly #statementGroupMap = new Map<string, Map<string, ClassFieldStatement[]>>;

public constructor(
iterable?: [string, string, ClassFieldStatementsArray][]
iterable?: [string, string, ClassFieldStatement[]][]
)
{
if (iterable) {
Expand Down Expand Up @@ -130,7 +130,7 @@ export default class ClassFieldStatementsMap
/**
* Yield the key-statements tuples of the collection.
*/
public * entries(): IterableIterator<[string, string, ClassFieldStatementsArray]>
public * entries(): IterableIterator<[string, string, ClassFieldStatement[]]>
{
const iterator = this.#map.entries();
for (const [hashed, statements] of iterator) {
Expand All @@ -146,7 +146,7 @@ export default class ClassFieldStatementsMap
*/
public forEach(
__callback__: (
statements: ClassFieldStatementsArray,
statements: ClassFieldStatement[],
fieldName: string,
statementGroup: string,
__collection__: ClassFieldStatementsMap
Expand All @@ -155,7 +155,7 @@ export default class ClassFieldStatementsMap
): void
{
this.#map.forEach(
(statements: ClassFieldStatementsArray, hashed: string) => {
(statements: ClassFieldStatement[], hashed: string) => {
const {fieldName, statementGroup} = ClassFieldStatementsMap.#parseKey(hashed);
__callback__.apply(__thisArg__, [statements, fieldName, statementGroup, this]);
}
Expand All @@ -169,7 +169,7 @@ export default class ClassFieldStatementsMap
* @param statementGroup - The statement group owning the statements.
* @returns The statements. Undefined if it isn't in the collection.
*/
public get(fieldName: string, statementGroup: string): ClassFieldStatementsArray | undefined
public get(fieldName: string, statementGroup: string): ClassFieldStatement[] | undefined
{
[fieldName, statementGroup] = ClassFieldStatementsMap.#normalizeKeys(fieldName, statementGroup);
return this.#map.get(ClassFieldStatementsMap.#hashKey(fieldName, statementGroup));
Expand Down Expand Up @@ -208,7 +208,7 @@ export default class ClassFieldStatementsMap
* @param statements - The statements.
* @returns This collection.
*/
public set(fieldName: string, statementGroup: string, statements: ClassFieldStatementsArray): this
public set(fieldName: string, statementGroup: string, statements: ClassFieldStatement[]): this
{
[fieldName, statementGroup] = ClassFieldStatementsMap.#normalizeKeys(fieldName, statementGroup);
this.#map.set(
Expand All @@ -217,7 +217,7 @@ export default class ClassFieldStatementsMap

let subMap = this.#statementGroupMap.get(statementGroup);
if (!subMap) {
subMap = new Map<string, ClassFieldStatementsArray>;
subMap = new Map<string, ClassFieldStatement[]>;
this.#statementGroupMap.set(statementGroup, subMap);
}
subMap.set(fieldName, statements);
Expand All @@ -228,12 +228,12 @@ export default class ClassFieldStatementsMap
/**
* Yield the statementss of the collection.
*/
public values(): IterableIterator<ClassFieldStatementsArray>
public values(): IterableIterator<ClassFieldStatement[]>
{
return this.#map.values();
}

public [Symbol.iterator](): IterableIterator<[string, string, ClassFieldStatementsArray]>
public [Symbol.iterator](): IterableIterator<[string, string, ClassFieldStatement[]]>
{
return this.entries();
}
Expand All @@ -251,7 +251,7 @@ export default class ClassFieldStatementsMap
*/
public groupStatementsMap(
statementGroup: string
): ReadonlyMap<string, ClassFieldStatementsArray> | undefined
): ReadonlyMap<string, ClassFieldStatement[]> | undefined
{
const iterator = this.#statementGroupMap.get(statementGroup)?.entries();
if (!iterator)
Expand Down
55 changes: 45 additions & 10 deletions stage_1_integration/toolbox/ClassMembersMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ import { StructureKind } from "ts-morph";
import {
ClassDeclarationImpl,
ConstructorDeclarationImpl,
PropertyDeclarationImpl,
GetAccessorDeclarationImpl,
SetAccessorDeclarationImpl,
PropertyDeclarationImpl,
MethodDeclarationImpl,
SetAccessorDeclarationImpl,
} from "../snapshot/source/exports.js";

import ClassFieldStatementsMap from "./ClassFieldStatementsMap.js";

export type ClassMemberImpl = (
ConstructorDeclarationImpl |
PropertyDeclarationImpl |
GetAccessorDeclarationImpl |
SetAccessorDeclarationImpl |
MethodDeclarationImpl
MethodDeclarationImpl |
PropertyDeclarationImpl |
SetAccessorDeclarationImpl
);

/**
Expand Down Expand Up @@ -77,6 +77,24 @@ extends Map<string, ClassMemberImpl>
return rv;
}

static fromClassDeclaration(
classDecl: ClassDeclarationImpl
): ClassMembersMap
{
const map = new ClassMembersMap;

const members: ClassMemberImpl[] = [
...classDecl.ctors,
...classDecl.getAccessors,
...classDecl.methods,
...classDecl.properties,
...classDecl.setAccessors
];
map.addMembers(members);

return map;
}

/**
* Add class members as values of this map, using standard keys.
*
Expand Down Expand Up @@ -111,8 +129,9 @@ extends Map<string, ClassMemberImpl>

/**
* A typed call to `this.get()` for a given kind.
* @param key - the key to get.
* @param kind - the structure kind.
* @param isStatic - true if the member is static.
* @param name - the name of the member.
* @returns - the class member, as the right type, or undefined if the wrong type.
*
* @see `ClassMembersMap::keyFromName`
Expand All @@ -121,13 +140,15 @@ extends Map<string, ClassMemberImpl>
Kind extends ClassMemberImpl["kind"]
>
(
key: string,
kind: Kind
): (ClassMemberImpl & { kind: Kind }) | undefined
kind: Kind,
isStatic: boolean,
name: string
): (Extract<ClassMemberImpl, { kind: Kind }>) | undefined
{
const key = ClassMembersMap.keyFromName(kind, isStatic, name);
const rv = this.get(key);
if (rv?.kind === kind)
return rv as ClassMemberImpl & { kind: Kind };
return rv as Extract<ClassMemberImpl, { kind: Kind }>;
return undefined;
}

Expand All @@ -141,6 +162,20 @@ extends Map<string, ClassMemberImpl>
statementsMaps: ClassFieldStatementsMap[],
): void
{
// validate setters have an argument
{
const setters = this.arrayOfKind<StructureKind.SetAccessor>(StructureKind.SetAccessor);
const missedNames: string[] = [];
setters.forEach(setter => {
if (setter.parameters.length !== 1) {
missedNames.push(setter.name);
}
});
if (missedNames.length > 0) {
throw new Error("The following setters do not have exactly one parameter: " + missedNames.join(", "));
}
}

this.forEach(member => this.#moveMemberToClass(classDecl, member, statementsMaps));
this.clear();
}
Expand Down
2 changes: 1 addition & 1 deletion stage_2_fullset/snapshot/source/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export { default as TypeParameterDeclarationImpl } from "./structures/TypeParame
export { default as VariableDeclarationImpl } from "./structures/VariableDeclarationImpl.js";
export { default as VariableStatementImpl } from "./structures/VariableStatementImpl.js";
export {
type ClassFieldStatementsArray,
type ClassFieldStatement,
default as ClassFieldStatementsMap,
} from "./toolbox/ClassFieldStatementsMap.js";
export {
Expand Down
51 changes: 23 additions & 28 deletions stage_2_fullset/snapshot/source/toolbox/ClassFieldStatementsMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import type { WriterFunction } from "ts-morph";

import type { StatementStructureImpls } from "../exports.js";

export type ClassFieldStatementsArray = (
export type ClassFieldStatement =
| string
| WriterFunction
| StatementStructureImpls
)[];
| StatementStructureImpls;
type keyPair = { fieldName: string; statementGroup: string };

/**
Expand Down Expand Up @@ -81,13 +80,13 @@ export default class ClassFieldStatementsMap {
return a.localeCompare(b);
}

readonly #map = new Map<string, ClassFieldStatementsArray>();
readonly #map = new Map<string, ClassFieldStatement[]>();
readonly #statementGroupMap = new Map<
string,
Map<string, ClassFieldStatementsArray>
Map<string, ClassFieldStatement[]>
>();

public constructor(iterable?: [string, string, ClassFieldStatementsArray][]) {
public constructor(iterable?: [string, string, ClassFieldStatement[]][]) {
if (iterable) {
for (const [fieldName, statementGroup, statements] of iterable) {
this.set(fieldName, statementGroup, statements);
Expand Down Expand Up @@ -133,9 +132,7 @@ export default class ClassFieldStatementsMap {
/**
* Yield the key-statements tuples of the collection.
*/
public *entries(): IterableIterator<
[string, string, ClassFieldStatementsArray]
> {
public *entries(): IterableIterator<[string, string, ClassFieldStatement[]]> {
const iterator = this.#map.entries();
for (const [hashed, statements] of iterator) {
const { fieldName, statementGroup } =
Expand All @@ -151,25 +148,23 @@ export default class ClassFieldStatementsMap {
*/
public forEach(
__callback__: (
statements: ClassFieldStatementsArray,
statements: ClassFieldStatement[],
fieldName: string,
statementGroup: string,
__collection__: ClassFieldStatementsMap,
) => void,
__thisArg__?: unknown,
): void {
this.#map.forEach(
(statements: ClassFieldStatementsArray, hashed: string) => {
const { fieldName, statementGroup } =
ClassFieldStatementsMap.#parseKey(hashed);
__callback__.apply(__thisArg__, [
statements,
fieldName,
statementGroup,
this,
]);
},
);
this.#map.forEach((statements: ClassFieldStatement[], hashed: string) => {
const { fieldName, statementGroup } =
ClassFieldStatementsMap.#parseKey(hashed);
__callback__.apply(__thisArg__, [
statements,
fieldName,
statementGroup,
this,
]);
});
}

/**
Expand All @@ -182,7 +177,7 @@ export default class ClassFieldStatementsMap {
public get(
fieldName: string,
statementGroup: string,
): ClassFieldStatementsArray | undefined {
): ClassFieldStatement[] | undefined {
[fieldName, statementGroup] = ClassFieldStatementsMap.#normalizeKeys(
fieldName,
statementGroup,
Expand Down Expand Up @@ -232,7 +227,7 @@ export default class ClassFieldStatementsMap {
public set(
fieldName: string,
statementGroup: string,
statements: ClassFieldStatementsArray,
statements: ClassFieldStatement[],
): this {
[fieldName, statementGroup] = ClassFieldStatementsMap.#normalizeKeys(
fieldName,
Expand All @@ -245,7 +240,7 @@ export default class ClassFieldStatementsMap {

let subMap = this.#statementGroupMap.get(statementGroup);
if (!subMap) {
subMap = new Map<string, ClassFieldStatementsArray>();
subMap = new Map<string, ClassFieldStatement[]>();
this.#statementGroupMap.set(statementGroup, subMap);
}
subMap.set(fieldName, statements);
Expand All @@ -256,12 +251,12 @@ export default class ClassFieldStatementsMap {
/**
* Yield the statementss of the collection.
*/
public values(): IterableIterator<ClassFieldStatementsArray> {
public values(): IterableIterator<ClassFieldStatement[]> {
return this.#map.values();
}

public [Symbol.iterator](): IterableIterator<
[string, string, ClassFieldStatementsArray]
[string, string, ClassFieldStatement[]]
> {
return this.entries();
}
Expand All @@ -278,7 +273,7 @@ export default class ClassFieldStatementsMap {
*/
public groupStatementsMap(
statementGroup: string,
): ReadonlyMap<string, ClassFieldStatementsArray> | undefined {
): ReadonlyMap<string, ClassFieldStatement[]> | undefined {
const iterator = this.#statementGroupMap.get(statementGroup)?.entries();
if (!iterator) return undefined;

Expand Down
Loading

0 comments on commit 2c89649

Please sign in to comment.