2010-01-20 02:26:47 -05:00
|
|
|
! Copyright (C) 2004, 2010 Slava Pestov.
|
2007-09-20 18:09:08 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2013-03-05 13:48:14 -05:00
|
|
|
USING: accessors assocs classes classes.algebra
|
|
|
|
classes.algebra.private classes.private classes.union
|
|
|
|
classes.union.private combinators definitions kernel sequences
|
|
|
|
words ;
|
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
|
|
|
|
2010-01-20 02:26:47 -05:00
|
|
|
M: mixin-class normalize-class ;
|
|
|
|
|
|
|
|
M: mixin-class (classes-intersect?)
|
2015-07-20 03:32:42 -04:00
|
|
|
class-members [ classes-intersect? ] with any? ;
|
2010-01-20 02:26:47 -05:00
|
|
|
|
2007-09-20 18:09:08 -04:00
|
|
|
M: mixin-class reset-class
|
2015-06-09 14:53:46 -04:00
|
|
|
[ call-next-method ] [ "mixin" remove-word-prop ] bi ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2010-07-29 19:57:23 -04:00
|
|
|
M: mixin-class rank-class drop 8 ;
|
2008-05-02 03:51:38 -04:00
|
|
|
|
2012-06-21 01:45:52 -04:00
|
|
|
ERROR: check-mixin-class-error class ;
|
2008-01-04 21:10:49 -05:00
|
|
|
|
|
|
|
: check-mixin-class ( mixin -- mixin )
|
|
|
|
dup mixin-class? [
|
2015-08-13 19:13:05 -04:00
|
|
|
check-mixin-class-error
|
2008-01-04 21:10:49 -05:00
|
|
|
] unless ;
|
|
|
|
|
2010-01-20 10:32:31 -05:00
|
|
|
<PRIVATE
|
|
|
|
|
|
|
|
: redefine-mixin-class ( class members -- )
|
|
|
|
[ (define-union-class) ]
|
2010-01-29 08:58:39 -05:00
|
|
|
[ drop changed-conditionally ]
|
2010-01-20 10:32:31 -05:00
|
|
|
[ drop t "mixin" set-word-prop ]
|
2010-01-29 03:40:09 -05:00
|
|
|
2tri ;
|
2010-01-20 10:32:31 -05:00
|
|
|
|
2008-01-04 21:10:49 -05:00
|
|
|
: if-mixin-member? ( class mixin true false -- )
|
2015-07-20 03:32:42 -04:00
|
|
|
[ check-mixin-class 2dup class-members member-eq? ] 2dip if ; inline
|
2008-01-04 21:10:49 -05:00
|
|
|
|
|
|
|
: change-mixin-class ( class mixin quot -- )
|
2015-07-20 03:32:42 -04:00
|
|
|
[ [ class-members swap bootstrap-word ] dip call ] [ drop ] 2bi
|
2008-01-04 21:10:49 -05:00
|
|
|
swap redefine-mixin-class ; inline
|
|
|
|
|
2009-03-16 01:04:34 -04:00
|
|
|
: (add-mixin-instance) ( class mixin -- )
|
2010-01-20 10:23:20 -05:00
|
|
|
#! Call update-methods before adding the member:
|
|
|
|
#! - Call sites of generics specializing on 'mixin'
|
|
|
|
#! where the inferred type is 'class' are updated,
|
|
|
|
#! - Call sites where the inferred type is a subtype
|
|
|
|
#! of 'mixin' disjoint from 'class' are not updated
|
|
|
|
dup class-usages {
|
|
|
|
[ nip update-methods ]
|
|
|
|
[ drop [ suffix ] change-mixin-class ]
|
|
|
|
[ drop [ f ] 2dip "instances" word-prop set-at ]
|
|
|
|
[ 2nip [ update-class ] each ]
|
|
|
|
} 3cleave ;
|
2009-03-16 01:04:34 -04:00
|
|
|
|
|
|
|
: (remove-mixin-instance) ( class mixin -- )
|
2010-01-20 10:23:20 -05:00
|
|
|
#! Call update-methods after removing the member:
|
|
|
|
#! - Call sites of generics specializing on 'mixin'
|
|
|
|
#! where the inferred type is 'class' are updated,
|
|
|
|
#! - Call sites where the inferred type is a subtype
|
|
|
|
#! of 'mixin' disjoint from 'class' are not updated
|
|
|
|
dup class-usages {
|
|
|
|
[ drop [ swap remove ] change-mixin-class ]
|
|
|
|
[ drop "instances" word-prop delete-at ]
|
|
|
|
[ 2nip [ update-class ] each ]
|
|
|
|
[ nip update-methods ]
|
|
|
|
} 3cleave ;
|
2009-03-16 01:04:34 -04:00
|
|
|
|
2010-01-20 10:32:31 -05:00
|
|
|
PRIVATE>
|
|
|
|
|
|
|
|
GENERIC# add-mixin-instance 1 ( class mixin -- )
|
|
|
|
|
|
|
|
M: class add-mixin-instance
|
|
|
|
[ 2drop ] [ (add-mixin-instance) ] if-mixin-member? ;
|
|
|
|
|
2008-01-04 21:10:49 -05:00
|
|
|
: remove-mixin-instance ( class mixin -- )
|
2010-01-20 06:44:34 -05:00
|
|
|
[ (remove-mixin-instance) ] [ 2drop ] if-mixin-member? ;
|
2008-01-04 21:10:49 -05:00
|
|
|
|
2010-01-31 08:48:39 -05:00
|
|
|
M: mixin-class metaclass-changed
|
|
|
|
over class? [ 2drop ] [ remove-mixin-instance ] if ;
|
2008-07-04 02:32:11 -04:00
|
|
|
|
2010-01-20 10:32:31 -05:00
|
|
|
: define-mixin-class ( class -- )
|
|
|
|
dup mixin-class? [
|
|
|
|
drop
|
|
|
|
] [
|
2010-01-29 03:40:09 -05:00
|
|
|
[ { } redefine-mixin-class ]
|
|
|
|
[ H{ } clone "instances" set-word-prop ]
|
|
|
|
[ update-classes ]
|
|
|
|
tri
|
2010-01-20 10:32:31 -05:00
|
|
|
] if ;
|
|
|
|
|
2008-01-04 21:10:49 -05:00
|
|
|
! Definition protocol implementation ensures that removing an
|
|
|
|
! INSTANCE: declaration from a source file updates the mixin.
|
2009-03-16 01:04:34 -04:00
|
|
|
TUPLE: mixin-instance class mixin ;
|
2008-01-05 19:37:13 -05:00
|
|
|
|
2009-03-16 01:04:34 -04:00
|
|
|
C: <mixin-instance> mixin-instance
|
2008-01-05 21:06:01 -05:00
|
|
|
|
2010-01-20 10:32:31 -05:00
|
|
|
<PRIVATE
|
|
|
|
|
2009-03-16 01:04:34 -04:00
|
|
|
: >mixin-instance< ( mixin-instance -- class mixin )
|
|
|
|
[ class>> ] [ mixin>> ] bi ; inline
|
2008-01-04 21:10:49 -05:00
|
|
|
|
2010-01-20 10:32:31 -05:00
|
|
|
PRIVATE>
|
|
|
|
|
2009-03-16 01:04:34 -04:00
|
|
|
M: mixin-instance where >mixin-instance< "instances" word-prop at ;
|
2008-01-04 21:10:49 -05:00
|
|
|
|
2009-03-16 01:04:34 -04:00
|
|
|
M: mixin-instance set-where >mixin-instance< "instances" word-prop set-at ;
|
2008-01-04 21:10:49 -05:00
|
|
|
|
|
|
|
M: mixin-instance definer drop \ INSTANCE: f ;
|
|
|
|
|
|
|
|
M: mixin-instance definition drop f ;
|
|
|
|
|
2008-01-09 16:51:55 -05:00
|
|
|
M: mixin-instance forget*
|
2009-03-16 01:04:34 -04:00
|
|
|
>mixin-instance<
|
2008-08-31 08:55:34 -04:00
|
|
|
dup mixin-class? [ remove-mixin-instance ] [ 2drop ] if ;
|