Skip to content

Commit

Permalink
#13, TypeMembersMap.fromMemberedObject, tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
ajvincent committed Jan 14, 2024
1 parent 53fce4b commit 56715e1
Show file tree
Hide file tree
Showing 6 changed files with 280 additions and 44 deletions.
13 changes: 7 additions & 6 deletions stage_1_integration/toolbox/ClassMembersMap.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
JSDocStructure,
StructureKind
KindedStructure,
StructureKind,
} from "ts-morph";

import {
Expand Down Expand Up @@ -39,7 +40,7 @@ export type ClassMemberImpl = (
* const foo = new PropertyDeclarationImpl(false, "foo");
* map.addMembers([foo]);
* // ...
* const classDecl = new ClassDeclaration;
* const classDecl = new ClassDeclarationImpl;
* classDecl.name = "FooClass";
* map.moveMembersToClass(classDecl);
* // classDecl.properties === [foo];
Expand Down Expand Up @@ -135,11 +136,11 @@ extends Map<string, ClassMemberImpl>
>
(
kind: Kind
): Extract<ClassMemberImpl , { kind: Kind }>[]
): Extract<ClassMemberImpl, KindedStructure<Kind>>[]
{
let items = Array.from(this.values());
items = items.filter(item => item.kind === kind);
return items as Extract<ClassMemberImpl , { kind: Kind }>[];
return items as Extract<ClassMemberImpl, KindedStructure<Kind>>[];
}

/**
Expand All @@ -158,12 +159,12 @@ extends Map<string, ClassMemberImpl>
kind: Kind,
isStatic: boolean,
name: string
): (Extract<ClassMemberImpl, { kind: Kind }>) | undefined
): (Extract<ClassMemberImpl, KindedStructure<Kind>>) | undefined
{
const key = ClassMembersMap.keyFromName(kind, isStatic, name);
const rv = this.get(key);
if (rv?.kind === kind)
return rv as Extract<ClassMemberImpl, { kind: Kind }>;
return rv as Extract<ClassMemberImpl, KindedStructure<Kind>>;
return undefined;
}

Expand Down
75 changes: 70 additions & 5 deletions stage_1_integration/toolbox/TypeMembersMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ export type TypeMemberImpl = (

export type NamedTypeMemberImpl = Extract<TypeMemberImpl, { name: string }>;

/**
* A map for members of `InterfaceDeclarationImpl` and `MemberedObjectTypeStructureImpl`. This
* doesn't replace the structures, rather it _feeds_ them.
*
* @example
*
* const map = new TypeMembersMap;
* const foo = new PropertySignatureImpl(false, "foo");
* map.addMembers([foo]);
* // ...
* const interfaceDecl = new InterfaceDeclarationImpl("FooInterface");
* map.moveMembersToType(interfaceDecl);
* // interfaceDecl.properties === [foo];
*/
export default class TypeMembersMap
extends Map<string, TypeMemberImpl>
{
Expand Down Expand Up @@ -82,6 +96,31 @@ extends Map<string, TypeMemberImpl>
return rv;
}

/**
* Create a `TypeMembersMap` from an interface or membered object.
* @param membered - the membered object.
* @returns the type members map.
*/
static fromMemberedObject(
membered: InterfaceDeclarationImpl | MemberedObjectTypeStructureImpl
): TypeMembersMap
{
const map = new TypeMembersMap;

const members: TypeMemberImpl[] = [
...membered.callSignatures,
...membered.constructSignatures,
...membered.getAccessors,
...membered.indexSignatures,
...membered.methods,
...membered.properties,
...membered.setAccessors,
];
map.addMembers(members);

return map;
}

/**
* Add type members as values of this map, using standard keys.
*
Expand Down Expand Up @@ -116,26 +155,52 @@ extends Map<string, TypeMemberImpl>

/**
* A typed call to `this.get()` for a given kind.
* @param key - the key to get.
* @param kind - the structure kind.
* @param name - the key to get.
* @returns - the type member, as the right type, or undefined if the wrong type.
*
* @see `ClassMembersMap::keyFromName`
* @see `TypeMembersMap::keyFromName`
*/
getAsKind<
Kind extends TypeMemberImpl["kind"]
>
(
key: string,
kind: Kind
kind: Kind,
name: string,
): Extract<TypeMemberImpl, KindedStructure<Kind>> | undefined
{
const rv = this.get(key);
const rv = this.get(name);
if (rv?.kind === kind)
return rv as Extract<TypeMemberImpl, KindedStructure<Kind>>;
return undefined;
}

convertAccessorsToProperty(
name: string
): void
{
void(name);
throw new Error("not yet implemented");
}

convertPropertyToAccessors(
name: string,
toGetter: boolean,
toSetter: boolean
): void
{
void(name);
void(toGetter);
void(toSetter);
throw new Error("not yet implemented");
}

resolveIndexSignature(
): never
{
throw new Error("not yet implemented");
}

/**
* Move type members from this map to an interface or type literal, and clear this map.
*
Expand Down
12 changes: 6 additions & 6 deletions stage_2_fullset/snapshot/source/toolbox/ClassMembersMap.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { JSDocStructure, StructureKind } from "ts-morph";
import { JSDocStructure, KindedStructure, StructureKind } from "ts-morph";

import {
ClassDeclarationImpl,
Expand Down Expand Up @@ -35,7 +35,7 @@ export type ClassMemberImpl =
* const foo = new PropertyDeclarationImpl(false, "foo");
* map.addMembers([foo]);
* // ...
* const classDecl = new ClassDeclaration;
* const classDecl = new ClassDeclarationImpl;
* classDecl.name = "FooClass";
* map.moveMembersToClass(classDecl);
* // classDecl.properties === [foo];
Expand Down Expand Up @@ -113,10 +113,10 @@ export default class ClassMembersMap extends Map<string, ClassMemberImpl> {
*/
public arrayOfKind<Kind extends ClassMemberImpl["kind"]>(
kind: Kind,
): Extract<ClassMemberImpl, { kind: Kind }>[] {
): Extract<ClassMemberImpl, KindedStructure<Kind>>[] {
let items = Array.from(this.values());
items = items.filter((item) => item.kind === kind);
return items as Extract<ClassMemberImpl, { kind: Kind }>[];
return items as Extract<ClassMemberImpl, KindedStructure<Kind>>[];
}

/**
Expand All @@ -132,11 +132,11 @@ export default class ClassMembersMap extends Map<string, ClassMemberImpl> {
kind: Kind,
isStatic: boolean,
name: string,
): Extract<ClassMemberImpl, { kind: Kind }> | undefined {
): Extract<ClassMemberImpl, KindedStructure<Kind>> | undefined {
const key = ClassMembersMap.keyFromName(kind, isStatic, name);
const rv = this.get(key);
if (rv?.kind === kind)
return rv as Extract<ClassMemberImpl, { kind: Kind }>;
return rv as Extract<ClassMemberImpl, KindedStructure<Kind>>;
return undefined;
}

Expand Down
66 changes: 62 additions & 4 deletions stage_2_fullset/snapshot/source/toolbox/TypeMembersMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ export type TypeMemberImpl =

export type NamedTypeMemberImpl = Extract<TypeMemberImpl, { name: string }>;

/**
* A map for members of `InterfaceDeclarationImpl` and `MemberedObjectTypeStructureImpl`. This
* doesn't replace the structures, rather it _feeds_ them.
*
* @example
*
* const map = new TypeMembersMap;
* const foo = new PropertySignatureImpl(false, "foo");
* map.addMembers([foo]);
* // ...
* const interfaceDecl = new InterfaceDeclarationImpl("FooInterface");
* map.moveMembersToType(interfaceDecl);
* // interfaceDecl.properties === [foo];
*/
export default class TypeMembersMap extends Map<string, TypeMemberImpl> {
static readonly #uniqueKey = new WeakMap<TypeMemberImpl, string>();
static #uniqueKeyCounter = 0;
Expand Down Expand Up @@ -62,6 +76,30 @@ export default class TypeMembersMap extends Map<string, TypeMemberImpl> {
return rv;
}

/**
* Create a `TypeMembersMap` from an interface or membered object.
* @param membered - the membered object.
* @returns the type members map.
*/
static fromMemberedObject(
membered: InterfaceDeclarationImpl | MemberedObjectTypeStructureImpl,
): TypeMembersMap {
const map = new TypeMembersMap();

const members: TypeMemberImpl[] = [
...membered.callSignatures,
...membered.constructSignatures,
...membered.getAccessors,
...membered.indexSignatures,
...membered.methods,
...membered.properties,
...membered.setAccessors,
];
map.addMembers(members);

return map;
}

/**
* Add type members as values of this map, using standard keys.
*
Expand Down Expand Up @@ -89,22 +127,42 @@ export default class TypeMembersMap extends Map<string, TypeMemberImpl> {

/**
* A typed call to `this.get()` for a given kind.
* @param key - the key to get.
* @param kind - the structure kind.
* @param name - the key to get.
* @returns - the type member, as the right type, or undefined if the wrong type.
*
* @see `ClassMembersMap::keyFromName`
* @see `TypeMembersMap::keyFromName`
*/
getAsKind<Kind extends TypeMemberImpl["kind"]>(
key: string,
kind: Kind,
name: string,
): Extract<TypeMemberImpl, KindedStructure<Kind>> | undefined {
const rv = this.get(key);
const rv = this.get(name);
if (rv?.kind === kind)
return rv as Extract<TypeMemberImpl, KindedStructure<Kind>>;
return undefined;
}

convertAccessorsToProperty(name: string): void {
void name;
throw new Error("not yet implemented");
}

convertPropertyToAccessors(
name: string,
toGetter: boolean,
toSetter: boolean,
): void {
void name;
void toGetter;
void toSetter;
throw new Error("not yet implemented");
}

resolveIndexSignature(): never {
throw new Error("not yet implemented");
}

/**
* Move type members from this map to an interface or type literal, and clear this map.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ describe("ClassMembersMap", () => {
});
});

it("static methods give us keys we can use in the map", () => {
it("static keyFromName() and keyFromMember() give us keys we can use in the map", () => {
expect(ClassMembersMap.keyFromMember(method3)).toBe("static three");

expect(ClassMembersMap.keyFromName(StructureKind.Constructor, true, "three")).toBe("constructor");
Expand Down
Loading

0 comments on commit 56715e1

Please sign in to comment.