void computeInboundRefs()

in packages/devtools_app/lib/src/memory/memory_service.dart [134:242]


void computeInboundRefs(
  List<ClassHeapDetailStats> allClasses,
  InboundReferences refs,
  BuildInboundEntry buildCallback,
) {
  final Iterable<InboundReference> elements = refs?.elements ?? [];
  for (InboundReference element in elements) {
    // Could be a reference to an evaluate so this isn't known.

    // Looks like an object created from an evaluate, ignore it.
    if (element.parentField == null && element.json == null) continue;

    // TODO(terry): Verify looks like internal class (maybe to C code).
    if (element.parentField.owner != null &&
        element.parentField.owner.name.contains('&')) continue;

    String referenceName;
    String owningAllocator; // Class or library that allocated.
    bool owningAllocatorIsAbstract;

    switch (element.parentField.runtimeType.toString()) {
      case 'ClassRef':
        final ClassRef classRef = element.classRef;
        owningAllocator = classRef.name;
        // TODO(terry): Quick way to detect if class is probably abstract-
        // TODO(terry): Does it exist in the class list table?
        owningAllocatorIsAbstract =
            _searchClass(allClasses, owningAllocator) == null;
        break;
      case 'FieldRef':
        final FieldRef fieldRef = element.fieldRef;
        referenceName = fieldRef.name;
        switch (fieldRef.owner.runtimeType.toString()) {
          case 'ClassRef':
            final ClassRef classRef = ClassRef.parse(fieldRef.owner.json);
            owningAllocator = classRef.name;
            // TODO(terry): Quick way to detect if class is probably abstract-
            // TODO(terry): Does it exist in the class list table?
            owningAllocatorIsAbstract =
                _searchClass(allClasses, owningAllocator) == null;
            break;
          case 'Library':
          case 'LibraryRef':
            final Library library = Library.parse(fieldRef.owner.json);
            owningAllocator = 'Library ${library?.name ?? ""}';
            break;
        }
        break;
      case 'FuncRef':
        _hoverInstanceAllocationsUnhandledTypeError(
          element.parentField.runtimeType,
        );
        // TODO(terry): TBD
        // final FuncRef funcRef = element.funcRef;
        break;
      case 'Instance':
        _hoverInstanceAllocationsUnhandledTypeError(
          element.parentField.runtimeType,
        );
        // TODO(terry): TBD
        // final Instance instance = element.instance;
        break;
      case 'InstanceRef':
        _hoverInstanceAllocationsUnhandledTypeError(
          element.parentField.runtimeType,
        );
        // TODO(terry): TBD
        // final InstanceRef instanceRef = element.instanceRef;
        break;
      case 'Library':
      case 'LibraryRef':
        _hoverInstanceAllocationsUnhandledTypeError(
          element.parentField.runtimeType,
        );
        // TODO(terry): TBD
        // final Library library = element.library;
        break;
      case 'NullVal':
      case 'NullValRef':
        _hoverInstanceAllocationsUnhandledTypeError(
          element.parentField.runtimeType,
        );
        // TODO(terry): TBD
        // final NullVal nullValue = element.nullVal;
        break;
      case 'Obj':
      case 'ObjRef':
        _hoverInstanceAllocationsUnhandledTypeError(
          element.parentField.runtimeType,
        );
        // TODO(terry): TBD
        // final Obj obj = element.obj;
        break;
      default:
        _hoverInstanceAllocationsUnhandledTypeError(
          element.parentField.runtimeType,
        );
    }

    // call the build UI callback.
    if (buildCallback != null) {
      buildCallback(
        referenceName,
        owningAllocator,
        owningAllocatorIsAbstract,
      );
    }
  }
}