@@ -1300,28 +1300,116 @@ given library. This will be allowed through the library introspection class,
1300
1300
which is available from the introspection APIs on all declarations via a
1301
1301
` library ` getter.
1302
1302
1303
- ** TODO** : Fully define the library introspection API for each phase.
1304
-
1305
1303
### API versioning
1306
1304
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.
1325
1413
1326
1414
## Resources
1327
1415
0 commit comments