Map _propertiesFromModelDescription()

in lib/src/db/model_db_impl.dart [314:367]


  Map<String, Property> _propertiesFromModelDescription(
      mirrors.ClassMirror modelClassMirror) {
    var properties = <String, Property>{};
    var propertyNames = <String>{};

    // Loop over all classes in the inheritance path up to the Object class.
    while (modelClassMirror.superclass != null) {
      var memberMap = modelClassMirror.instanceMembers;
      // Loop over all declarations (which includes fields)
      modelClassMirror.declarations
          .forEach((Symbol fieldSymbol, mirrors.DeclarationMirror decl) {
        // Look if the symbol is a getter and we have metadata attached to it.
        if (memberMap.containsKey(fieldSymbol) &&
            memberMap[fieldSymbol]!.isGetter) {
          final propertyAnnotations = decl.metadata
              .map((mirrors.InstanceMirror mirror) => mirror.reflectee)
              .whereType<Property>()
              .toList();

          if (propertyAnnotations.length > 1) {
            throw StateError(
                'Cannot have more than one Property annotation on a model '
                'field.');
          } else if (propertyAnnotations.length == 1) {
            var property = propertyAnnotations.first;

            // Get a String representation of the field and the value.
            var fieldName = mirrors.MirrorSystem.getName(fieldSymbol);

            // Determine the name to use for the property in datastore.
            var propertyName = property.propertyName;
            propertyName ??= fieldName;

            if (properties.containsKey(fieldName)) {
              throw StateError(
                  'Cannot have two Property objects describing the same field '
                  'in a model object class hierarchy.');
            }

            if (propertyNames.contains(propertyName)) {
              throw StateError(
                  'Cannot have two Property objects mapping to the same '
                  'datastore property name "$propertyName".');
            }
            properties[fieldName] = property;
            propertyNames.add(propertyName);
          }
        }
      });
      modelClassMirror = modelClassMirror.superclass!;
    }

    return properties;
  }