Skip to content

Commit

Permalink
Normalize field keys for initializers.
Browse files Browse the repository at this point in the history
  • Loading branch information
ajvincent committed Nov 3, 2023
1 parent 2892a83 commit c6c251f
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ it("ClassFieldStatementsMap works", () => {
map.set(ClassFieldStatementsMap.FIELD_HEAD_SUPER_CALL, "toJSON", ["const rv: Record<string, unknown> = {};"]);
map.set(ClassFieldStatementsMap.FIELD_TAIL_FINAL_RETURN, "toJSON", ["return rv;"]);

map.set("first", ClassFieldStatementsMap.GROUP_INITIALIZER_OR_PROPERTY, [`"one"`]);
// s/\b[gs]et // for initializers
map.set("get first", ClassFieldStatementsMap.GROUP_INITIALIZER_OR_PROPERTY, [`"one"`]);

expect(map.groupKeys()).toEqual([
"constructor",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,31 @@ export type StatementsArray = (string | WriterFunction | StatementStructureImpls
type keyPair = {fieldName: string, statementGroup: string};

/**
* This is a map for specifying statements across several locations for a single class field.
* This is a map for specifying statements across several class members for a single class field.
*
* For example, a field may require statements for:
* - defining a getter and/or a setter
* - initializing in a constructor
* - implementing a .toJSON() method
*
* The field name specifies which field the statements are about. The statement group specifies where the statements go.
* The field name specifies which field the statements are about.
* The statement group specifies where the statements go (what method, or an initializer).
*
* Special field keys:
* ClassFieldStatementsMap.FIELD_HEAD_SUPER_CALL:
* These statements will appear at the head of the statement block.
* ClassFieldStatementsMap.FIELD_TAIL_FINAL_RETURN:
* These statements will appear at the tail of the statement block.
*
* Special statement group keys:
* ClassFieldStatementsMap.GROUP_INITIALIZER_OR_PROPERTY:
* This represents an initializer for a property, or a value reference for a getter or setter.
* Field keys will have `get ` or `set ` stripped from them for this group key.
* Statement arrays for this group key should contain exactly one statement, and should be just a string.
*
* @example
* ```typescript
* map.set("foo", ClassFieldStatementsMap.INITIALIZER_OR_PROPERTY, ['this.#foo.value']);
* map.set("foo", ClassFieldStatementsMap.GROUP_INITIALIZER_OR_PROPERTY, ['this.#foo.value']);
* map.set("foo", "toJSON", ["rv.foo = this.foo;"]);
* // ...
* map.set(ClassFieldsStatementsMap.FIELD_HEAD_SUPER_CALL, "toJSON", ["const rv = super.toJSON();"]);
Expand All @@ -33,6 +46,13 @@ type keyPair = {fieldName: string, statementGroup: string};
*/
export default class ClassFieldStatementsMap
{
static #normalizeKeys(fieldName: string, statementGroup: string): [string, string] {
if (statementGroup === ClassFieldStatementsMap.GROUP_INITIALIZER_OR_PROPERTY) {
fieldName = fieldName.replace(/\b[gs]et /, "");
}
return [fieldName, statementGroup];
}

static #hashKey(fieldName: string, statementGroup: string): string {
return JSON.stringify({fieldName, statementGroup});
}
Expand Down Expand Up @@ -101,6 +121,7 @@ export default class ClassFieldStatementsMap
*/
public delete(fieldName: string, statementGroup: string): boolean
{
[fieldName, statementGroup] = ClassFieldStatementsMap.#normalizeKeys(fieldName, statementGroup);
const rv = this.#map.delete(ClassFieldStatementsMap.#hashKey(fieldName, statementGroup));
this.#statementGroupMap.get(statementGroup)?.delete(fieldName);
return rv;
Expand Down Expand Up @@ -150,6 +171,7 @@ export default class ClassFieldStatementsMap
*/
public get(fieldName: string, statementGroup: string): StatementsArray | undefined
{
[fieldName, statementGroup] = ClassFieldStatementsMap.#normalizeKeys(fieldName, statementGroup);
return this.#map.get(ClassFieldStatementsMap.#hashKey(fieldName, statementGroup));
}

Expand All @@ -162,6 +184,7 @@ export default class ClassFieldStatementsMap
*/
public has(fieldName: string, statementGroup: string): boolean
{
[fieldName, statementGroup] = ClassFieldStatementsMap.#normalizeKeys(fieldName, statementGroup);
return this.#map.has(ClassFieldStatementsMap.#hashKey(fieldName, statementGroup));
}

Expand All @@ -187,6 +210,7 @@ export default class ClassFieldStatementsMap
*/
public set(fieldName: string, statementGroup: string, statements: StatementsArray): this
{
[fieldName, statementGroup] = ClassFieldStatementsMap.#normalizeKeys(fieldName, statementGroup);
this.#map.set(
ClassFieldStatementsMap.#hashKey(fieldName, statementGroup), statements
);
Expand Down
47 changes: 44 additions & 3 deletions stage_2_fullset/snapshot/source/toolbox/ClassFieldStatementsMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,31 @@ export type StatementsArray = (
type keyPair = { fieldName: string; statementGroup: string };

/**
* This is a map for specifying statements across several locations for a single class field.
* This is a map for specifying statements across several class members for a single class field.
*
* For example, a field may require statements for:
* - defining a getter and/or a setter
* - initializing in a constructor
* - implementing a .toJSON() method
*
* The field name specifies which field the statements are about. The statement group specifies where the statements go.
* The field name specifies which field the statements are about.
* The statement group specifies where the statements go (what method, or an initializer).
*
* Special field keys:
* ClassFieldStatementsMap.FIELD_HEAD_SUPER_CALL:
* These statements will appear at the head of the statement block.
* ClassFieldStatementsMap.FIELD_TAIL_FINAL_RETURN:
* These statements will appear at the tail of the statement block.
*
* Special statement group keys:
* ClassFieldStatementsMap.GROUP_INITIALIZER_OR_PROPERTY:
* This represents an initializer for a property, or a value reference for a getter or setter.
* Field keys will have `get ` or `set ` stripped from them for this group key.
* Statement arrays for this group key should contain exactly one statement, and should be just a string.
*
* @example
* ```typescript
* map.set("foo", ClassFieldStatementsMap.INITIALIZER_OR_PROPERTY, ['this.#foo.value']);
* map.set("foo", ClassFieldStatementsMap.GROUP_INITIALIZER_OR_PROPERTY, ['this.#foo.value']);
* map.set("foo", "toJSON", ["rv.foo = this.foo;"]);
* // ...
* map.set(ClassFieldsStatementsMap.FIELD_HEAD_SUPER_CALL, "toJSON", ["const rv = super.toJSON();"]);
Expand All @@ -32,6 +45,18 @@ type keyPair = { fieldName: string; statementGroup: string };
* ```
*/
export default class ClassFieldStatementsMap {
static #normalizeKeys(
fieldName: string,
statementGroup: string,
): [string, string] {
if (
statementGroup === ClassFieldStatementsMap.GROUP_INITIALIZER_OR_PROPERTY
) {
fieldName = fieldName.replace(/\b[gs]et /, "");
}
return [fieldName, statementGroup];
}

static #hashKey(fieldName: string, statementGroup: string): string {
return JSON.stringify({ fieldName, statementGroup });
}
Expand Down Expand Up @@ -91,6 +116,10 @@ export default class ClassFieldStatementsMap {
* @returns True if we found the statements and deleted it.
*/
public delete(fieldName: string, statementGroup: string): boolean {
[fieldName, statementGroup] = ClassFieldStatementsMap.#normalizeKeys(
fieldName,
statementGroup,
);
const rv = this.#map.delete(
ClassFieldStatementsMap.#hashKey(fieldName, statementGroup),
);
Expand Down Expand Up @@ -147,6 +176,10 @@ export default class ClassFieldStatementsMap {
fieldName: string,
statementGroup: string,
): StatementsArray | undefined {
[fieldName, statementGroup] = ClassFieldStatementsMap.#normalizeKeys(
fieldName,
statementGroup,
);
return this.#map.get(
ClassFieldStatementsMap.#hashKey(fieldName, statementGroup),
);
Expand All @@ -160,6 +193,10 @@ export default class ClassFieldStatementsMap {
* @returns True if the key set refers to a statements in the collection.
*/
public has(fieldName: string, statementGroup: string): boolean {
[fieldName, statementGroup] = ClassFieldStatementsMap.#normalizeKeys(
fieldName,
statementGroup,
);
return this.#map.has(
ClassFieldStatementsMap.#hashKey(fieldName, statementGroup),
);
Expand Down Expand Up @@ -190,6 +227,10 @@ export default class ClassFieldStatementsMap {
statementGroup: string,
statements: StatementsArray,
): this {
[fieldName, statementGroup] = ClassFieldStatementsMap.#normalizeKeys(
fieldName,
statementGroup,
);
this.#map.set(
ClassFieldStatementsMap.#hashKey(fieldName, statementGroup),
statements,
Expand Down

0 comments on commit c6c251f

Please sign in to comment.