Skip to content

Patch files using augmentation parts. #4568

@lrhn

Description

@lrhn

The Dart SDK has "patch files" which are used to weave platform-specific implementations into generic platform library declarations. They have the following properties:

  • Can patch existing (external) members with implementation.
  • Cannot add new public declarations, neither top-level nor static or instance members.
  • Can add new private declarations, but they are not accessible outside of the patch.

This ensures that the API of the patched library is independent of the contents of the patch files - they cannot change the avialable and accessible members.

(In practice, the VM implementation has broken these rules, so it can overwrite exsting concrete declarations with a different implementation, and it can add new public members, even if it never should.)

We could extend enhanced part files and augmentations to support something similar.

Strawman proposal:

  • A part can be included as augment part 'thepart.dart';. This file is called an "augmenting part".
  • It must refer back to the including file as augment part of 'parent.dart';. (The files must agree!)
  • If a Dart file of the library is below an augmenting part, including the augmenting part itself,
    • It's a compile-time error if the file contains an export directive.
    • It's a compile-time error if the file contains an introductory declaration with a public name,
      unless it's an instance member declaration of a class, mixin or enum declaration, which is itself
      introduced inside the same augmenting part and the member signature of the declaration
      is exactly the same as that of a same-named member of the declaration's combined superinterface
      (which must exist, otherwise that's a compile-time error too).
    • If the file contains an introductory statically-resolved declaration with a private name,
      it's a compile-time error if that member is referenced in any file which is not also below that
      augmenting part. (Statically resolved means top-level, static, constructor declarations,
      or extension or extension type instance member declarations.)

Other than the instance member thing, it's fairly simple.

An augmenting part(-file hieararchy):

  • cannot declare any new public names, by declaration or export.
  • can declare any amount of private declarations, as long as nobody else refers to them.
  • can create new classes, with a private name, and those can contain any public-named declarations
    needed to implement its super-interfaces (and nothing more). It cannot add new public names
    to class declarations it didn't introduce itself. Nothing outside can augment the class declared inside.
  • Anything that the outside code needs to rely on, it has to declare itself and let the augmenting part add implementation using augment declarations.

_The rules are written so that nested augmenting parts are possible and every declaration belongs to the closest enclosing augmenting part, and must be checked relative to that.

With that in place an augmenting part can use conditional URI.
You can have conditional parts, as long as those parts don't change the public API of the class.

Metadata

Metadata

Assignees

No one assigned

    Labels

    augmentationsIssues related to the augmentations proposal.enhanced-syntaxUsed with proposals about improvements of the Dart grammarfeatureProposed language feature that solves one or more problems

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions