getNodeDetails method

Future<RPCResponse> getNodeDetails(
  1. String nodeId,
  2. String groupName
)

Gets detailed information about a specific node in the diagnostic tree. nodeId is the ID of the node to get details for groupName is the name of the object group that contains the node Returns detailed information about the node including:

  • All diagnostic properties
  • Widget type information
  • Creation location if available

Implementation

Future<RPCResponse> getNodeDetails(
  final String nodeId,
  final String groupName,
) async {
  final serviceManager = devtoolsService.serviceManager;
  if (!serviceManager.connectedState.value.connected) {
    return RPCResponse.error('Not connected to VM service');
  }

  final vmService = serviceManager.service;
  if (vmService == null) {
    return RPCResponse.error('VM service not available');
  }

  final isolateId = serviceManager.isolateManager.mainIsolate.value?.id;
  if (isolateId == null) {
    return RPCResponse.error('No main isolate available');
  }

  try {
    // First get the properties for the node
    final propertiesResponse = await vmService.callServiceExtension(
      'ext.flutter.inspector.${WidgetInspectorServiceExtensions.getProperties.name}',
      isolateId: isolateId,
      args: {'arg': nodeId, 'objectGroup': groupName},
    );

    if (propertiesResponse.json == null ||
        propertiesResponse.json!['result'] == null) {
      return RPCResponse.error('Node properties not available');
    }

    // Parse the properties
    final List<Object?> propertiesList =
        propertiesResponse.json!['result'] as List<Object?>;
    final properties =
        propertiesList.map((final prop) {
          final propNode = RemoteDiagnosticsNode(
            prop! as Map<String, Object?>,
            null, // objectGroupApi not needed for properties viewing
            true, // this is a property
            null, // no parent
          );
          return {
            'name': propNode.name,
            'description': propNode.description,
            'value': propNode.valueRef.id,
            'type': propNode.type,
            'level': propNode.level.toString(),
            'propertyType': propNode.propertyType,
            'style': propNode.style.toString(),
          };
        }).toList();

    // Get the parent chain for context
    final parentChainResponse = await vmService.callServiceExtension(
      'ext.flutter.inspector.${WidgetInspectorServiceExtensions.getParentChain.name}',
      isolateId: isolateId,
      args: {'arg': nodeId, 'objectGroup': groupName},
    );

    List<Map<String, Object?>> parentChain = [];
    if (parentChainResponse.json != null &&
        parentChainResponse.json!['result'] != null) {
      final List<Object?> chainList =
          parentChainResponse.json!['result'] as List<Object?>;
      parentChain =
          chainList.map((final node) {
            final parentNode = RemoteDiagnosticsNode(
              node! as Map<String, Object?>,
              null,
              false,
              null,
            );
            return {
              'id': parentNode.valueRef.id,
              'type': parentNode.type,
              'description': parentNode.description,
              'widgetRuntimeType': parentNode.widgetRuntimeType,
            };
          }).toList();
    }

    return RPCResponse.successMap({
      'properties': properties,
      'parentChain': parentChain,
    });
  } catch (e, stack) {
    return RPCResponse.error('Error getting node details: $e', stack);
  }
}