@@ -1300,28 +1300,116 @@ given library. This will be allowed through the library introspection class,
13001300which is available from the introspection APIs on all declarations via a
13011301` library ` getter.
13021302
1303- ** TODO** : Fully define the library introspection API for each phase.
1304-
13051303### API versioning
13061304
1307- ** TODO** : Finalize the approach here (#1934 ).
1308-
1309- It is possible that future language changes would require a breaking change to
1310- an existing imperative macro API. For instance you could consider what would
1311- happen if we added multiple return values from functions. That would
1312- necessitate a change to many APIs so that they would support multiple return
1313- types instead of a single one.
1314-
1315- #### Proposal: Ship macro APIs as a Pub package
1316-
1317- Likely, this package would only export directly an existing ` dart: ` uri, but
1318- it would be able to be versioned like a public package, including tight sdk
1319- constraints (likely on minor version ranges). This would work similar to the
1320- ` dart:_internal ` library.
1321-
1322- This approach would involve more work on our end (to release this package with
1323- each dart release). But it would help keep users on the rails, and give us a
1324- lot of flexibility with the API going forward.
1305+ It is expected that future language changes will require breaking changes to the
1306+ macro APIs. For instance you could consider what would happen if we added
1307+ multiple return values from functions. That would necessitate a change to many
1308+ APIs so that they would support multiple return types instead of a single one.
1309+
1310+ #### Design goals
1311+
1312+ * Enable us to make API changes when needed.
1313+ * Minimize churn for macro authors - most SDK versions will not be breaking and
1314+ it would be ideal to not ask packages to have super tight SDK constraints.
1315+ * Give early and actionable error messages to consumers of macros when a macro
1316+ they are using does not support a new language feature.
1317+ * Enable as much forwards/backwards compatibility as possible.
1318+
1319+ #### Solution: Ship macro APIs as a Pub package
1320+
1321+ The implementation of this package will always come from the SDK, through a
1322+ ` dart:_macros ` library, which will be exported by this package. The
1323+ ` dart:_macros ` library will be blocked from being imported or exported by any
1324+ library other than other ` dart: ` libraries and this package.
1325+
1326+ We use a ` dart: ` library here to ensure that the binaries shipped with the SDK
1327+ are compiled with exactly the same version of the API that macros are compiled
1328+ with. This ensures the communication protocol between macros and the SDK
1329+ binaries are compatible.
1330+
1331+ This package will have tight upper bound SDK constraints, constrained to the
1332+ minor release versions instead of major release versions.
1333+
1334+ The release/versioning strategy for the package is as follows:
1335+
1336+ - We will not allow any changes to the macro APIs in patch releases of the SDK,
1337+ even non-breaking changes. The package restricts itself to minor releases and
1338+ not patch releases of the SDK, so these changes would silently be visible to
1339+ users in a way that wasn't versioned through the package.
1340+
1341+ - When a new version of the Dart SDK is released which ** does not have any**
1342+ changes to the macro API, then we will do a patch release of this package
1343+ which simply expands the SDK upper bound to include that version (specifically
1344+ it will be updated to less than the next minor version). For example,
1345+ if version ` 3.5.0 ` of the SDK was just released, and it has no changes to the
1346+ macro API, the new upper bound SDK constraint would be ` <3.6.0 ` and the lower
1347+ bound would remain unchanged.
1348+
1349+ Since this is only a patch release of this package, all existing packages that
1350+ depend on this package (with a standard version constraint) will support it
1351+ already, so no work is required on macro authors' part to work with the new
1352+ Dart SDK.
1353+
1354+ - When a new version of the Dart SDK is released which has ** non-breaking**
1355+ changes to the macro API, then we will do a minor release of this package,
1356+ which increases the lower bound SDK constraint to the newly released version,
1357+ and the upper bound to less than the next minor release version. For example,
1358+ if version ` 3.5.0 ` of the SDK was just released, and it has ** non-breaking**
1359+ changes to the macro API, the new SDK constraint would be ` >=3.5.0 <3.6.0 ` .
1360+
1361+ Note that only users on the newest SDK will get this new version, but that is
1362+ by design. The new features are being exposed only by the new SDK and are not
1363+ available to older SDKs.
1364+
1365+ Since this is only a minor release, all existing packages that depend on this
1366+ package (with a standard version constraint) will support it already, so no
1367+ work is required on macro authors' part to work with the new Dart SDK.
1368+
1369+ If a macro author wants to ** use** the new features, they must update their
1370+ minimum constraint on this package to the latest version to ensure the new
1371+ features are available.
1372+
1373+ - When a new version of the Dart SDK includes a ** breaking** change to the macro
1374+ API, then we will release a new major version of this package, and update the
1375+ SDK constraints in the same way as non-breaking changes (update both the
1376+ minimum and maximum SDK constraints, so only the current minor version is
1377+ allowed). By default, existing packages containing macros will not accept that
1378+ version of the macro package and thus will not work with the new Dart SDK.
1379+
1380+ Authors of packages containing macros will need to test to see if their macro
1381+ is compatible with the latest macro API. If so, they can ship a new patch
1382+ version of their package with a constraint on the macro package that includes
1383+ the new major version as well as the previous major version it's already known
1384+ to work with. If their package is broken by the macro API change, then, they
1385+ will fix their macro and ship a new version of their package with a dependency
1386+ on the macro package that only allows the latest major versions.
1387+
1388+ This approach has several advantages for macro authors and users, which are
1389+ closely aligned with the design goals:
1390+
1391+ * Fewer releases for macro authors (this package shouldn't have very many
1392+ breaking changes).
1393+ * Gives us flexibility with the API when needed.
1394+ * Gives early errors if a macro dependency doesn't support the users current
1395+ SDK. The failure will be in the form of a failed version solve.
1396+ * Macros can easily depend on wide ranges of this package (if they are
1397+ compatible).
1398+
1399+ There are some downsides to this approach as well:
1400+
1401+ * More work for us, we need to consistently prepare these releases for new SDKs.
1402+ * Version solve errors can sometimes be very cryptic to understand. This is a
1403+ general problem though, and we will benefit from any improvements in this
1404+ area.
1405+ * Dependency overrides on this package won't actually have any affect, which may
1406+ be confusing to users. The API is always dictated by the ` dart: ` library and
1407+ not the package itself. Note that this is different from ` dart_internal ` ,
1408+ which wraps the ` dart: ` APIs it exposes. I don't think this would be
1409+ desireable for this use case, but we could see if it is feasible.
1410+ * It is possible we could forget to bump the min SDK when altering the internal
1411+ API for the ` dart:_macros ` package. We should put some sort of check in place
1412+ to help ensure we get this right.
13251413
13261414## Resources
13271415
0 commit comments