wasiComponentWitWorldFunctions function

List<WASIComponentWitFunctionBinding> wasiComponentWitWorldFunctions(
  1. WASIComponentWitDocument document,
  2. WASIComponentWitWorld world, {
  3. WASIComponentWitTargetResolver? resolveTarget,
  4. Set<String>? visiting,
  5. String qualifyInterfaceName(
    1. String interfaceName
    )?,
})

Expands local and resolved WIT import/export interface functions from world.

Implementation

List<WASIComponentWitFunctionBinding> wasiComponentWitWorldFunctions(
  WASIComponentWitDocument document,
  WASIComponentWitWorld world, {
  WASIComponentWitTargetResolver? resolveTarget,
  Set<String>? visiting,
  String Function(String interfaceName)? qualifyInterfaceName,
}) {
  final active = visiting ?? <String>{};
  final visitKey = _witWorldVisitKey(document, world);
  if (!active.add(visitKey)) {
    return const <WASIComponentWitFunctionBinding>[];
  }
  final functions = <WASIComponentWitFunctionBinding>[];
  for (final item in world.items) {
    final target = item.target;
    if (item.direction == WASIComponentWitWorldItemDirection.include) {
      if (target.isQualified) {
        final resolved = resolveTarget?.call(target.text);
        if (resolved == null) {
          throw WASIComponentWitTargetResolutionException(
            target.text,
            'no resolver result',
          );
        }
        final included = resolved.document.worldNamed(resolved.memberName);
        if (included == null) {
          throw WASIComponentWitTargetResolutionException(
            target.text,
            "world '${resolved.memberName}' does not exist in the resolved document",
          );
        }
        functions.addAll(
          wasiComponentWitWorldFunctions(
            resolved.document,
            included,
            resolveTarget: resolveTarget,
            visiting: active,
            qualifyInterfaceName: resolved.qualifiedInterfaceName,
          ),
        );
        continue;
      }
      final included = document.worldNamed(target.text);
      if (included != null) {
        functions.addAll(
          wasiComponentWitWorldFunctions(
            document,
            included,
            resolveTarget: resolveTarget,
            visiting: active,
            qualifyInterfaceName: qualifyInterfaceName,
          ),
        );
      }
      continue;
    }
    final resolved = target.isQualified
        ? resolveTarget?.call(target.text)
        : null;
    if (target.isQualified && resolved == null) {
      throw WASIComponentWitTargetResolutionException(
        target.text,
        'no resolver result',
      );
    }
    final interfaceDocument = resolved?.document ?? document;
    final interfaceName = resolved?.memberName ?? target.text;
    final interface = interfaceDocument.interfaceNamed(interfaceName);
    if (interface == null) {
      if (target.isQualified) {
        throw WASIComponentWitTargetResolutionException(
          target.text,
          "interface '$interfaceName' does not exist in the resolved document",
        );
      }
      continue;
    }
    final callbackInterfaceName =
        resolved?.qualifiedInterfaceName(interface.name) ??
        qualifyInterfaceName?.call(interface.name) ??
        interface.name;
    for (final function in interface.functions) {
      functions.add(
        WASIComponentWitFunctionBinding._(
          item: item,
          interfaceName: callbackInterfaceName,
          function: function,
          direction: item.direction,
          signature: _parseWitAdapterSignature(
            function,
            interface,
            document: interfaceDocument,
            resolveTarget: resolveTarget,
          ),
        ),
      );
    }
  }
  active.remove(visitKey);
  return List<WASIComponentWitFunctionBinding>.unmodifiable(functions);
}