From 2e3878e08d1a9d60d956b33dbbcf344c6e4a5e9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 24 Feb 2024 20:41:16 +0100 Subject: [PATCH] TraitExpressionBuilder refactoring --- src/TraitExpressionBuilder.ts | 175 ++++++++++++++++++++-------------- src/tests.ts | 1 + 2 files changed, 106 insertions(+), 70 deletions(-) diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index 4ade9dd..e5d3aaa 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -5,75 +5,60 @@ import { TraitExpression } from "./TraitExpression" import { Extendable, StaticMembers } from "./util" -type SpreadSupertraits = ( - Traits extends [ - infer El extends Trait, - ...infer Rest, - ] - ? [ - ...Trait.Supertraits, - El, - ...SpreadSupertraits, - ] - : [] -) - -type TraitsUniq = ( - Traits extends [ - ...infer Rest, - infer El extends Trait, - ] - ? IsTraitInTupleFromRight extends true - ? TraitsUniq - : [...TraitsUniq, El] - : [] -) -type IsTraitInTupleFromRight = ( - Traits extends [...infer Rest, infer El] - ? IsEqual extends true - ? true - : IsTraitInTupleFromRight - : false -) - - -type BuildTraitExpression< - Superclass extends AbstractClass, - Traits extends Trait[], -> = ( - Extendable> extends false - ? "Type conflict between the traits abstract definitions." - : Extendable> extends false - ? "Type conflict between the traits static abstract definitions." - : Extendable<[ - InstanceType, - ...TraitTuple.MapImplInstance, - ]> extends false - ? "Type conflict between the traits implementation instance and/or the superclass instance." - : Extendable<[ - StaticMembers, - ...TraitTuple.MapImplStaticMembers, - ]> extends false - ? "Type conflict between the traits implementation static members and/or the superclass static members." - : TraitExpression -) - - export class TraitExpressionBuilder< Superclass extends AbstractClass, const Traits extends Trait[], > { + declare ["constructor"]: typeof TraitExpressionBuilder + constructor( readonly expressionSuperclass: Superclass, readonly expressionTraits: Traits, ) {} + + static spreadSupertraits< + const T extends Trait< + TraitExpression< + typeof TraitExpression.NullSuperclass, + Trait[] + >, + any, + any, + any + >[] + >( + traits: T + ) { + return traits.flatMap(trait => [ + ...trait.superExpression.traits, + trait, + ]) as TraitExpressionBuilder.SpreadSupertraits + } + + static uniqTraits< + const T extends Trait< + TraitExpression< + typeof TraitExpression.NullSuperclass, + Trait[] + >, + any, + any, + any + >[] + >( + traits: T + ) { + return uniq(traits) as TraitExpressionBuilder.UniqTraits + } + + extends< Super extends AbstractClass >( superclass: Super ) { - return new TraitExpressionBuilder( + return new this.constructor( superclass, this.expressionTraits, ) @@ -92,16 +77,13 @@ export class TraitExpressionBuilder< >( ...traits: T ) { - return new TraitExpressionBuilder( + return new this.constructor( this.expressionSuperclass, - uniq([ + this.constructor.uniqTraits([ ...this.expressionTraits, - ...traits.flatMap(trait => [ - ...trait.superExpression.traits, - trait, - ]), - ]) as TraitsUniq<[...Traits, ...SpreadSupertraits]>, + ...this.constructor.spreadSupertraits(traits), + ]), ) } @@ -118,24 +100,22 @@ export class TraitExpressionBuilder< >( ...traits: T ) { - return new TraitExpressionBuilder( + return new this.constructor( this.expressionSuperclass, - uniq([ - ...traits.flatMap(trait => [ - ...trait.superExpression.traits, - trait, - ]), + this.constructor.uniqTraits([ + ...this.constructor.spreadSupertraits(traits), ...this.expressionTraits, - ]) as TraitsUniq<[...SpreadSupertraits, ...Traits]>, + ]), ) } + build() { return new TraitExpression( this.expressionSuperclass, this.expressionTraits, - ) as BuildTraitExpression + ) as TraitExpressionBuilder.BuildTraitExpression } then(fn: (expression: ReturnType) => V): V { @@ -154,4 +134,59 @@ export class TraitExpressionBuilder< } } +export namespace TraitExpressionBuilder { + export type SpreadSupertraits = ( + Traits extends [ + infer El extends Trait, + ...infer Rest, + ] + ? [ + ...Trait.Supertraits, + El, + ...SpreadSupertraits, + ] + : [] + ) + + export type UniqTraits = ( + Traits extends [ + ...infer Rest, + infer El extends Trait, + ] + ? IsTraitInTupleFromRight extends true + ? UniqTraits + : [...UniqTraits, El] + : [] + ) + type IsTraitInTupleFromRight = ( + Traits extends [...infer Rest, infer El] + ? IsEqual extends true + ? true + : IsTraitInTupleFromRight + : false + ) + + export type BuildTraitExpression< + Superclass extends AbstractClass, + Traits extends Trait[], + > = ( + Extendable> extends false + ? "Type conflict between the traits abstract definitions." + : Extendable> extends false + ? "Type conflict between the traits static abstract definitions." + : Extendable<[ + InstanceType, + ...TraitTuple.MapImplInstance, + ]> extends false + ? "Type conflict between the traits implementation instance and/or the superclass instance." + : Extendable<[ + StaticMembers, + ...TraitTuple.MapImplStaticMembers, + ]> extends false + ? "Type conflict between the traits implementation static members and/or the superclass static members." + : TraitExpression + ) +} + + export const expression = new TraitExpressionBuilder(TraitExpression.NullSuperclass, []) diff --git a/src/tests.ts b/src/tests.ts index 2618486..af9b93f 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -64,6 +64,7 @@ const exp = expression PrintsHelloOnNew, Identifiable(), // Identifiable(), + // StatefulSubscription, ActiveStatefulSubscription, ) .build()