Sent from my iPad
> On Feb 20, 2017, at 7:36 PM, Brent Royal-Gordon via swift-evolution > <swift-evolution@swift.org> wrote: > > Okay, lots of people want to have some kind of submodule feature, so I'd like > to sketch one out so we can hopefully agree on what submodules might look > like. > > *** > > Any group of Swift files can be grouped together to form a submodule. It isn't clear to me how you express that a particular group of files forms a submodule. Can you elaborate? > Submodules belong within a particular module, and have a dotted name: If > `ModKit` is a module, it might have a submodule called `ModKit.Foo`. > Submodules can be nested within one another: `ModKit.Foo.Bar` is a submodule > of `ModKit.Foo`, which is a submodule of `ModKit`. > > No new access levels are necessary. `internal` APIs are only visible within > the submodule they're declared in; a module cannot see its submodules' > `internal` APIs, and a submodule cannot see its parent module's `internal` > APIs. If a submodule wants to expose some of its APIs to its parent or > sibling modules, it must mark them as `public` or `open`. Then they can > import the submodule to see its APIs: > > import ModKit.Foo > > By default, outside modules cannot import a submodule. But an import in the > parent module can be decorated by an access control keyword to allow that: > > /// Any module outside ModKit can import ModKit.Foo and access its > `public` and `open` APIs. > open import ModKit.Foo > > /// Any module outside ModKit can import ModKit.Foo and access its > `public` and `open` APIs, > /// except `open` APIs are treated as `public`. > public import ModKit.Foo > > Imports may also be decorated by the `@exported` attribute, which exposes the > submodule's APIs as though they were parent module APIs: > > @exported open import ModKit.Foo > > @exported public import ModKit.Foo > > (This is sort of half-implemented already in a buggy `@_exported` attribute.) > > Finally, the standard syntax for importing individual symbols can be used to > cherry-pick types to treat differently: > > // Most ModKit.Foo APIs are not importable... > import ModKit.Foo > > // ...but SomeEnum can be imported as public... > public import enum ModKit.Foo.SomeEnum > > // ...SomeClass can be imported as open... > open import class ModKit.Foo.SomeClass > > // And ImportantStruct will import whenever you import ModKit. > @exported public import struct ModKit.Foo.ImportantStruct > > (This syntax should be enhanced to allow cherry-picked importing of global > functions, constants, and variables.) > > If there are several different `import`s covering the same submodule or > submodule symbol, the most permissive one wins. > > (In large projects, `public`, `open`, and `@exported` imports will most > likely all be put in a single Policy.swift file or something, but this is not > enforced by the language.) > > A submodule may not import any direct parent module (parent, grandparent, > etc.), but may import any other submodule in the same module. This list shows > permitted imports for a project with four modules/submodules: > > ModKit > - ModKit.Foo > - ModKit.Foo.Bar > - ModKit.Quux > ModKit.Foo > - ModKit.Foo.Bar > - ModKit.Quux > ModKit.Foo.Bar > - ModKit.Quux > ModKit.Quux > - ModKit.Foo > - ModKit.Foo.Bar > > However, submodules may not form circular dependencies through imports—if > `ModKit.Quux` imports `ModKit.Foo`, then `ModKit.Foo` cannot import > `ModKit.Quux`. The `#if canImport()` feature cannot be used to probe for > other submodules within the same top-level module you're in. > > At the compiler driver level, a submodule is specified by giving a > `-module-name` parameter with a dot in it. When a file is compiled, only the > filenames of the other .swift files in the same module are specified, along > with .o files for any submodules; then all the .o files within that submodule > are linked into a single .o file for the whole submodule. So files in > `ModKit.Foo` would be compiled with only the .swift files in `ModKit.Foo` and > the .o file for `ModKit.Foo.Bar`; then all the `ModKit.Foo` .o files would be > linked into one .o file for the top-level `ModKit` to use. None of > `ModKit.Foo`'s .swift files would be included in the command line when > compiling the top-level `ModKit` module. > > (That bit is kind of speculative—particularly the idea of linking submodule > files into a single .o file—but I think something like what I'm describing > could work.) > > Because the compiler driver is used to group submodules together, Xcode can > specify submodules in project file metadata and calculate a submodule > dependency graph, while SwiftPM can use folders and compile submodules > whenever the compiler emits an error indicating that a file tried to import a > nonexistent submodule. Other build systems can do whatever best suits their > style. > > *** > > Thoughts? > > -- > Brent Royal-Gordon > Architechies > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution