visitTypeDefinition method

  1. @override
Future<Element> visitTypeDefinition(
  1. TypeDefinition node
)
override

Implementation

@override
Future<Element> visitTypeDefinition(TypeDefinition node) async {
  const source = CurrentPackage();

  final definition = TypeDefinitionElement(name: node.name.lexeme);

  final definitionType = PolymorphicType(
    name: node.name.lexeme,
    source: source,
    arguments: [
      if (node.parameters case final parameters?)
        for (final parameter in parameters) TypeParameterType(name: parameter.identifier.lexeme),
    ],
    element: definition,
  );

  definition.definedType = definitionType;

  _environment.defineSymbol(
    node.name.lexeme,
    definition,
  );
  _environment = _environment.fork();

  if (node.parameters case final parameters?) {
    for (final parameter in parameters) {
      final definedType = _environment.getDefinition(parameter.identifier.lexeme);

      if (definedType is TypeParameterType) {
        _errorHandler?.emit(
          TypeParameterAlreadyDefinedError(parameter.identifier),
        );
      } else if (definedType == null) {
        final element = TypeParameterElement(name: parameter.identifier.lexeme);
        final type = TypeParameterType(name: parameter.identifier.lexeme);

        type.element = element;
        element.definedType = type;

        _environment.defineSymbol(
          parameter.identifier.lexeme,
          element,
        );

        definition.parameters.add(element);
      }
    }
  }

  for (final statementVariant in node.variants) {
    final variant = await statementVariant.accept(this) as TypeVariantElement;
    variant.enclosingElement = definition;
    definition.variants.add(variant);
  }

  _environment = _environment.enclosing!;

  return definition;
}