Introduce and use #externalMacro for externally-defined macros.

Align the grammar of macro declarations with SE-0382, so that macro
definitions are parsed as an expression. External macro definitions
are referenced via a referenced to the macro `#externalMacro`. Define
that macro in the standard library, and recognize uses of it as the
definition of other macros to use externally-defined macros. For
example, this means that the "stringify" macro used in a lot of
examples is now defined as something like this:

    @expression macro stringify<T>(_ value: T) -> (T, String) =
        #externalMacro(module: "MyMacros", type: "StringifyMacro")

We still parse the old "A.B" syntax for two reasons. First, it's
helpful to anyone who has existing code using the prior syntax, so they
get a warning + Fix-It to rewrite to the new syntax. Second, we use it
to define builtin macros like `externalMacro` itself, which looks like this:

    @expression
    public macro externalMacro<T>(module: String, type: String) -> T =
        Builtin.ExternalMacro

This uses the same virtual `Builtin` module as other library builtins,
and we can expand it to handle other builtin macro implementations
(such as #line) over time.
This commit is contained in:
Doug Gregor
2023-01-02 16:39:00 -08:00
parent 49b42b4ef3
commit 7000969f14
24 changed files with 487 additions and 167 deletions

View File

@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
/// Don't worry about adhering to the 80-column limit for this line.
const uint16_t SWIFTMODULE_VERSION_MINOR = 730; // local discriminator change
const uint16_t SWIFTMODULE_VERSION_MINOR = 731; // macro definition
/// A standard hash seed used for all string hashes in a serialized module.
///
@@ -1683,8 +1683,9 @@ namespace decls_block {
TypeIDField, // result interface type
AccessLevelField, // access level
BCVBR<5>, // number of parameter name components
IdentifierIDField, // external module name
IdentifierIDField, // external type name
BCVBR<3>, // builtin macro definition ID
IdentifierIDField, // external module name, for external macros
IdentifierIDField, // external type name, for external macros
BCArray<IdentifierIDField> // name components,
// followed by TypeID dependencies
// The record is trailed by: