Rework how keyword methods are handled by TR
Override the `define/foo` forms for racket/class to allow type annotations and to use TR's keyword property.
This commit is contained in:
parent
2d81c9667c
commit
4aa438937a
|
@ -35,8 +35,16 @@ additional provides all other bindings from @racketmodname[racket/class].
|
||||||
@;; in certain cases rather than the class defined here
|
@;; in certain cases rather than the class defined here
|
||||||
@(module id-holder racket/base
|
@(module id-holder racket/base
|
||||||
(require scribble/manual (for-label racket/class))
|
(require scribble/manual (for-label racket/class))
|
||||||
(provide class-element)
|
(provide class-element
|
||||||
(define class-element (racket class)))
|
d/p-element d/o-element
|
||||||
|
d/pm-element d/a-element
|
||||||
|
d/pr-element)
|
||||||
|
(define class-element (racket class))
|
||||||
|
(define d/p-element (racket define/public))
|
||||||
|
(define d/o-element (racket define/override))
|
||||||
|
(define d/pm-element (racket define/pubment))
|
||||||
|
(define d/a-element (racket define/augment))
|
||||||
|
(define d/pr-element (racket define/private)))
|
||||||
@(require 'id-holder)
|
@(require 'id-holder)
|
||||||
|
|
||||||
@defform[#:literals (inspect init init-field init-rest field inherit-field
|
@defform[#:literals (inspect init init-field init-rest field inherit-field
|
||||||
|
@ -183,6 +191,39 @@ additional provides all other bindings from @racketmodname[racket/class].
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(define (define/foo-content define/foo)
|
||||||
|
@elem{
|
||||||
|
Like @define/foo from @racketmodname[racket/class], but uses the binding of
|
||||||
|
@racket[define] from Typed Racket.
|
||||||
|
|
||||||
|
The @racket[formals] may specify type annotations as in @racket[define].
|
||||||
|
})
|
||||||
|
|
||||||
|
@defform*[((define/public id expr)
|
||||||
|
(define/public (id . formals) body ...+))]{
|
||||||
|
@define/foo-content[d/p-element]
|
||||||
|
}
|
||||||
|
|
||||||
|
@defform*[((define/override id expr)
|
||||||
|
(define/override (id . formals) body ...+))]{
|
||||||
|
@define/foo-content[d/o-element]
|
||||||
|
}
|
||||||
|
|
||||||
|
@defform*[((define/pubment id expr)
|
||||||
|
(define/pubment (id . formals) body ...+))]{
|
||||||
|
@define/foo-content[d/pm-element]
|
||||||
|
}
|
||||||
|
|
||||||
|
@defform*[((define/augment id expr)
|
||||||
|
(define/augment (id . formals) body ...+))]{
|
||||||
|
@define/foo-content[d/a-element]
|
||||||
|
}
|
||||||
|
|
||||||
|
@defform*[((define/private id expr)
|
||||||
|
(define/private (id . formals) body ...+))]{
|
||||||
|
@define/foo-content[d/pr-element]
|
||||||
|
}
|
||||||
|
|
||||||
@section{Types}
|
@section{Types}
|
||||||
|
|
||||||
@defform[#:literals (init init-field init-rest field augment)
|
@defform[#:literals (init init-field init-rest field augment)
|
||||||
|
|
|
@ -278,9 +278,12 @@
|
||||||
(template ((?@ . mand.form) ... (?@ . opt.form) ... . rest.form))))
|
(template ((?@ . mand.form) ... (?@ . opt.form) ... . rest.form))))
|
||||||
|
|
||||||
(define-syntax-class curried-formals
|
(define-syntax-class curried-formals
|
||||||
#:attributes (erased)
|
#:attributes (erased fun-name)
|
||||||
(pattern fun:id #:with erased #'fun)
|
(pattern fun:id
|
||||||
|
#:with fun-name #'fun
|
||||||
|
#:with erased #'fun)
|
||||||
(pattern (fun:curried-formals . formals:lambda-formals)
|
(pattern (fun:curried-formals . formals:lambda-formals)
|
||||||
|
#:with fun-name #'fun.fun-name
|
||||||
#:with erased #`(fun.erased . #,(attribute formals.erased))))
|
#:with erased #`(fun.erased . #,(attribute formals.erased))))
|
||||||
|
|
||||||
(define-splicing-syntax-class return-ann
|
(define-splicing-syntax-class return-ann
|
||||||
|
|
|
@ -2,9 +2,17 @@
|
||||||
|
|
||||||
;; This module provides TR primitives for classes and objects
|
;; This module provides TR primitives for classes and objects
|
||||||
|
|
||||||
(require (rename-in racket/class [class untyped-class])
|
(require (rename-in (except-in racket/class
|
||||||
|
define/public
|
||||||
|
define/override
|
||||||
|
define/pubment
|
||||||
|
define/augment
|
||||||
|
define/private)
|
||||||
|
[class untyped-class])
|
||||||
"colon.rkt"
|
"colon.rkt"
|
||||||
"../typecheck/internal-forms.rkt"
|
"../typecheck/internal-forms.rkt"
|
||||||
|
"../private/class-literals.rkt"
|
||||||
|
(only-in "prims.rkt" [define tr:define])
|
||||||
(for-syntax
|
(for-syntax
|
||||||
racket/base
|
racket/base
|
||||||
racket/class
|
racket/class
|
||||||
|
@ -23,21 +31,35 @@
|
||||||
syntax/parse
|
syntax/parse
|
||||||
syntax/stx
|
syntax/stx
|
||||||
unstable/list
|
unstable/list
|
||||||
|
"annotate-classes.rkt"
|
||||||
"../private/syntax-properties.rkt"
|
"../private/syntax-properties.rkt"
|
||||||
"../utils/tc-utils.rkt"))
|
"../utils/tc-utils.rkt"))
|
||||||
|
|
||||||
(provide ;; Typed class macro that coordinates with TR
|
(provide ;; Typed class macro that coordinates with TR
|
||||||
class
|
class
|
||||||
;; for use in ~literal clauses
|
;; override these macros to use TR define
|
||||||
class-internal
|
define/public
|
||||||
:-augment)
|
define/override
|
||||||
|
define/pubment
|
||||||
|
define/augment
|
||||||
|
define/private)
|
||||||
|
|
||||||
;; give it a binding, but it shouldn't be used directly
|
;; overriden forms
|
||||||
(define-syntax (class-internal stx)
|
(define-syntax-rule (define-define/class-kw ((?id ?class-kw) ...))
|
||||||
(raise-syntax-error 'class "should only be used internally"))
|
(begin (define-syntax (?id stx)
|
||||||
|
(syntax-parse stx
|
||||||
|
[(_ ??header:curried-formals . ??body)
|
||||||
|
(quasisyntax/loc stx
|
||||||
|
(begin (tr:define ??header . ??body)
|
||||||
|
(?class-kw ??header.fun-name)))]))
|
||||||
|
...))
|
||||||
|
|
||||||
(define-syntax (:-augment stx)
|
(define-define/class-kw
|
||||||
(raise-syntax-error 'class "should only be used internally"))
|
([define/public public]
|
||||||
|
[define/override override]
|
||||||
|
[define/pubment pubment]
|
||||||
|
[define/augment augment]
|
||||||
|
[define/private private]))
|
||||||
|
|
||||||
(begin-for-syntax
|
(begin-for-syntax
|
||||||
;; forms that are not allowed by Typed Racket yet
|
;; forms that are not allowed by Typed Racket yet
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require (for-syntax racket/base))
|
||||||
|
|
||||||
|
(provide ;; for use in ~literal clauses
|
||||||
|
class-internal
|
||||||
|
:-augment)
|
||||||
|
|
||||||
|
;; give it a binding, but it shouldn't be used directly
|
||||||
|
(define-syntax (class-internal stx)
|
||||||
|
(raise-syntax-error 'class "should only be used internally"))
|
||||||
|
|
||||||
|
(define-syntax (:-augment stx)
|
||||||
|
(raise-syntax-error 'class "should only be used internally"))
|
|
@ -14,7 +14,6 @@
|
||||||
syntax/stx
|
syntax/stx
|
||||||
"signatures.rkt"
|
"signatures.rkt"
|
||||||
(private parse-type syntax-properties type-annotation)
|
(private parse-type syntax-properties type-annotation)
|
||||||
(base-env class-prims)
|
|
||||||
(env lexical-env tvar-env)
|
(env lexical-env tvar-env)
|
||||||
(types utils abbrev union subtype resolve generalize)
|
(types utils abbrev union subtype resolve generalize)
|
||||||
(typecheck check-below internal-forms)
|
(typecheck check-below internal-forms)
|
||||||
|
@ -22,7 +21,7 @@
|
||||||
(rep type-rep)
|
(rep type-rep)
|
||||||
(for-syntax racket/base)
|
(for-syntax racket/base)
|
||||||
(for-template racket/base
|
(for-template racket/base
|
||||||
(base-env class-prims)
|
(private class-literals)
|
||||||
(typecheck internal-forms)))
|
(typecheck internal-forms)))
|
||||||
|
|
||||||
(import tc-if^ tc-lambda^ tc-app^ tc-let^ tc-expr^)
|
(import tc-if^ tc-lambda^ tc-app^ tc-let^ tc-expr^)
|
||||||
|
@ -886,6 +885,9 @@
|
||||||
;; type-check pubments/augments.
|
;; type-check pubments/augments.
|
||||||
[(set-member? names-to-check external-name)
|
[(set-member? names-to-check external-name)
|
||||||
(do-timestamp (format "started checking method ~a" external-name))
|
(do-timestamp (format "started checking method ~a" external-name))
|
||||||
|
;; FIXME: this case doesn't work very well yet for keyword methods
|
||||||
|
;; because TR can't recognize that the expansion is a kw
|
||||||
|
;; function (unlike the expected case).
|
||||||
(define type (tc-expr/t meth))
|
(define type (tc-expr/t meth))
|
||||||
(do-timestamp (format "finished method ~a" external-name))
|
(do-timestamp (format "finished method ~a" external-name))
|
||||||
(cons (list external-name
|
(cons (list external-name
|
||||||
|
@ -1415,12 +1417,13 @@
|
||||||
(#%plain-lambda (#,annotated-self-param . params)
|
(#%plain-lambda (#,annotated-self-param . params)
|
||||||
body ...))])
|
body ...))])
|
||||||
m)]
|
m)]
|
||||||
[(let-values ([(meth-name:id)
|
[(~and (let-values ([(meth-name:id)
|
||||||
(let-values (((core:id)
|
(let-values (((core:id)
|
||||||
(#%plain-lambda params
|
(#%plain-lambda params
|
||||||
core-body ...)))
|
core-body ...)))
|
||||||
method-body ...)])
|
method-body ...)])
|
||||||
m)
|
m)
|
||||||
|
kw:kw-lambda^)
|
||||||
#`(let-values ([(#,(type-label-property #'meth-name method-type))
|
#`(let-values ([(#,(type-label-property #'meth-name method-type))
|
||||||
#,(kw-lambda-property
|
#,(kw-lambda-property
|
||||||
#`(let-values (((core)
|
#`(let-values (((core)
|
||||||
|
@ -1429,7 +1432,7 @@
|
||||||
(#%plain-lambda params
|
(#%plain-lambda params
|
||||||
core-body ...))))
|
core-body ...))))
|
||||||
method-body ...)
|
method-body ...)
|
||||||
#t)])
|
(attribute kw.value))])
|
||||||
m)]
|
m)]
|
||||||
;; case-lambda methods
|
;; case-lambda methods
|
||||||
[(let-values ([(meth-name:id)
|
[(let-values ([(meth-name:id)
|
||||||
|
|
|
@ -1,7 +1,18 @@
|
||||||
#lang racket/base
|
#lang racket/base
|
||||||
|
|
||||||
(require (except-in racket/class class)
|
(require (except-in racket/class
|
||||||
|
class
|
||||||
|
define/public
|
||||||
|
define/override
|
||||||
|
define/pubment
|
||||||
|
define/augment
|
||||||
|
define/private)
|
||||||
typed-racket/base-env/class-prims)
|
typed-racket/base-env/class-prims)
|
||||||
|
|
||||||
(provide class
|
(provide class
|
||||||
|
define/public
|
||||||
|
define/override
|
||||||
|
define/pubment
|
||||||
|
define/augment
|
||||||
|
define/private
|
||||||
(all-from-out racket/class))
|
(all-from-out racket/class))
|
||||||
|
|
|
@ -17,7 +17,9 @@
|
||||||
|
|
||||||
;; see typecheck-tests.rkt for rationale on imports
|
;; see typecheck-tests.rkt for rationale on imports
|
||||||
(require rackunit
|
(require rackunit
|
||||||
(except-in racket/class class)
|
(except-in racket/class
|
||||||
|
class define/public define/override
|
||||||
|
define/pubment define/augment define/private)
|
||||||
(except-in typed-racket/utils/utils private)
|
(except-in typed-racket/utils/utils private)
|
||||||
(except-in (base-env extra-procs prims class-prims
|
(except-in (base-env extra-procs prims class-prims
|
||||||
base-types base-types-extra)
|
base-types base-types-extra)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user