Skip to content
This repository was archived by the owner on Sep 16, 2022. It is now read-only.
This repository was archived by the owner on Sep 16, 2022. It is now read-only.

OpaqueToken cannot be implemented in Dart #35

@chalin

Description

@chalin

Migrated from angular/angular#8928, but with links refreshed.

Summary: The Angular DI OpaqueToken wrapper class exists solely to create unique token instances, independent of any string argument value that might be provided to the constructor. Given that the OpaqueToken constructor must be const in Dart, and that const constructors are canonicalized, it fails to serve its purpose. In fact, a const constructor that always returns a unique instance cannot be written in Dart.

Details

Each new Angular DI OpaqueToken is meant to be unique. Given that, in Dart, OpaqueTokens are meant to be used in annotations, they must be const; hence the class is defined as follows (note the const constructor):

class OpaqueToken {
  final String _desc;
  const OpaqueToken(this._desc);
  String toString() {
    return '''Token ${ this . _desc}''';
  }
}

But const objects are _canonicalized_ (cf. this commentary in the latex source, or correspondingly, page 68 in the 4th ed. of the spec). Those who might have a doubt can try:

@Component(
    selector: 'my-app',
    template: "<p>const OpaqueToken('abc') == const OpaqueToken('abc') is {{test}}</p>")
class AppComponent {
  final bool test = const OpaqueToken('abc') == const OpaqueToken('abc');
}

yields

const OpaqueToken('abc') == const OpaqueToken('abc') is true

Note: since OpaqueToken doesn't override ==, it uses the one defined in Object, which is true iff the operands are identical.

This issue came to light during rework of the angular.io DI chapters (for Dart and TS). Issue angular/angular.io#1563 has been opened to hold the thread of discussion of alternatives to OpaqueToken. Once an alternative has been agreed upon, at least for Dart, then OpaqueToken should be deprecated --- given that the Dart implementation is faulty and cannot be fixed, it should just be removed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions