| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  | 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 -- )
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  |     [ (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
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2008-08-28 23:28:34 -04:00
										 |  |  |         [ { } redefine-mixin-class ] | 
					
						
							|  |  |  |         [ update-classes ] | 
					
						
							|  |  |  |         bi
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-03 10:33:32 -05:00
										 |  |  | TUPLE: check-mixin-class class ;
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : check-mixin-class ( mixin -- mixin )
 | 
					
						
							|  |  |  |     dup mixin-class? [ | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:09 -04:00
										 |  |  |         \ check-mixin-class boa throw
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  |     ] unless ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : if-mixin-member? ( class mixin true false -- )
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  |     [ check-mixin-class 2dup members memq? ] 2dip if ; inline
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : change-mixin-class ( class mixin quot -- )
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  |     [ [ members swap bootstrap-word ] dip call ] [ drop ] 2bi
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  |     swap redefine-mixin-class ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-30 03:31:27 -04:00
										 |  |  | : update-classes/new ( mixin -- )
 | 
					
						
							|  |  |  |     class-usages | 
					
						
							|  |  |  |     [ [ update-class ] each ] | 
					
						
							| 
									
										
										
										
											2008-11-03 04:51:28 -05:00
										 |  |  |     [ implementors [ remake-generic ] each ] bi ;
 | 
					
						
							| 
									
										
										
										
											2008-08-30 03:31:27 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : add-mixin-instance ( class mixin -- )
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  |     #! 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-08-30 03:31:27 -04:00
										 |  |  |         [ [ suffix ] change-mixin-class ] 2keep
 | 
					
						
							|  |  |  |         tuck [ new-class? ] either? [ | 
					
						
							|  |  |  |             update-classes/new | 
					
						
							|  |  |  |         ] [ | 
					
						
							|  |  |  |             update-classes | 
					
						
							|  |  |  |         ] if
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  |     ] if-mixin-member? ;
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : remove-mixin-instance ( class mixin -- )
 | 
					
						
							| 
									
										
										
										
											2008-09-03 18:24:06 -04:00
										 |  |  |     #! The order of the three clauses is important here. The last | 
					
						
							|  |  |  |     #! one must come after the other two so that the entries it | 
					
						
							|  |  |  |     #! adds to changed-generics are not overwritten. | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-08-31 02:34:00 -04:00
										 |  |  |         [ [ swap remove ] change-mixin-class ] | 
					
						
							|  |  |  |         [ nip update-classes ] | 
					
						
							| 
									
										
										
										
											2008-09-03 18:24:06 -04:00
										 |  |  |         [ class-usages update-methods ] | 
					
						
							| 
									
										
										
										
											2008-08-31 02:34:00 -04:00
										 |  |  |         2tri
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  |     ] [ 2drop ] if-mixin-member? ;
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-04 02:32:11 -04:00
										 |  |  | M: mixin-class class-forgotten remove-mixin-instance ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-08-31 08:45:33 -04:00
										 |  |  |         { [ 2dup [ class>> ] bi@ = not ] [ f ] } | 
					
						
							|  |  |  |         { [ 2dup [ 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* | 
					
						
							| 
									
										
										
										
											2008-03-29 01:59:05 -04:00
										 |  |  |     [ 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 )
 | 
					
						
							| 
									
										
										
										
											2008-06-30 06:22:05 -04:00
										 |  |  |     mixin-instance new
 | 
					
						
							|  |  |  |         swap >>mixin | 
					
						
							|  |  |  |         swap >>class ;
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-31 08:45:33 -04:00
										 |  |  | M: mixin-instance where loc>> ;
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-31 08:45:33 -04:00
										 |  |  | M: mixin-instance set-where (>>loc) ;
 | 
					
						
							| 
									
										
										
										
											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* | 
					
						
							| 
									
										
										
										
											2008-08-31 08:45:33 -04:00
										 |  |  |     [ class>> ] [ mixin>> ] bi
 | 
					
						
							| 
									
										
										
										
											2008-08-31 08:55:34 -04:00
										 |  |  |     dup mixin-class? [ remove-mixin-instance ] [ 2drop ] if ;
 |