External field contracts FTW!
svn: r18202
This commit is contained in:
parent
1688a6c3f7
commit
d87794a8d2
|
@ -2513,6 +2513,14 @@
|
|||
[inner-projs (if (null? (class/c-inners ctc))
|
||||
(class-inner-projs cls)
|
||||
(make-vector method-width))]
|
||||
[field-pub-width (class-field-pub-width cls)]
|
||||
[field-ht (class-field-ht cls)]
|
||||
[ext-field-refs (if (null? (class/c-fields ctc))
|
||||
(class-ext-field-refs cls)
|
||||
(make-vector field-pub-width))]
|
||||
[ext-field-sets (if (null? (class/c-fields ctc))
|
||||
(class-ext-field-sets cls)
|
||||
(make-vector field-pub-width))]
|
||||
[class-make (if name
|
||||
(make-naming-constructor
|
||||
struct:class
|
||||
|
@ -2537,14 +2545,14 @@
|
|||
inner-projs
|
||||
|
||||
(class-field-width cls)
|
||||
(class-field-pub-width cls)
|
||||
(class-field-ht cls)
|
||||
field-pub-width
|
||||
field-ht
|
||||
(class-field-ids cls)
|
||||
|
||||
(class-int-field-refs cls)
|
||||
(class-int-field-sets cls)
|
||||
(class-ext-field-refs cls)
|
||||
(class-ext-field-sets cls)
|
||||
ext-field-refs
|
||||
ext-field-sets
|
||||
|
||||
'struct:object 'object? 'make-object
|
||||
'field-ref 'field-set!
|
||||
|
@ -2615,6 +2623,27 @@
|
|||
(vector-set! inner-projs i
|
||||
(compose (vector-ref inner-projs i) p))))))
|
||||
|
||||
;; Handle external field contracts
|
||||
(unless (null? (class/c-fields ctc))
|
||||
(let ([old-refs (class-ext-field-refs cls)]
|
||||
[old-sets (class-ext-field-sets cls)])
|
||||
(for ([n (in-range field-pub-width)])
|
||||
(vector-set! ext-field-refs n (vector-ref old-refs n))
|
||||
(vector-set! ext-field-sets n (vector-ref old-sets n))))
|
||||
(let ([bset (blame-swap blame)])
|
||||
(for ([f (in-list (class/c-fields ctc))]
|
||||
[c (in-list (class/c-field-contracts ctc))])
|
||||
(let* ([i (hash-ref field-ht f)]
|
||||
[pre-p (contract-projection c)]
|
||||
[old-ref (vector-ref ext-field-refs i)]
|
||||
[old-set (vector-ref ext-field-sets i)])
|
||||
(vector-set! ext-field-refs i
|
||||
(λ (o)
|
||||
((pre-p blame) (old-ref o))))
|
||||
(vector-set! ext-field-sets i
|
||||
(λ (o v)
|
||||
(old-set o ((pre-p bset) v))))))))
|
||||
|
||||
c))))
|
||||
|
||||
(define-struct class/c
|
||||
|
|
|
@ -4494,6 +4494,44 @@
|
|||
[e% (class d% (super-new) (define/override (m x) (+ x (super m #f))))])
|
||||
(send (new e%) m 3)))
|
||||
|
||||
(test/spec-passed/result
|
||||
'class/c-higher-order-field-1
|
||||
'(let* ([c% (contract (class/c (field [f number?]))
|
||||
(class object% (super-new) (field [f 10]))
|
||||
'pos
|
||||
'neg)])
|
||||
(get-field f (new c%)))
|
||||
10)
|
||||
|
||||
(test/spec-passed/result
|
||||
'class/c-higher-order-field-2
|
||||
'(let* ([c% (contract (class/c (field [f number?]))
|
||||
(class object% (super-new) (field [f 10]))
|
||||
'pos
|
||||
'neg)]
|
||||
[o (new c%)])
|
||||
(set-field! f o 5)
|
||||
(get-field f o))
|
||||
5)
|
||||
|
||||
(test/pos-blame
|
||||
'class/c-higher-order-field-3
|
||||
'(let* ([c% (contract (class/c (field [f number?]))
|
||||
(class object% (super-new) (field [f #f]))
|
||||
'pos
|
||||
'neg)]
|
||||
[o (new c%)])
|
||||
(get-field f o)))
|
||||
|
||||
(test/neg-blame
|
||||
'class/c-higher-order-field-4
|
||||
'(let* ([c% (contract (class/c (field [f number?]))
|
||||
(class object% (super-new) (field [f 10]))
|
||||
'pos
|
||||
'neg)]
|
||||
[o (new c%)])
|
||||
(set-field! f o #f)))
|
||||
|
||||
;
|
||||
;
|
||||
; ;; ;; ; ;;
|
||||
|
|
Loading…
Reference in New Issue
Block a user