diff --git a/src/Trait.ts b/src/Trait.ts index cffd410..7422207 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -1,6 +1,6 @@ -import { Call, Fn } from "hotscript" +import { Fn } from "hotscript" import { AbstractClass, Class, Opaque } from "type-fest" -import { AbstractTag, TraitExpression, TraitExpressionNullSuperclass, TraitExpressionTraitsFn, emptyTraitExpression } from "." +import { AbstractTag, TraitExpression, TraitExpressionAllTraits, TraitExpressionNullSuperclass, emptyTraitExpression } from "." import { StaticMembers } from "./util" @@ -33,9 +33,9 @@ export class Trait< ImplClass extends Class<{}, []>, > { constructor( - readonly superExpression: Super, - readonly abstract: Abstract, - readonly apply: (Super: AbstractClass<{}>) => ImplClass, + readonly supertraits: Super, + readonly abstract: Abstract, + readonly apply: (Super: AbstractClass<{}>) => ImplClass, ) {} } @@ -87,10 +87,13 @@ export interface TraitOwnInstanceFn extends Fn { } -export interface TraitSupertraitsFn extends Fn { - return: this["arg0"] extends Trait - ? Call +export type TraitSupertraits = ( + T extends Trait + ? TraitExpressionAllTraits : never +) +export interface TraitSupertraitsFn extends Fn { + return: TraitSupertraits } diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 0e9cc13..1ea1b01 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -1,7 +1,7 @@ -import { Call, ComposeLeft, Fn, Pipe, Tuples } from "hotscript" +import { Call, Fn, Pipe, Tuples } from "hotscript" import { AbstractClass, Class, Opaque } from "type-fest" -import { AbstractTag, Trait, TraitApplierSuperTag, TraitOwnAbstractFn, TraitOwnImplClassFn, TraitOwnImplInstanceFn, TraitSupertraitsFn } from "." -import { ExtendFn, ExtendableFn, SimplifyFn, StaticMembersFn } from "./util" +import { AbstractTag, Trait, TraitApplierSuperTag, TraitOwnAbstractFn, TraitOwnImplClassFn, TraitOwnImplInstanceFn } from "." +import { ExtendFn, SimplifyFn, StaticMembersFn } from "./util" export class TraitExpressionNullSuperclass {} @@ -39,7 +39,7 @@ export class TraitExpression< SimplifyFn, ]> ) { - return this.ownTraits.reduce( + return this.allTraits.reduce( (previous, trait) => trait.apply(previous), this.superclass as Opaque, ) as any @@ -50,10 +50,9 @@ export class TraitExpression< SubtraitImplWithAbstract extends Class<{}>, >( abstract: ( - abstract: Call< - ComposeLeft<[TraitExpressionAbstractFn, SimplifyFn]>, - typeof this - > + abstract: Pipe ) => Opaque, // impl: () @@ -62,42 +61,47 @@ export class TraitExpression< } } -export const emptyTraitExpression = new TraitExpression( - TraitExpressionNullSuperclass, - [] as const, - [] as const, +export type TraitExpressionSuper = ( + T extends TraitExpression + ? Super + : never ) - -interface PrependTraitSupertraitsFn extends Fn { - return: this["arg0"] extends Trait - ? [ - ...Call, - this["arg0"], - ] - : never -} -export interface TraitExpressionTraitsFn extends Fn { - return: this["arg0"] extends TraitExpression - ? Call, Traits> - : never +export interface TraitExpressionSuperFn extends Fn { + return: TraitExpressionSuper } -export interface TraitExpressionAbstractFn extends Fn { - return: this["arg0"] extends TraitExpression - ? Pipe, - ExtendFn, - ]> +export type TraitExpressionOwnTraits = ( + T extends TraitExpression + ? OwnTraits : never +) +export interface TraitExpressionOwnTraitsFn extends Fn { + return: TraitExpressionOwnTraits } -export type Implements> = ( - Exp extends TraitExpression - ? Pipe = ( + T extends TraitExpression + ? AllTraits + : never +) +export interface TraitExpressionAllTraitsFn extends Fn { + return: TraitExpressionAllTraits +} + + +export type Implements> = ( + Exp extends TraitExpression + ? Pipe, ExtendFn, SimplifyFn, ]> : never ) + + +export const emptyTraitExpression = new TraitExpression( + TraitExpressionNullSuperclass, + [] as const, + [] as const, +) diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index 9de8c52..3974336 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -1,6 +1,6 @@ import { Call, Fn, Pipe, Tuples } from "hotscript" import { AbstractClass } from "type-fest" -import { Trait, TraitExpression, TraitOwnAbstractFn, TraitOwnImplClassFn, TraitOwnImplInstanceFn, TraitSupertraitsFn, emptyTraitExpression } from "." +import { Trait, TraitExpression, TraitOwnAbstractFn, TraitOwnImplClassFn, TraitOwnImplInstanceFn, emptyTraitExpression } from "." import { ExtendableFn, StaticMembersFn } from "./util" @@ -27,17 +27,18 @@ class TraitExpressionBuilder< Traits extends Trait[] >( ...traits: Traits - ) { + ): TraitExpressionBuilder< + Super, + [...OwnTraits, ...Traits], + [...AllTraits, SpreadSupertraits] + > { return new TraitExpressionBuilder( new TraitExpression( this.expression.superclass, [...this.expression.ownTraits, ...traits] as const, - [ - ...this.expression.allTraits, - ...this.spreadSupertraits(traits) as SpreadTraitsHierarchy, - ] as const, + [...this.expression.allTraits, ...this.spreadSupertraits(traits)] as const, ) - ) + ) as any } private spreadSupertraits< @@ -50,9 +51,9 @@ class TraitExpressionBuilder< traits: Traits ) { return traits.flatMap(trait => [ - ...trait.superExpression.allTraits, + ...trait.supertraits.allTraits, trait, - ]) + ]) as SpreadSupertraits } get() { @@ -65,18 +66,17 @@ class TraitExpressionBuilder< } -type SpreadTraitsHierarchy[]> = ( +type SpreadSupertraits[]> = ( Call< Tuples.FlatMap, Traits > ) interface PrependTraitSupertraitsFn extends Fn { - return: this["arg0"] extends Trait - ? [ - ...Call, - this["arg0"], - ] + return: this["arg0"] extends Trait + ? Super extends TraitExpression + ? [...AllTraits, this["arg0"]] + : never : never } diff --git a/src/tests.ts b/src/tests.ts index 2fd07a4..6a03f21 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,6 +1,4 @@ -import { Call, ComposeLeft } from "hotscript" -import { Implements, TraitExpressionAbstractFn, abstract, expression, trait } from "." -import { SimplifyFn } from "./util" +import { Implements, abstract, expression, trait } from "." const PrintsHelloOnNew = trait( @@ -60,10 +58,7 @@ const builder = expression ) const exp = builder.get() -type Abs = Call, typeof exp> +type Abs = Implements // exp.subtrait( // s => {