getAllInterfaceMembers method

Map<String, String> getAllInterfaceMembers()

Returns a map representing all members required by the interfaces implemented by this class and its superclasses, including those from super-interfaces. Key: member name, Value: String indicating type ('method', 'getter', 'setter')

Implementation

Map<String, String> getAllInterfaceMembers() {
  final requiredMembers = <String, String>{};
  final Set<InterpretedClass> visited = {}; // To avoid cycles/redundancy
  final List<InterpretedClass> queue = [];

  // Start with directly implemented interfaces
  queue.addAll(interfaces);
  // Also consider interfaces/abstract members from superclasses
  var currentSuper = superclass;
  while (currentSuper != null) {
    queue.add(
        currentSuper); // Add superclass to check its interfaces/abstract members
    currentSuper = currentSuper.superclass;
  }

  while (queue.isNotEmpty) {
    final currentClass = queue.removeAt(0);

    if (!visited.add(currentClass)) {
      continue; // Already processed this class/interface
    }

    // Add members defined directly in this interface/class
    // We only care about the *signature* required, not the implementation.
    // Note: Static members are NOT part of the interface contract.
    currentClass.methods.forEach((name, func) {
      // Abstract methods from superclasses also count as required signatures
      requiredMembers.putIfAbsent(
          name, () => func.isAbstract ? 'method' : 'method');
    });
    currentClass.getters.forEach((name, func) {
      requiredMembers.putIfAbsent(
          name, () => func.isAbstract ? 'getter' : 'getter');
    });
    currentClass.setters.forEach((name, func) {
      requiredMembers.putIfAbsent(
          name, () => func.isAbstract ? 'setter' : 'setter');
    });

    // Add interfaces implemented by this class to the queue
    queue.addAll(currentClass.interfaces);
    // Also add its superclass to the queue (if not already visited)
    if (currentClass.superclass != null &&
        !visited.contains(currentClass.superclass)) {
      // No, superclass was added initially. We traverse the interface graph here.
      // We need to get members from the superclass chain separately potentially.
      // Let's reconsider. The check needs *all* members required by interfaces
      // AND *all* abstract members from superclasses.
    }
  }

  // Re-think: The above mixes inherited abstract members and interface members.
  // Let's separate concerns.
  // 1. Get all members required ONLY by interfaces.
  // 2. Get all abstract members inherited via `extends` (already done).
  // 3. The class needs to satisfy BOTH.

  final requiredInterfaceMembers = <String, String>{};
  final Set<InterpretedClass> visitedInterfaces = {};
  final List<InterpretedClass> interfaceQueue = [];
  interfaceQueue.addAll(interfaces);

  // Add interfaces from superclasses as well
  currentSuper = superclass;
  while (currentSuper != null) {
    interfaceQueue.addAll(currentSuper.interfaces);
    currentSuper = currentSuper.superclass;
  }

  while (interfaceQueue.isNotEmpty) {
    final currentInterface = interfaceQueue.removeAt(0);
    if (!visitedInterfaces.add(currentInterface)) {
      continue;
    }

    // Add members from the current interface
    currentInterface.methods.forEach((name, func) {
      requiredInterfaceMembers.putIfAbsent(name, () => 'method');
    });
    currentInterface.getters.forEach((name, func) {
      requiredInterfaceMembers.putIfAbsent(name, () => 'getter');
    });
    currentInterface.setters.forEach((name, func) {
      requiredInterfaceMembers.putIfAbsent(name, () => 'setter');
    });

    // Add its super-interfaces to the queue
    interfaceQueue.addAll(currentInterface.interfaces);
    // IMPORTANT: Also add the interface's OWN superclass to the queue,
    // as the implementing class must satisfy members from the entire hierarchy.
    if (currentInterface.superclass != null) {
      interfaceQueue.add(currentInterface.superclass!); // Non-null asserted
    }
  }

  return requiredInterfaceMembers;
}