memberGet method

  1. @override
dynamic memberGet(
  1. dynamic id, {
  2. String? from,
  3. bool isRecursive = false,
  4. bool ignoreUndefined = true,
  5. HTStruct? caller,
})
override

Fetch a member by the id, in the form of

object.id

id must be of String type.

Implementation

@override
dynamic memberGet(
  dynamic id, {
  String? from,
  bool isRecursive = false,
  bool ignoreUndefined = true,
  HTStruct? caller,
}) {
  if (id == null) {
    return null;
  }
  if (id is! String) {
    id = id.toString();
  }
  if (id == InternalIdentifier.prototype) {
    return prototype;
  }

  dynamic value;
  final getter = '${InternalIdentifier.getter}$id';
  final constructor = this.id != id
      ? '${InternalIdentifier.namedConstructorPrefix}$id'
      : InternalIdentifier.defaultConstructor;

  if (_fields.containsKey(id)) {
    if (interpreter.lexicon.isPrivate(id) &&
        from != null &&
        !from.startsWith(namespace.fullName)) {
      throw HTError.privateMember(id);
    }
    value = _fields[id];
    if (caller?.prototype != this &&
        (value is HTFunction && value.isStatic)) {
      value = null;
    }
  } else if (_fields.containsKey(getter)) {
    if (interpreter.lexicon.isPrivate(id) &&
        from != null &&
        !from.startsWith(namespace.fullName)) {
      throw HTError.privateMember(id);
    }
    value = _fields[getter];
    if (caller?.prototype != this &&
        (value is HTFunction && value.isStatic)) {
      value = null;
    }
  } else if (_fields.containsKey(constructor)) {
    if (interpreter.lexicon.isPrivate(id) &&
        from != null &&
        !from.startsWith(namespace.fullName)) {
      throw HTError.privateMember(id);
    }
    value = _fields[constructor];
  } else if (prototype != null) {
    value = prototype!.memberGet(id, from: from, caller: caller ?? this);
  }

  if (value is HTDeclaration) {
    value.resolve();
  }
  // assign the original struct as instance, not the prototype object
  if (caller == null) {
    if (value is HTFunction) {
      value.namespace = namespace;
      value.instance = this;
      if (value.category == FunctionCategory.getter) {
        value = value.call();
      }
    }
  }
  return value;
}