visitSuperConstructorInvocation method

  1. @override
Object? visitSuperConstructorInvocation(
  1. SSuperConstructorInvocation node
)
override

Implementation

@override
Object? visitSuperConstructorInvocation(SSuperConstructorInvocation node) {
  // 1. Retrieve the 'this' instance currently being created.
  InterpretedInstance? thisInstance;
  try {
    final thisValue = environment.get('this');
    if (thisValue is InterpretedInstance) {
      thisInstance = thisValue;
    } else {
      throw RuntimeD4rtException(
        "Internal error: 'this' is not an InterpretedInstance during super constructor call.",
      );
    }
  } on RuntimeD4rtException {
    throw RuntimeD4rtException(
      "Internal error: Could not find 'this' during super constructor call.",
    );
  }

  // 2. Check that the class has a bridged superclass.
  final currentClass = thisInstance.klass;
  final bridgedSuper = currentClass.bridgedSuperclass;
  if (bridgedSuper == null) {
    // If the superclass is interpreted, this call should be handled differently
    // (standard inherited constructor call).
    // For now, assume that if we get here, it's because of a bridged superclass.
    throw RuntimeD4rtException(
      "Cannot call super() constructor: Class '${currentClass.name}' does not have a registered bridged superclass.",
    );
  }

  // 3. Determine the name of the super constructor to call.
  final constructorName =
      node.constructorName?.name ?? ''; // '' for the default

  // 4. Find the constructor adapter for the bridged superclass.
  final constructorAdapter = bridgedSuper.findConstructorAdapter(
    constructorName,
  );
  if (constructorAdapter == null) {
    throw RuntimeD4rtException(
      "Bridged superclass '${bridgedSuper.name}' has no constructor named '$constructorName'.",
    );
  }

  // 5. Evaluate the arguments passed to super(...).
  final (positionalArgs, namedArgs) = _evaluateArguments(node.argumentList);

  // 6. Call the constructor adapter.
  Object? nativeSuperObject;
  try {
    nativeSuperObject = constructorAdapter(this, positionalArgs, namedArgs);
    if (nativeSuperObject == null) {
      throw RuntimeD4rtException(
        "Bridged super constructor adapter for '${bridgedSuper.name}.$constructorName' returned null.",
      );
    }
  } catch (e, s) {
    Logger.error(
      "Native exception during super constructor call to '${bridgedSuper.name}.$constructorName': $e\n$s",
    );
    throw RuntimeD4rtException(
      "Native error during super constructor call '$constructorName': $e",
      originalException: e,
    );
  }

  // 7. Store the returned native object on the 'this' instance.
  thisInstance.bridgedSuperObject = nativeSuperObject;
  Logger.debug(
    "[SSuperConstructorInvocation] Stored native super object (${nativeSuperObject.runtimeType}) on instance of ${currentClass.name}.",
  );

  return null; // The super() call itself doesn't return a value.
}