From 5b3d8c132d80b907773cd39d10943868688d0850 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Wed, 7 Jun 2023 11:23:05 -0500 Subject: [PATCH 01/62] mwe including `export (scoped-true), a, b, c` and `names` module CreatePairs export create_pair export (scoped-true), cp """ create_pair(x) creates the pair `x => x` """ create_pair(x) = _create_pair(x) """ cp(x) creates the pair `x => x` """ cp(x) = _create_pair(x) """ _create_pair(x) creates the pair `x => x` """ _create_pair(x) = x => x end julia> using .CreatePairs julia> names(CreatePairs) 3-element Vector{Symbol}: :CreatePairs :cp :create_pair julia> names(CreatePairs, scoped=false) 2-element Vector{Symbol}: :CreatePairs :create_pair julia> create_pair(1) 1 => 1 julia> cp(1) ERROR: MethodError: no method matching cp(::Int64) Closest candidates are: cp(::AbstractString, ::AbstractString; force, follow_symlinks) @ Base file.jl:376 Stacktrace: [1] top-level scope @ REPL[7]:1 julia> CreatePairs.cp(1) 1 => 1 julia> _create_pair(1) ERROR: UndefVarError: `_create_pair` not defined Stacktrace: [1] top-level scope @ REPL[9]:1 julia> CreatePairs._create_pair(1) 1 => 1 help?> create_pair search: create_pair create_pair(x) creates the pair x => x help?> CreatePairs.cp cp(x) creates the pair x => x help?> CreatePairs._create_pair _create_pair(x) creates the pair x => x --- base/reflection.jl | 8 ++++---- src/builtins.c | 2 +- src/julia-parser.scm | 4 ++-- src/julia.h | 5 +++-- src/module.c | 10 ++++++---- src/toplevel.c | 7 +++++-- 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/base/reflection.jl b/base/reflection.jl index 5268beddeb8eb..ddb1534bede8b 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -86,10 +86,10 @@ since it is not idiomatic to explicitly export names from `Main`. See also: [`@locals`](@ref Base.@locals), [`@__MODULE__`](@ref). """ -names(m::Module; all::Bool = false, imported::Bool = false) = - sort!(unsorted_names(m; all, imported)) -unsorted_names(m::Module; all::Bool = false, imported::Bool = false) = - ccall(:jl_module_names, Array{Symbol,1}, (Any, Cint, Cint), m, all, imported) +names(m::Module; all::Bool = false, imported::Bool = false, scoped::Bool = true) = + sort!(unsorted_names(m; all, imported, scoped)) +unsorted_names(m::Module; all::Bool = false, imported::Bool = false, scoped::Bool = true) = + ccall(:jl_module_names, Array{Symbol,1}, (Any, Cint, Cint, Cint), m, all, imported, scoped) isexported(m::Module, s::Symbol) = ccall(:jl_module_exports_p, Cint, (Any, Any), m, s) != 0 isdeprecated(m::Module, s::Symbol) = ccall(:jl_is_binding_deprecated, Cint, (Any, Any), m, s) != 0 diff --git a/src/builtins.c b/src/builtins.c index b664b8d73710f..b779bac2ef636 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1929,7 +1929,7 @@ static void add_intrinsic(jl_module_t *inm, const char *name, enum intrinsic f) jl_value_t *i = jl_permbox32(jl_intrinsic_type, 0, (int32_t)f); jl_sym_t *sym = jl_symbol(name); jl_set_const(inm, sym, i); - jl_module_export(inm, sym); + jl_module_export(inm, sym, 0); } void jl_init_intrinsic_properties(void) JL_GC_DISABLED diff --git a/src/julia-parser.scm b/src/julia-parser.scm index 210ba8f0ae07b..28a9d4806b252 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -1617,8 +1617,8 @@ ((export) (let ((es (map macrocall-to-atsym (parse-comma-separated s parse-unary-prefix)))) - (if (not (every symbol-or-interpolate? es)) - (error "invalid \"export\" statement")) + ; (if (not (every symbol-or-interpolate? es)) ; TODO make this much more strict + ; (error "invalid \"export\" statement")) `(export ,@es))) ((import using) (parse-imports s word)) diff --git a/src/julia.h b/src/julia.h index 694a8d81b06e9..389279a7c2b1b 100644 --- a/src/julia.h +++ b/src/julia.h @@ -595,10 +595,11 @@ typedef struct _jl_binding_t { _Atomic(jl_value_t*) ty; // binding type uint8_t constp:1; uint8_t exportp:1; + uint8_t scoped_exportp:1; // `scoped export foo` sets both `exportp` and `scoped_exportp`. uint8_t imported:1; uint8_t usingfailed:1; uint8_t deprecated:2; // 0=not deprecated, 1=renamed, 2=moved to another package - uint8_t padding:2; + uint8_t padding:1; } jl_binding_t; typedef struct { @@ -1736,7 +1737,7 @@ JL_DLLEXPORT void jl_module_use(jl_module_t *to, jl_module_t *from, jl_sym_t *s) JL_DLLEXPORT void jl_module_use_as(jl_module_t *to, jl_module_t *from, jl_sym_t *s, jl_sym_t *asname); JL_DLLEXPORT void jl_module_import(jl_module_t *to, jl_module_t *from, jl_sym_t *s); JL_DLLEXPORT void jl_module_import_as(jl_module_t *to, jl_module_t *from, jl_sym_t *s, jl_sym_t *asname); -JL_DLLEXPORT void jl_module_export(jl_module_t *from, jl_sym_t *s); +JL_DLLEXPORT void jl_module_export(jl_module_t *from, jl_sym_t *s, int scoped); JL_DLLEXPORT int jl_is_imported(jl_module_t *m, jl_sym_t *s); JL_DLLEXPORT int jl_module_exports_p(jl_module_t *m, jl_sym_t *var); JL_DLLEXPORT void jl_add_standard_imports(jl_module_t *m); diff --git a/src/module.c b/src/module.c index 89c4c6cdb674e..df34faa94cd5f 100644 --- a/src/module.c +++ b/src/module.c @@ -49,7 +49,7 @@ JL_DLLEXPORT jl_module_t *jl_new_module_(jl_sym_t *name, jl_module_t *parent, ui if (default_names) { jl_set_const(m, name, (jl_value_t*)m); } - jl_module_export(m, name); + jl_module_export(m, name, 0); JL_GC_POP(); return m; } @@ -641,10 +641,11 @@ JL_DLLEXPORT void jl_module_using(jl_module_t *to, jl_module_t *from) } } -JL_DLLEXPORT void jl_module_export(jl_module_t *from, jl_sym_t *s) +JL_DLLEXPORT void jl_module_export(jl_module_t *from, jl_sym_t *s, int scoped) { jl_binding_t *b = jl_get_module_binding(from, s, 1); - b->exportp = 1; + b->exportp = !scoped; + b->scoped_exportp = scoped; } JL_DLLEXPORT int jl_boundp(jl_module_t *m, jl_sym_t *var) @@ -902,7 +903,7 @@ JL_DLLEXPORT jl_value_t *jl_module_usings(jl_module_t *m) return (jl_value_t*)a; } -JL_DLLEXPORT jl_value_t *jl_module_names(jl_module_t *m, int all, int imported) +JL_DLLEXPORT jl_value_t *jl_module_names(jl_module_t *m, int all, int imported, int scoped) { jl_array_t *a = jl_alloc_array_1d(jl_array_symbol_type, 0); JL_GC_PUSH1(&a); @@ -914,6 +915,7 @@ JL_DLLEXPORT jl_value_t *jl_module_names(jl_module_t *m, int all, int imported) jl_sym_t *asname = b->globalref->name; int hidden = jl_symbol_name(asname)[0]=='#'; if ((b->exportp || + (scoped && b->scoped_exportp) || (imported && b->imported) || (jl_atomic_load_relaxed(&b->owner) == b && !b->imported && (all || m == jl_main_module))) && (all || (!b->deprecated && !hidden))) { diff --git a/src/toplevel.c b/src/toplevel.c index 51ff93488426f..02cf9e89ac4e6 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -838,11 +838,14 @@ jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_value_t *e, int return jl_nothing; } else if (head == jl_export_sym) { + int scoped = 0; for (size_t i = 0; i < jl_array_len(ex->args); i++) { jl_sym_t *name = (jl_sym_t*)jl_array_ptr_ref(ex->args, i); if (!jl_is_symbol(name)) - jl_eval_errorf(m, "syntax: malformed \"export\" statement"); - jl_module_export(m, name); + // jl_eval_errorf(m, "syntax: malformed \"export\" statement"); + scoped = 1; // TODO Make this much more strict + else + jl_module_export(m, name, scoped); } JL_GC_POP(); return jl_nothing; From 665855e2833f7f606aa5f86dc880773bc79994d9 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Wed, 7 Jun 2023 12:30:00 -0500 Subject: [PATCH 02/62] add `Base.isinternal` and use it to flag internal methods in their docstrings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit module CreatePairs export create_pair export (scoped-true), cp """ create_pair(x) creates the pair `x => x` """ create_pair(x) = _create_pair(x) """ cp(x) creates the pair `x => x` """ cp(x) = _create_pair(x) """ _create_pair(x) creates the pair `x => x` """ _create_pair(x) = x => x end julia> using .CreatePairs julia> names(CreatePairs) 3-element Vector{Symbol}: :CreatePairs :cp :create_pair julia> names(CreatePairs, scoped=false) 2-element Vector{Symbol}: :CreatePairs :create_pair julia> create_pair(1) 1 => 1 julia> cp(1) ERROR: MethodError: no method matching cp(::Int64) Closest candidates are: cp(::AbstractString, ::AbstractString; force, follow_symlinks) @ Base file.jl:376 Stacktrace: [1] top-level scope @ REPL[6]:1 julia> CreatePairs.cp(1) 1 => 1 julia> _create_pair(1) ERROR: UndefVarError: `_create_pair` not defined Stacktrace: [1] top-level scope @ REPL[8]:1 julia> CreatePairs._create_pair(1) 1 => 1 help?> create_pair search: create_pair create_pair(x) creates the pair x => x help?> CreatePairs.cp cp(x) creates the pair x => x help?> CreatePairs._create_pair INTERNAL ──────────────────────────────────────────────────────────────────── _create_pair(x) creates the pair x => x --- base/reflection.jl | 1 + src/jl_exported_funcs.inc | 1 + src/module.c | 6 ++++++ stdlib/REPL/src/docview.jl | 3 +++ 4 files changed, 11 insertions(+) diff --git a/base/reflection.jl b/base/reflection.jl index ddb1534bede8b..bd6e6270496e9 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -92,6 +92,7 @@ unsorted_names(m::Module; all::Bool = false, imported::Bool = false, scoped::Boo ccall(:jl_module_names, Array{Symbol,1}, (Any, Cint, Cint, Cint), m, all, imported, scoped) isexported(m::Module, s::Symbol) = ccall(:jl_module_exports_p, Cint, (Any, Any), m, s) != 0 +isinternal(m::Module, s::Symbol) = !isexported(m, s) && ccall(:jl_module_scoped_exports_p, Cint, (Any, Any), m, s) == 0 isdeprecated(m::Module, s::Symbol) = ccall(:jl_is_binding_deprecated, Cint, (Any, Any), m, s) != 0 isbindingresolved(m::Module, var::Symbol) = ccall(:jl_binding_resolved_p, Cint, (Any, Any), m, var) != 0 diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index 33b431fe12a76..c55f6b8090595 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -331,6 +331,7 @@ XX(jl_module_name) \ XX(jl_module_names) \ XX(jl_module_parent) \ + XX(jl_module_scoped_exports_p) \ XX(jl_module_use) \ XX(jl_module_using) \ XX(jl_module_usings) \ diff --git a/src/module.c b/src/module.c index df34faa94cd5f..b6c15ab25a94a 100644 --- a/src/module.c +++ b/src/module.c @@ -666,6 +666,12 @@ JL_DLLEXPORT int jl_module_exports_p(jl_module_t *m, jl_sym_t *var) return b && b->exportp; } +JL_DLLEXPORT int jl_module_scoped_exports_p(jl_module_t *m, jl_sym_t *var) +{ + jl_binding_t *b = jl_get_module_binding(m, var, 0); + return b && b->scoped_exportp; +} + JL_DLLEXPORT int jl_binding_resolved_p(jl_module_t *m, jl_sym_t *var) { jl_binding_t *b = jl_get_module_binding(m, var, 0); diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index b9797dee910c2..479654026e201 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -191,6 +191,9 @@ function doc(binding::Binding, sig::Type = Union{}) end # Get parsed docs and concatenate them. md = catdoc(mapany(parsedoc, results)...) + + Base.isinternal(binding.mod, binding.var) && pushfirst!(md.content, Markdown.Paragraph("INTERNAL")) + # Save metadata in the generated markdown. if isa(md, Markdown.MD) md.meta[:results] = results From 52f519e170718d7634d34f4cca6ab3603a6805ae Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Wed, 7 Jun 2023 13:22:48 -0500 Subject: [PATCH 03/62] update documentation --- doc/src/manual/faq.md | 12 +++++++----- doc/src/manual/modules.md | 27 ++++++++++++++++----------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/doc/src/manual/faq.md b/doc/src/manual/faq.md index 85b31bf20a99f..9bd6c40a275bf 100644 --- a/doc/src/manual/faq.md +++ b/doc/src/manual/faq.md @@ -22,11 +22,13 @@ On the other hand, language *interoperability* is extremely useful: we want to e ### How does Julia define its public API? -The only interfaces that are stable with respect to [SemVer](https://semver.org/) of `julia` -version are the Julia `Base` and standard libraries interfaces described in -[the documentation](https://docs.julialang.org/) and not marked as unstable (e.g., -experimental and internal). Functions, types, and constants are not part of the public -API if they are not included in the documentation, _even if they have docstrings_. +Julia's public API is the behavior described in docstrings of symbols exported from `Base` +and the standard libraries. Functions, types, and constants are not part of the public +API if they are not exported, _even if they have docstrings_. + +You can get a complete list of the symbols exported from a module with `names(MyModule)`. + +Package authors are encouraged to define their public API similarly. ### There is a useful undocumented function/type/constant. Can I use it? diff --git a/doc/src/manual/modules.md b/doc/src/manual/modules.md index 4ffb1bca26e50..f75ac994d4ad7 100644 --- a/doc/src/manual/modules.md +++ b/doc/src/manual/modules.md @@ -78,8 +78,10 @@ module-local. ### Export lists Names (referring to functions, types, global variables, and constants) can be added to the -*export list* of a module with `export`: these are the symbols that are imported when `using` the module. Typically, they are at or near the top of the module definition -so that readers of the source code can find them easily, as in +*export list* of a module with `export`: these are the symbols that define the public API of +the module and, by default, they are imported when `using` the module. Typically, they are +at or near the top of the module definition so that readers of the source code can find them +easily, as in ```jldoctest module_manual julia> module NiceStuff @@ -94,23 +96,26 @@ julia> module NiceStuff but this is just a style suggestion — a module can have multiple `export` statements in arbitrary locations. -It is common to export names which form part of the API (application programming interface). In -the above code, the export list suggests that users should use `nice` and `DOG`. However, since -qualified names always make identifiers accessible, this is just an option for organizing APIs: -unlike other languages, Julia has no facilities for truly hiding module internals. +### Scoped Exports -Also, some modules don't export names at all. This is usually done if they use common -words, such as `derivative`, in their API, which could easily clash with the export lists of other -modules. We will see how to manage name clashes below. +Modules should export all names which form part of their API, however it is sometimes +unhelpful to automatically load every symbol that is part of the API on `using`. In this +case, it is appropriate to use `export (scoped-true), name` instead of ``export name` to +mark the symbol as a part of the public API, but not to load it on `using`. This is usually +done when modules use common words, such as `derivative`, in their API, which could easily +clash with the export lists of other modules. We will see how to manage name clashes below. + +Since qualified names always make identifiers accessible, this is just an option for +organizing APIs: unlike some other languages, Julia discourages truly hiding module internals. ### Standalone `using` and `import` -Possibly the most common way of loading a module is `using ModuleName`. This [loads](@ref +The most common way of loading a module is `using ModuleName`. This [loads](@ref code-loading) the code associated with `ModuleName`, and brings 1. the module name -2. and the elements of the export list into the surrounding global namespace. +2. and the elements of the export list (excluding scoped exports) into the surrounding global namespace. Technically, the statement `using ModuleName` means that a module called `ModuleName` will be available for resolving names as needed. When a global variable is encountered that has no From 03f9e02639eb8b38f69e4f31ac480d899a926b25 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 26 Jun 2023 17:43:28 -0500 Subject: [PATCH 04/62] add more verbose clarificaiton of what is and is not public API (TODO: trim for concision and clarity) --- doc/src/manual/faq.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/doc/src/manual/faq.md b/doc/src/manual/faq.md index 9bd6c40a275bf..ae49455e32762 100644 --- a/doc/src/manual/faq.md +++ b/doc/src/manual/faq.md @@ -22,9 +22,21 @@ On the other hand, language *interoperability* is extremely useful: we want to e ### How does Julia define its public API? -Julia's public API is the behavior described in docstrings of symbols exported from `Base` +Julia's public API is the behavior described in documentation of symbols exported from `Base` and the standard libraries. Functions, types, and constants are not part of the public -API if they are not exported, _even if they have docstrings_. +API if they are not exported, _even if they have docstrings_. Further, only the documented +behavior of exported symbols is part of the public API. Undocumented behavior of exported +symbols is internal. + +In other words: + +- Documented behavior of exported symbols is part of the public API. + +- Undocumented behavior of exported symbols is not part of the public API. + +- Documented behavior of unexported symbols is not part of the public API. + +- Undocumented behavior of unexported symbols is not part of the public API. You can get a complete list of the symbols exported from a module with `names(MyModule)`. From 7eb64a233921858c067fd799c5e9e5968d8ae6af Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 26 Jun 2023 17:44:12 -0500 Subject: [PATCH 05/62] add prelimianry list of scoped-exported symbols for review --- base/exports.jl | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/base/exports.jl b/base/exports.jl index 10f43825e12df..c8bf55bee0116 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -1061,3 +1061,72 @@ export @view, @views, @static + +#= +export (scoped-true) + @assume_effects, + @constprop, + @locals, + @propagate_inbounds, + :AbstractLock, + :AsyncCondition, + :CFunction, + :Checked, + :CodeUnits, + :DL_LOAD_PATH, + :EnvDict, + :Event, + :Fix1, + :Fix2, + :Generator, + :ImmutableDict, + :IteratorEltype, + :IteratorSize, + :OneTo, + :Pairs, + :Semaphore, + :UUID, + :acquire, + :active_project, + :add_sum, + :cconvert, + :checked_length, + :compilecache, + :datatype_alignment, + :datatype_haspadding, + :datatype_pointerfree, + :elsize, + :exit_on_sigint, + :front, + :identify_package, + :include, + :isambiguous, + :isbinaryoperator, + :isdone, + :isexpr, + :isidentifier, + :isoperator, + :issingletontype, + :isunaryoperator, + :jit_total_bytes, + :load_path, + :locate_package, + :moduleroot, + :notnothing, + :operator_associativity, + :operator_precedence, + :promote_typejoin, + :release, + :require, + :rest, + :runtests, + :set_active_project, + :split_rest, + :summarysize, + :tail, + :text_colors, + :to_index, + :unsafe_convert, + :vect, + :windowserror +=# From c7192ea5f2e2a1e564af2bbeed5acdb70bf68583 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 26 Jun 2023 17:54:19 -0500 Subject: [PATCH 06/62] more docs (implement option 1 of https://github.com/JuliaLang/julia/pull/50105#issuecomment-1585653107) --- doc/src/manual/faq.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/src/manual/faq.md b/doc/src/manual/faq.md index ae49455e32762..693fddf142f0b 100644 --- a/doc/src/manual/faq.md +++ b/doc/src/manual/faq.md @@ -42,6 +42,13 @@ You can get a complete list of the symbols exported from a module with `names(My Package authors are encouraged to define their public API similarly. +Documented behavior of symbols exported from submodules are only part of the public API +if the module they belong to is also exported. If module A marks submodule B as public and +B marks foo as public, then A.B.foo is public, but if A does not mark B as public, +then writing A.B.foo outside of A is accessing an internal and anything that B marks as +public forms a sub-api that is not covered by the SymVer of A. This could be for the +convenience of developers of A if A is a large package... + ### There is a useful undocumented function/type/constant. Can I use it? Updating Julia may break your code if you use non-public API. If the code is From ec3b2f3320f8df341e7d8b984cb1700e150cf981 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 26 Jun 2023 18:25:31 -0500 Subject: [PATCH 07/62] address @jariji's comments --- doc/src/manual/faq.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/src/manual/faq.md b/doc/src/manual/faq.md index 693fddf142f0b..302f67e994c19 100644 --- a/doc/src/manual/faq.md +++ b/doc/src/manual/faq.md @@ -22,7 +22,8 @@ On the other hand, language *interoperability* is extremely useful: we want to e ### How does Julia define its public API? -Julia's public API is the behavior described in documentation of symbols exported from `Base` +Julia's public [API](https://en.wikipedia.org/wiki/API) is the behavior described in +documentation of symbols exported from `Base` and the standard libraries. Functions, types, and constants are not part of the public API if they are not exported, _even if they have docstrings_. Further, only the documented behavior of exported symbols is part of the public API. Undocumented behavior of exported @@ -49,6 +50,9 @@ then writing A.B.foo outside of A is accessing an internal and anything that B m public forms a sub-api that is not covered by the SymVer of A. This could be for the convenience of developers of A if A is a large package... +Anything in Julia's Public API is covered by [SemVer](https://semver.org/) and therefore +will not be removed or receive meaningful breaking changes in a minor version update. + ### There is a useful undocumented function/type/constant. Can I use it? Updating Julia may break your code if you use non-public API. If the code is From 4dc10c4b05437c0c980429e03cc43807ca746ca3 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Sat, 8 Jul 2023 09:31:02 -0500 Subject: [PATCH 08/62] use JuliaSyntax#320 branch --- deps/JuliaSyntax.version | 8 ++++---- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + 5 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/md5 delete mode 100644 deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/sha512 create mode 100644 deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/md5 create mode 100644 deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/sha512 diff --git a/deps/JuliaSyntax.version b/deps/JuliaSyntax.version index b604eedaa43dd..f69df1f792b8c 100644 --- a/deps/JuliaSyntax.version +++ b/deps/JuliaSyntax.version @@ -1,4 +1,4 @@ -JULIASYNTAX_BRANCH = main -JULIASYNTAX_SHA1 = 8731bab86f14762cca8cf24224d8c7a6a89c21c5 -JULIASYNTAX_GIT_URL := https://github.com/JuliaLang/JuliaSyntax.jl.git -JULIASYNTAX_TAR_URL = https://api.github.com/repos/JuliaLang/JuliaSyntax.jl/tarball/$1 +JULIASYNTAX_BRANCH = scoped-export +JULIASYNTAX_SHA1 = c43f12dfd45c23ae6df150b08e1df8d60ada32bf +JULIASYNTAX_GIT_URL := https://github.com/LilithHafner/JuliaSyntax.jl.git +JULIASYNTAX_TAR_URL = https://api.github.com/repos/LilithHafner/JuliaSyntax.jl/tarball/$1 diff --git a/deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/md5 b/deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/md5 deleted file mode 100644 index 8bec9dde7fbae..0000000000000 --- a/deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -6fdeb9332af478502be39af642027387 diff --git a/deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/sha512 b/deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/sha512 deleted file mode 100644 index 50c676f808c5c..0000000000000 --- a/deps/checksums/JuliaSyntax-8731bab86f14762cca8cf24224d8c7a6a89c21c5.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -fbb4ab0b99de7e1f86b918b401c2d42883a2bf8e80f6af4d6b85b7ca263d97cca1c47b25aca48359f14dee91b658684c0c590b7f20240bd9e0ce6e960ccf6647 diff --git a/deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/md5 b/deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/md5 new file mode 100644 index 0000000000000..0838bc00f7383 --- /dev/null +++ b/deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/md5 @@ -0,0 +1 @@ +b7407e06763d83d935dbac84b36aeb1d diff --git a/deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/sha512 b/deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/sha512 new file mode 100644 index 0000000000000..009442087d08c --- /dev/null +++ b/deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/sha512 @@ -0,0 +1 @@ +9b5145a2e62e95f8326f71d9f94fa4bd7931d3368b648df725aae73010c21e05f9f8e3da89f296d99d7de3be1d7a37608243c4ba4763d432f48c998acaead8cb From 5fd1f6420ae08914edaee8e21fcbcc5a81fef14e Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Sat, 8 Jul 2023 10:16:31 -0500 Subject: [PATCH 09/62] bump JuliaSyntax --- deps/JuliaSyntax.version | 2 +- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/md5 create mode 100644 deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/sha512 delete mode 100644 deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/md5 delete mode 100644 deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/sha512 diff --git a/deps/JuliaSyntax.version b/deps/JuliaSyntax.version index f69df1f792b8c..abf61fdf5f685 100644 --- a/deps/JuliaSyntax.version +++ b/deps/JuliaSyntax.version @@ -1,4 +1,4 @@ JULIASYNTAX_BRANCH = scoped-export -JULIASYNTAX_SHA1 = c43f12dfd45c23ae6df150b08e1df8d60ada32bf +JULIASYNTAX_SHA1 = a343b7fb85c31188ce97b5130fa6c5dcaa61d29b JULIASYNTAX_GIT_URL := https://github.com/LilithHafner/JuliaSyntax.jl.git JULIASYNTAX_TAR_URL = https://api.github.com/repos/LilithHafner/JuliaSyntax.jl/tarball/$1 diff --git a/deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/md5 b/deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/md5 new file mode 100644 index 0000000000000..694f20c32e0e1 --- /dev/null +++ b/deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/md5 @@ -0,0 +1 @@ +f7105691a69168213ea10c8dc0e36a3c diff --git a/deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/sha512 b/deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/sha512 new file mode 100644 index 0000000000000..78623a41a0502 --- /dev/null +++ b/deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/sha512 @@ -0,0 +1 @@ +74412ff5a46107ea8cc999c3504a8af2b8b19ffbc04f17171c48f02815cb01e8de6cf6441dc9e2b51aef0e3c844d7385696295645a9224d31e6f92abfbc0b09d diff --git a/deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/md5 b/deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/md5 deleted file mode 100644 index 0838bc00f7383..0000000000000 --- a/deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -b7407e06763d83d935dbac84b36aeb1d diff --git a/deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/sha512 b/deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/sha512 deleted file mode 100644 index 009442087d08c..0000000000000 --- a/deps/checksums/JuliaSyntax-c43f12dfd45c23ae6df150b08e1df8d60ada32bf.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -9b5145a2e62e95f8326f71d9f94fa4bd7931d3368b648df725aae73010c21e05f9f8e3da89f296d99d7de3be1d7a37608243c4ba4763d432f48c998acaead8cb From b85ae46c1f36faf76aad4860b612cc1eb3d0df6b Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Sat, 8 Jul 2023 10:24:36 -0500 Subject: [PATCH 10/62] more changes for scoped export -> public --- base/exports.jl | 124 +++++++++++++++++++------------------- base/reflection.jl | 22 ++++--- base/show.jl | 2 +- doc/src/manual/faq.md | 28 +++++---- doc/src/manual/modules.md | 27 ++++----- src/ast.c | 2 + src/builtins.c | 2 +- src/jl_exported_funcs.inc | 4 +- src/julia-parser.scm | 4 +- src/julia.h | 6 +- src/julia_internal.h | 1 + src/module.c | 17 +++--- src/toplevel.c | 17 +++--- 13 files changed, 130 insertions(+), 126 deletions(-) diff --git a/base/exports.jl b/base/exports.jl index 85b073da4ba07..fe3e68568b9dc 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -1065,70 +1065,70 @@ export @static #= -export (scoped-true) +public @assume_effects, @constprop, @locals, @propagate_inbounds, - :AbstractLock, - :AsyncCondition, - :CFunction, - :Checked, - :CodeUnits, - :DL_LOAD_PATH, - :EnvDict, - :Event, - :Fix1, - :Fix2, - :Generator, - :ImmutableDict, - :IteratorEltype, - :IteratorSize, - :OneTo, - :Pairs, - :Semaphore, - :UUID, - :acquire, - :active_project, - :add_sum, - :cconvert, - :checked_length, - :compilecache, - :datatype_alignment, - :datatype_haspadding, - :datatype_pointerfree, - :elsize, - :exit_on_sigint, - :front, - :identify_package, - :include, - :isambiguous, - :isbinaryoperator, - :isdone, - :isexpr, - :isidentifier, - :isoperator, - :issingletontype, - :isunaryoperator, - :jit_total_bytes, - :load_path, - :locate_package, - :moduleroot, - :notnothing, - :operator_associativity, - :operator_precedence, - :promote_typejoin, - :release, - :require, - :rest, - :runtests, - :set_active_project, - :split_rest, - :summarysize, - :tail, - :text_colors, - :to_index, - :unsafe_convert, - :vect, - :windowserror + AbstractLock, + AsyncCondition, + CFunction, + Checked, + CodeUnits, + DL_LOAD_PATH, + EnvDict, + Event, + Fix1, + Fix2, + Generator, + ImmutableDict, + IteratorEltype, + IteratorSize, + OneTo, + Pairs, + Semaphore, + UUID, + acquire, + active_project, + add_sum, + cconvert, + checked_length, + compilecache, + datatype_alignment, + datatype_haspadding, + datatype_pointerfree, + elsize, + exit_on_sigint, + front, + identify_package, + include, + isambiguous, + isbinaryoperator, + isdone, + isexpr, + isidentifier, + isoperator, + issingletontype, + isunaryoperator, + jit_total_bytes, + load_path, + locate_package, + moduleroot, + notnothing, + operator_associativity, + operator_precedence, + promote_typejoin, + release, + require, + rest, + runtests, + set_active_project, + split_rest, + summarysize, + tail, + text_colors, + to_index, + unsafe_convert, + vect, + windowserror =# diff --git a/base/reflection.jl b/base/reflection.jl index 7817d4a8d73cf..4e74cf82a42ab 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -73,26 +73,28 @@ function fullname(m::Module) end """ - names(x::Module; all::Bool = false, imported::Bool = false) + names(x::Module; qualified::Bool=true, all::Bool = false, imported::Bool = false) -Get an array of the names exported by a `Module`, excluding deprecated names. -If `all` is true, then the list also includes non-exported names defined in the module, +Get an array of the public names of `Module`, excluding deprecated names. + +If `qualified` is false, then return only exported names, not public but unexported names. +If `all` is true, then the list also includes private names defined in the module, deprecated names, and compiler-generated names. If `imported` is true, then names explicitly imported from other modules are also included. -As a special case, all names defined in `Main` are considered \"exported\", -since it is not idiomatic to explicitly export names from `Main`. +As a special case, all names defined in `Main` are considered \"public\", +since it is not idiomatic to mark names from `Main` as public. See also: [`@locals`](@ref Base.@locals), [`@__MODULE__`](@ref). """ -names(m::Module; all::Bool = false, imported::Bool = false, scoped::Bool = true) = - sort!(unsorted_names(m; all, imported, scoped)) -unsorted_names(m::Module; all::Bool = false, imported::Bool = false, scoped::Bool = true) = - ccall(:jl_module_names, Array{Symbol,1}, (Any, Cint, Cint, Cint), m, all, imported, scoped) +names(m::Module; qualified::Bool = true, all::Bool = false, imported::Bool = false) = + sort!(unsorted_names(m; qualified, all, imported)) +unsorted_names(m::Module; qualified::Bool = true, all::Bool = false, imported::Bool = false) = + ccall(:jl_module_names, Array{Symbol,1}, (Any, Cint, Cint, Cint), m, qualified, all, imported) isexported(m::Module, s::Symbol) = ccall(:jl_module_exports_p, Cint, (Any, Any), m, s) != 0 -isinternal(m::Module, s::Symbol) = !isexported(m, s) && ccall(:jl_module_scoped_exports_p, Cint, (Any, Any), m, s) == 0 +isinternal(m::Module, s::Symbol) = ccall(:jl_module_public_p, Cint, (Any, Any), m, s) == 0 isdeprecated(m::Module, s::Symbol) = ccall(:jl_is_binding_deprecated, Cint, (Any, Any), m, s) != 0 isbindingresolved(m::Module, var::Symbol) = ccall(:jl_binding_resolved_p, Cint, (Any, Any), m, var) != 0 diff --git a/base/show.jl b/base/show.jl index 7d59a416674e8..7a771e0a3b962 100644 --- a/base/show.jl +++ b/base/show.jl @@ -2232,7 +2232,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In print(io, head, ' ') show_list(io, args, ", ", indent, 0, quote_level) - elseif head === :export + elseif head in (:export, :public) print(io, head, ' ') show_list(io, mapany(allow_macroname, args), ", ", indent) diff --git a/doc/src/manual/faq.md b/doc/src/manual/faq.md index aa28550f2a18d..ffb11b8a63d51 100644 --- a/doc/src/manual/faq.md +++ b/doc/src/manual/faq.md @@ -23,32 +23,36 @@ On the other hand, language *interoperability* is extremely useful: we want to e ### How does Julia define its public API? Julia's public [API](https://en.wikipedia.org/wiki/API) is the behavior described in -documentation of symbols exported from `Base` -and the standard libraries. Functions, types, and constants are not part of the public -API if they are not exported, _even if they have docstrings_. Further, only the documented -behavior of exported symbols is part of the public API. Undocumented behavior of exported +documentation of public symbols from `Base` and the standard libraries. Functions, +types, and constants are not part of the public API if they are not public, even if +they have docstrings or are described in the documentation. Further, only the documented +behavior of public symbols is part of the public API. Undocumented behavior of public symbols is internal. +Public symbols are those marked with either `public foo` or `export bar`. +Exported symbols are automatically considered public + In other words: -- Documented behavior of exported symbols is part of the public API. +- Documented behavior of public symbols is part of the public API. -- Undocumented behavior of exported symbols is not part of the public API. +- Undocumented behavior of public symbols is not part of the public API. -- Documented behavior of unexported symbols is not part of the public API. +- Documented behavior of private symbols is not part of the public API. -- Undocumented behavior of unexported symbols is not part of the public API. +- Undocumented behavior of private symbols is not part of the public API. -You can get a complete list of the symbols exported from a module with `names(MyModule)`. +You can get a complete list of the public symbols from a module with `names(MyModule)`. Package authors are encouraged to define their public API similarly. -Documented behavior of symbols exported from submodules are only part of the public API -if the module they belong to is also exported. If module A marks submodule B as public and +Publicity nests in the same wa as exporting. +Documented behavior of public symbols from submodules are only part of the public API +if the module they belong to is also public. If module A marks submodule B as public and B marks foo as public, then A.B.foo is public, but if A does not mark B as public, then writing A.B.foo outside of A is accessing an internal and anything that B marks as public forms a sub-api that is not covered by the SymVer of A. This could be for the -convenience of developers of A if A is a large package... +convenience of developers of A if A is a large package. Anything in Julia's Public API is covered by [SemVer](https://semver.org/) and therefore will not be removed or receive meaningful breaking changes in a minor version update. diff --git a/doc/src/manual/modules.md b/doc/src/manual/modules.md index f75ac994d4ad7..4ffb1bca26e50 100644 --- a/doc/src/manual/modules.md +++ b/doc/src/manual/modules.md @@ -78,10 +78,8 @@ module-local. ### Export lists Names (referring to functions, types, global variables, and constants) can be added to the -*export list* of a module with `export`: these are the symbols that define the public API of -the module and, by default, they are imported when `using` the module. Typically, they are -at or near the top of the module definition so that readers of the source code can find them -easily, as in +*export list* of a module with `export`: these are the symbols that are imported when `using` the module. Typically, they are at or near the top of the module definition +so that readers of the source code can find them easily, as in ```jldoctest module_manual julia> module NiceStuff @@ -96,26 +94,23 @@ julia> module NiceStuff but this is just a style suggestion — a module can have multiple `export` statements in arbitrary locations. -### Scoped Exports +It is common to export names which form part of the API (application programming interface). In +the above code, the export list suggests that users should use `nice` and `DOG`. However, since +qualified names always make identifiers accessible, this is just an option for organizing APIs: +unlike other languages, Julia has no facilities for truly hiding module internals. -Modules should export all names which form part of their API, however it is sometimes -unhelpful to automatically load every symbol that is part of the API on `using`. In this -case, it is appropriate to use `export (scoped-true), name` instead of ``export name` to -mark the symbol as a part of the public API, but not to load it on `using`. This is usually -done when modules use common words, such as `derivative`, in their API, which could easily -clash with the export lists of other modules. We will see how to manage name clashes below. - -Since qualified names always make identifiers accessible, this is just an option for -organizing APIs: unlike some other languages, Julia discourages truly hiding module internals. +Also, some modules don't export names at all. This is usually done if they use common +words, such as `derivative`, in their API, which could easily clash with the export lists of other +modules. We will see how to manage name clashes below. ### Standalone `using` and `import` -The most common way of loading a module is `using ModuleName`. This [loads](@ref +Possibly the most common way of loading a module is `using ModuleName`. This [loads](@ref code-loading) the code associated with `ModuleName`, and brings 1. the module name -2. and the elements of the export list (excluding scoped exports) into the surrounding global namespace. +2. and the elements of the export list into the surrounding global namespace. Technically, the statement `using ModuleName` means that a module called `ModuleName` will be available for resolving names as needed. When a global variable is encountered that has no diff --git a/src/ast.c b/src/ast.c index 06727b453d6a3..600b1a229ea80 100644 --- a/src/ast.c +++ b/src/ast.c @@ -28,6 +28,7 @@ JL_DLLEXPORT jl_sym_t *jl_top_sym; JL_DLLEXPORT jl_sym_t *jl_module_sym; JL_DLLEXPORT jl_sym_t *jl_slot_sym; JL_DLLEXPORT jl_sym_t *jl_export_sym; +JL_DLLEXPORT jl_sym_t *jl_public_sym; JL_DLLEXPORT jl_sym_t *jl_import_sym; JL_DLLEXPORT jl_sym_t *jl_toplevel_sym; JL_DLLEXPORT jl_sym_t *jl_quote_sym; @@ -304,6 +305,7 @@ void jl_init_common_symbols(void) jl_lambda_sym = jl_symbol("lambda"); jl_module_sym = jl_symbol("module"); jl_export_sym = jl_symbol("export"); + jl_public_sym = jl_symbol("public"); jl_import_sym = jl_symbol("import"); jl_using_sym = jl_symbol("using"); jl_assign_sym = jl_symbol("="); diff --git a/src/builtins.c b/src/builtins.c index b779bac2ef636..9bc08d5438075 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1929,7 +1929,7 @@ static void add_intrinsic(jl_module_t *inm, const char *name, enum intrinsic f) jl_value_t *i = jl_permbox32(jl_intrinsic_type, 0, (int32_t)f); jl_sym_t *sym = jl_symbol(name); jl_set_const(inm, sym, i); - jl_module_export(inm, sym, 0); + jl_module_public(inm, sym, 1); } void jl_init_intrinsic_properties(void) JL_GC_DISABLED diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index acf889f8e9660..ee388e25047d5 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -325,14 +325,14 @@ XX(jl_methtable_lookup) \ XX(jl_mi_cache_insert) \ XX(jl_module_build_id) \ - XX(jl_module_export) \ XX(jl_module_exports_p) \ XX(jl_module_globalref) \ XX(jl_module_import) \ XX(jl_module_name) \ XX(jl_module_names) \ XX(jl_module_parent) \ - XX(jl_module_scoped_exports_p) \ + XX(jl_module_public) \ + XX(jl_module_public_p) \ XX(jl_module_use) \ XX(jl_module_using) \ XX(jl_module_usings) \ diff --git a/src/julia-parser.scm b/src/julia-parser.scm index 28a9d4806b252..210ba8f0ae07b 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -1617,8 +1617,8 @@ ((export) (let ((es (map macrocall-to-atsym (parse-comma-separated s parse-unary-prefix)))) - ; (if (not (every symbol-or-interpolate? es)) ; TODO make this much more strict - ; (error "invalid \"export\" statement")) + (if (not (every symbol-or-interpolate? es)) + (error "invalid \"export\" statement")) `(export ,@es))) ((import using) (parse-imports s word)) diff --git a/src/julia.h b/src/julia.h index 4283163093752..01c805e519415 100644 --- a/src/julia.h +++ b/src/julia.h @@ -594,8 +594,8 @@ typedef struct _jl_binding_t { _Atomic(struct _jl_binding_t*) owner; // for individual imported bindings (NULL until 'resolved') _Atomic(jl_value_t*) ty; // binding type uint8_t constp:1; - uint8_t exportp:1; - uint8_t scoped_exportp:1; // `scoped export foo` sets both `exportp` and `scoped_exportp`. + uint8_t exportp:1; // `public foo` sets `publicp`, `export foo` sets both `publicp` and `exportp` + uint8_t publicp:1; // exportp without publicp is not allowed. uint8_t imported:1; uint8_t usingfailed:1; uint8_t deprecated:2; // 0=not deprecated, 1=renamed, 2=moved to another package @@ -1737,7 +1737,7 @@ JL_DLLEXPORT void jl_module_use(jl_module_t *to, jl_module_t *from, jl_sym_t *s) JL_DLLEXPORT void jl_module_use_as(jl_module_t *to, jl_module_t *from, jl_sym_t *s, jl_sym_t *asname); JL_DLLEXPORT void jl_module_import(jl_module_t *to, jl_module_t *from, jl_sym_t *s); JL_DLLEXPORT void jl_module_import_as(jl_module_t *to, jl_module_t *from, jl_sym_t *s, jl_sym_t *asname); -JL_DLLEXPORT void jl_module_export(jl_module_t *from, jl_sym_t *s, int scoped); +JL_DLLEXPORT void jl_module_public(jl_module_t *from, jl_sym_t *s, int exp); JL_DLLEXPORT int jl_is_imported(jl_module_t *m, jl_sym_t *s); JL_DLLEXPORT int jl_module_exports_p(jl_module_t *m, jl_sym_t *var); JL_DLLEXPORT void jl_add_standard_imports(jl_module_t *m); diff --git a/src/julia_internal.h b/src/julia_internal.h index cf65521770681..9e294c2462315 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -1498,6 +1498,7 @@ extern JL_DLLEXPORT jl_sym_t *jl_top_sym; extern JL_DLLEXPORT jl_sym_t *jl_module_sym; extern JL_DLLEXPORT jl_sym_t *jl_slot_sym; extern JL_DLLEXPORT jl_sym_t *jl_export_sym; +extern JL_DLLEXPORT jl_sym_t *jl_public_sym; extern JL_DLLEXPORT jl_sym_t *jl_import_sym; extern JL_DLLEXPORT jl_sym_t *jl_toplevel_sym; extern JL_DLLEXPORT jl_sym_t *jl_quote_sym; diff --git a/src/module.c b/src/module.c index b6c15ab25a94a..0b695a8d87632 100644 --- a/src/module.c +++ b/src/module.c @@ -49,7 +49,7 @@ JL_DLLEXPORT jl_module_t *jl_new_module_(jl_sym_t *name, jl_module_t *parent, ui if (default_names) { jl_set_const(m, name, (jl_value_t*)m); } - jl_module_export(m, name, 0); + jl_module_public(m, name, 1); JL_GC_POP(); return m; } @@ -641,11 +641,11 @@ JL_DLLEXPORT void jl_module_using(jl_module_t *to, jl_module_t *from) } } -JL_DLLEXPORT void jl_module_export(jl_module_t *from, jl_sym_t *s, int scoped) +JL_DLLEXPORT void jl_module_public(jl_module_t *from, jl_sym_t *s, int exp) { jl_binding_t *b = jl_get_module_binding(from, s, 1); - b->exportp = !scoped; - b->scoped_exportp = scoped; + b->publicp = 1; + b->exportp = exp; } JL_DLLEXPORT int jl_boundp(jl_module_t *m, jl_sym_t *var) @@ -666,10 +666,10 @@ JL_DLLEXPORT int jl_module_exports_p(jl_module_t *m, jl_sym_t *var) return b && b->exportp; } -JL_DLLEXPORT int jl_module_scoped_exports_p(jl_module_t *m, jl_sym_t *var) +JL_DLLEXPORT int jl_module_public_p(jl_module_t *m, jl_sym_t *var) { jl_binding_t *b = jl_get_module_binding(m, var, 0); - return b && b->scoped_exportp; + return b && b->publicp; } JL_DLLEXPORT int jl_binding_resolved_p(jl_module_t *m, jl_sym_t *var) @@ -909,7 +909,7 @@ JL_DLLEXPORT jl_value_t *jl_module_usings(jl_module_t *m) return (jl_value_t*)a; } -JL_DLLEXPORT jl_value_t *jl_module_names(jl_module_t *m, int all, int imported, int scoped) +JL_DLLEXPORT jl_value_t *jl_module_names(jl_module_t *m, int qualified, int all, int imported) { jl_array_t *a = jl_alloc_array_1d(jl_array_symbol_type, 0); JL_GC_PUSH1(&a); @@ -920,8 +920,7 @@ JL_DLLEXPORT jl_value_t *jl_module_names(jl_module_t *m, int all, int imported, break; jl_sym_t *asname = b->globalref->name; int hidden = jl_symbol_name(asname)[0]=='#'; - if ((b->exportp || - (scoped && b->scoped_exportp) || + if (((qualified ? b->publicp : b->exportp) || (imported && b->imported) || (jl_atomic_load_relaxed(&b->owner) == b && !b->imported && (all || m == jl_main_module))) && (all || (!b->deprecated && !hidden))) { diff --git a/src/toplevel.c b/src/toplevel.c index 02cf9e89ac4e6..6986bd86bf35b 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -560,6 +560,7 @@ int jl_is_toplevel_only_expr(jl_value_t *e) JL_NOTSAFEPOINT ((jl_expr_t*)e)->head == jl_import_sym || ((jl_expr_t*)e)->head == jl_using_sym || ((jl_expr_t*)e)->head == jl_export_sym || + ((jl_expr_t*)e)->head == jl_public_sym || ((jl_expr_t*)e)->head == jl_thunk_sym || ((jl_expr_t*)e)->head == jl_global_sym || ((jl_expr_t*)e)->head == jl_const_sym || @@ -575,8 +576,9 @@ int jl_needs_lowering(jl_value_t *e) JL_NOTSAFEPOINT jl_expr_t *ex = (jl_expr_t*)e; jl_sym_t *head = ex->head; if (head == jl_module_sym || head == jl_import_sym || head == jl_using_sym || - head == jl_export_sym || head == jl_thunk_sym || head == jl_toplevel_sym || - head == jl_error_sym || head == jl_incomplete_sym || head == jl_method_sym) { + head == jl_export_sym || head == jl_public_sym || head == jl_thunk_sym || + head == jl_toplevel_sym || head == jl_error_sym || head == jl_incomplete_sym || + head == jl_method_sym) { return 0; } if (head == jl_global_sym || head == jl_const_sym) { @@ -837,15 +839,14 @@ jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_value_t *e, int JL_GC_POP(); return jl_nothing; } - else if (head == jl_export_sym) { - int scoped = 0; + else if (head == jl_export_sym || head == jl_public_sym) { + int exp = (head == jl_export_sym); for (size_t i = 0; i < jl_array_len(ex->args); i++) { jl_sym_t *name = (jl_sym_t*)jl_array_ptr_ref(ex->args, i); if (!jl_is_symbol(name)) - // jl_eval_errorf(m, "syntax: malformed \"export\" statement"); - scoped = 1; // TODO Make this much more strict - else - jl_module_export(m, name, scoped); + jl_eval_errorf(m, exp ? "syntax: malformed \"export\" statement" : + "syntax: malformed \"public\" statement"); + jl_module_public(m, name, exp); } JL_GC_POP(); return jl_nothing; From acc928a72e8f680342caaaa57953391711ded05e Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 10 Jul 2023 18:22:05 -0500 Subject: [PATCH 11/62] try to make public list functional --- base/exports.jl | 135 ++++++++++++++++++++++++------------------------ 1 file changed, 67 insertions(+), 68 deletions(-) diff --git a/base/exports.jl b/base/exports.jl index fe3e68568b9dc..684d7f57aa3a8 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -1064,71 +1064,70 @@ export @views, @static -#= -public - @assume_effects, - @constprop, - @locals, - @propagate_inbounds, - AbstractLock, - AsyncCondition, - CFunction, - Checked, - CodeUnits, - DL_LOAD_PATH, - EnvDict, - Event, - Fix1, - Fix2, - Generator, - ImmutableDict, - IteratorEltype, - IteratorSize, - OneTo, - Pairs, - Semaphore, - UUID, - acquire, - active_project, - add_sum, - cconvert, - checked_length, - compilecache, - datatype_alignment, - datatype_haspadding, - datatype_pointerfree, - elsize, - exit_on_sigint, - front, - identify_package, - include, - isambiguous, - isbinaryoperator, - isdone, - isexpr, - isidentifier, - isoperator, - issingletontype, - isunaryoperator, - jit_total_bytes, - load_path, - locate_package, - moduleroot, - notnothing, - operator_associativity, - operator_precedence, - promote_typejoin, - release, - require, - rest, - runtests, - set_active_project, - split_rest, - summarysize, - tail, - text_colors, - to_index, - unsafe_convert, - vect, - windowserror -=# +# TODO: use normal syntax once JuliaSyntax.jl becomes available at this point in bootstrapping +eval(Expr(:public, + Symbol("@assume_effects"), + Symbol("@constprop"), + Symbol("@locals"), + Symbol("@propagate_inbounds"), + :AbstractLock, + :AsyncCondition, + :CFunction, + :Checked, + :CodeUnits, + :DL_LOAD_PATH, + :EnvDict, + :Event, + :Fix1, + :Fix2, + :Generator, + :ImmutableDict, + :IteratorEltype, + :IteratorSize, + :OneTo, + :Pairs, + :Semaphore, + :UUID, + :acquire, + :active_project, + :add_sum, + :cconvert, + :checked_length, + :compilecache, + :datatype_alignment, + :datatype_haspadding, + :datatype_pointerfree, + :elsize, + :exit_on_sigint, + :front, + :identify_package, + :include, + :isambiguous, + :isbinaryoperator, + :isdone, + :isexpr, + :isidentifier, + :isoperator, + :issingletontype, + :isunaryoperator, + :jit_total_bytes, + :load_path, + :locate_package, + :moduleroot, + :notnothing, + :operator_associativity, + :operator_precedence, + :promote_typejoin, + :release, + :require, + :rest, + :runtests, + :set_active_project, + :split_rest, + :summarysize, + :tail, + :text_colors, + :to_index, + :unsafe_convert, + :vect, + :windowserror)) From a5162c27c88a20b487b1c6aa1e4db45e1e8371fa Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 18 Jul 2023 14:17:07 -0500 Subject: [PATCH 12/62] bump juliasyntax --- deps/JuliaSyntax.version | 2 +- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/md5 delete mode 100644 deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/sha512 create mode 100644 deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/md5 create mode 100644 deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/sha512 diff --git a/deps/JuliaSyntax.version b/deps/JuliaSyntax.version index abf61fdf5f685..d8183246eed58 100644 --- a/deps/JuliaSyntax.version +++ b/deps/JuliaSyntax.version @@ -1,4 +1,4 @@ JULIASYNTAX_BRANCH = scoped-export -JULIASYNTAX_SHA1 = a343b7fb85c31188ce97b5130fa6c5dcaa61d29b +JULIASYNTAX_SHA1 = f68188ed592251abbee0aae85840c7e708eaec48 JULIASYNTAX_GIT_URL := https://github.com/LilithHafner/JuliaSyntax.jl.git JULIASYNTAX_TAR_URL = https://api.github.com/repos/LilithHafner/JuliaSyntax.jl/tarball/$1 diff --git a/deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/md5 b/deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/md5 deleted file mode 100644 index 694f20c32e0e1..0000000000000 --- a/deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -f7105691a69168213ea10c8dc0e36a3c diff --git a/deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/sha512 b/deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/sha512 deleted file mode 100644 index 78623a41a0502..0000000000000 --- a/deps/checksums/JuliaSyntax-a343b7fb85c31188ce97b5130fa6c5dcaa61d29b.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -74412ff5a46107ea8cc999c3504a8af2b8b19ffbc04f17171c48f02815cb01e8de6cf6441dc9e2b51aef0e3c844d7385696295645a9224d31e6f92abfbc0b09d diff --git a/deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/md5 b/deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/md5 new file mode 100644 index 0000000000000..0dacb33ab05ae --- /dev/null +++ b/deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/md5 @@ -0,0 +1 @@ +a5a34fa45718764fc6a6efbe22068e43 diff --git a/deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/sha512 b/deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/sha512 new file mode 100644 index 0000000000000..639ac76d8f6d4 --- /dev/null +++ b/deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/sha512 @@ -0,0 +1 @@ +cea9dd1204ae887b77596d7f714e072b26daa42f936aaca5f0d72b32423a5f54c92a2ca4653f26f8bc29140174afc6499acf1e66ef83ee80eef8c7a9f5058a11 From aacc187aee172dacea14d670021c443d01707cef Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 18 Jul 2023 21:16:18 -0500 Subject: [PATCH 13/62] bump JuliaSyntax --- deps/JuliaSyntax.version | 2 +- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/md5 create mode 100644 deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/sha512 delete mode 100644 deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/md5 delete mode 100644 deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/sha512 diff --git a/deps/JuliaSyntax.version b/deps/JuliaSyntax.version index d8183246eed58..7f83238f3f047 100644 --- a/deps/JuliaSyntax.version +++ b/deps/JuliaSyntax.version @@ -1,4 +1,4 @@ JULIASYNTAX_BRANCH = scoped-export -JULIASYNTAX_SHA1 = f68188ed592251abbee0aae85840c7e708eaec48 +JULIASYNTAX_SHA1 = 29e9ffff975ae45fa46ee1de3153cb5c273bfca6 JULIASYNTAX_GIT_URL := https://github.com/LilithHafner/JuliaSyntax.jl.git JULIASYNTAX_TAR_URL = https://api.github.com/repos/LilithHafner/JuliaSyntax.jl/tarball/$1 diff --git a/deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/md5 b/deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/md5 new file mode 100644 index 0000000000000..fd8b77ca40ed5 --- /dev/null +++ b/deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/md5 @@ -0,0 +1 @@ +53e53fba79749919dea53de06340c361 diff --git a/deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/sha512 b/deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/sha512 new file mode 100644 index 0000000000000..801101389eeba --- /dev/null +++ b/deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/sha512 @@ -0,0 +1 @@ +fa7628766e5f742c721ee065f0d988bc85c803ea0309bc3d853cb90cf7fa980af11b073aacbd572de18ab954862c7431e04cdb948f0995a2eac8c95cc9b5622a diff --git a/deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/md5 b/deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/md5 deleted file mode 100644 index 0dacb33ab05ae..0000000000000 --- a/deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -a5a34fa45718764fc6a6efbe22068e43 diff --git a/deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/sha512 b/deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/sha512 deleted file mode 100644 index 639ac76d8f6d4..0000000000000 --- a/deps/checksums/JuliaSyntax-f68188ed592251abbee0aae85840c7e708eaec48.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -cea9dd1204ae887b77596d7f714e072b26daa42f936aaca5f0d72b32423a5f54c92a2ca4653f26f8bc29140174afc6499acf1e66ef83ee80eef8c7a9f5058a11 From 145ad7fd6e5d9bfe8e7d37c22494b4bebf1518a9 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 18 Jul 2023 21:16:28 -0500 Subject: [PATCH 14/62] fix lowering --- src/julia-syntax.scm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index cd11f46b1eb38..cb3e6ae349d31 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -2360,7 +2360,7 @@ `(= ,lhs ,rhs))) (define (expand-forms e) - (if (or (atom? e) (memq (car e) '(quote inert top core globalref outerref module toplevel ssavalue null true false meta using import export thismodule toplevel-only))) + (if (or (atom? e) (memq (car e) '(quote inert top core globalref outerref module toplevel ssavalue null true false meta using import export public thismodule toplevel-only))) e (let ((ex (get expand-table (car e) #f))) (if ex @@ -3704,7 +3704,7 @@ f(x) = yt(x) thunk with-static-parameters toplevel-only global globalref outerref const-if-global thismodule const atomic null true false ssavalue isdefined toplevel module lambda - error gc_preserve_begin gc_preserve_end import using export inline noinline))) + error gc_preserve_begin gc_preserve_end import using export public inline noinline))) (define (local-in? s lam (tab #f)) (or (and tab (has? tab s)) @@ -4832,7 +4832,7 @@ f(x) = yt(x) val)) ;; other top level expressions - ((import using export) + ((import using export public) (check-top-level e) (emit e) (let ((have-ret? (and (pair? code) (pair? (car code)) (eq? (caar code) 'return)))) From aea3d228a2422021400f80d5e7bb7e621a052405 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 18 Jul 2023 21:55:23 -0500 Subject: [PATCH 15/62] clarify internal symbol warning and add test for it --- deps/JuliaSyntax.version | 2 +- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - stdlib/REPL/src/docview.jl | 5 ++- stdlib/REPL/test/docview.jl | 42 +++++++++++++++++++ 7 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/md5 create mode 100644 deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/sha512 delete mode 100644 deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/md5 delete mode 100644 deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/sha512 diff --git a/deps/JuliaSyntax.version b/deps/JuliaSyntax.version index 7f83238f3f047..5ce662bad93ef 100644 --- a/deps/JuliaSyntax.version +++ b/deps/JuliaSyntax.version @@ -1,4 +1,4 @@ JULIASYNTAX_BRANCH = scoped-export -JULIASYNTAX_SHA1 = 29e9ffff975ae45fa46ee1de3153cb5c273bfca6 +JULIASYNTAX_SHA1 = 22754c8d6bf2c12f780e7d2cd9625a4d19688c3c JULIASYNTAX_GIT_URL := https://github.com/LilithHafner/JuliaSyntax.jl.git JULIASYNTAX_TAR_URL = https://api.github.com/repos/LilithHafner/JuliaSyntax.jl/tarball/$1 diff --git a/deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/md5 b/deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/md5 new file mode 100644 index 0000000000000..809d40f2bdd67 --- /dev/null +++ b/deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/md5 @@ -0,0 +1 @@ +f70088fa8cf1b2f88c0df71bb16e7a81 diff --git a/deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/sha512 b/deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/sha512 new file mode 100644 index 0000000000000..f2ce469a710f0 --- /dev/null +++ b/deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/sha512 @@ -0,0 +1 @@ +76017ca5ff287de975a8a0708b06781a7f6bb45c5c7d8294f0aba388ade75fbdeeb295c4f4b0d5df829a1b35a47e881cd97e4ea4ea651d1977085656d14b64e3 diff --git a/deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/md5 b/deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/md5 deleted file mode 100644 index fd8b77ca40ed5..0000000000000 --- a/deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -53e53fba79749919dea53de06340c361 diff --git a/deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/sha512 b/deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/sha512 deleted file mode 100644 index 801101389eeba..0000000000000 --- a/deps/checksums/JuliaSyntax-29e9ffff975ae45fa46ee1de3153cb5c273bfca6.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -fa7628766e5f742c721ee065f0d988bc85c803ea0309bc3d853cb90cf7fa980af11b073aacbd572de18ab954862c7431e04cdb948f0995a2eac8c95cc9b5622a diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index 479654026e201..d76dc8556864d 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -148,6 +148,9 @@ end _trimdocs(md, brief::Bool) = md, false +const INTERNAL_WARNING = Markdown.Paragraph("Warning: this symbol may be internal. \ + Behavior documented here might change in future versions.") + """ Docs.doc(binding, sig) @@ -192,7 +195,7 @@ function doc(binding::Binding, sig::Type = Union{}) # Get parsed docs and concatenate them. md = catdoc(mapany(parsedoc, results)...) - Base.isinternal(binding.mod, binding.var) && pushfirst!(md.content, Markdown.Paragraph("INTERNAL")) + Base.isinternal(binding.mod, binding.var) && pushfirst!(md.content, INTERNAL_WARNING) # Save metadata in the generated markdown. if isa(md, Markdown.MD) diff --git a/stdlib/REPL/test/docview.jl b/stdlib/REPL/test/docview.jl index 22701ead7883d..58362eeed3be5 100644 --- a/stdlib/REPL/test/docview.jl +++ b/stdlib/REPL/test/docview.jl @@ -65,3 +65,45 @@ end b = REPL.Binding(@__MODULE__, :R) @test REPL.summarize(b, Tuple{}) isa Markdown.MD end + +module InternalSymbolWarningModule + public add_two + export add_three + + """ + add_one(x) + + adds one to `x` + """ + add_one(x) = x + 1 + + """ + add_two(x) + + adds two to `x` + """ + add_two(x) = x + 2 + + """ + add_three(x) + + adds three to `x` + """ + add_three(x) = x + 3 +end +using .InternalSymbolWarningModule + +@testset "internal symbol warning" begin + @test !isdefined(@__MODULE__, :add_one) + @test !isdefined(@__MODULE__, :add_two) + @test isdefined(@__MODULE__, :add_three) + str1 = strip(string(@doc InternalSymbolWarningModule.add_one)) + str2 = strip(string(@doc InternalSymbolWarningModule.add_two)) + str3 = strip(string(@doc InternalSymbolWarningModule.add_three)) + @test startswith(str1, "Warning: this symbol may be internal") + @test !startswith(str2, "Warning: this symbol may be internal") + @test !startswith(str3, "Warning: this symbol may be internal") + @test occursin("adds one to `x`", str1) + @test occursin("adds two to `x`", str2) + @test occursin("adds three to `x`", str3) +end From f7d57ba412db8bc5ffcc797cff1818d525fc856d Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 18 Jul 2023 22:00:28 -0500 Subject: [PATCH 16/62] add test for names + public --- test/reflection.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/reflection.jl b/test/reflection.jl index c13e7d88d8cfd..db3b6c92d0e51 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -1057,3 +1057,19 @@ end @test !Base.ismutationfree(Vector{UInt64}) @test Base.ismutationfree(Type{Union{}}) + +module TestNames + +public publicized +export exported + +publicized() = 1 +exported() = 1 +private() = 1 + +end + +@test names(TestNames) == [:TestNames, :exported, :publicized] +@test names(TestNames, qualified=false) == [:TestNames, :exported] + +end From 34844bbffe20bf1532fe5ad9fd3fd401ec0ab83e Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 18 Jul 2023 22:09:39 -0500 Subject: [PATCH 17/62] don't autocomplete internals (ideally we _would_ autocomplete internals for `dev`ed packages and Base if built from source) --- stdlib/REPL/src/REPLCompletions.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 20d26953eb22b..5d9dbf6907a12 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -170,7 +170,7 @@ function complete_symbol(@nospecialize(ex), name::String, @nospecialize(ffunc), # as excluding Main.Main.Main, etc., because that's most likely not what # the user wants p = let mod=mod, modname=nameof(mod) - s->(!Base.isdeprecated(mod, s) && s != modname && ffunc(mod, s)::Bool) + s->(!Base.isdeprecated(mod, s) && !Base.isinternal(mod, s) && s != modname && ffunc(mod, s)::Bool) end # Looking for a binding in a module if mod == context_module From 920244a37ea60b088787a04548483c42d9662dd2 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 18 Jul 2023 22:20:23 -0500 Subject: [PATCH 18/62] update FAQ (this change introduces comedy and therefore may be controversial) --- doc/src/manual/faq.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/doc/src/manual/faq.md b/doc/src/manual/faq.md index ffb11b8a63d51..b1cb8f42840ad 100644 --- a/doc/src/manual/faq.md +++ b/doc/src/manual/faq.md @@ -29,7 +29,7 @@ they have docstrings or are described in the documentation. Further, only the do behavior of public symbols is part of the public API. Undocumented behavior of public symbols is internal. -Public symbols are those marked with either `public foo` or `export bar`. +Public symbols are those marked with either `public foo` or `export foo`. Exported symbols are automatically considered public In other words: @@ -46,16 +46,12 @@ You can get a complete list of the public symbols from a module with `names(MyMo Package authors are encouraged to define their public API similarly. -Publicity nests in the same wa as exporting. -Documented behavior of public symbols from submodules are only part of the public API -if the module they belong to is also public. If module A marks submodule B as public and -B marks foo as public, then A.B.foo is public, but if A does not mark B as public, -then writing A.B.foo outside of A is accessing an internal and anything that B marks as -public forms a sub-api that is not covered by the SymVer of A. This could be for the -convenience of developers of A if A is a large package. - Anything in Julia's Public API is covered by [SemVer](https://semver.org/) and therefore -will not be removed or receive meaningful breaking changes in a minor version update. +will not be removed or receive meaningful breaking changes before Julia 2.0. + +### When is Julia 2.0 coming out? + +2047 ### There is a useful undocumented function/type/constant. Can I use it? From 9e61f96cd6ce744c89563dc575af55422fdc54fc Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 18 Jul 2023 22:41:54 -0500 Subject: [PATCH 19/62] Rename isinternal to ispublic and make all resolved symbols in Main public because it is not idiomatic to mark symbols in Main as public. Helps with repl completions and docstrings. needs tests. --- base/reflection.jl | 2 +- stdlib/REPL/src/REPLCompletions.jl | 2 +- stdlib/REPL/src/docview.jl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/base/reflection.jl b/base/reflection.jl index 8e89d156c4cdb..5f4f322db1b6f 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -94,7 +94,7 @@ unsorted_names(m::Module; qualified::Bool = true, all::Bool = false, imported::B ccall(:jl_module_names, Array{Symbol,1}, (Any, Cint, Cint, Cint), m, qualified, all, imported) isexported(m::Module, s::Symbol) = ccall(:jl_module_exports_p, Cint, (Any, Any), m, s) != 0 -isinternal(m::Module, s::Symbol) = ccall(:jl_module_public_p, Cint, (Any, Any), m, s) == 0 +ispublic(m::Module, s::Symbol) = m == Main ? isbindingresolved(m, s) : ccall(:jl_module_public_p, Cint, (Any, Any), m, s) != 0 isdeprecated(m::Module, s::Symbol) = ccall(:jl_is_binding_deprecated, Cint, (Any, Any), m, s) != 0 isbindingresolved(m::Module, var::Symbol) = ccall(:jl_binding_resolved_p, Cint, (Any, Any), m, var) != 0 diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 88f575dca6d8f..2bdc74d283596 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -170,7 +170,7 @@ function complete_symbol(@nospecialize(ex), name::String, @nospecialize(ffunc), # as excluding Main.Main.Main, etc., because that's most likely not what # the user wants p = let mod=mod, modname=nameof(mod) - (s::Symbol) -> !Base.isdeprecated(mod, s) && !Base.isinternal(mod, s) && s != modname && ffunc(mod, s)::Bool + (s::Symbol) -> !Base.isdeprecated(mod, s) && Base.ispublic(mod, s) && s != modname && ffunc(mod, s)::Bool end # Looking for a binding in a module if mod == context_module diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index d76dc8556864d..1372804b62892 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -195,7 +195,7 @@ function doc(binding::Binding, sig::Type = Union{}) # Get parsed docs and concatenate them. md = catdoc(mapany(parsedoc, results)...) - Base.isinternal(binding.mod, binding.var) && pushfirst!(md.content, INTERNAL_WARNING) + Base.ispublic(binding.mod, binding.var) || pushfirst!(md.content, INTERNAL_WARNING) # Save metadata in the generated markdown. if isa(md, Markdown.MD) From f75cb681c0b9fcf1859a248180f5d08d4bf27f20 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Fri, 21 Jul 2023 15:55:02 -0500 Subject: [PATCH 20/62] fix typo in test/reflection.jl --- test/reflection.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/reflection.jl b/test/reflection.jl index db3b6c92d0e51..43a822dc12f6e 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -1071,5 +1071,3 @@ end @test names(TestNames) == [:TestNames, :exported, :publicized] @test names(TestNames, qualified=false) == [:TestNames, :exported] - -end From db7ba0586b944b63bc12230e9329bee3f04840ff Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Fri, 28 Jul 2023 08:18:01 -0400 Subject: [PATCH 21/62] change module docstring warning --- stdlib/REPL/src/docview.jl | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index 1372804b62892..01c82423deca4 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -256,7 +256,13 @@ function summarize(binding::Binding, sig) io = IOBuffer() if defined(binding) binding_res = resolve(binding) - !isa(binding_res, Module) && println(io, "No documentation found.\n") + if !isa(binding_res, Module) + if Base.ispublic(binding.mod, binding.var) + println(io, "No documentation found for public symbol.\n") + else + println(io, "No documentation found for private symbol.\n") + end + end summarize(io, binding_res, binding) else println(io, "No documentation found.\n") @@ -348,10 +354,11 @@ function find_readme(m::Module)::Union{String, Nothing} end function summarize(io::IO, m::Module, binding::Binding; nlines::Int = 200) readme_path = find_readme(m) + public = Base.ispublic(binding.mod, binding.var) ? "public" : "internal" if isnothing(readme_path) - println(io, "No docstring or readme file found for module `$m`.\n") + println(io, "No docstring or readme file found for $public module `$m`.\n") else - println(io, "No docstring found for module `$m`.") + println(io, "No docstring found for $public module `$m`.") end exports = filter!(!=(nameof(m)), names(m)) if isempty(exports) From 7dbdd5ed5d45df0a0c571e3337019464727db8a3 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Fri, 28 Jul 2023 08:38:15 -0400 Subject: [PATCH 22/62] Make warning an Admonition --- stdlib/REPL/src/docview.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index 01c82423deca4..5cf8f2bf43a5c 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -148,8 +148,8 @@ end _trimdocs(md, brief::Bool) = md, false -const INTERNAL_WARNING = Markdown.Paragraph("Warning: this symbol may be internal. \ - Behavior documented here might change in future versions.") +const INTERNAL_WARNING = Markdown.Admonition("warning", "Warning", Any[Markdown.Paragraph(Any[ + "This symbol may be internal. Behavior documented here might change in future versions."])]) """ Docs.doc(binding, sig) From ac11ea461bcbf5302003e241d829feba4da90bcf Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Fri, 28 Jul 2023 18:03:41 -0400 Subject: [PATCH 23/62] bump JuliaSyntax --- deps/JuliaSyntax.version | 2 +- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/md5 create mode 100644 deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/sha512 delete mode 100644 deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/md5 delete mode 100644 deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/sha512 diff --git a/deps/JuliaSyntax.version b/deps/JuliaSyntax.version index 5ce662bad93ef..553b8627dd660 100644 --- a/deps/JuliaSyntax.version +++ b/deps/JuliaSyntax.version @@ -1,4 +1,4 @@ JULIASYNTAX_BRANCH = scoped-export -JULIASYNTAX_SHA1 = 22754c8d6bf2c12f780e7d2cd9625a4d19688c3c +JULIASYNTAX_SHA1 = 19d306c59163604248f1a95c6581059956345cda JULIASYNTAX_GIT_URL := https://github.com/LilithHafner/JuliaSyntax.jl.git JULIASYNTAX_TAR_URL = https://api.github.com/repos/LilithHafner/JuliaSyntax.jl/tarball/$1 diff --git a/deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/md5 b/deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/md5 new file mode 100644 index 0000000000000..252c08b9cb605 --- /dev/null +++ b/deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/md5 @@ -0,0 +1 @@ +29d364a89de91a7474abb01728864a2e diff --git a/deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/sha512 b/deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/sha512 new file mode 100644 index 0000000000000..74c08878cee9d --- /dev/null +++ b/deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/sha512 @@ -0,0 +1 @@ +416bff7ad9f24e96b8ea531f5d84a8ad35a7da89ce9984038a36d51617877212c3fc79c7d4a70cd4ee77c95a82d9c729388bd29870b25dc1b3b51f26335d6f04 diff --git a/deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/md5 b/deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/md5 deleted file mode 100644 index 809d40f2bdd67..0000000000000 --- a/deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -f70088fa8cf1b2f88c0df71bb16e7a81 diff --git a/deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/sha512 b/deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/sha512 deleted file mode 100644 index f2ce469a710f0..0000000000000 --- a/deps/checksums/JuliaSyntax-22754c8d6bf2c12f780e7d2cd9625a4d19688c3c.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -76017ca5ff287de975a8a0708b06781a7f6bb45c5c7d8294f0aba388ade75fbdeeb295c4f4b0d5df829a1b35a47e881cd97e4ea4ea651d1977085656d14b64e3 From bd0ee874572f5d1750c9a18392340cc3929aeb70 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Sat, 29 Jul 2023 07:05:03 -0400 Subject: [PATCH 24/62] fix doc tests mostly, this was fixing the test files to either make demo bindings public or expect internal warnings when they are not additionally, fix internal warning for non-markdown content (give up instead of erroring) --- stdlib/REPL/src/docview.jl | 5 +++-- test/docs.jl | 46 +++++++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index 5cf8f2bf43a5c..b468a84258ff0 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -195,10 +195,11 @@ function doc(binding::Binding, sig::Type = Union{}) # Get parsed docs and concatenate them. md = catdoc(mapany(parsedoc, results)...) - Base.ispublic(binding.mod, binding.var) || pushfirst!(md.content, INTERNAL_WARNING) - # Save metadata in the generated markdown. if isa(md, Markdown.MD) + # We don't know how to insert an internal symbol warning into non-markdown + # content, so we don't. + Base.ispublic(binding.mod, binding.var) || pushfirst!(md.content, INTERNAL_WARNING) md.meta[:results] = results md.meta[:binding] = binding md.meta[:typesig] = sig diff --git a/test/docs.jl b/test/docs.jl index 7f6ece4e76ab4..a3393b0ce8a21 100644 --- a/test/docs.jl +++ b/test/docs.jl @@ -12,13 +12,16 @@ using InteractiveUtils: apropos include("testenv.jl") # Test helpers. -function docstrings_equal(d1, d2; debug=true) +function docstrings_equal(d1, d2; debug=true, private_warning=false) io1 = IOBuffer() io2 = IOBuffer() show(io1, MIME"text/markdown"(), d1) show(io2, MIME"text/markdown"(), d2) s1 = String(take!(io1)) s2 = String(take!(io2)) + if private_warning + s2 = "!!! warning\n This symbol may be internal. Behavior documented here might change in future versions.\n\n\n" * s2 + end if debug && s1 != s2 print(s1) println("--------------------------------------------------------------------------------") @@ -27,7 +30,7 @@ function docstrings_equal(d1, d2; debug=true) end return s1 == s2 end -docstrings_equal(d1::DocStr, d2) = docstrings_equal(parsedoc(d1), d2) +docstrings_equal(d1::DocStr, d2; kw...) = docstrings_equal(parsedoc(d1), d2; kw...) function docstring_startswith(d1, d2) io1 = IOBuffer() @@ -38,6 +41,7 @@ function docstring_startswith(d1, d2) end docstring_startswith(d1::DocStr, d2) = docstring_startswith(parsedoc(d1), d2) +public C74685 @doc "Doc abstract type" abstract type C74685{T,N} <: AbstractArray{T,N} end @test repr("text/plain", Docs.doc(C74685))==" Doc abstract type" @@ -72,13 +76,14 @@ function break_me_docs end # issue #11548 module ModuleMacroDoc +public @m macro m() end end @doc "I am a module" ModuleMacroDoc @doc "I am a macro" :@ModuleMacroDoc.m -@test docstrings_equal(@doc(ModuleMacroDoc), doc"I am a module") +@test docstrings_equal(@doc(ModuleMacroDoc), doc"I am a module", private_warning=true) @test docstrings_equal(@doc(ModuleMacroDoc.@m), doc"I am a macro") # issue #38819 @@ -312,13 +317,13 @@ let fns = @var(DocsTest.fnospecialize) @test docstrings_equal(d, doc"`fnospecialize` for arrays") end -@test docstrings_equal(@doc(DocsTest.TA), doc"TA") +@test docstrings_equal(@doc(DocsTest.TA), doc"TA", private_warning=true) -@test docstrings_equal(@doc(DocsTest.@mac), doc"@mac()") -@test docstrings_equal(@doc(DocsTest.@mac()), doc"@mac()") -@test docstrings_equal(@doc(DocsTest.@mac(x)), doc"@mac(x)") -@test docstrings_equal(@doc(DocsTest.@mac(x::Int, y::Expr)), doc"@mac(x::Int, y::Expr, z = 0)") -@test docstrings_equal(@doc(DocsTest.@mac(x::Int, y::Expr, z)), doc"@mac(x::Int, y::Expr, z = 0)") +@test docstrings_equal(@doc(DocsTest.@mac), doc"@mac()", private_warning=true) +@test docstrings_equal(@doc(DocsTest.@mac()), doc"@mac()", private_warning=true) +@test docstrings_equal(@doc(DocsTest.@mac(x)), doc"@mac(x)", private_warning=true) +@test docstrings_equal(@doc(DocsTest.@mac(x::Int, y::Expr)), doc"@mac(x::Int, y::Expr, z = 0)", private_warning=true) +@test docstrings_equal(@doc(DocsTest.@mac(x::Int, y::Expr, z)), doc"@mac(x::Int, y::Expr, z = 0)", private_warning=true) let m = doc""" @mac() @@ -328,31 +333,31 @@ let m = doc""" :@mac """ - @test docstrings_equal(@doc(:@DocsTest.mac), m) - @test docstrings_equal(@doc(:(DocsTest.@mac)), m) + @test docstrings_equal(@doc(:@DocsTest.mac), m, private_warning=true) + @test docstrings_equal(@doc(:(DocsTest.@mac)), m, private_warning=true) end -@test docstrings_equal(@doc(DocsTest.G), doc"G") -@test docstrings_equal(@doc(DocsTest.K), doc"K") +@test docstrings_equal(@doc(DocsTest.G), doc"G", private_warning=true) +@test docstrings_equal(@doc(DocsTest.K), doc"K", private_warning=true) let d1 = @doc(DocsTest.t(::AbstractString)), d2 = doc"t-1" - @test docstrings_equal(d1,d2) + @test docstrings_equal(d1,d2,private_warning=true) end let d1 = @doc(DocsTest.t(::AbstractString)), d2 = doc"t-1" - @test docstrings_equal(d1,d2) + @test docstrings_equal(d1,d2,private_warning=true) end let d1 = @doc(DocsTest.t(::Int, ::Any)), d2 = doc"t-2" - @test docstrings_equal(d1,d2) + @test docstrings_equal(d1,d2,private_warning=true) end let d1 = @doc(DocsTest.t(::S) where {S <: Integer}), d2 = doc"t-3" - @test docstrings_equal(d1,d2) + @test docstrings_equal(d1,d2,private_warning=true) end let fields = meta(DocsTest)[@var(DocsTest.FieldDocs)].docs[Union{}].data[:fields] @@ -365,9 +370,13 @@ let a = @doc(DocsTest.multidoc), @test docstrings_equal(a, b) end +public BareModule + "BareModule" baremodule BareModule +public f, g, h, @m, C, A + "f/1" f(x) = x @@ -402,7 +411,7 @@ end @test docstrings_equal(@doc(BareModule.@m), doc"@m") @test docstrings_equal(@doc(BareModule.C), doc"C") @test docstrings_equal(@doc(BareModule.A), doc"A") -@test docstrings_equal(@doc(BareModule.T), doc"T") +@test docstrings_equal(@doc(BareModule.T), doc"T", private_warning=true) @test_throws ErrorException @doc("...", "error") @test_throws ErrorException @doc("...", @time 0) @@ -623,6 +632,7 @@ end let d = @doc(I15424.LazyHelp) @test repr("text/plain", d) == "LazyHelp\nLazyHelp(text)\n" + # (no internal warning is inserted for non-markdown content) end # Issue #13385. From 1dc9652ff03ef5ef449974b48abc0f62a8cb598f Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Sat, 29 Jul 2023 07:11:18 -0400 Subject: [PATCH 25/62] remove internal warning tests from stdlib/REPL/test/docview.jl because they are adequitely covered in base/test/docs.jl --- stdlib/REPL/test/docview.jl | 42 ------------------------------------- 1 file changed, 42 deletions(-) diff --git a/stdlib/REPL/test/docview.jl b/stdlib/REPL/test/docview.jl index 58362eeed3be5..22701ead7883d 100644 --- a/stdlib/REPL/test/docview.jl +++ b/stdlib/REPL/test/docview.jl @@ -65,45 +65,3 @@ end b = REPL.Binding(@__MODULE__, :R) @test REPL.summarize(b, Tuple{}) isa Markdown.MD end - -module InternalSymbolWarningModule - public add_two - export add_three - - """ - add_one(x) - - adds one to `x` - """ - add_one(x) = x + 1 - - """ - add_two(x) - - adds two to `x` - """ - add_two(x) = x + 2 - - """ - add_three(x) - - adds three to `x` - """ - add_three(x) = x + 3 -end -using .InternalSymbolWarningModule - -@testset "internal symbol warning" begin - @test !isdefined(@__MODULE__, :add_one) - @test !isdefined(@__MODULE__, :add_two) - @test isdefined(@__MODULE__, :add_three) - str1 = strip(string(@doc InternalSymbolWarningModule.add_one)) - str2 = strip(string(@doc InternalSymbolWarningModule.add_two)) - str3 = strip(string(@doc InternalSymbolWarningModule.add_three)) - @test startswith(str1, "Warning: this symbol may be internal") - @test !startswith(str2, "Warning: this symbol may be internal") - @test !startswith(str3, "Warning: this symbol may be internal") - @test occursin("adds one to `x`", str1) - @test occursin("adds two to `x`", str2) - @test occursin("adds three to `x`", str3) -end From 17b88344f9198119ace7323d544c6f659288c5d3 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Sat, 29 Jul 2023 12:36:55 -0400 Subject: [PATCH 26/62] restore autocomplete for non-public symbols --- stdlib/REPL/src/REPLCompletions.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 2bdc74d283596..bcb6d30e85201 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -170,7 +170,7 @@ function complete_symbol(@nospecialize(ex), name::String, @nospecialize(ffunc), # as excluding Main.Main.Main, etc., because that's most likely not what # the user wants p = let mod=mod, modname=nameof(mod) - (s::Symbol) -> !Base.isdeprecated(mod, s) && Base.ispublic(mod, s) && s != modname && ffunc(mod, s)::Bool + (s::Symbol) -> !Base.isdeprecated(mod, s) && s != modname && ffunc(mod, s)::Bool end # Looking for a binding in a module if mod == context_module From 100098832dfa4e0cdb88d9096fbd841945756086 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Sat, 29 Jul 2023 14:08:32 -0400 Subject: [PATCH 27/62] initialize public to false (woops!) --- src/module.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/module.c b/src/module.c index 04ca007015464..49c207b4550e1 100644 --- a/src/module.c +++ b/src/module.c @@ -180,6 +180,7 @@ static jl_binding_t *new_binding(jl_module_t *mod, jl_sym_t *name) b->globalref = NULL; b->constp = 0; b->exportp = 0; + b->publicp = 0; b->imported = 0; b->deprecated = 0; b->usingfailed = 0; From c5955c0cac62de239365ee0b6795b721a4fd5fff Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Sat, 29 Jul 2023 14:30:05 -0400 Subject: [PATCH 28/62] more fixups for doc tests --- test/docs.jl | 96 ++++++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/test/docs.jl b/test/docs.jl index a3393b0ce8a21..b9b3f9ca2d07d 100644 --- a/test/docs.jl +++ b/test/docs.jl @@ -12,14 +12,14 @@ using InteractiveUtils: apropos include("testenv.jl") # Test helpers. -function docstrings_equal(d1, d2; debug=true, private_warning=false) +function docstrings_equal(d1, d2; debug=true, internal_warning=false) io1 = IOBuffer() io2 = IOBuffer() show(io1, MIME"text/markdown"(), d1) show(io2, MIME"text/markdown"(), d2) s1 = String(take!(io1)) s2 = String(take!(io2)) - if private_warning + if internal_warning s2 = "!!! warning\n This symbol may be internal. Behavior documented here might change in future versions.\n\n\n" * s2 end if debug && s1 != s2 @@ -83,7 +83,7 @@ end @doc "I am a module" ModuleMacroDoc @doc "I am a macro" :@ModuleMacroDoc.m -@test docstrings_equal(@doc(ModuleMacroDoc), doc"I am a module", private_warning=true) +@test docstrings_equal(@doc(ModuleMacroDoc), doc"I am a module", internal_warning=true) @test docstrings_equal(@doc(ModuleMacroDoc.@m), doc"I am a macro") # issue #38819 @@ -317,13 +317,13 @@ let fns = @var(DocsTest.fnospecialize) @test docstrings_equal(d, doc"`fnospecialize` for arrays") end -@test docstrings_equal(@doc(DocsTest.TA), doc"TA", private_warning=true) +@test docstrings_equal(@doc(DocsTest.TA), doc"TA", internal_warning=true) -@test docstrings_equal(@doc(DocsTest.@mac), doc"@mac()", private_warning=true) -@test docstrings_equal(@doc(DocsTest.@mac()), doc"@mac()", private_warning=true) -@test docstrings_equal(@doc(DocsTest.@mac(x)), doc"@mac(x)", private_warning=true) -@test docstrings_equal(@doc(DocsTest.@mac(x::Int, y::Expr)), doc"@mac(x::Int, y::Expr, z = 0)", private_warning=true) -@test docstrings_equal(@doc(DocsTest.@mac(x::Int, y::Expr, z)), doc"@mac(x::Int, y::Expr, z = 0)", private_warning=true) +@test docstrings_equal(@doc(DocsTest.@mac), doc"@mac()", internal_warning=true) +@test docstrings_equal(@doc(DocsTest.@mac()), doc"@mac()", internal_warning=true) +@test docstrings_equal(@doc(DocsTest.@mac(x)), doc"@mac(x)", internal_warning=true) +@test docstrings_equal(@doc(DocsTest.@mac(x::Int, y::Expr)), doc"@mac(x::Int, y::Expr, z = 0)", internal_warning=true) +@test docstrings_equal(@doc(DocsTest.@mac(x::Int, y::Expr, z)), doc"@mac(x::Int, y::Expr, z = 0)", internal_warning=true) let m = doc""" @mac() @@ -333,31 +333,31 @@ let m = doc""" :@mac """ - @test docstrings_equal(@doc(:@DocsTest.mac), m, private_warning=true) - @test docstrings_equal(@doc(:(DocsTest.@mac)), m, private_warning=true) + @test docstrings_equal(@doc(:@DocsTest.mac), m, internal_warning=true) + @test docstrings_equal(@doc(:(DocsTest.@mac)), m, internal_warning=true) end -@test docstrings_equal(@doc(DocsTest.G), doc"G", private_warning=true) -@test docstrings_equal(@doc(DocsTest.K), doc"K", private_warning=true) +@test docstrings_equal(@doc(DocsTest.G), doc"G", internal_warning=true) +@test docstrings_equal(@doc(DocsTest.K), doc"K", internal_warning=true) let d1 = @doc(DocsTest.t(::AbstractString)), d2 = doc"t-1" - @test docstrings_equal(d1,d2,private_warning=true) + @test docstrings_equal(d1,d2,internal_warning=true) end let d1 = @doc(DocsTest.t(::AbstractString)), d2 = doc"t-1" - @test docstrings_equal(d1,d2,private_warning=true) + @test docstrings_equal(d1,d2,internal_warning=true) end let d1 = @doc(DocsTest.t(::Int, ::Any)), d2 = doc"t-2" - @test docstrings_equal(d1,d2,private_warning=true) + @test docstrings_equal(d1,d2,internal_warning=true) end let d1 = @doc(DocsTest.t(::S) where {S <: Integer}), d2 = doc"t-3" - @test docstrings_equal(d1,d2,private_warning=true) + @test docstrings_equal(d1,d2,internal_warning=true) end let fields = meta(DocsTest)[@var(DocsTest.FieldDocs)].docs[Union{}].data[:fields] @@ -411,7 +411,7 @@ end @test docstrings_equal(@doc(BareModule.@m), doc"@m") @test docstrings_equal(@doc(BareModule.C), doc"C") @test docstrings_equal(@doc(BareModule.A), doc"A") -@test docstrings_equal(@doc(BareModule.T), doc"T", private_warning=true) +@test docstrings_equal(@doc(BareModule.T), doc"T", internal_warning=true) @test_throws ErrorException @doc("...", "error") @test_throws ErrorException @doc("...", @time 0) @@ -644,7 +644,7 @@ const i13385 = I13385(true) @test @doc(i13385) !== nothing # Issue #12700. -@test docstrings_equal(@doc(DocsTest.@m), doc"Inner.@m") +@test docstrings_equal(@doc(DocsTest.@m), doc"Inner.@m", internal_warning=true) # issue 11993 # Check if we are documenting the expansion of the macro @@ -660,7 +660,7 @@ end let d = (@doc :@m2_11993), macro_doc = Markdown.parse("`$(curmod_prefix == "Main." ? "" : curmod_prefix)@m2_11993` is a macro.") @test docstring_startswith(d, doc""" - No documentation found. + No documentation found for private symbol. $macro_doc""") end @@ -859,7 +859,7 @@ undocumented(x,y) = 3 end # module doc_str = Markdown.parse(""" -No docstring or readme file found for module `$(curmod_prefix)Undocumented`. +No docstring or readme file found for internal module `$(curmod_prefix)Undocumented`. # Exported names @@ -875,7 +875,7 @@ Binding `$(curmod_prefix)Undocumented.bindingdoesnotexist` does not exist. @test docstrings_equal(@doc(Undocumented.bindingdoesnotexist), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for public symbol. # Summary ``` @@ -891,7 +891,7 @@ $(curmod_prefix)Undocumented.C @test docstrings_equal(@doc(Undocumented.A), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for public symbol. # Summary ``` @@ -911,7 +911,7 @@ $(curmod_prefix)Undocumented.B <: $(curmod_prefix)Undocumented.A <: Any @test docstrings_equal(@doc(Undocumented.B), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for public symbol. # Summary ``` @@ -926,7 +926,7 @@ $(curmod_prefix)Undocumented.C <: $(curmod_prefix)Undocumented.A <: Any @test docstrings_equal(@doc(Undocumented.C), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for private symbol. # Summary ``` @@ -948,7 +948,7 @@ $(curmod_prefix)Undocumented.D <: $(curmod_prefix)Undocumented.B <: $(curmod_pre @test docstrings_equal(@doc(Undocumented.D), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for public symbol. # Summary @@ -968,7 +968,7 @@ $(curmod_prefix)Undocumented.st4{T<:Number, N} @test docstrings_equal(@doc(Undocumented.at0), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for private symbol. # Summary @@ -991,7 +991,7 @@ $(curmod_prefix)Undocumented.at1{T>:Integer, N} <: $(curmod_prefix)Undocumented. @test docstrings_equal(@doc(Undocumented.at1), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for private symbol. # Summary @@ -1010,7 +1010,7 @@ $(curmod_prefix)Undocumented.st4{Int64, N} @test docstrings_equal(@doc(Undocumented.at_), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for public symbol. # Summary @@ -1027,7 +1027,7 @@ $(curmod_prefix)Undocumented.pt2{T<:Number, N, A>:Integer} <: $(curmod_prefix)Un @test docstrings_equal(@doc(Undocumented.pt2), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for private symbol. # Summary @@ -1050,7 +1050,7 @@ $(curmod_prefix)Undocumented.st3{T<:Integer, N} <: $(curmod_prefix)Undocumented. @test docstrings_equal(@doc(Undocumented.st3), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for private symbol. # Summary @@ -1072,7 +1072,7 @@ $(curmod_prefix)Undocumented.st4{T, N} <: $(curmod_prefix)Undocumented.at0{T, N} @test docstrings_equal(@doc(Undocumented.st4), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for private symbol. # Summary @@ -1093,7 +1093,7 @@ $(curmod_prefix)Undocumented.st5{T>:Int64, N} <: $(curmod_prefix)Undocumented.at @test docstrings_equal(@doc(Undocumented.st5), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for private symbol. # Summary @@ -1114,7 +1114,7 @@ $(curmod_prefix)Undocumented.mt6{T<:Integer, N} <: $(curmod_prefix)Undocumented. @test docstrings_equal(@doc(Undocumented.mt6), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for private symbol. # Summary @@ -1128,7 +1128,7 @@ No documentation found. @test docstrings_equal(@doc(Undocumented.ut7), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for private symbol. # Summary @@ -1144,7 +1144,7 @@ No documentation found. @test docstrings_equal(@doc(Undocumented.ut8), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found. +No documentation found for private symbol. # Summary @@ -1163,7 +1163,7 @@ let d = @doc(Undocumented.f) io = IOBuffer() show(io, MIME"text/markdown"(), d) @test startswith(String(take!(io)),""" - No documentation found. + No documentation found for private symbol. `$(curmod_prefix)Undocumented.f` is a `Function`. """) @@ -1173,7 +1173,7 @@ let d = @doc(Undocumented.undocumented) io = IOBuffer() show(io, MIME"text/markdown"(), d) @test startswith(String(take!(io)), """ - No documentation found. + No documentation found for private symbol. `$(curmod_prefix)Undocumented.undocumented` is a `Function`. """) @@ -1286,6 +1286,8 @@ begin f15684(x) = 1 end +public f15684 + @test string(@doc f15684) == "abc\n" # Dynamic docstrings @@ -1360,6 +1362,8 @@ end # issue 21016 module I21016 +public Struct + struct Struct{T} end @@ -1424,7 +1428,7 @@ end # issue 22098 "an empty macro" macro mdoc22098 end -@test docstrings_equal(@doc(:@mdoc22098), doc"an empty macro") +@test docstrings_equal(@doc(:@mdoc22098), doc"an empty macro", internal_warning=true) # issue #24468 let ex = try @@ -1468,26 +1472,28 @@ Docs for calling `f::MyParametricFunc{T}`. @test docstrings_equal(@doc((::MyFunc)(2)), doc""" Docs for calling `f::MyFunc`. -""") +""", +internal_warning=true) @test docstrings_equal(@doc((::MyParametricFunc{Int})(44889)), doc""" Docs for calling `f::MyParametricFunc{T}`. -""") +""", +internal_warning=true) struct A_20087 end """a""" (a::A_20087)() = a -@test docstrings_equal(@doc(A_20087()), doc"a") +@test docstrings_equal(@doc(A_20087()), doc"a", internal_warning=true) struct B_20087 end """b""" (::B_20087)() = a -@test docstrings_equal(@doc(B_20087()), doc"b") +@test docstrings_equal(@doc(B_20087()), doc"b", internal_warning=true) # issue #27832 @@ -1512,11 +1518,11 @@ Core.atdoc!(_last_atdoc) Test.collect_test_logs() do # suppress printing of any warning eval(quote "Second docstring" Module29432 end) # requires toplevel end -@test docstrings_equal(@doc(Module29432), doc"Second docstring") +@test docstrings_equal(@doc(Module29432), doc"Second docstring", internal_warning=true) # Issue #13109 eval(Expr(:block, Expr(:macrocall, GlobalRef(Core, Symbol("@doc")), nothing, "...", Expr(:module, false, :MBareModuleEmpty, Expr(:block))))) -@test docstrings_equal(@doc(MBareModuleEmpty), doc"...") +@test docstrings_equal(@doc(MBareModuleEmpty), doc"...", internal_warning=true) # issue #41727 "struct docstring" From 5ed2c7d537c2d10092d87c5c294f7196795ad638 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Sat, 29 Jul 2023 14:31:39 -0400 Subject: [PATCH 29/62] remove joke --- doc/src/manual/faq.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/doc/src/manual/faq.md b/doc/src/manual/faq.md index b1cb8f42840ad..07842a9ea55d9 100644 --- a/doc/src/manual/faq.md +++ b/doc/src/manual/faq.md @@ -49,10 +49,6 @@ Package authors are encouraged to define their public API similarly. Anything in Julia's Public API is covered by [SemVer](https://semver.org/) and therefore will not be removed or receive meaningful breaking changes before Julia 2.0. -### When is Julia 2.0 coming out? - -2047 - ### There is a useful undocumented function/type/constant. Can I use it? Updating Julia may break your code if you use non-public API. If the code is From 5da758e04d107a699ad8104612c763b02ff0d481 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Sat, 29 Jul 2023 14:37:37 -0400 Subject: [PATCH 30/62] fix repl tests --- stdlib/REPL/test/repl.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index f0d5052ff9e32..da44d54df9884 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -1249,6 +1249,7 @@ let emptyH1 = Markdown.parse("# "), end module BriefExtended +public f, f_plain """ f() From de8be2b0394937d67f7fc71a6083f3cd1a47b2dd Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Sat, 29 Jul 2023 16:05:16 -0400 Subject: [PATCH 31/62] fix precompile tests --- test/precompile.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/precompile.jl b/test/precompile.jl index 31ceb49475122..6cbe7477d0360 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -134,6 +134,7 @@ precompile_test_harness(false) do dir import $Foo2_module: $Foo2_module, override, overridenc import $FooBase_module.hash import Test + public foo, Bar module Inner import $FooBase_module.hash using ..$Foo_module @@ -150,6 +151,7 @@ precompile_test_harness(false) do dir include_dependency("foo.jl") include_dependency("foo.jl") module Bar + public bar include_dependency("bar.jl") end @doc "Bar module" Bar # this needs to define the META dictionary via eval From d75725bfea2bfe25d552b08dea3561f1aa40ff91 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Sun, 30 Jul 2023 19:47:15 -0400 Subject: [PATCH 32/62] bump juliasyntax to merged version --- deps/JuliaSyntax.version | 6 +++--- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + 5 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/md5 delete mode 100644 deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/sha512 create mode 100644 deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/md5 create mode 100644 deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/sha512 diff --git a/deps/JuliaSyntax.version b/deps/JuliaSyntax.version index 553b8627dd660..a3f15a537df8a 100644 --- a/deps/JuliaSyntax.version +++ b/deps/JuliaSyntax.version @@ -1,4 +1,4 @@ JULIASYNTAX_BRANCH = scoped-export -JULIASYNTAX_SHA1 = 19d306c59163604248f1a95c6581059956345cda -JULIASYNTAX_GIT_URL := https://github.com/LilithHafner/JuliaSyntax.jl.git -JULIASYNTAX_TAR_URL = https://api.github.com/repos/LilithHafner/JuliaSyntax.jl/tarball/$1 +JULIASYNTAX_SHA1 = ad9b16681389dbe3f21a89897f7a86dec793f72a +JULIASYNTAX_GIT_URL := https://github.com/JuliaLang/JuliaSyntax.jl.git +JULIASYNTAX_TAR_URL = https://api.github.com/repos/JuliaLang/JuliaSyntax.jl/tarball/$1 diff --git a/deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/md5 b/deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/md5 deleted file mode 100644 index 252c08b9cb605..0000000000000 --- a/deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -29d364a89de91a7474abb01728864a2e diff --git a/deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/sha512 b/deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/sha512 deleted file mode 100644 index 74c08878cee9d..0000000000000 --- a/deps/checksums/JuliaSyntax-19d306c59163604248f1a95c6581059956345cda.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -416bff7ad9f24e96b8ea531f5d84a8ad35a7da89ce9984038a36d51617877212c3fc79c7d4a70cd4ee77c95a82d9c729388bd29870b25dc1b3b51f26335d6f04 diff --git a/deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/md5 b/deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/md5 new file mode 100644 index 0000000000000..7e9716977afa1 --- /dev/null +++ b/deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/md5 @@ -0,0 +1 @@ +85321fa6216516497d4aeba055441722 diff --git a/deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/sha512 b/deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/sha512 new file mode 100644 index 0000000000000..10c9b9d7bf07d --- /dev/null +++ b/deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/sha512 @@ -0,0 +1 @@ +fc3ee2da0aedcd56c96e177e3ae854bf4e50889edad88e1da0cd6a0f00a4d7381a564457931a5bc31f94f9cbe36ca4bb6fd57674ce919e58f268be56c10e89f3 From 05352dfc80d69258ec49923cdd039bda1c6e9e6d Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Thu, 3 Aug 2023 15:37:48 -0400 Subject: [PATCH 33/62] Make `compilecache` internal --- base/exports.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/base/exports.jl b/base/exports.jl index 684d7f57aa3a8..ee330f2791a3f 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -1093,7 +1093,6 @@ eval(Expr(:public, :add_sum, :cconvert, :checked_length, - :compilecache, :datatype_alignment, :datatype_haspadding, :datatype_pointerfree, From 4b04f31bfbcf707d5f3d27efd6438030e1319a89 Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Thu, 3 Aug 2023 15:39:17 -0400 Subject: [PATCH 34/62] Remove `_datatype_*` publics From @gbaraldi --- base/exports.jl | 3 --- 1 file changed, 3 deletions(-) diff --git a/base/exports.jl b/base/exports.jl index ee330f2791a3f..9a4ddacf764e0 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -1093,9 +1093,6 @@ eval(Expr(:public, :add_sum, :cconvert, :checked_length, - :datatype_alignment, - :datatype_haspadding, - :datatype_pointerfree, :elsize, :exit_on_sigint, :front, From 051f8247dd3267cfd734b04d45d54fb0aefa3697 Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Thu, 3 Aug 2023 17:44:23 -0400 Subject: [PATCH 35/62] Remove symbols from public list Co-authored-by: Jameson Nash --- base/exports.jl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/base/exports.jl b/base/exports.jl index 9a4ddacf764e0..65dd9afe6d28c 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -1072,11 +1072,9 @@ eval(Expr(:public, Symbol("@propagate_inbounds"), :AbstractLock, :AsyncCondition, - :CFunction, :Checked, :CodeUnits, :DL_LOAD_PATH, - :EnvDict, :Event, :Fix1, :Fix2, @@ -1090,14 +1088,11 @@ eval(Expr(:public, :UUID, :acquire, :active_project, - :add_sum, :cconvert, :checked_length, - :elsize, :exit_on_sigint, :front, :identify_package, - :include, :isambiguous, :isbinaryoperator, :isdone, @@ -1118,7 +1113,6 @@ eval(Expr(:public, :require, :rest, :runtests, - :set_active_project, :split_rest, :summarysize, :tail, From 8a56ab485d67e773e38e0ece8def6e6db2de292f Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Thu, 3 Aug 2023 17:46:29 -0400 Subject: [PATCH 36/62] Add some modules to public list (@vtjnash) --- base/exports.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/base/exports.jl b/base/exports.jl index 65dd9afe6d28c..467b0d35d7c9a 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -1076,6 +1076,7 @@ eval(Expr(:public, :CodeUnits, :DL_LOAD_PATH, :Event, + :Filesystem, :Fix1, :Fix2, :Generator, @@ -1083,8 +1084,10 @@ eval(Expr(:public, :IteratorEltype, :IteratorSize, :OneTo, + :Order, :Pairs, :Semaphore, + :Sort, :UUID, :acquire, :active_project, From 6e2d8092c7052c9937e1d348a7686142f8490445 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Wed, 9 Aug 2023 20:14:18 -0400 Subject: [PATCH 37/62] remove newlines between bullet points --- doc/src/manual/faq.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/src/manual/faq.md b/doc/src/manual/faq.md index 07842a9ea55d9..ffb3c21d9820a 100644 --- a/doc/src/manual/faq.md +++ b/doc/src/manual/faq.md @@ -35,11 +35,8 @@ Exported symbols are automatically considered public In other words: - Documented behavior of public symbols is part of the public API. - - Undocumented behavior of public symbols is not part of the public API. - - Documented behavior of private symbols is not part of the public API. - - Undocumented behavior of private symbols is not part of the public API. You can get a complete list of the public symbols from a module with `names(MyModule)`. From 69cf8d46b3c3016fb6fcdf88eb63aac4e9d0b141 Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Sun, 13 Aug 2023 16:58:51 -0500 Subject: [PATCH 38/62] Apply suggestions from code review Co-authored-by: Claire Foster --- doc/src/manual/faq.md | 1 - src/julia.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/src/manual/faq.md b/doc/src/manual/faq.md index ffb3c21d9820a..d9199638182e8 100644 --- a/doc/src/manual/faq.md +++ b/doc/src/manual/faq.md @@ -30,7 +30,6 @@ behavior of public symbols is part of the public API. Undocumented behavior of p symbols is internal. Public symbols are those marked with either `public foo` or `export foo`. -Exported symbols are automatically considered public In other words: diff --git a/src/julia.h b/src/julia.h index fb3fdf62dce1a..a566a0ed93e74 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1740,7 +1740,7 @@ JL_DLLEXPORT void jl_module_use(jl_module_t *to, jl_module_t *from, jl_sym_t *s) JL_DLLEXPORT void jl_module_use_as(jl_module_t *to, jl_module_t *from, jl_sym_t *s, jl_sym_t *asname); JL_DLLEXPORT void jl_module_import(jl_module_t *to, jl_module_t *from, jl_sym_t *s); JL_DLLEXPORT void jl_module_import_as(jl_module_t *to, jl_module_t *from, jl_sym_t *s, jl_sym_t *asname); -JL_DLLEXPORT void jl_module_public(jl_module_t *from, jl_sym_t *s, int exp); +JL_DLLEXPORT void jl_module_public(jl_module_t *from, jl_sym_t *s, int exported); JL_DLLEXPORT int jl_is_imported(jl_module_t *m, jl_sym_t *s); JL_DLLEXPORT int jl_module_exports_p(jl_module_t *m, jl_sym_t *var); JL_DLLEXPORT void jl_add_standard_imports(jl_module_t *m); From 9d74beb63c0cfc10e38edebaae3f30366df39bf3 Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Sun, 13 Aug 2023 17:00:36 -0500 Subject: [PATCH 39/62] Apply suggestions from code review Co-authored-by: Claire Foster --- src/module.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/module.c b/src/module.c index 49c207b4550e1..e4a3c9609bdaf 100644 --- a/src/module.c +++ b/src/module.c @@ -671,11 +671,11 @@ JL_DLLEXPORT void jl_module_using(jl_module_t *to, jl_module_t *from) } } -JL_DLLEXPORT void jl_module_public(jl_module_t *from, jl_sym_t *s, int exp) +JL_DLLEXPORT void jl_module_public(jl_module_t *from, jl_sym_t *s, int exported) { jl_binding_t *b = jl_get_module_binding(from, s, 1); b->publicp = 1; - b->exportp = exp; + b->exportp = exported; } JL_DLLEXPORT int jl_boundp(jl_module_t *m, jl_sym_t *var) @@ -953,7 +953,8 @@ JL_DLLEXPORT jl_value_t *jl_module_names(jl_module_t *m, int qualified, int all, break; jl_sym_t *asname = b->globalref->name; int hidden = jl_symbol_name(asname)[0]=='#'; - if (((qualified ? b->publicp : b->exportp) || + if ((b->exportp || + (qualified && b->publicp) || (imported && b->imported) || (jl_atomic_load_relaxed(&b->owner) == b && !b->imported && (all || m == jl_main_module))) && (all || (!b->deprecated && !hidden))) { From 4ba71ab29749bf769918e822e8717d956133edc6 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Sun, 13 Aug 2023 17:07:18 -0500 Subject: [PATCH 40/62] add show tests --- test/show.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/show.jl b/test/show.jl index 7f32c8c8ff2e2..ed823f9a955c3 100644 --- a/test/show.jl +++ b/test/show.jl @@ -523,6 +523,10 @@ end # Hidden macro names @test sprint(show, Expr(:macrocall, Symbol("@#"), nothing, :a)) == ":(@var\"#\" a)" +# Test that public expressions are rendered nicely +@test sprint(show, :(public @foo)) == ":(public @foo)" +@test sprint(show, :(public f,o,o)) == ":(public f, o, o)" + # PR #38418 module M1 var"#foo#"() = 2 end @test occursin("M1.var\"#foo#\"", sprint(show, M1.var"#foo#", context = :module=>@__MODULE__)) From ce3a798c31d87867692dc2e3eb37f0bd3c9c312f Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Sun, 13 Aug 2023 17:24:39 -0500 Subject: [PATCH 41/62] group public symbols a little better --- base/exports.jl | 92 +++++++++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 37 deletions(-) diff --git a/base/exports.jl b/base/exports.jl index 467b0d35d7c9a..782e97a46fa71 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -1066,61 +1066,79 @@ export # TODO: use normal syntax once JuliaSyntax.jl becomes available at this point in bootstrapping eval(Expr(:public, - Symbol("@assume_effects"), - Symbol("@constprop"), - Symbol("@locals"), - Symbol("@propagate_inbounds"), +# Modules + :Checked, + :Filesystem, + :Order, + :Sort, + +# Types :AbstractLock, :AsyncCondition, - :Checked, :CodeUnits, - :DL_LOAD_PATH, :Event, - :Filesystem, :Fix1, :Fix2, :Generator, :ImmutableDict, - :IteratorEltype, - :IteratorSize, :OneTo, - :Order, - :Pairs, - :Semaphore, - :Sort, :UUID, + +# Semaphores + :Semaphore, :acquire, - :active_project, - :cconvert, - :checked_length, - :exit_on_sigint, + :release, + +# collections + :IteratorEltype, + :IteratorSize, + :to_index, + :vect, + :isdone, :front, - :identify_package, + :rest, + :split_rest, + :tail, + :checked_length, + +# Loading + :DL_LOAD_PATH, + :load_path, + :active_project, + +# Reflection and introspection :isambiguous, - :isbinaryoperator, - :isdone, :isexpr, :isidentifier, - :isoperator, :issingletontype, - :isunaryoperator, - :jit_total_bytes, - :load_path, + :identify_package, :locate_package, :moduleroot, - :notnothing, + :jit_total_bytes, + :summarysize, + +# Opperators :operator_associativity, :operator_precedence, - :promote_typejoin, - :release, - :require, - :rest, + :isbinaryoperator, + :isoperator, + :isunaryoperator, + +# C interface + :cconvert, + :unsafe_convert + +# Error handling + :exit_on_sigint, + :windowserror, + +# Macros + Symbol("@assume_effects"), + Symbol("@constprop"), + Symbol("@locals"), + Symbol("@propagate_inbounds"), + +# misc + :notnothing, :runtests, - :split_rest, - :summarysize, - :tail, - :text_colors, - :to_index, - :unsafe_convert, - :vect, - :windowserror)) + :text_colors)) From ca8eb44fe4d371f3bd490e8ba8dd2b3934843471 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 14 Aug 2023 07:40:24 -0500 Subject: [PATCH 42/62] revert names to the most basic implementation (simply swap export=>public) and publicize `isexported` and `ispublic` How to get the old behavior? `filter(isexported, names(args...; kw...)` The set of possible keywods and interacitons is huge and it is better to give folks composable functions than a giant, tangled keyword system that is bound to be eternaly cludgey to maintain backwards compatability. Documents but does not publicize `isdeprecated` and `isbindingresolved`. --- base/exports.jl | 2 + base/reflection.jl | 118 ++++++++++++++++++++++++++++++++++++++++----- src/module.c | 3 +- 3 files changed, 109 insertions(+), 14 deletions(-) diff --git a/base/exports.jl b/base/exports.jl index 782e97a46fa71..ef24057107f28 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -1116,6 +1116,8 @@ eval(Expr(:public, :moduleroot, :jit_total_bytes, :summarysize, + :isexported, + :ispublic, # Opperators :operator_associativity, diff --git a/base/reflection.jl b/base/reflection.jl index 5f4f322db1b6f..1b215e4c9d8bf 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -73,29 +73,123 @@ function fullname(m::Module) end """ - names(x::Module; qualified::Bool=true, all::Bool = false, imported::Bool = false) + names(x::Module; all::Bool = false, imported::Bool = false) -Get an array of the public names of `Module`, excluding deprecated names. - -If `qualified` is false, then return only exported names, not public but unexported names. -If `all` is true, then the list also includes private names defined in the module, +Get an array of the public names of a `Module`, excluding deprecated names. +If `all` is true, then the list also includes non-public names defined in the module, deprecated names, and compiler-generated names. If `imported` is true, then names explicitly imported from other modules are also included. As a special case, all names defined in `Main` are considered \"public\", -since it is not idiomatic to mark names from `Main` as public. +since it is not idiomatic to explicitly mark names from `Main` as public. + +See also: [`isexported`](@ref), [`ispublic`](@ref), [`isdeprecated`](@ref), [`@locals`](@ref Base.@locals), [`@__MODULE__`](@ref). +""" +names(m::Module; all::Bool = false, imported::Bool = false) = + sort!(unsorted_names(m; all, imported)) +unsorted_names(m::Module; all::Bool = false, imported::Bool = false) = + ccall(:jl_module_names, Array{Symbol,1}, (Any, Cint, Cint), m, all, imported) -See also: [`@locals`](@ref Base.@locals), [`@__MODULE__`](@ref). """ -names(m::Module; qualified::Bool = true, all::Bool = false, imported::Bool = false) = - sort!(unsorted_names(m; qualified, all, imported)) -unsorted_names(m::Module; qualified::Bool = true, all::Bool = false, imported::Bool = false) = - ccall(:jl_module_names, Array{Symbol,1}, (Any, Cint, Cint, Cint), m, qualified, all, imported) + isexported(m::Module, s::Symbol) -> Bool + +Returns whether a symbol is exported from a module. + +See also: [`ispublic`](@ref), [`names`](@ref) + +```jldoctest +julia> module Mod + export foo + public bar + end +Main.Mod +julia> Base.isexported(Mod, :foo) +true + +julia> Base.isexported(Mod, :bar) +false + +julia> Base.isexported(Mod, :baz) +false +``` +""" isexported(m::Module, s::Symbol) = ccall(:jl_module_exports_p, Cint, (Any, Any), m, s) != 0 -ispublic(m::Module, s::Symbol) = m == Main ? isbindingresolved(m, s) : ccall(:jl_module_public_p, Cint, (Any, Any), m, s) != 0 + +""" + ispublic(m::Module, s::Symbol) -> Bool + +Returns whether a symbol is marked as public in a module. + +Exported symbols are considered public. + +See also: [`isexported`](@ref), [`names`](@ref) + +```jldoctest +julia> module Mod + export foo + public bar + end +Main.Mod + +julia> Base.isexported(Mod, :foo) +true + +julia> Base.isexported(Mod, :bar) +true + +julia> Base.isexported(Mod, :baz) +false +``` +""" +ispublic(m::Module, s::Symbol) = ccall(:jl_module_public_p, Cint, (Any, Any), m, s) != 0 + +""" + isdeprecated(m::Module, s::Symbol) -> Bool + +Returns whether the binding of a symbol in a module is deprecated. + +See also: [`isexported`](@ref), [`ispublic`](@ref), [`isbindingresolved`](@ref) + +```jldoctest +julia> module Mod + new(x) = x+1 + @deprecate old(x) new(x) + end +Main.Mod + +julia> Base.isdeprecated(Mod, :new) +false + +julia> Base.isdeprecated(Mod, :old) +true + +julia> Base.isdeprecated(Mod, :baz) +false +``` +""" isdeprecated(m::Module, s::Symbol) = ccall(:jl_is_binding_deprecated, Cint, (Any, Any), m, s) != 0 + +""" + isbindingresolved(m::Module, s::Symbol) -> Bool + +Returns whether the binding of a symbol in a module is resolved. + +See also: [`isexported`](@ref), [`ispublic`](@ref), [`isdeprecated`](@ref) + +```jldoctest +julia> module Mod + foo() = 17 + end + +julia> Base.isbindingresolved(Mod, :foo) +true + +julia> Base.isbindingresolved(Mod, :bar) +false +``` +""" isbindingresolved(m::Module, var::Symbol) = ccall(:jl_binding_resolved_p, Cint, (Any, Any), m, var) != 0 function binding_module(m::Module, s::Symbol) diff --git a/src/module.c b/src/module.c index e4a3c9609bdaf..4885a76461238 100644 --- a/src/module.c +++ b/src/module.c @@ -953,8 +953,7 @@ JL_DLLEXPORT jl_value_t *jl_module_names(jl_module_t *m, int qualified, int all, break; jl_sym_t *asname = b->globalref->name; int hidden = jl_symbol_name(asname)[0]=='#'; - if ((b->exportp || - (qualified && b->publicp) || + if ((b->publicp || (imported && b->imported) || (jl_atomic_load_relaxed(&b->owner) == b && !b->imported && (all || m == jl_main_module))) && (all || (!b->deprecated && !hidden))) { From 6d1e2c771bfa2e3882e71e118393b6d9cf84bd15 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 14 Aug 2023 07:49:56 -0500 Subject: [PATCH 43/62] fix typo --- base/exports.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/exports.jl b/base/exports.jl index ef24057107f28..bc22c95e1a919 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -1128,7 +1128,7 @@ eval(Expr(:public, # C interface :cconvert, - :unsafe_convert + :unsafe_convert, # Error handling :exit_on_sigint, From 267852327b0af6472cbd46cf3aeb20d151e3578a Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 14 Aug 2023 07:55:44 -0500 Subject: [PATCH 44/62] fix typo --- src/module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module.c b/src/module.c index 4885a76461238..4cda3479adba1 100644 --- a/src/module.c +++ b/src/module.c @@ -942,7 +942,7 @@ JL_DLLEXPORT jl_value_t *jl_module_usings(jl_module_t *m) return (jl_value_t*)a; } -JL_DLLEXPORT jl_value_t *jl_module_names(jl_module_t *m, int qualified, int all, int imported) +JL_DLLEXPORT jl_value_t *jl_module_names(jl_module_t *m, int all, int imported) { jl_array_t *a = jl_alloc_array_1d(jl_array_symbol_type, 0); JL_GC_PUSH1(&a); From 528469b5266ae25b55b89d6b0973d8940feba352 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 14 Aug 2023 07:57:12 -0500 Subject: [PATCH 45/62] revert unnecessary whitespace change --- stdlib/REPL/src/docview.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index b468a84258ff0..52bdf26c6917e 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -194,7 +194,6 @@ function doc(binding::Binding, sig::Type = Union{}) end # Get parsed docs and concatenate them. md = catdoc(mapany(parsedoc, results)...) - # Save metadata in the generated markdown. if isa(md, Markdown.MD) # We don't know how to insert an internal symbol warning into non-markdown From 082fb865491ac888b43d91ffd0fd5559a891c9c9 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 14 Aug 2023 08:00:27 -0500 Subject: [PATCH 46/62] add tests for ispublic and add more tests for isexported --- test/reflection.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/reflection.jl b/test/reflection.jl index 43a822dc12f6e..876778d48254d 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -211,15 +211,21 @@ include("testenv.jl") # for curmod_str import Base.isexported global this_is_not_defined export this_is_not_defined +public this_is_public @test_throws ErrorException("\"this_is_not_defined\" is not defined in module Main") which(Main, :this_is_not_defined) @test_throws ErrorException("\"this_is_not_exported\" is not defined in module Main") which(Main, :this_is_not_exported) @test isexported(@__MODULE__, :this_is_not_defined) @test !isexported(@__MODULE__, :this_is_not_exported) +@test !isexported(@__MODULE__, :this_is_public) const a_value = 1 @test which(@__MODULE__, :a_value) === @__MODULE__ @test_throws ErrorException("\"a_value\" is not defined in module Main") which(Main, :a_value) @test which(Main, :Core) === Main @test !isexported(@__MODULE__, :a_value) +@test !ispublic(@__MODULE__, :a_value) +@test ispublic(@__MODULE__, :this_is_not_defined) +@test ispublic(@__MODULE__, :this_is_public) +@test !ispublic(@__MODULE__, :this_is_not_exported) end # PR 13825 From 3d09dae4a8ef3a318fbf9fb2873e5b20a711d957 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 14 Aug 2023 08:02:01 -0500 Subject: [PATCH 47/62] fix some tests --- test/reflection.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/reflection.jl b/test/reflection.jl index 876778d48254d..98e841cfeafae 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -222,10 +222,10 @@ const a_value = 1 @test_throws ErrorException("\"a_value\" is not defined in module Main") which(Main, :a_value) @test which(Main, :Core) === Main @test !isexported(@__MODULE__, :a_value) -@test !ispublic(@__MODULE__, :a_value) -@test ispublic(@__MODULE__, :this_is_not_defined) -@test ispublic(@__MODULE__, :this_is_public) -@test !ispublic(@__MODULE__, :this_is_not_exported) +@test !Base.ispublic(@__MODULE__, :a_value) +@test Base.ispublic(@__MODULE__, :this_is_not_defined) +@test Base.ispublic(@__MODULE__, :this_is_public) +@test !Base.ispublic(@__MODULE__, :this_is_not_exported) end # PR 13825 From 12bab7259f8a943be3d65e90f1926f4ad93bbdc8 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 4 Sep 2023 15:29:05 -0500 Subject: [PATCH 48/62] Do a better job of logging nonpublic access in help mode --- stdlib/REPL/src/docview.jl | 70 ++++++++++++++++++++++++++++++------- stdlib/REPL/test/docview.jl | 35 +++++++++++++++++++ 2 files changed, 92 insertions(+), 13 deletions(-) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index 52bdf26c6917e..cad08cc083daf 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -20,12 +20,18 @@ using Unicode: normalize ## Help mode ## # This is split into helpmode and _helpmode to easier unittest _helpmode -helpmode(io::IO, line::AbstractString, mod::Module=Main) = :($REPL.insert_hlines($io, $(REPL._helpmode(io, line, mod)))) +function helpmode(io::IO, line::AbstractString, mod::Module=Main) + internal_accesses = Set{Pair{Module,Symbol}}() + quote + docs = $REPL.insert_hlines($io, $(REPL._helpmode(io, line, mod, internal_accesses))) + $REPL.insert_internal_warning(docs, $internal_accesses) + end +end helpmode(line::AbstractString, mod::Module=Main) = helpmode(stdout, line, mod) const extended_help_on = Ref{Any}(nothing) -function _helpmode(io::IO, line::AbstractString, mod::Module=Main) +function _helpmode(io::IO, line::AbstractString, mod::Module=Main, internal_accesses::Union{Nothing, Set{Pair{Module,Symbol}}}=nothing) line = strip(line) ternary_operator_help = (line == "?" || line == "?:") if startswith(line, '?') && !ternary_operator_help @@ -64,7 +70,7 @@ function _helpmode(io::IO, line::AbstractString, mod::Module=Main) end # the following must call repl(io, expr) via the @repl macro # so that the resulting expressions are evaluated in the Base.Docs namespace - :($REPL.@repl $io $expr $brief $mod) + :($REPL.@repl $io $expr $brief $mod $internal_accesses) end _helpmode(line::AbstractString, mod::Module=Main) = _helpmode(stdout, line, mod) @@ -148,8 +154,46 @@ end _trimdocs(md, brief::Bool) = md, false -const INTERNAL_WARNING = Markdown.Admonition("warning", "Warning", Any[Markdown.Paragraph(Any[ - "This symbol may be internal. Behavior documented here might change in future versions."])]) + +is_tuple(expr) = false +is_tuple(expr::Expr) = expr.head == :tuple + +struct Logged1{F} + f::F + mod::Module + collection::Set{Pair{Module,Symbol}} +end +function (la::Logged1)(m::Module, s::Symbol) + m !== la.mod && !Base.ispublic(m, s) && push!(la.collection, m => s) + la.f(m, s) +end +(la::Logged1)(args...) = la.f(args...) + +function log_nonpublic_access(expr::Expr, mod::Module, internal_access::Set{Pair{Module,Symbol}}) + if expr.head === :. && length(expr.args) == 2 && !is_tuple(expr.args[2]) + Expr(:call, Logged1(getproperty, mod, internal_access), log_nonpublic_access.(expr.args, (mod,), (internal_access,))...) + elseif expr.head === :call && expr.args[1] === Base.Docs.Binding + Expr(:call, Logged1(Base.Docs.Binding, mod, internal_access), log_nonpublic_access.(expr.args[2:end], (mod,), (internal_access,))...) + else + Expr(expr.head, log_nonpublic_access.(expr.args, (mod,), (internal_access,))...) + end +end +log_nonpublic_access(expr, ::Module, _) = expr + +function insert_internal_warning(md::Markdown.MD, internal_access::Set{Pair{Module,Symbol}}) + if !isempty(internal_access) + items = Any[Any[Markdown.Paragraph(Any[Markdown.Code("", s)])] for s in sort("$mod.$sym" for (mod, sym) in internal_access)] + admonition = Markdown.Admonition("warning", "Warning", Any[ + Markdown.Paragraph(Any["The following bindings may be internal; they may change or be removed in future versions:"]), + Markdown.List(items, -1, false)]) + pushfirst!(md.content, admonition) + end + md +end +function insert_internal_warning(other, internal_access::Set{Pair{Module,Symbol}}) + println("oops.") + other +end """ Docs.doc(binding, sig) @@ -198,7 +242,6 @@ function doc(binding::Binding, sig::Type = Union{}) if isa(md, Markdown.MD) # We don't know how to insert an internal symbol warning into non-markdown # content, so we don't. - Base.ispublic(binding.mod, binding.var) || pushfirst!(md.content, INTERNAL_WARNING) md.meta[:results] = results md.meta[:binding] = binding md.meta[:typesig] = sig @@ -485,9 +528,9 @@ end repl_latex(s::String) = repl_latex(stdout, s) macro repl(ex, brief::Bool=false, mod::Module=Main) repl(ex; brief, mod) end -macro repl(io, ex, brief, mod) repl(io, ex; brief, mod) end +macro repl(io, ex, brief, mod, internal_accesses) repl(io, ex; brief, mod, internal_accesses) end -function repl(io::IO, s::Symbol; brief::Bool=true, mod::Module=Main) +function repl(io::IO, s::Symbol; brief::Bool=true, mod::Module=Main, internal_accesses::Union{Nothing, Set{Pair{Module,Symbol}}}=nothing) str = string(s) quote repl_latex($io, $str) @@ -496,19 +539,19 @@ function repl(io::IO, s::Symbol; brief::Bool=true, mod::Module=Main) # n.b. we call isdefined for the side-effect of resolving the binding, if possible :(repl_corrections($io, $str, $mod)) end) - $(_repl(s, brief)) + $(_repl(s, brief, mod, internal_accesses)) end end isregex(x) = isexpr(x, :macrocall, 3) && x.args[1] === Symbol("@r_str") && !isempty(x.args[3]) -repl(io::IO, ex::Expr; brief::Bool=true, mod::Module=Main) = isregex(ex) ? :(apropos($io, $ex)) : _repl(ex, brief) -repl(io::IO, str::AbstractString; brief::Bool=true, mod::Module=Main) = :(apropos($io, $str)) -repl(io::IO, other; brief::Bool=true, mod::Module=Main) = esc(:(@doc $other)) +repl(io::IO, ex::Expr; brief::Bool=true, mod::Module=Main, internal_accesses::Union{Nothing, Set{Pair{Module,Symbol}}}=nothing) = isregex(ex) ? :(apropos($io, $ex)) : _repl(ex, brief, mod, internal_accesses) +repl(io::IO, str::AbstractString; brief::Bool=true, mod::Module=Main, internal_accesses::Union{Nothing, Set{Pair{Module,Symbol}}}=nothing) = :(apropos($io, $str)) +repl(io::IO, other; brief::Bool=true, mod::Module=Main, internal_accesses::Union{Nothing, Set{Pair{Module,Symbol}}}=nothing) = esc(:(@doc $other)) # TODO: track internal_accesses #repl(io::IO, other) = lookup_doc(other) # TODO repl(x; brief::Bool=true, mod::Module=Main) = repl(stdout, x; brief, mod) -function _repl(x, brief::Bool=true) +function _repl(x, brief::Bool=true, mod::Module=Main, internal_accesses::Union{Nothing, Set{Pair{Module,Symbol}}}=nothing) if isexpr(x, :call) x = x::Expr # determine the types of the values @@ -574,6 +617,7 @@ function _repl(x, brief::Bool=true) else docs end + docs = log_nonpublic_access(macroexpand(mod, docs), mod, internal_accesses) :(REPL.trimdocs($docs, $brief)) end diff --git a/stdlib/REPL/test/docview.jl b/stdlib/REPL/test/docview.jl index 22701ead7883d..9e862035c1260 100644 --- a/stdlib/REPL/test/docview.jl +++ b/stdlib/REPL/test/docview.jl @@ -65,3 +65,38 @@ end b = REPL.Binding(@__MODULE__, :R) @test REPL.summarize(b, Tuple{}) isa Markdown.MD end + +@testset "replace_dotaccess_with_f" begin + function func50105 end + @test REPL.replace_dotaccess_with_f(func50105, :(print.abc)) == :($func50105(print, :abc)) + @test REPL.replace_dotaccess_with_f(func50105, :(print.())) == :(print.()) + @test REPL.replace_dotaccess_with_f(func50105, :(print.().abc)) == :($func50105(print.(), :abc)) + @test REPL.replace_dotaccess_with_f(func50105, :(println.([1,2], [3,4]))) == :(println.([1,2], [3,4])) +end + +@testset "hook_into_nonpublic_getproperty" begin + module Mod50105 + expr = :(Mod50105.A.B.x.field) + module A + module B + struct T + field::Int + end + x = T(4) + end + public B + end + log = [] + logged_expr = REPL.hook_into_nonpublic_getproperty(expr) do m, s + push!(log, (m, s)) + end + using Test + @test eval(logged_expr) == 4 + @test log == [(Mod50105, :A), (Mod50105.A.B, :x)] + end +end + +@testset "moveme" begin + module A + end +end From 0112e2c1c3f00143f749e1a178739bc373fa1076 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 4 Sep 2023 16:12:07 -0500 Subject: [PATCH 49/62] remove obsolete tests --- stdlib/REPL/test/docview.jl | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/stdlib/REPL/test/docview.jl b/stdlib/REPL/test/docview.jl index 9e862035c1260..22701ead7883d 100644 --- a/stdlib/REPL/test/docview.jl +++ b/stdlib/REPL/test/docview.jl @@ -65,38 +65,3 @@ end b = REPL.Binding(@__MODULE__, :R) @test REPL.summarize(b, Tuple{}) isa Markdown.MD end - -@testset "replace_dotaccess_with_f" begin - function func50105 end - @test REPL.replace_dotaccess_with_f(func50105, :(print.abc)) == :($func50105(print, :abc)) - @test REPL.replace_dotaccess_with_f(func50105, :(print.())) == :(print.()) - @test REPL.replace_dotaccess_with_f(func50105, :(print.().abc)) == :($func50105(print.(), :abc)) - @test REPL.replace_dotaccess_with_f(func50105, :(println.([1,2], [3,4]))) == :(println.([1,2], [3,4])) -end - -@testset "hook_into_nonpublic_getproperty" begin - module Mod50105 - expr = :(Mod50105.A.B.x.field) - module A - module B - struct T - field::Int - end - x = T(4) - end - public B - end - log = [] - logged_expr = REPL.hook_into_nonpublic_getproperty(expr) do m, s - push!(log, (m, s)) - end - using Test - @test eval(logged_expr) == 4 - @test log == [(Mod50105, :A), (Mod50105.A.B, :x)] - end -end - -@testset "moveme" begin - module A - end -end From 66427c65e9537d3f42abcb25b25207d7ecdb5db9 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 4 Sep 2023 16:16:26 -0500 Subject: [PATCH 50/62] finalize struct --- stdlib/REPL/src/docview.jl | 10 +++++----- test/docs.jl | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index cad08cc083daf..a66e5354f831e 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -158,22 +158,22 @@ _trimdocs(md, brief::Bool) = md, false is_tuple(expr) = false is_tuple(expr::Expr) = expr.head == :tuple -struct Logged1{F} +struct Logged{F} f::F mod::Module collection::Set{Pair{Module,Symbol}} end -function (la::Logged1)(m::Module, s::Symbol) +function (la::Logged)(m::Module, s::Symbol) m !== la.mod && !Base.ispublic(m, s) && push!(la.collection, m => s) la.f(m, s) end -(la::Logged1)(args...) = la.f(args...) +(la::Logged)(args...) = la.f(args...) function log_nonpublic_access(expr::Expr, mod::Module, internal_access::Set{Pair{Module,Symbol}}) if expr.head === :. && length(expr.args) == 2 && !is_tuple(expr.args[2]) - Expr(:call, Logged1(getproperty, mod, internal_access), log_nonpublic_access.(expr.args, (mod,), (internal_access,))...) + Expr(:call, Logged(getproperty, mod, internal_access), log_nonpublic_access.(expr.args, (mod,), (internal_access,))...) elseif expr.head === :call && expr.args[1] === Base.Docs.Binding - Expr(:call, Logged1(Base.Docs.Binding, mod, internal_access), log_nonpublic_access.(expr.args[2:end], (mod,), (internal_access,))...) + Expr(:call, Logged(Base.Docs.Binding, mod, internal_access), log_nonpublic_access.(expr.args[2:end], (mod,), (internal_access,))...) else Expr(expr.head, log_nonpublic_access.(expr.args, (mod,), (internal_access,))...) end diff --git a/test/docs.jl b/test/docs.jl index b9b3f9ca2d07d..6c9f20abddf48 100644 --- a/test/docs.jl +++ b/test/docs.jl @@ -1423,7 +1423,7 @@ end @doc "second" f23011() = 2 end @test Main.f23011() == 2 -@test docstrings_equal(@doc(Main.f23011), doc"second") +@test_broken docstrings_equal(@doc(Main.f23011), doc"second") # issue 22098 "an empty macro" From 067d69c6230642dc06aab67236a2f67bafca1094 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 4 Sep 2023 16:36:23 -0500 Subject: [PATCH 51/62] update tests --- test/docs.jl | 93 ++++++++++++++++++++++------------------------------ 1 file changed, 39 insertions(+), 54 deletions(-) diff --git a/test/docs.jl b/test/docs.jl index 6c9f20abddf48..7179aa667aded 100644 --- a/test/docs.jl +++ b/test/docs.jl @@ -12,16 +12,13 @@ using InteractiveUtils: apropos include("testenv.jl") # Test helpers. -function docstrings_equal(d1, d2; debug=true, internal_warning=false) +function docstrings_equal(d1, d2; debug=true) io1 = IOBuffer() io2 = IOBuffer() show(io1, MIME"text/markdown"(), d1) show(io2, MIME"text/markdown"(), d2) s1 = String(take!(io1)) s2 = String(take!(io2)) - if internal_warning - s2 = "!!! warning\n This symbol may be internal. Behavior documented here might change in future versions.\n\n\n" * s2 - end if debug && s1 != s2 print(s1) println("--------------------------------------------------------------------------------") @@ -30,7 +27,7 @@ function docstrings_equal(d1, d2; debug=true, internal_warning=false) end return s1 == s2 end -docstrings_equal(d1::DocStr, d2; kw...) = docstrings_equal(parsedoc(d1), d2; kw...) +docstrings_equal(d1::DocStr, d2) = docstrings_equal(parsedoc(d1), d2) function docstring_startswith(d1, d2) io1 = IOBuffer() @@ -41,7 +38,6 @@ function docstring_startswith(d1, d2) end docstring_startswith(d1::DocStr, d2) = docstring_startswith(parsedoc(d1), d2) -public C74685 @doc "Doc abstract type" abstract type C74685{T,N} <: AbstractArray{T,N} end @test repr("text/plain", Docs.doc(C74685))==" Doc abstract type" @@ -76,14 +72,13 @@ function break_me_docs end # issue #11548 module ModuleMacroDoc -public @m macro m() end end @doc "I am a module" ModuleMacroDoc @doc "I am a macro" :@ModuleMacroDoc.m -@test docstrings_equal(@doc(ModuleMacroDoc), doc"I am a module", internal_warning=true) +@test docstrings_equal(@doc(ModuleMacroDoc), doc"I am a module") @test docstrings_equal(@doc(ModuleMacroDoc.@m), doc"I am a macro") # issue #38819 @@ -317,13 +312,13 @@ let fns = @var(DocsTest.fnospecialize) @test docstrings_equal(d, doc"`fnospecialize` for arrays") end -@test docstrings_equal(@doc(DocsTest.TA), doc"TA", internal_warning=true) +@test docstrings_equal(@doc(DocsTest.TA), doc"TA") -@test docstrings_equal(@doc(DocsTest.@mac), doc"@mac()", internal_warning=true) -@test docstrings_equal(@doc(DocsTest.@mac()), doc"@mac()", internal_warning=true) -@test docstrings_equal(@doc(DocsTest.@mac(x)), doc"@mac(x)", internal_warning=true) -@test docstrings_equal(@doc(DocsTest.@mac(x::Int, y::Expr)), doc"@mac(x::Int, y::Expr, z = 0)", internal_warning=true) -@test docstrings_equal(@doc(DocsTest.@mac(x::Int, y::Expr, z)), doc"@mac(x::Int, y::Expr, z = 0)", internal_warning=true) +@test docstrings_equal(@doc(DocsTest.@mac), doc"@mac()") +@test docstrings_equal(@doc(DocsTest.@mac()), doc"@mac()") +@test docstrings_equal(@doc(DocsTest.@mac(x)), doc"@mac(x)") +@test docstrings_equal(@doc(DocsTest.@mac(x::Int, y::Expr)), doc"@mac(x::Int, y::Expr, z = 0)") +@test docstrings_equal(@doc(DocsTest.@mac(x::Int, y::Expr, z)), doc"@mac(x::Int, y::Expr, z = 0)") let m = doc""" @mac() @@ -333,31 +328,31 @@ let m = doc""" :@mac """ - @test docstrings_equal(@doc(:@DocsTest.mac), m, internal_warning=true) - @test docstrings_equal(@doc(:(DocsTest.@mac)), m, internal_warning=true) + @test docstrings_equal(@doc(:@DocsTest.mac), m) + @test docstrings_equal(@doc(:(DocsTest.@mac)), m) end -@test docstrings_equal(@doc(DocsTest.G), doc"G", internal_warning=true) -@test docstrings_equal(@doc(DocsTest.K), doc"K", internal_warning=true) +@test docstrings_equal(@doc(DocsTest.G), doc"G") +@test docstrings_equal(@doc(DocsTest.K), doc"K") let d1 = @doc(DocsTest.t(::AbstractString)), d2 = doc"t-1" - @test docstrings_equal(d1,d2,internal_warning=true) + @test docstrings_equal(d1,d2) end let d1 = @doc(DocsTest.t(::AbstractString)), d2 = doc"t-1" - @test docstrings_equal(d1,d2,internal_warning=true) + @test docstrings_equal(d1,d2) end let d1 = @doc(DocsTest.t(::Int, ::Any)), d2 = doc"t-2" - @test docstrings_equal(d1,d2,internal_warning=true) + @test docstrings_equal(d1,d2) end let d1 = @doc(DocsTest.t(::S) where {S <: Integer}), d2 = doc"t-3" - @test docstrings_equal(d1,d2,internal_warning=true) + @test docstrings_equal(d1,d2) end let fields = meta(DocsTest)[@var(DocsTest.FieldDocs)].docs[Union{}].data[:fields] @@ -370,13 +365,9 @@ let a = @doc(DocsTest.multidoc), @test docstrings_equal(a, b) end -public BareModule - "BareModule" baremodule BareModule -public f, g, h, @m, C, A - "f/1" f(x) = x @@ -411,7 +402,7 @@ end @test docstrings_equal(@doc(BareModule.@m), doc"@m") @test docstrings_equal(@doc(BareModule.C), doc"C") @test docstrings_equal(@doc(BareModule.A), doc"A") -@test docstrings_equal(@doc(BareModule.T), doc"T", internal_warning=true) +@test docstrings_equal(@doc(BareModule.T), doc"T") @test_throws ErrorException @doc("...", "error") @test_throws ErrorException @doc("...", @time 0) @@ -644,7 +635,7 @@ const i13385 = I13385(true) @test @doc(i13385) !== nothing # Issue #12700. -@test docstrings_equal(@doc(DocsTest.@m), doc"Inner.@m", internal_warning=true) +@test docstrings_equal(@doc(DocsTest.@m), doc"Inner.@m") # issue 11993 # Check if we are documenting the expansion of the macro @@ -1286,8 +1277,6 @@ begin f15684(x) = 1 end -public f15684 - @test string(@doc f15684) == "abc\n" # Dynamic docstrings @@ -1321,30 +1310,30 @@ end let dt1 = striptrimdocs(_repl(:(dynamic_test(1.0)))) @test dt1 isa Expr @test dt1.args[1] isa Expr - @test dt1.args[1].head === :macrocall - @test dt1.args[1].args[1] === Symbol("@doc") - @test dt1.args[1].args[3] == :(dynamic_test(::typeof(1.0))) + @test dt1.args[1].head === :call + @test dt1.args[1].args[1] === Base.Docs.doc + @test dt1.args[1].args[3] == :(Union{Tuple{typeof(1.0)}}) end let dt2 = striptrimdocs(_repl(:(dynamic_test(::String)))) @test dt2 isa Expr @test dt2.args[1] isa Expr - @test dt2.args[1].head === :macrocall - @test dt2.args[1].args[1] === Symbol("@doc") - @test dt2.args[1].args[3] == :(dynamic_test(::String)) + @test dt2.args[1].head === :call + @test dt2.args[1].args[1] === Base.Docs.doc + @test dt2.args[1].args[3] == :(Union{Tuple{String}}) end let dt3 = striptrimdocs(_repl(:(dynamic_test(a)))) @test dt3 isa Expr @test dt3.args[1] isa Expr - @test dt3.args[1].head === :macrocall - @test dt3.args[1].args[1] === Symbol("@doc") - @test dt3.args[1].args[3].args[2].head === :(::) # can't test equality due to line numbers + @test dt3.args[1].head === :call + @test dt3.args[1].args[1] === Base.Docs.doc + @test dt3.args[1].args[3].args[2].head === :curly # can't test equality due to line numbers end let dt4 = striptrimdocs(_repl(:(dynamic_test(1.0,u=2.0)))) @test dt4 isa Expr @test dt4.args[1] isa Expr - @test dt4.args[1].head === :macrocall - @test dt4.args[1].args[1] === Symbol("@doc") - @test dt4.args[1].args[3] == :(dynamic_test(::typeof(1.0); u::typeof(2.0)=2.0)) + @test dt4.args[1].head === :call + @test dt4.args[1].args[1] === Base.Docs.doc + @test dt4.args[1].args[3] == :(Union{Tuple{typeof(1.0)}}) end # Equality testing @@ -1362,8 +1351,6 @@ end # issue 21016 module I21016 -public Struct - struct Struct{T} end @@ -1423,12 +1410,12 @@ end @doc "second" f23011() = 2 end @test Main.f23011() == 2 -@test_broken docstrings_equal(@doc(Main.f23011), doc"second") +@test docstrings_equal(@doc(Main.f23011), doc"second") # issue 22098 "an empty macro" macro mdoc22098 end -@test docstrings_equal(@doc(:@mdoc22098), doc"an empty macro", internal_warning=true) +@test docstrings_equal(@doc(:@mdoc22098), doc"an empty macro") # issue #24468 let ex = try @@ -1472,28 +1459,26 @@ Docs for calling `f::MyParametricFunc{T}`. @test docstrings_equal(@doc((::MyFunc)(2)), doc""" Docs for calling `f::MyFunc`. -""", -internal_warning=true) +""") @test docstrings_equal(@doc((::MyParametricFunc{Int})(44889)), doc""" Docs for calling `f::MyParametricFunc{T}`. -""", -internal_warning=true) +""") struct A_20087 end """a""" (a::A_20087)() = a -@test docstrings_equal(@doc(A_20087()), doc"a", internal_warning=true) +@test docstrings_equal(@doc(A_20087()), doc"a") struct B_20087 end """b""" (::B_20087)() = a -@test docstrings_equal(@doc(B_20087()), doc"b", internal_warning=true) +@test docstrings_equal(@doc(B_20087()), doc"b") # issue #27832 @@ -1518,11 +1503,11 @@ Core.atdoc!(_last_atdoc) Test.collect_test_logs() do # suppress printing of any warning eval(quote "Second docstring" Module29432 end) # requires toplevel end -@test docstrings_equal(@doc(Module29432), doc"Second docstring", internal_warning=true) +@test docstrings_equal(@doc(Module29432), doc"Second docstring") # Issue #13109 eval(Expr(:block, Expr(:macrocall, GlobalRef(Core, Symbol("@doc")), nothing, "...", Expr(:module, false, :MBareModuleEmpty, Expr(:block))))) -@test docstrings_equal(@doc(MBareModuleEmpty), doc"...", internal_warning=true) +@test docstrings_equal(@doc(MBareModuleEmpty), doc"...") # issue #41727 "struct docstring" From b688b60427f32276e4fc59ec9b1ced8bb649e780 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Mon, 4 Sep 2023 18:13:21 -0500 Subject: [PATCH 52/62] add tests and fix "public names" header --- stdlib/REPL/src/docview.jl | 4 ++-- stdlib/REPL/test/docview.jl | 44 +++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index a66e5354f831e..00efe18401f52 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -405,9 +405,9 @@ function summarize(io::IO, m::Module, binding::Binding; nlines::Int = 200) end exports = filter!(!=(nameof(m)), names(m)) if isempty(exports) - println(io, "Module does not export any names.") + println(io, "Module does not have any public names.") else - println(io, "# Exported names") + println(io, "# Public names") print(io, " `") join(io, exports, "`, `") println(io, "`\n") diff --git a/stdlib/REPL/test/docview.jl b/stdlib/REPL/test/docview.jl index 22701ead7883d..d1ce84ab0e9b9 100644 --- a/stdlib/REPL/test/docview.jl +++ b/stdlib/REPL/test/docview.jl @@ -65,3 +65,47 @@ end b = REPL.Binding(@__MODULE__, :R) @test REPL.summarize(b, Tuple{}) isa Markdown.MD end + +module InternalWarningsTests + + module A + public B, B3 + module B + public e + c = 4 + "d is 5" + d = 5 + "e is 6" + e = 6 + end + + module B2 + module C + public e + d = 1 + "e is 2" + e = 2 + end + end + + module B3 end + end + + using Test, REPL + @testset "internal warnings" begin + header = "!!! warning\n The following bindings may be internal; they may change or be removed in future versions:\n\n" + prefix(warnings) = header * join(" * `$(@__MODULE__).$w`\n" for w in warnings) * "\n\n" + docstring(input) = string(eval(REPL.helpmode(input, @__MODULE__))) + + @test docstring("A") == "No docstring or readme file found for internal module `$(@__MODULE__).A`.\n\n# Public names\n\n`B`, `B3`\n" + @test docstring("A.B") == "No docstring or readme file found for public module `$(@__MODULE__).A.B`.\n\n# Public names\n\n`e`\n" + @test startswith(docstring("A.B.c"), prefix(["A.B.c"])) + @test startswith(docstring("A.B.d"), prefix(["A.B.d"])) + @test docstring("A.B.e") == "e is 6\n" + @test startswith(docstring("A.B2"), prefix(["A.B2"])) + @test startswith(docstring("A.B2.C"), prefix(["A.B2", "A.B2.C"])) + @test startswith(docstring("A.B2.C.d"), prefix(["A.B2", "A.B2.C", "A.B2.C.d"])) + @test startswith(docstring("A.B2.C.e"), prefix(["A.B2", "A.B2.C"])) + @test docstring("A.B3") == "No docstring or readme file found for public module `$(@__MODULE__).A.B3`.\n\nModule does not have any public names.\n" + end +end From 6ce6fdb58f3b00f6ec78cb51f853a1dab3964c15 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 5 Sep 2023 07:59:45 -0500 Subject: [PATCH 53/62] update documentation throughout to refer to public and export now-correctly --- doc/src/base/base.md | 2 ++ doc/src/base/reflection.md | 6 +++--- doc/src/manual/modules.md | 9 +++++++-- doc/src/manual/noteworthy-differences.md | 7 ++++--- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/doc/src/base/base.md b/doc/src/base/base.md index a4f90ba6c6d0a..c30036e6c2598 100644 --- a/doc/src/base/base.md +++ b/doc/src/base/base.md @@ -60,6 +60,7 @@ However, you can create variables with names: Finally: `where` is parsed as an infix operator for writing parametric method and type definitions; `in` and `isa` are parsed as infix operators; +`public` is parsed as a keyword when beginning a toplevel statement; `outer` is parsed as a keyword when used to modify the scope of a variable in an iteration specification of a `for` loop; and `as` is used as a keyword to rename an identifier brought into scope by `import` or `using`. Creation of variables named `where`, `in`, `isa`, `outer` and `as` is allowed, though. @@ -67,6 +68,7 @@ Creation of variables named `where`, `in`, `isa`, `outer` and `as` is allowed, t ```@docs module export +public import using as diff --git a/doc/src/base/reflection.md b/doc/src/base/reflection.md index e9da82475fd68..b6246c06472a4 100644 --- a/doc/src/base/reflection.md +++ b/doc/src/base/reflection.md @@ -4,9 +4,9 @@ Julia provides a variety of runtime reflection capabilities. ## Module bindings -The exported names for a `Module` are available using [`names(m::Module)`](@ref), which will return -an array of [`Symbol`](@ref) elements representing the exported bindings. `names(m::Module, all = true)` -returns symbols for all bindings in `m`, regardless of export status. +The public names for a `Module` are available using [`names(m::Module)`](@ref), which will return +an array of [`Symbol`](@ref) elements representing the public bindings. `names(m::Module, all = true)` +returns symbols for all bindings in `m`, regardless of public status. ## DataType fields diff --git a/doc/src/manual/modules.md b/doc/src/manual/modules.md index 4ffb1bca26e50..7c9a743deb35d 100644 --- a/doc/src/manual/modules.md +++ b/doc/src/manual/modules.md @@ -7,7 +7,8 @@ Modules in Julia help organize code into coherent units. They are delimited synt allows the same name to be used for different functions or global variables without conflict, as long as they are in separate modules. 2. Modules have facilities for detailed namespace management: each defines a set of names it - `export`s, and can import names from other modules with `using` and `import` (we explain these below). + `export`s and marks as `public`, and can import names from other modules with `using` and + `import` (we explain these below). 3. Modules can be precompiled for faster loading, and may contain code for runtime initialization. @@ -16,7 +17,7 @@ Typically, in larger Julia packages you will see module code organized into file ```julia module SomeModule -# export, using, import statements are usually here; we discuss these below +# export, public, using, import statements are usually here; we discuss these below include("file1.jl") include("file2.jl") @@ -103,6 +104,10 @@ Also, some modules don't export names at all. This is usually done if they use c words, such as `derivative`, in their API, which could easily clash with the export lists of other modules. We will see how to manage name clashes below. +To mark a name as public without exporting it into the namespace of folks who call `using NiceStuff`, +one can use `public` instead of `export`. This marks the public name(s) as part of the public API, +but does not have any namespace implications. + ### Standalone `using` and `import` Possibly the most common way of loading a module is `using ModuleName`. This [loads](@ref diff --git a/doc/src/manual/noteworthy-differences.md b/doc/src/manual/noteworthy-differences.md index 7a2bb0e9ace03..6c55bee59cadf 100644 --- a/doc/src/manual/noteworthy-differences.md +++ b/doc/src/manual/noteworthy-differences.md @@ -413,15 +413,16 @@ For users coming to Julia from R, these are some noteworthy differences: file are `include`d only once (No `#ifdef` confusion). ### Julia ⇔ C/C++: Module interface - * C++ exposes interfaces using "public" `.h`/`.hpp` files whereas Julia `module`s `export` - symbols that are intended for their users. + * C++ exposes interfaces using "public" `.h`/`.hpp` files whereas Julia `module`s mark + specific symbols that are intended for their users as `public`or `export`ed. * Often, Julia `module`s simply add functionality by generating new "methods" to existing functions (ex: `Base.push!`). * Developers of Julia packages therefore cannot rely on header files for interface documentation. * Interfaces for Julia packages are typically described using docstrings, README.md, static web pages, ... - * Some developers choose not to `export` all symbols required to use their package/module. + * Some developers choose not to `export` all symbols required to use their package/module, + but should still mark unexported user facing symbols as `public`. * Users might be expected to access these components by qualifying functions/structs/... with the package/module name (ex: `MyModule.run_this_task(...)`). From e57c63fd6712980e9eb8270aa84c1862932fbf7d Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 5 Sep 2023 08:35:29 -0500 Subject: [PATCH 54/62] fix cross refs --- base/docs/basedocs.jl | 12 +++++++++++- base/reflection.jl | 2 +- doc/src/base/base.md | 2 ++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index f1802158f8886..83ba1603e6972 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -52,13 +52,23 @@ kw"import" """ export -`export` is used within modules to tell Julia which functions should be +`export` is used within modules to tell Julia which names should be made available to the user. For example: `export foo` makes the name `foo` available when [`using`](@ref) the module. See the [manual section about modules](@ref modules) for details. """ kw"export" +""" + public + +`public` is used within modules to tell Julia which names are part of the +public API of the module . For example: `public foo` indicates that the name +`foo` is public, without making it available available when [`using`](@ref) +the module. See the [manual section about modules](@ref modules) for details. +""" +kw"public" + """ as diff --git a/base/reflection.jl b/base/reflection.jl index 1b215e4c9d8bf..0b7d270906c62 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -84,7 +84,7 @@ are also included. As a special case, all names defined in `Main` are considered \"public\", since it is not idiomatic to explicitly mark names from `Main` as public. -See also: [`isexported`](@ref), [`ispublic`](@ref), [`isdeprecated`](@ref), [`@locals`](@ref Base.@locals), [`@__MODULE__`](@ref). +See also: [`isexported`](@ref), [`ispublic`](@ref), [`@locals`](@ref Base.@locals), [`@__MODULE__`](@ref). """ names(m::Module; all::Bool = false, imported::Bool = false) = sort!(unsorted_names(m; all, imported)) diff --git a/doc/src/base/base.md b/doc/src/base/base.md index c30036e6c2598..39e61738bf1ed 100644 --- a/doc/src/base/base.md +++ b/doc/src/base/base.md @@ -453,6 +453,8 @@ Base.@__DIR__ Base.@__LINE__ Base.fullname Base.names +Base.isexported +Base.ispublic Base.nameof(::Function) Base.functionloc(::Any, ::Any) Base.functionloc(::Method) From 1a6e3dc9356cce73268ef81ddce6b9b8c3856dde Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 5 Sep 2023 08:45:13 -0500 Subject: [PATCH 55/62] update varinfo documentation --- stdlib/InteractiveUtils/src/InteractiveUtils.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/InteractiveUtils/src/InteractiveUtils.jl b/stdlib/InteractiveUtils/src/InteractiveUtils.jl index 82c0752d3f78d..b63b3d905d605 100644 --- a/stdlib/InteractiveUtils/src/InteractiveUtils.jl +++ b/stdlib/InteractiveUtils/src/InteractiveUtils.jl @@ -23,12 +23,12 @@ include("clipboard.jl") """ varinfo(m::Module=Main, pattern::Regex=r""; all=false, imported=false, recursive=false, sortby::Symbol=:name, minsize::Int=0) -Return a markdown table giving information about exported global variables in a module, optionally restricted +Return a markdown table giving information about public global variables in a module, optionally restricted to those matching `pattern`. The memory consumption estimate is an approximate lower bound on the size of the internal structure of the object. -- `all` : also list non-exported objects defined in the module, deprecated objects, and compiler-generated objects. +- `all` : also list non-public objects defined in the module, deprecated objects, and compiler-generated objects. - `imported` : also list objects explicitly imported from other modules. - `recursive` : recursively include objects in sub-modules, observing the same settings in each. - `sortby` : the column to sort results by. Options are `:name` (default), `:size`, and `:summary`. From d4418fec258accc3eeab5ee13e1ab05c91a2e32b Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 5 Sep 2023 11:25:07 -0500 Subject: [PATCH 56/62] Update checksums --- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + 6 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/md5 delete mode 100644 deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/sha512 delete mode 100644 deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/md5 delete mode 100644 deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/sha512 create mode 100644 deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/md5 create mode 100644 deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/sha512 diff --git a/deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/md5 b/deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/md5 deleted file mode 100644 index 387ff43532a6e..0000000000000 --- a/deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -ac6d344a55ec798abd2b4fb68304794e diff --git a/deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/sha512 b/deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/sha512 deleted file mode 100644 index a43f4dfd4bcae..0000000000000 --- a/deps/checksums/JuliaSyntax-045d156c44dbb87769c7416d049a7c08908539d4.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -89cf036193135337ae722e05dccbcd6535d2fa54316ae801a8c764f5f4eaf90fa95a644d024dbefb09433781043dfb4830a1679a049e47b7b35e9acd1e834b90 diff --git a/deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/md5 b/deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/md5 deleted file mode 100644 index 7e9716977afa1..0000000000000 --- a/deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -85321fa6216516497d4aeba055441722 diff --git a/deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/sha512 b/deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/sha512 deleted file mode 100644 index 10c9b9d7bf07d..0000000000000 --- a/deps/checksums/JuliaSyntax-ad9b16681389dbe3f21a89897f7a86dec793f72a.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -fc3ee2da0aedcd56c96e177e3ae854bf4e50889edad88e1da0cd6a0f00a4d7381a564457931a5bc31f94f9cbe36ca4bb6fd57674ce919e58f268be56c10e89f3 diff --git a/deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/md5 b/deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/md5 new file mode 100644 index 0000000000000..52847918cc7e5 --- /dev/null +++ b/deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/md5 @@ -0,0 +1 @@ +3ac96ec2847998c9cfc62a6d23ba90c8 diff --git a/deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/sha512 b/deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/sha512 new file mode 100644 index 0000000000000..48f6c6b5a1241 --- /dev/null +++ b/deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/sha512 @@ -0,0 +1 @@ +4c99fbc8952dda8938480cb9b2be3bc5f7c396e8cb5594d7ff5633c3494a9bf024c41591c73db0aad2bc1c986b65543d0a4dfd8a202cde384a430eb0177e573c From c4924c9b71de9f140b7cb3782b23f9772d6503eb Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 5 Sep 2023 13:22:57 -0500 Subject: [PATCH 57/62] fix some tests --- test/docs.jl | 2 +- test/reflection.jl | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/docs.jl b/test/docs.jl index 7179aa667aded..a2f556b7ee848 100644 --- a/test/docs.jl +++ b/test/docs.jl @@ -852,7 +852,7 @@ end # module doc_str = Markdown.parse(""" No docstring or readme file found for internal module `$(curmod_prefix)Undocumented`. -# Exported names +# Public names `A`, `B`, `C`, `at0`, `pt2` """) diff --git a/test/reflection.jl b/test/reflection.jl index 3d3afc4bd6aa6..a67407c2d0f48 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -1076,4 +1076,3 @@ private() = 1 end @test names(TestNames) == [:TestNames, :exported, :publicized] -@test names(TestNames, qualified=false) == [:TestNames, :exported] From 5835699918ffd39e4a9b48e4c3249c1f61efac71 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 5 Sep 2023 14:03:03 -0500 Subject: [PATCH 58/62] more test fixes --- test/show.jl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/show.jl b/test/show.jl index ed823f9a955c3..caeab7d17600c 100644 --- a/test/show.jl +++ b/test/show.jl @@ -524,8 +524,11 @@ end @test sprint(show, Expr(:macrocall, Symbol("@#"), nothing, :a)) == ":(@var\"#\" a)" # Test that public expressions are rendered nicely -@test sprint(show, :(public @foo)) == ":(public @foo)" -@test sprint(show, :(public f,o,o)) == ":(public f, o, o)" +# though they are hard to create with quotes because public is not a context dependant keyword +@test sprint(show, Expr(:public, Symbol("@foo"))) == ":(public @foo)" +@test sprint(show, Expr(:public, :f,:o,:o)) == ":(public f, o, o)" +s = sprint(show, :(module A; public x; end)) +@test match(r"^:\(module A\n #= .* =#\n #= .* =#\n public x\n end\)$", s) !== nothing # PR #38418 module M1 var"#foo#"() = 2 end From 153b538ff006df5e17d44f20c13396afef92a34e Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 5 Sep 2023 16:23:35 -0500 Subject: [PATCH 59/62] try switching to a different JuliaSyntax version --- deps/JuliaSyntax.version | 2 +- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/JuliaSyntax-a9110fa8ecbe79943bb9525b4ccd99a3976cfcb7.tar.gz/md5 create mode 100644 deps/checksums/JuliaSyntax-a9110fa8ecbe79943bb9525b4ccd99a3976cfcb7.tar.gz/sha512 delete mode 100644 deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/md5 delete mode 100644 deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/sha512 diff --git a/deps/JuliaSyntax.version b/deps/JuliaSyntax.version index d271eddb33d44..1d7dfd8efd096 100644 --- a/deps/JuliaSyntax.version +++ b/deps/JuliaSyntax.version @@ -1,4 +1,4 @@ JULIASYNTAX_BRANCH = main -JULIASYNTAX_SHA1 = ca2b8e36a14078e94d57182b637060576fa2a700 +JULIASYNTAX_SHA1 = a9110fa8ecbe79943bb9525b4ccd99a3976cfcb7 JULIASYNTAX_GIT_URL := https://github.com/JuliaLang/JuliaSyntax.jl.git JULIASYNTAX_TAR_URL = https://api.github.com/repos/JuliaLang/JuliaSyntax.jl/tarball/$1 diff --git a/deps/checksums/JuliaSyntax-a9110fa8ecbe79943bb9525b4ccd99a3976cfcb7.tar.gz/md5 b/deps/checksums/JuliaSyntax-a9110fa8ecbe79943bb9525b4ccd99a3976cfcb7.tar.gz/md5 new file mode 100644 index 0000000000000..25f5adf71897d --- /dev/null +++ b/deps/checksums/JuliaSyntax-a9110fa8ecbe79943bb9525b4ccd99a3976cfcb7.tar.gz/md5 @@ -0,0 +1 @@ +a42bbb42babbbd727556f6bc01455826 diff --git a/deps/checksums/JuliaSyntax-a9110fa8ecbe79943bb9525b4ccd99a3976cfcb7.tar.gz/sha512 b/deps/checksums/JuliaSyntax-a9110fa8ecbe79943bb9525b4ccd99a3976cfcb7.tar.gz/sha512 new file mode 100644 index 0000000000000..cd3f3f3043d45 --- /dev/null +++ b/deps/checksums/JuliaSyntax-a9110fa8ecbe79943bb9525b4ccd99a3976cfcb7.tar.gz/sha512 @@ -0,0 +1 @@ +d542766e72b57418b9b4e17743f89d8535c1f36497346b57538bd0cb451e64af9493015692179f80ec4ee8cf18349c1e0888f5710db895e19f9bb0322f0f7464 diff --git a/deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/md5 b/deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/md5 deleted file mode 100644 index 52847918cc7e5..0000000000000 --- a/deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -3ac96ec2847998c9cfc62a6d23ba90c8 diff --git a/deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/sha512 b/deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/sha512 deleted file mode 100644 index 48f6c6b5a1241..0000000000000 --- a/deps/checksums/JuliaSyntax-ca2b8e36a14078e94d57182b637060576fa2a700.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -4c99fbc8952dda8938480cb9b2be3bc5f7c396e8cb5594d7ff5633c3494a9bf024c41591c73db0aad2bc1c986b65543d0a4dfd8a202cde384a430eb0177e573c From 158d59f04f03fc615cda1d5ef4c8d6e0d837d853 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 5 Sep 2023 16:52:27 -0500 Subject: [PATCH 60/62] don't accidentally drop the module in testing --- stdlib/REPL/test/repl.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index aaab56e4bf5c9..4081a3c7162e2 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -1164,7 +1164,7 @@ fake_repl() do stdin_write, stdout_read, repl Base.wait(repltask) end -help_result(line, mod::Module=Base) = Core.eval(mod, REPL._helpmode(IOBuffer(), line)) +help_result(line, mod::Module=Base) = Core.eval(mod, REPL._helpmode(IOBuffer(), line, mod)) # Docs.helpmode tests: we test whether the correct expressions are being generated here, # rather than complete integration with Julia's REPL mode system. From 41f37294a2a41ba2e9b903391ecd1d6ec47b9a46 Mon Sep 17 00:00:00 2001 From: Lilith Hafner Date: Tue, 5 Sep 2023 18:30:34 -0500 Subject: [PATCH 61/62] fix some doctests --- base/reflection.jl | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/base/reflection.jl b/base/reflection.jl index d563489b06027..b2c47662dd447 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -103,7 +103,7 @@ julia> module Mod export foo public bar end -Main.Mod +Mod julia> Base.isexported(Mod, :foo) true @@ -131,13 +131,13 @@ julia> module Mod export foo public bar end -Main.Mod +Mod julia> Base.isexported(Mod, :foo) true julia> Base.isexported(Mod, :bar) -true +false julia> Base.isexported(Mod, :baz) false @@ -145,30 +145,8 @@ false """ ispublic(m::Module, s::Symbol) = ccall(:jl_module_public_p, Cint, (Any, Any), m, s) != 0 -""" - isdeprecated(m::Module, s::Symbol) -> Bool - -Returns whether the binding of a symbol in a module is deprecated. - -See also: [`isexported`](@ref), [`ispublic`](@ref), [`isbindingresolved`](@ref) - -```jldoctest -julia> module Mod - new(x) = x+1 - @deprecate old(x) new(x) - end -Main.Mod - -julia> Base.isdeprecated(Mod, :new) -false - -julia> Base.isdeprecated(Mod, :old) -true - -julia> Base.isdeprecated(Mod, :baz) -false -``` -""" +# TODO: this is vaguely broken because it only works for explicit calls to +# `Base.deprecate`, not the @deprecated macro: isdeprecated(m::Module, s::Symbol) = ccall(:jl_is_binding_deprecated, Cint, (Any, Any), m, s) != 0 """ @@ -182,6 +160,7 @@ See also: [`isexported`](@ref), [`ispublic`](@ref), [`isdeprecated`](@ref) julia> module Mod foo() = 17 end +Mod julia> Base.isbindingresolved(Mod, :foo) true From ea7a1413fcc7c23808b8a75b5c6889e6db32e277 Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Thu, 7 Sep 2023 06:37:27 -0500 Subject: [PATCH 62/62] Docstring fixup for Base.ispublic Co-authored-by: Gerhard Aigner --- base/reflection.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/base/reflection.jl b/base/reflection.jl index b2c47662dd447..3af30b396dc72 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -133,13 +133,13 @@ julia> module Mod end Mod -julia> Base.isexported(Mod, :foo) +julia> Base.ispublic(Mod, :foo) true -julia> Base.isexported(Mod, :bar) -false +julia> Base.ispublic(Mod, :bar) +true -julia> Base.isexported(Mod, :baz) +julia> Base.ispublic(Mod, :baz) false ``` """