factor/core/classes/mixin/mixin.factor

100 lines
2.9 KiB
Factor
Raw Normal View History

2008-01-05 19:37:13 -05:00
! Copyright (C) 2004, 2008 Slava Pestov.
2007-09-20 18:09:08 -04:00
! See http://factorcode.org/license.txt for BSD license.
2008-01-04 21:10:49 -05:00
USING: classes classes.union words kernel sequences
definitions combinators arrays assocs generic accessors ;
2007-09-20 18:09:08 -04:00
IN: classes.mixin
2008-03-26 19:23:19 -04:00
PREDICATE: mixin-class < union-class "mixin" word-prop ;
2007-09-20 18:09:08 -04:00
M: mixin-class reset-class
2008-06-25 04:25:08 -04:00
[ call-next-method ] [ { "mixin" } reset-props ] bi ;
2007-09-20 18:09:08 -04:00
2008-05-02 03:51:38 -04:00
M: mixin-class rank-class drop 3 ;
2007-09-20 18:09:08 -04:00
: redefine-mixin-class ( class members -- )
[ (define-union-class) ]
[ drop t "mixin" set-word-prop ]
2bi ;
2007-09-20 18:09:08 -04:00
: define-mixin-class ( class -- )
dup mixin-class? [
drop
] [
{ } redefine-mixin-class
] if ;
2008-01-04 21:10:49 -05:00
TUPLE: check-mixin-class mixin ;
: check-mixin-class ( mixin -- mixin )
dup mixin-class? [
\ check-mixin-class boa throw
2008-01-04 21:10:49 -05:00
] unless ;
: if-mixin-member? ( class mixin true false -- )
[ check-mixin-class 2dup members memq? ] 2dip if ; inline
2008-01-04 21:10:49 -05:00
: change-mixin-class ( class mixin quot -- )
[ [ members swap bootstrap-word ] dip call ] [ drop ] 2bi
2008-01-04 21:10:49 -05:00
swap redefine-mixin-class ; inline
: update-classes/new ( mixin -- )
class-usages
2008-06-11 18:40:33 -04:00
[ [ update-class ] each ]
[ implementors [ make-generic ] each ] bi ;
2007-09-20 18:09:08 -04:00
: add-mixin-instance ( class mixin -- )
#! Note: we call update-classes on the new member, not the
#! mixin. This ensures that we only have to update the
#! methods whose specializer intersects the new member, not
#! the entire mixin (since the other mixin members are not
#! affected at all). Also, all usages of the mixin will get
#! updated by transitivity; the mixins usages appear in
#! class-usages of the member, now that it's been added.
[ 2drop ] [
2008-06-11 03:58:38 -04:00
[ [ suffix ] change-mixin-class ] 2keep
tuck [ new-class? ] either? [
update-classes/new
] [
update-classes
] if
] if-mixin-member? ;
2008-01-04 21:10:49 -05:00
: remove-mixin-instance ( class mixin -- )
[
[ [ swap remove ] change-mixin-class ] keep
update-classes
] [ 2drop ] if-mixin-member? ;
2008-01-04 21:10:49 -05:00
! Definition protocol implementation ensures that removing an
! INSTANCE: declaration from a source file updates the mixin.
TUPLE: mixin-instance loc class mixin ;
2008-01-05 19:37:13 -05:00
M: mixin-instance equal?
{
{ [ over mixin-instance? not ] [ f ] }
2008-03-29 21:36:58 -04:00
{ [ 2dup [ mixin-instance-class ] bi@ = not ] [ f ] }
{ [ 2dup [ mixin-instance-mixin ] bi@ = not ] [ f ] }
2008-04-11 13:53:22 -04:00
[ t ]
2008-01-05 19:37:13 -05:00
} cond 2nip ;
2008-01-05 21:06:01 -05:00
M: mixin-instance hashcode*
[ class>> ] [ mixin>> ] bi 2array hashcode* ;
2008-01-05 21:06:01 -05:00
2008-01-04 21:10:49 -05:00
: <mixin-instance> ( class mixin -- definition )
mixin-instance new
swap >>mixin
swap >>class ;
2008-01-04 21:10:49 -05:00
M: mixin-instance where mixin-instance-loc ;
M: mixin-instance set-where set-mixin-instance-loc ;
M: mixin-instance definer drop \ INSTANCE: f ;
M: mixin-instance definition drop f ;
M: mixin-instance forget*
2008-01-04 21:10:49 -05:00
dup mixin-instance-class
2008-01-05 21:06:01 -05:00
swap mixin-instance-mixin dup mixin-class?
[ remove-mixin-instance ] [ 2drop ] if ;