encapsulate method

HTObject? encapsulate(
  1. dynamic object
)

Encapsulate any value to a Hetu object, for members accessing and type check.

Implementation

HTObject? encapsulate(dynamic object) {
  if (object == null) {
    return null;
  } else if (object is HTObject) {
    return object;
  } else if (object is HTType) {
    return HTTypeObject(object);
  }

  var canCache = true;
  late String typeString;
  if (object is bool) {
    canCache = false;
    typeString = _lexicon.idBoolean;
  } else if (object is int) {
    canCache = false;
    typeString = _lexicon.idInteger;
  } else if (object is double) {
    canCache = false;
    typeString = _lexicon.idFloat;
  } else if (object is String) {
    canCache = false;
    typeString = _lexicon.idString;
  } else if (object is List) {
    typeString = 'List';
    // var valueType = HTType.ANY;
    // if (object.isNotEmpty) {
    //   valueType = encapsulate(object.first).valueType;
    //   for (final item in object) {
    //     final value = encapsulate(item).valueType;
    //     if (value.isNotA(valueType)) {
    //       valueType = HTType.ANY;
    //       break;
    //     }
    //   }
    // }
    // return HTList(object, this, valueType: valueType);
  } else if (object is Set) {
    typeString = 'Set';
  } else if (object is Map) {
    typeString = 'Map';
    // var keyType = HTType.ANY;
    // var valueType = HTType.ANY;
    // if (object.keys.isNotEmpty) {
    //   keyType = encapsulate(object.keys.first).valueType;
    //   for (final item in object.keys) {
    //     final value = encapsulate(item).valueType;
    //     if (value.isNotA(keyType)) {
    //       keyType = HTType.ANY;
    //       break;
    //     }
    //   }
    // }
    // if (object.values.isNotEmpty) {
    //   valueType = encapsulate(object.values.first).valueType;
    //   for (final item in object.values) {
    //     final value = encapsulate(item).valueType;
    //     if (value.isNotA(valueType)) {
    //       valueType = HTType.ANY;
    //       break;
    //     }
    //   }
    // }
    // return HTMap(object, this, keyType: keyType, valueType: valueType);
  } else if (object is Iterable) {
    typeString = 'Iterable';
  } else if (object is Iterator) {
    typeString = 'Iterator';
  } else if (object is math.Random) {
    typeString = 'Random';
  } else {
    canCache = object is! BigInt && object is! Record && object is! Expando;
    if (canCache) {
      final cached = _externalInstances[object];
      if (cached != null && identical(cached.namespace, currentNamespace)) {
        ++externalInstanceCacheHits;
        return cached;
      }
    }
    var reflected = false;
    for (final reflect in externalTypeReflection) {
      final result = reflect(object);
      if (result != null) {
        reflected = true;
        typeString = result;
        break;
      }
    }
    if (!reflected) {
      typeString = object.runtimeType.toString();
      typeString = _lexicon.getBaseTypeId(typeString);
    }
  }

  if (!canCache) {
    return HTExternalInstance(object, this, typeString);
  }

  final cached = _externalInstances[object];
  if (cached != null && identical(cached.namespace, currentNamespace)) {
    ++externalInstanceCacheHits;
    return cached;
  }
  ++externalInstanceCacheMisses;
  final instance = HTExternalInstance(object, this, typeString);
  _externalInstances[object] = instance;
  return instance;
}