buildInterpretedExtension method

InterpretedExtension buildInterpretedExtension(
  1. RuntimeType onType
)

Builds an InterpretedExtension from this definition.

The onType is the resolved RuntimeType for onTypeName, provided by the caller (typically the module loader) after the type has been looked up in the environment.

Implementation

InterpretedExtension buildInterpretedExtension(RuntimeType onType) {
  final members = <String, Callable>{};

  // Wrap getters as NativeExtensionCallable
  for (final entry in getters.entries) {
    members[entry.key] = NativeExtensionCallable(
      name: entry.key,
      adapter: (InterpreterVisitor visitor,
          List<Object?> positionalArgs,
          Map<String, Object?> namedArgs,
          List<RuntimeType>? typeArgs) {
        final target = _unwrapBridgedEnum(positionalArgs[0]);
        return entry.value(visitor, target!);
      },
      isGetter: true,
      arity: 1,
    );
  }

  // Wrap setters as NativeExtensionCallable
  for (final entry in setters.entries) {
    members[entry.key] = NativeExtensionCallable(
      name: entry.key,
      adapter: (InterpreterVisitor visitor,
          List<Object?> positionalArgs,
          Map<String, Object?> namedArgs,
          List<RuntimeType>? typeArgs) {
        final target = _unwrapBridgedEnum(positionalArgs[0]);
        final value = positionalArgs.length > 1
            ? _unwrapBridgedEnum(positionalArgs[1])
            : null;
        entry.value(visitor, target!, value);
        return null;
      },
      isSetter: true,
      arity: 2,
    );
  }

  // Wrap methods as NativeExtensionCallable
  for (final entry in methods.entries) {
    members[entry.key] = NativeExtensionCallable(
      name: entry.key,
      adapter: (InterpreterVisitor visitor,
          List<Object?> positionalArgs,
          Map<String, Object?> namedArgs,
          List<RuntimeType>? typeArgs) {
        // Bucket #4 fix: Unwrap BridgedEnumValue → nativeValue so the
        // generated adapter (which casts target to the native interface)
        // receives the native enum, not the wrapper. Right operands of
        // operator methods (e.g. `WidgetState.a | WidgetState.b`) need
        // the same treatment.
        final target = _unwrapBridgedEnum(positionalArgs[0]);
        final methodArgs = positionalArgs
            .sublist(1)
            .map(_unwrapBridgedEnum)
            .toList();
        final unwrappedNamed = namedArgs
            .map((k, v) => MapEntry(k, _unwrapBridgedEnum(v)));
        return entry.value(
            visitor, target!, methodArgs, unwrappedNamed, typeArgs);
      },
      // Mark operator methods (e.g. `|`, `&`, `~`, `[]`, `==`) so the
      // binary/unary operator dispatch sites recognise them as operator
      // overloads rather than plain extension methods.
      isOperator: _isDartOperatorName(entry.key),
      arity: 1,
    );
  }

  return InterpretedExtension(
    name: name,
    onType: onType,
    members: members,
  );
}