From c0c97a60904258509a49612fa749ec7a56a2d83d Mon Sep 17 00:00:00 2001
From: Matthew Flatt <mflatt@racket-lang.org>
Date: Tue, 5 Feb 2008 16:33:26 +0000
Subject: [PATCH] add #:use-sources to Scribble module declarations, so that
 scheme/base and mzscheme can better share documentation; finish documenting
 legacy mzscheme bindings

svn: r8538

original commit: 794e6c8a398da5857097795ff5c8d022bf55fed2
---
 collects/scribble/manual.ss                | 80 ++++++++++++++++------
 collects/scribblings/scribble/manual.scrbl | 52 ++++++++++----
 2 files changed, 98 insertions(+), 34 deletions(-)

diff --git a/collects/scribble/manual.ss b/collects/scribble/manual.ss
index 77b6fbc9..daf0434b 100644
--- a/collects/scribble/manual.ss
+++ b/collects/scribble/manual.ss
@@ -108,10 +108,15 @@
                 #f
                 (list . content)))
 
-  (define-syntax-rule (defmodule* (name ...) . content)
-    (begin
-      (declare-exporting name ...)
-      (defmodule*/no-declare (name ...) . content)))
+  (define-syntax defmodule*
+    (syntax-rules ()
+      [(_ (name ...) #:use-sources (pname ...) . content)
+       (begin
+         (declare-exporting name ... #:use-sources (pname ...))
+         (defmodule*/no-declare (name ...) . content))]
+      [(_ (name ...) . content)
+       (defmodule* (name ...) #:use-sources () . content)]))
+      
 
   (define-syntax-rule (defmodule name . content)
     (defmodule* (name) . content))
@@ -121,10 +126,14 @@
                 #t
                 (list . content)))
 
-  (define-syntax-rule (defmodulelang* (name ...) . content)
-    (begin
-      (declare-exporting name ...)
-      (defmodulelang*/no-declare (name ...) . content)))
+  (define-syntax defmodulelang* 
+    (syntax-rules ()
+      [(_ (name ...) #:use-sources (pname ...) . content)
+       (begin
+         (declare-exporting name ... #:use-sources (pname ...))
+         (defmodulelang*/no-declare (name ...) . content))]
+      [(_ (name ...) . content)
+       (defmodulelang* (name ...) #:use-sources () . content)]))
 
   (define-syntax-rule (defmodulelang lang . content)
     (defmodulelang* (lang) . content))
@@ -338,14 +347,38 @@
           (annote-exporting-library
            (to-element (make-just-context name stx-id))))))
 
-  (define (libs->taglet libs)
-    (and (pair? libs)
-         (let ([p (resolved-module-path-name
-                   (module-path-index-resolve
-                    (module-path-index-join (car libs) #f)))])
-           (if (path? p)
-               (intern-taglet (path->main-collects-relative p))
-               p))))
+  (define checkers (make-hash-table 'equal))
+
+  (define (libs->taglet id libs source-libs)
+    (let ([lib 
+           (or (ormap (lambda (lib)
+                        (let ([checker (hash-table-get checkers lib
+                                                       (lambda ()
+                                                         (let ([ns (make-base-empty-namespace)])
+                                                           (parameterize ([current-namespace ns])
+                                                             (namespace-require `(for-label ,lib)))
+                                                           (let ([checker
+                                                                  (lambda (id)
+                                                                    (parameterize ([current-namespace ns])
+                                                                      (let ([new-id (namespace-syntax-introduce
+                                                                                     (datum->syntax
+                                                                                      #f
+                                                                                      (syntax-e id)))])
+                                                                        (free-label-identifier=? new-id id))))])
+                                                             (hash-table-put! checkers lib checker)
+                                                             checker))))])
+                          (and (checker id)
+                               lib)))
+                      source-libs)
+               (and (pair? libs)
+                    (car libs)))])
+      (and lib
+           (let ([p (resolved-module-path-name
+                     (module-path-index-resolve
+                      (module-path-index-join lib #f)))])
+             (if (path? p)
+                 (intern-taglet (path->main-collects-relative p))
+                 p)))))
 
   (define (id-to-target-maker id dep?)
     (*id-to-target-maker 'def id dep?))
@@ -373,7 +406,11 @@
                                      "no declared exporting libraries for definition"
                                      id)))
              (if e
-                 (let* ([lib-taglet (libs->taglet (exporting-libraries-libs e))]
+                 (let* ([lib-taglet (libs->taglet (if sig
+                                                      (sig-id sig)
+                                                      id)
+                                                  (exporting-libraries-libs e)
+                                                  (exporting-libraries-source-libs e))]
                         [tag (list (if sig
                                        (case sym
                                          [(def) 'sig-val]
@@ -529,11 +566,12 @@
 
   (define-syntax declare-exporting
     (syntax-rules ()
-      [(_ lib ...) (*declare-exporting '(lib ...))]))
+      [(_ lib ... #:use-sources (plib ...)) (*declare-exporting '(lib ...) '(plib ...))]
+      [(_ lib ...) (*declare-exporting '(lib ...) '())]))
 
-  (define-struct (exporting-libraries element) (libs))
+  (define-struct (exporting-libraries element) (libs source-libs))
 
-  (define (*declare-exporting libs)
+  (define (*declare-exporting libs source-libs)
     (make-splice
      (list
       (make-part-collect-decl
@@ -542,7 +580,7 @@
                              (lambda (ri)
                                (collect-put! ri '(exporting-libraries #f) libs))))
       (make-part-collect-decl
-       (make-exporting-libraries #f null libs)))))
+       (make-exporting-libraries #f null libs source-libs)))))
 
   (define-syntax (quote-syntax/loc stx)
     (syntax-case stx ()
diff --git a/collects/scribblings/scribble/manual.scrbl b/collects/scribblings/scribble/manual.scrbl
index b84632be..b6306d14 100644
--- a/collects/scribblings/scribble/manual.scrbl
+++ b/collects/scribblings/scribble/manual.scrbl
@@ -184,7 +184,8 @@ in a form definition.}
 @; ------------------------------------------------------------------------
 @section[#:tag "doc-modules"]{Documenting Modules}
 
-@defform[(defmodule id pre-flow ...)]{
+@defform/subs[(defmodule id maybe-sources pre-flow ...)
+              ([maybe-sources #:use-sources (mod-path ...)])]
 
 Produces a sequence of flow elements (encaptured in a @scheme[splice])
 to start the documentation for a module that can be @scheme[require]d
@@ -192,27 +193,29 @@ using the path @scheme[id]. The @tech{decode}d @scheme[pre-flow]s
 introduce the module, but need not include all of the module content.
 
 Besides generating text, this form expands to a use of
-@scheme[declare-exporting] with @scheme[id]. Consequently,
-@scheme[defmodule] should be used at most once in a section, though it
-can be shadowed with @scheme[defmodule]s in sub-sections.
+@scheme[declare-exporting] with @scheme[id]; the
+@scheme[#:use-sources] clause, if provided, is propagated to
+@scheme[declare-exporting]. Consequently, @scheme[defmodule] should be
+used at most once in a section, though it can be shadowed with
+@scheme[defmodule]s in sub-sections.
 
 Hyperlinks created by @scheme[schememodname] are associated with the
 enclosing section, rather than the local @scheme[id] text.}
 
 
-@defform[(defmodulelang id pre-flow ...)]{
+@defform[(defmodulelang id maybe-sources pre-flow ...)]{
 
 Like @scheme[defmodule], but documents @scheme[id] as a module path
 suitable for use by either @scheme[require] or @schememodfont{#lang}.}
 
 
-@defform[(defmodule* (id ...) pre-flow ...)]{
+@defform[(defmodule* (id ...) maybe-sources pre-flow ...)]{
 
 Like @scheme[defmodule], but introduces multiple module paths instead
 of just one.}
 
 
-@defform[(defmodulelang* (id ...) pre-flow ...)]{
+@defform[(defmodulelang* (id ...) maybe-sources pre-flow ...)]{
 
 Like @scheme[defmodulelang], but introduces multiple module paths
 instead of just one.}
@@ -233,13 +236,36 @@ Like @scheme[defmodulelang*], but without expanding to
 @scheme[declare-exporting].}
 
 
-@defform[(declare-exporting module-path ...)]{
-
-Associates the @scheme[module-paths]s to all bindings defined within
-the enclosing section, except as overridden by other
+@defform/subs[(declare-exporting mod-path ... maybe-sources)
+              ([maybe-sources #:use-sources (mod-path ...)])]{
+                                 
+Associates the @scheme[mod-path]s to all bindings defined within the
+enclosing section, except as overridden by other
 @scheme[declare-exporting] declarations in nested sub-sections.  The
-list of @scheme[module-path]s is shown, for example, when the user
-hovers the mouse over one of the bindings defined within the section.
+list of @scheme[mod-path]s is shown, for example, when the user hovers
+the mouse over one of the bindings defined within the section.
+
+More significantly, the first @scheme[mod-path] plus the
+@scheme[#:use-sources] @scheme[mod-path]s determine the binding that
+is documented by each @scheme[defform], @scheme[defproc], or similar
+form within the section that contains the @scheme[declare-exporting]
+declaration:
+
+@itemize{
+
+ @item{If no @scheme[#:use-sources] clause is supplied, then the
+       documentation applies to the given name as exported by the first
+       @scheme[mod-path].}
+
+ @item{If @scheme[#:use-sources] @scheme[mod-path]s are supplied, then
+       they are tried in order. The first one to provide an export
+       with the same symbolic name and
+       @scheme[free-label-identifier=?] to the given name is used as
+       the documented binding. This binding is assumed to be the same
+       as the identifier as exported by the first @scheme[mod-path] in
+       the @scheme[declare-exporting] declaration.}
+
+}
 
 The @scheme[declare-exporting] form should be used no more than once
 per section, since the declaration applies to the entire section,