Support type alias definitions in class bodies
This commit is contained in:
parent
a45fd96224
commit
066e4356b4
|
@ -13,7 +13,7 @@
|
|||
racket/list
|
||||
racket/match
|
||||
syntax/id-table
|
||||
syntax/kerncase
|
||||
syntax/parse
|
||||
(for-template
|
||||
(typecheck internal-forms)
|
||||
racket/base))
|
||||
|
@ -231,12 +231,11 @@
|
|||
;; Syntax -> Syntax Syntax Syntax Option<Integer>
|
||||
;; Parse a type alias internal declaration
|
||||
(define (parse-type-alias form)
|
||||
(kernel-syntax-case* form #f
|
||||
(define-type-alias-internal values)
|
||||
[(define-values ()
|
||||
(begin (quote-syntax (define-type-alias-internal nm ty args))
|
||||
(#%plain-app values)))
|
||||
(values #'nm #'ty (syntax-e #'args))]
|
||||
(syntax-parse form
|
||||
#:literal-sets (kernel-literals)
|
||||
#:literals (values)
|
||||
[t:type-alias
|
||||
(values #'t.name #'t.type (syntax-e #'t.args))]
|
||||
;; this version is for `let`-like bodies
|
||||
[(begin (quote-syntax (define-type-alias-internal nm ty args))
|
||||
(#%plain-app values))
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
syntax/stx
|
||||
"signatures.rkt"
|
||||
(private parse-type syntax-properties)
|
||||
(env lexical-env tvar-env global-env)
|
||||
(env lexical-env tvar-env global-env type-alias-helper)
|
||||
(types utils abbrev union subtype resolve generalize)
|
||||
(typecheck check-below internal-forms)
|
||||
(utils tc-utils)
|
||||
|
@ -338,6 +338,14 @@
|
|||
(define top-level-exprs
|
||||
(trawl-for-property make-methods-stx tr:class:top-level-property))
|
||||
|
||||
;; Set up type aliases before any types get parsed
|
||||
(define type-aliases
|
||||
(filter (syntax-parser [t:type-alias #t] [_ #f])
|
||||
(syntax->list (hash-ref parse-info 'initializer-body))))
|
||||
|
||||
(define-values (alias-names alias-map) (get-type-alias-info type-aliases))
|
||||
(register-all-type-aliases alias-names alias-map)
|
||||
|
||||
;; Filter top level expressions into several groups, each processed
|
||||
;; into appropriate data structures
|
||||
;;
|
||||
|
|
|
@ -75,7 +75,10 @@
|
|||
(define-syntax-class internal^
|
||||
#:attributes (value)
|
||||
#:literal-sets (kernel-literals internal-form-literals)
|
||||
(pattern (define-values () (begin (quote-syntax value:expr) (#%plain-app values)))))
|
||||
(pattern (define-values () (begin (quote-syntax value:expr) (#%plain-app values))))
|
||||
;; for use in forms like classes that transform definitions
|
||||
(pattern (let-values ([() (begin (quote-syntax value:expr) (#%plain-app values))])
|
||||
(#%plain-app void))))
|
||||
|
||||
(define-syntax (define-internal-classes stx)
|
||||
(define-syntax-class clause
|
||||
|
|
|
@ -1800,4 +1800,38 @@
|
|||
(: y (Object (field [x Any])))
|
||||
(define y x)
|
||||
(error "foo"))
|
||||
#:msg "parse error in type"]))
|
||||
#:msg "parse error in type"]
|
||||
;; Test type aliases inside class bodies
|
||||
[tc-e (class object%
|
||||
(super-new)
|
||||
(define-type-alias X String)
|
||||
(: x X)
|
||||
(define x "foo"))
|
||||
(-class)]
|
||||
[tc-e (class object%
|
||||
(super-new)
|
||||
(define-type-alias (F X) (Listof X))
|
||||
(: x (F String))
|
||||
(define x (list "foo")))
|
||||
(-class)]
|
||||
[tc-err (let ()
|
||||
(class object%
|
||||
(super-new)
|
||||
(define-type-alias X String)
|
||||
(: x X)
|
||||
(define x "foo"))
|
||||
(: x2 X)
|
||||
(define x2 "bar")
|
||||
(error "foo"))
|
||||
#:msg "type name `X' is unbound"]
|
||||
[tc-e (let ()
|
||||
(class object%
|
||||
(super-new)
|
||||
(define-type-alias X String)
|
||||
(: x X)
|
||||
(define x "foo"))
|
||||
(define-type-alias X Symbol)
|
||||
(: x2 X)
|
||||
(define x2 'bar)
|
||||
(void))
|
||||
-Void]))
|
||||
|
|
Loading…
Reference in New Issue
Block a user