serializable-struct, etc.: export deserialization info in submodule
This change is slightly incompatible, because `serializable-struct`, `define-serializable-struct`, and `define-serializable-class` no longer `provide` and identifier that they used to. Instead, the identifier is provided by a `deserialize-info` submodule. The deserializer looks for a `deserialize-info` submodule, and then falls back to using a module if the submodule is not available.
This commit is contained in:
parent
0bc89dc641
commit
90142edc5b
|
@ -1,7 +1,8 @@
|
|||
(module serialize mzscheme
|
||||
(require-for-syntax syntax/struct)
|
||||
(require ;; core [de]serializer:
|
||||
racket/private/serialize)
|
||||
racket/private/serialize
|
||||
(only racket/base module+))
|
||||
|
||||
(provide define-serializable-struct
|
||||
define-serializable-struct/versions
|
||||
|
@ -361,7 +362,7 @@
|
|||
#`(begin
|
||||
(define deserializer-id (make-deserialize-info #,(cadr other-version)
|
||||
#,(caddr other-version)))
|
||||
#,@(make-deserialize-provide stx #'deserializer-id))))
|
||||
#,@(make-deserialize-provide stx #'deserializer-id))))
|
||||
|
||||
(define (make-deserialize-name id version-num)
|
||||
(datum->syntax-object
|
||||
|
@ -379,9 +380,10 @@
|
|||
(list (quasisyntax/loc stx
|
||||
(namespace-set-variable-value! '#,deserializer-id-stx
|
||||
#,deserializer-id-stx )))
|
||||
;; In a module; provide:
|
||||
;; In a module; provide via submodule:
|
||||
(list (quasisyntax/loc stx
|
||||
(provide #,deserializer-id-stx)))))
|
||||
(module+ deserialize-info
|
||||
(provide #,deserializer-id-stx))))))
|
||||
|
||||
;; ------------------------------
|
||||
;; The transformers
|
||||
|
|
|
@ -2249,7 +2249,7 @@ This form can only be used at the top level, either within a module
|
|||
or outside. The @racket[class-id] identifier is bound to the new
|
||||
class, and @racketidfont{deserialize-info:}@racket[class-id] is also
|
||||
defined; if the definition is within a module, then the latter is
|
||||
provided from the module.
|
||||
provided from a @racket[deserialize-info] submodule via @racket[module+].
|
||||
|
||||
Serialization for the class works in one of two ways:
|
||||
|
||||
|
|
|
@ -392,7 +392,8 @@ In addition to the bindings generated by @racket[struct],
|
|||
@racket[serializable-struct] binds
|
||||
@racketidfont{deserialize-info:}@racket[_id]@racketidfont{-v0} to
|
||||
deserialization information. Furthermore, in a module context, it
|
||||
automatically @racket[provide]s this binding.
|
||||
automatically @racket[provide]s this binding in a @racket[deserialize-info]
|
||||
submodule using @racket[module+].
|
||||
|
||||
The @racket[serializable-struct] form enables the construction of
|
||||
structure instances from places where @racket[id] is not accessible,
|
||||
|
@ -550,7 +551,10 @@ must be one of the following:
|
|||
@item{If @racket[deserialize-id] is an identifier, and if
|
||||
@racket[(identifier-binding deserialize-id)] produces a list, then
|
||||
the third element is used for the exporting module, otherwise the
|
||||
top-level is assumed. In either case, @racket[syntax-e] is used to
|
||||
top-level is assumed. Before trying an exporting module directly,
|
||||
its @racket[deserialize-info] submodule is tried; the module
|
||||
itself is tried if no @racket[deserialize-info]
|
||||
submodule is available. In either case, @racket[syntax-e] is used to
|
||||
obtain the name of an exported identifier or top-level definition.}
|
||||
|
||||
@item{If @racket[deserialize-id] is a symbol, it indicates a
|
||||
|
|
|
@ -478,6 +478,47 @@
|
|||
|
||||
;; ----------------------------------------
|
||||
|
||||
;; Custom deserialize:
|
||||
(module my-own-deserialize racket/base
|
||||
(require racket/serialize)
|
||||
(provide a
|
||||
deserialize-info)
|
||||
(struct a ()
|
||||
#:property prop:serializable
|
||||
(make-serialize-info (lambda (v) #())
|
||||
#'deserialize-info
|
||||
#f
|
||||
(or (current-load-relative-directory)
|
||||
(current-directory))))
|
||||
(define deserialize-info
|
||||
(make-deserialize-info (lambda () 'a)
|
||||
(lambda () (values 'a void)))))
|
||||
|
||||
(require 'my-own-deserialize)
|
||||
(test 'a deserialize (serialize (a)))
|
||||
|
||||
;; Same thing, but with submodule:
|
||||
(module my-own-deserialize/sub racket/base
|
||||
(require racket/serialize)
|
||||
(provide b)
|
||||
(module+ deserialize-info
|
||||
(provide deserialize-info))
|
||||
(struct b ()
|
||||
#:property prop:serializable
|
||||
(make-serialize-info (lambda (v) #())
|
||||
#'deserialize-info
|
||||
#f
|
||||
(or (current-load-relative-directory)
|
||||
(current-directory))))
|
||||
(define deserialize-info
|
||||
(make-deserialize-info (lambda () 'b)
|
||||
(lambda () (values 'b void)))))
|
||||
|
||||
(require 'my-own-deserialize/sub)
|
||||
(test 'b deserialize (serialize (b)))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
(let ([fn (make-temporary-file)])
|
||||
(with-output-to-file fn
|
||||
#:exists 'truncate
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
make-page-target-element make-redirect-target-element make-link-element
|
||||
make-index-element
|
||||
make-target-url target-url struct:target-url target-url? target-url-addr
|
||||
deserialize-info:target-url-v0
|
||||
toc-element-toc-content part-title-content paragraph-content
|
||||
element? element-content element-style)
|
||||
(for-label scribble/manual-struct
|
||||
|
|
|
@ -352,7 +352,8 @@
|
|||
[sizer (-> any)]
|
||||
[plain (-> any)])))
|
||||
|
||||
(provide deserialize-delayed-element)
|
||||
(module+ deserialize-info
|
||||
(provide deserialize-delayed-element))
|
||||
(define deserialize-delayed-element
|
||||
(make-deserialize-info values values))
|
||||
|
||||
|
@ -396,7 +397,8 @@
|
|||
[sizer (-> any)]
|
||||
[plain (-> any)])))
|
||||
|
||||
(provide deserialize-part-relative-element)
|
||||
(module+ deserialize-info
|
||||
(provide deserialize-part-relative-element))
|
||||
(define deserialize-part-relative-element
|
||||
(make-deserialize-info values values))
|
||||
|
||||
|
@ -437,7 +439,8 @@
|
|||
(provide/contract
|
||||
(struct delayed-index-desc ([resolve (any/c part? resolve-info? . -> . any)])))
|
||||
|
||||
(provide deserialize-delayed-index-desc)
|
||||
(module+ deserialize-info
|
||||
(provide deserialize-delayed-index-desc))
|
||||
(define deserialize-delayed-index-desc
|
||||
(make-deserialize-info values values))
|
||||
|
||||
|
@ -457,7 +460,8 @@
|
|||
(or (current-load-relative-directory) (current-directory)))
|
||||
#:transparent)
|
||||
|
||||
(provide deserialize-collect-element)
|
||||
(module+ deserialize-info
|
||||
(provide deserialize-collect-element))
|
||||
(define deserialize-collect-element
|
||||
(make-deserialize-info values values))
|
||||
|
||||
|
@ -481,7 +485,8 @@
|
|||
(or (current-load-relative-directory) (current-directory)))
|
||||
#:transparent)
|
||||
|
||||
(provide deserialize-render-element)
|
||||
(module+ deserialize-info
|
||||
(provide deserialize-render-element))
|
||||
(define deserialize-render-element
|
||||
(make-deserialize-info values values))
|
||||
|
||||
|
@ -513,7 +518,8 @@
|
|||
|
||||
(provide (struct-out generated-tag))
|
||||
|
||||
(provide deserialize-generated-tag)
|
||||
(module+ deserialize-info
|
||||
(provide deserialize-generated-tag))
|
||||
(define deserialize-generated-tag
|
||||
(make-deserialize-info values values))
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#lang scheme/base
|
||||
(require (rename-in (except-in "core.rkt"
|
||||
target-url struct:target-url target-url? target-url-addr
|
||||
deserialize-info:target-url-v0)
|
||||
target-url struct:target-url target-url? target-url-addr)
|
||||
[make-target-url core:make-target-url])
|
||||
"private/provide-structs.rkt"
|
||||
"html-properties.rkt"
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
syntax/stx)
|
||||
racket/promise
|
||||
racket/serialize
|
||||
racket/runtime-path
|
||||
ffi/unsafe
|
||||
(only-in '#%foreign ctype-c->scheme))
|
||||
|
||||
|
@ -67,7 +68,7 @@
|
|||
[serialize-inplace (and (attribute serialize-inplace-kw) #t)]
|
||||
[deserialize-inplace (and (attribute deserialize-inplace-kw) #t)])
|
||||
|
||||
(syntax/loc stx
|
||||
(quasisyntax/loc stx
|
||||
(begin
|
||||
;; the wrapped cstruct
|
||||
(define-cstruct _ID ([field-id type-expr] ...)
|
||||
|
@ -99,7 +100,10 @@
|
|||
(malloc _ID malloc-mode)))
|
||||
|
||||
;; deserialization proc
|
||||
(provide deser-ID)
|
||||
#,@(if (eq? (syntax-local-context) 'module)
|
||||
#`((runtime-require (submod "." deserialize-info))
|
||||
(module+ deserialize-info (provide deser-ID)))
|
||||
null)
|
||||
(define deser-ID (id->deserialize-info _ID _ID-pointer deserialize-inplace malloc-ID))
|
||||
|
||||
;; mode-aware make-ID
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
Version 5.90.0.10
|
||||
Changed serializable-struct, etc. to provide deserialized-info:...
|
||||
through a derialized-info submodule
|
||||
Added chaperone-channel and impersonate-channel
|
||||
Change string->path-element and bytes->path-element to raise an
|
||||
exception for an empty [byte-]string argument
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
racket/stxparam
|
||||
racket/unsafe/ops
|
||||
"serialize-structs.rkt"
|
||||
racket/runtime-path
|
||||
(for-syntax racket/stxparam
|
||||
syntax/kerncase
|
||||
syntax/stx
|
||||
|
@ -1711,7 +1712,8 @@
|
|||
#'orig-stx))
|
||||
(with-syntax ([deserialize-name-info deserialize-name-info]
|
||||
[(provision ...) (if (eq? (syntax-local-context) 'module)
|
||||
#`((provide #,deserialize-name-info))
|
||||
#`((runtime-require (submod "." deserialize-info))
|
||||
(module+ deserialize-info (provide #,deserialize-name-info)))
|
||||
#'())])
|
||||
#'(begin
|
||||
(define-values (name deserialize-name-info)
|
||||
|
|
|
@ -73,6 +73,16 @@
|
|||
`(submod ,(unprotect-path (cadr p)) . ,(cddr p))]
|
||||
[else p]))
|
||||
|
||||
;; A deserialization function is provided from a `deserialize-info`
|
||||
;; module:
|
||||
(define (add-submodule p)
|
||||
(module-path-index-join '(submod "." deserialize-info)
|
||||
(if (resolved-module-path? p)
|
||||
p
|
||||
(module-path-index-join
|
||||
p
|
||||
#f))))
|
||||
|
||||
(define (revive-symbol s)
|
||||
(if (string? s)
|
||||
(string->unreadable-symbol s)
|
||||
|
@ -648,7 +658,12 @@
|
|||
(let ([p (unprotect-path (car path+name))]
|
||||
[sym (revive-symbol (cdr path+name))])
|
||||
((deserialize-module-guard) p sym)
|
||||
(dynamic-require p sym))
|
||||
(let ([sub (add-submodule p)])
|
||||
(if (module-declared? sub #t)
|
||||
(dynamic-require sub sym)
|
||||
;; On failure, for backward compatibility,
|
||||
;; try module instead of submodule:
|
||||
(dynamic-require p sym))))
|
||||
(namespace-variable-value (cdr path+name)))])
|
||||
;; Register maker and struct type:
|
||||
(vector-set! mod-map n des))
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
(module serialize racket/base
|
||||
(require "private/serialize.rkt"
|
||||
(for-syntax racket/base
|
||||
racket/struct-info))
|
||||
racket/struct-info)
|
||||
racket/runtime-path)
|
||||
|
||||
(provide (all-from-out "private/serialize.rkt")
|
||||
serializable-struct
|
||||
|
@ -191,16 +192,25 @@
|
|||
(syntax->list #'(make-proc-expr ...))
|
||||
(syntax->list #'(cycle-make-proc-expr ...)))
|
||||
;; =============== provide ===============
|
||||
#,@(map (lambda (deserialize-id)
|
||||
(if (eq? 'top-level (syntax-local-context))
|
||||
;; Top level; in case deserializer-id-stx is macro-introduced,
|
||||
;; explicitly use namespace-set-variable-value!
|
||||
#`(namespace-set-variable-value! '#,deserialize-id
|
||||
#,deserialize-id)
|
||||
;; In a module; provide:
|
||||
#`(provide #,deserialize-id)))
|
||||
(cons deserialize-id
|
||||
other-deserialize-ids))))]
|
||||
;; If we're in a module context, then provide through
|
||||
;; a submodule:
|
||||
(#,@(if (eq? 'top-level (syntax-local-context))
|
||||
#'(begin)
|
||||
#'(module+ deserialize-info))
|
||||
#,@(map (lambda (deserialize-id)
|
||||
(if (eq? 'top-level (syntax-local-context))
|
||||
;; Top level; in case deserializer-id-stx is macro-introduced,
|
||||
;; explicitly use namespace-set-variable-value!
|
||||
#`(namespace-set-variable-value! '#,deserialize-id
|
||||
#,deserialize-id)
|
||||
;; In a module; provide:
|
||||
#`(provide #,deserialize-id)))
|
||||
(cons deserialize-id
|
||||
other-deserialize-ids)))
|
||||
;; Make sure submodule is pulled along for run time:
|
||||
#,@(if (eq? 'top-level (syntax-local-context))
|
||||
null
|
||||
#'((runtime-require (submod "." deserialize-info))))))]
|
||||
;; -- More error cases ---
|
||||
;; Check fields
|
||||
[(_ orig-stx id/sup vers fields . _rest)
|
||||
|
|
Loading…
Reference in New Issue
Block a user