Skip to content

Commit

Permalink
Apply suggestions from code review
Browse files Browse the repository at this point in the history
Co-authored-by: blagoev <[email protected]>
  • Loading branch information
nielsenko and blagoev committed Oct 28, 2022
1 parent 923bebf commit 7bdd8ec
Show file tree
Hide file tree
Showing 10 changed files with 34 additions and 35 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* Added `User.functions`. This is the entry point for calling Atlas App functions. Functions allow you to define and execute server-side logic for your application. Atlas App functions are created on the server, written in modern JavaScript (ES6+) and executed in a serverless manner. When you call a function, you can dynamically access components of the current application as well as information about the request to execute the function and the logged in user that sent the request. ([#973](https://github.com/realm/realm-dart/pull/973))
* Support results of primitives, ie. `RealmResult<int>`. (Issue [#162](https://github.com/realm/realm-dart/issues/162))
* Support notifications on all managed realm lists, including list of primitives, ie. `RealmList<int>.changes` is supported. ([#893](https://github.com/realm/realm-dart/pull/893))
* Support named backlinks on realm models. You can now add and annotate a realm object iterator field with `@Backlink(#symbolName)`. ([#996](https://github.com/realm/realm-dart/pull/996))
* Support named backlinks on realm models. You can now add and annotate a realm object iterator field with `@Backlink(#fieldName)`. ([#996](https://github.com/realm/realm-dart/pull/996))

### Fixed
* Fixed a wrong mapping for `AuthProviderType` returned by `User.provider` for google, facebook and apple credentials.
Expand Down
7 changes: 4 additions & 3 deletions common/lib/src/realm_common_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,10 @@ class Ignored {
const Ignored();
}

/// Indicates a backlink property.
/// Indicates that the field it decorates is the inverse end of a relationship.
/// {@category Annotations}
class Backlink {
final Symbol symbol;
const Backlink(this.symbol);
/// The name of the field in the other class that links to this class.
final Symbol fieldName;
const Backlink(this.fieldName);
}
2 changes: 1 addition & 1 deletion generator/lib/src/class_element_ex.dart
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ extension ClassElementEx on ClassElement {

final objectType = ObjectType.values[modelInfo.value.getField('type')!.getField('index')!.toIntValue()!];

// Computed fields go last. This is important for the schema generation.
// Realm Core requires computed properties at the end so we sort them at generation time versus doing it at runtime every time.
final mappedFields = fields.realmInfo.toList()..sort((a, b) => a.isComputed ^ b.isComputed ? (a.isComputed ? 1 : -1) : -1);

if (objectType == ObjectType.embeddedObject && mappedFields.any((field) => field.isPrimaryKey)) {
Expand Down
2 changes: 1 addition & 1 deletion generator/lib/src/dart_type_ex.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ extension DartTypeEx on DartType {

DartType get mappedType {
final self = this;
final provider = session.typeProvider;
if (isRealmCollection) {
if (self is ParameterizedType) {
final mapped = self.typeArguments.last.mappedType;
if (self != mapped) {
final provider = session.typeProvider;
if (self.isDartCoreList) {
final mappedList = provider.listType(mapped);
return PseudoType('Realm${mappedList.getDisplayString(withNullability: true)}', nullabilitySuffix: mappedList.nullabilitySuffix);
Expand Down
12 changes: 6 additions & 6 deletions generator/lib/src/field_element_ex.dart
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ extension FieldElementEx on FieldElement {
//
// However, this may change in the future. Either as the dart language team change this
// blemish. Or perhaps we can avoid the late modifier, once static meta programming lands
// in dart. Therefor we keep the code out-commented for later.
// in dart. Therefore we keep the code out-commented for later.
/*
if (!isFinal) {
throw RealmInvalidGenerationSourceError(
Expand Down Expand Up @@ -182,9 +182,9 @@ extension FieldElementEx on FieldElement {
todo: todo,
);
} else {
// Validate collections and back-links
// Validate collections and backlinks
if (type.isRealmCollection || backlink != null) {
final typeDescription = type.isRealmCollection ? 'collections' : 'back-links';
final typeDescription = type.isRealmCollection ? 'collections' : 'backlinks';
if (type.isNullable) {
throw RealmInvalidGenerationSourceError(
'Realm $typeDescription cannot be nullable',
Expand All @@ -204,7 +204,7 @@ extension FieldElementEx on FieldElement {
}
}

// Validate back-links
// Validate backlinks
if (backlink != null) {
if (!type.isDartCoreIterable || !(type as ParameterizedType).typeArguments.first.isRealmModel) {
throw RealmInvalidGenerationSourceError(
Expand All @@ -216,7 +216,7 @@ extension FieldElementEx on FieldElement {
);
}

final sourceFieldName = backlink.value.getField('symbol')?.toSymbolValue();
final sourceFieldName = backlink.value.getField('fieldName')?.toSymbolValue();
final sourceType = (type as ParameterizedType).typeArguments.first;
final sourceField = (sourceType.element2 as ClassElement?)?.fields.where((f) => f.name == sourceFieldName).singleOrNull;

Expand All @@ -235,7 +235,7 @@ extension FieldElementEx on FieldElement {
final listOf = session.typeProvider.listType(thisType);
if (sourceField.type != linkType && sourceField.type != listOf) {
throw RealmInvalidGenerationSourceError(
'Incompatible back-link type',
'Incompatible backlink type',
primarySpan: typeSpan(file),
primaryLabel: "$sourceType.$sourceFieldName is not a '$linkType' or '$listOf'",
todo: '',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Incompatible back-link type
Incompatible backlink type

in: asset:pkg/test/error_test_data/backlink_illegal_symbol.dart:11:8
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Incompatible back-link type
Incompatible backlink type

in: asset:pkg/test/error_test_data/backlink_incompatible_type.dart:11:8
Expand Down
2 changes: 1 addition & 1 deletion generator/test/test_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class LinesEqualsMatcher extends Matcher {
}
}

if (actualLines.length > expectedLines.length) {
if (actualLines.length != expectedLines.length) {
matchState["Error"] = "Different number of lines. \nExpected: ${expectedLines.length}\nActual: ${actualLines.length}";
return false;
}
Expand Down
34 changes: 16 additions & 18 deletions lib/src/realm_object.dart
Original file line number Diff line number Diff line change
Expand Up @@ -149,26 +149,24 @@ class RealmCoreAccessor implements RealmAccessor {
final sourceProperty = sourceMeta[propertyMeta.linkOriginProperty!];
final handle = realmCore.getBacklinks(object, sourceMeta.classKey, sourceProperty.key);
return RealmResultsInternal.create<T>(handle, object.realm, metadata);
} else {
final handle = realmCore.getListProperty(object, propertyMeta.key);
final listMetadata = propertyMeta.objectType == null ? null : object.realm.metadata.getByName(propertyMeta.objectType!);

// listMetadata is not null when we have list of RealmObjects. If the API was
// called with a generic object arg - get<Object> we construct a list of
// RealmObjects since we don't know the type of the object.
if (listMetadata != null && _isTypeGenericObject<T>()) {
switch (listMetadata.schema.baseType) {
case ObjectType.realmObject:
return object.realm.createList<RealmObject>(handle, listMetadata);
case ObjectType.embeddedObject:
return object.realm.createList<EmbeddedObject>(handle, listMetadata);
default:
throw RealmError('List of ${listMetadata.schema.baseType} is not supported yet');
}
}
final handle = realmCore.getListProperty(object, propertyMeta.key);
final listMetadata = propertyMeta.objectType == null ? null : object.realm.metadata.getByName(propertyMeta.objectType!);

// listMetadata is not null when we have list of RealmObjects. If the API was
// called with a generic object arg - get<Object> we construct a list of
// RealmObjects since we don't know the type of the object.
if (listMetadata != null && _isTypeGenericObject<T>()) {
switch (listMetadata.schema.baseType) {
case ObjectType.realmObject:
return object.realm.createList<RealmObject>(handle, listMetadata);
case ObjectType.embeddedObject:
return object.realm.createList<EmbeddedObject>(handle, listMetadata);
default:
throw RealmError('List of ${listMetadata.schema.baseType} is not supported yet');
}

return object.realm.createList<T>(handle, listMetadata);
}
return object.realm.createList<T>(handle, listMetadata);
}

Object? value = realmCore.getProperty(object, propertyMeta.key);
Expand Down
4 changes: 2 additions & 2 deletions test/backlinks_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ class _Source {
@RealmModel()
class _Target {
@Backlink(#oneTarget)
late Iterable<_Source> oneToMany; // computed property, so must go last in generated class!
late Iterable<_Source> oneToMany;

String name = 'target';

@Backlink(#manyTargets)
late Iterable<_Source> manyToMany; // computed property, so must go last in generated class!
late Iterable<_Source> manyToMany;
}

Future<void> main([List<String>? args]) async {
Expand Down

0 comments on commit 7bdd8ec

Please sign in to comment.