linkToOpaqueToken method

TypeLink linkToOpaqueToken(
  1. DartType type
)

Returns type as a TypeLink to the corresponding class definition.

Runs a number of validations to ensure that the class is defined properly and in a way that the AngularDart compilers are able to use for code generation.

Implementation

TypeLink linkToOpaqueToken(DartType type) {
  if (!$OpaqueToken.isAssignableFromType(type)) {
    throw BuildError.forElement(type.element!, 'Must implement OpaqueToken.');
  }
  if ($OpaqueToken.isExactlyType(type) || $MultiToken.isExactlyType(type)) {
    return linkTypeOf(type);
  }
  final clazz = type.element as ClassElement;
  if (clazz.interfaces.isNotEmpty || clazz.mixins.isNotEmpty) {
    throw BuildError.forElement(
      type.element!,
      'A sub-type of OpaqueToken cannot implement or mixin any interfaces.',
    );
  }
  if (clazz.isPrivate || clazz.isAbstract) {
    throw BuildError.forElement(
      type.element!,
      'Must not be abstract or a private (i.e. prefixed with `_`) class.',
    );
  }
  if (clazz.constructors.length != 1 ||
      clazz.unnamedConstructor == null ||
      !clazz.unnamedConstructor!.isConst ||
      clazz.unnamedConstructor!.parameters.isNotEmpty ||
      clazz.typeParameters.isNotEmpty) {
    var supertypeName =
        clazz.supertype!.getDisplayString(withNullability: false);
    throw BuildError.forElement(
      type.element!,
      ''
      'A sub-type of OpaqueToken must have a single unnamed const '
      'constructor with no parameters or type parameters. For example, '
      'consider writing instead:\n'
      '  class ${clazz.name} extends $supertypeName {\n'
      '    const ${clazz.name}();\n'
      '  }\n\n'
      'We may loosten these restrictions in the future. See: '
      'https://github.com/angulardart/angular/issues/899',
    );
  }
  if (!$OpaqueToken.isExactlyType(clazz.supertype!) &&
      !$MultiToken.isExactlyType(clazz.supertype!)) {
    throw BuildError.forElement(
      type.element!,
      ''
      'A sub-type of OpaqueToken must directly extend OpaqueToken or '
      'MultiToken, and cannot extend another class that in turn extends '
      'OpaqueToken or MultiToken.\n\n'
      'We may loosten these restrictions in the future. See: '
      'https://github.com/angulardart/angular/issues/899',
    );
  }
  return linkTypeOf(type);
}