From c7c8f7061ed6fe18001a3cdb8b091f0e017a639d Mon Sep 17 00:00:00 2001 From: Stevie Strickland Date: Mon, 15 Mar 2010 08:47:09 +0000 Subject: [PATCH] Add documentation, and also add tests for appropriate init-field behavior. svn: r18541 --- collects/scribblings/reference/class.scrbl | 11 ++++++- collects/tests/mzscheme/contract-test.ss | 36 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/collects/scribblings/reference/class.scrbl b/collects/scribblings/reference/class.scrbl index 93215880ee..36f85ee5dc 100644 --- a/collects/scribblings/reference/class.scrbl +++ b/collects/scribblings/reference/class.scrbl @@ -1476,13 +1476,15 @@ resulting trait is the same as for @scheme[trait-sum], otherwise the @section{Object and Class Contracts} @defform/subs[ -#:literals (field inherit inherit-field super inner override augment augride) +#:literals (field init init-field inherit inherit-field super inner override augment augride) (class/c member-spec ...) ([member-spec method-spec (field field-spec ...) + (init field-spec ...) + (init-field field-spec ...) (inherit method-spec ...) (inherit-field field-spec ...) (super method-spec ...) @@ -1525,6 +1527,13 @@ The external contracts are as follows: value contained in that field when accessed via an object of that class. Since fields may be mutated, these contracts are checked on any external access and/or mutation of the field.} + @item{An initialization argument contract, tagged with @scheme[init], describes the + expected behavior of the value paired with that name during class instantiation. + The same name can be provided more than once, in which case the first such contract + in the @scheme[class/c] form is applied to the first value tagged with that name in + the list of initialization arguments, and so on.} + @item{The contracts listed in an @scheme[init-field] section are treated as if each + contract appeared in an @scheme[init] section and a @scheme[field] section.} ] The internal contracts are as follows: diff --git a/collects/tests/mzscheme/contract-test.ss b/collects/tests/mzscheme/contract-test.ss index 2ee7630835..6f81cc76de 100644 --- a/collects/tests/mzscheme/contract-test.ss +++ b/collects/tests/mzscheme/contract-test.ss @@ -4717,6 +4717,42 @@ [d%/c (contract (class/c (init [a integer?] [a string?])) d% 'pos 'neg)] [d%/c/c (contract (class/c (init [a number?])) d%/c 'pos 'neg)]) (new d%/c/c [a #t] [a "foo"]))) + + (test/spec-passed + 'class/c-higher-order-init-field-1 + '(let ([c% (contract (class/c (init-field [f (-> number? number?)])) + (class object% (super-new) (init-field f) (f 3)) + 'pos + 'neg)]) + (new c% [f (lambda (x) x)]))) + + (test/pos-blame + 'class/c-higher-order-init-field-2 + '(let ([c% (contract (class/c (init-field [f (-> number? number?)])) + (class object% (super-new) (init-field f) (f #t)) + 'pos + 'neg)]) + (new c% [f (lambda (x) x)]))) + + (test/neg-blame + 'class/c-higher-order-init-field-3 + '(let ([c% (contract (class/c (init-field [f (-> number? number?)])) + (class object% (super-new) (init-field f) (f 3)) + 'pos + 'neg)]) + (new c% [f (lambda (x) (zero? x))]))) + + ;; Make sure that the original provider of the value is blamed if an + ;; init arg is given an invalid value, and then that is retrieved by + ;; an external client. + (test/neg-blame + 'class/c-higher-order-init-field-4 + '(let* ([c% (contract (class/c (init-field [f (-> number? number?)])) + (class object% (super-new) (init-field f)) + 'pos + 'neg)] + [o (new c% [f (lambda (x) (zero? x))])]) + ((get-field f o) 3))) (test/spec-passed 'class/c-higher-order-method-1