@@ -2,7 +2,7 @@ import 'dart:async';
2
2
import 'dart:convert' ;
3
3
4
4
import 'package:analyzer/dart/constant/value.dart' ;
5
- import 'package:analyzer/dart/element/element .dart' ;
5
+ import 'package:analyzer/dart/element/element2 .dart' ;
6
6
import 'package:analyzer/dart/element/nullability_suffix.dart' ;
7
7
import 'package:analyzer/dart/element/type.dart' ;
8
8
import 'package:build/build.dart' ;
@@ -53,10 +53,10 @@ class EntityResolver extends Builder {
53
53
}
54
54
55
55
ModelEntity generateForAnnotatedElement (
56
- Element classElement, ConstantReader annotation) {
57
- if (classElement is ! ClassElement ) {
56
+ Element2 classElement, ConstantReader annotation) {
57
+ if (classElement is ! ClassElement2 ) {
58
58
throw InvalidGenerationSourceError (
59
- "Entity '${classElement .name }': annotated element must be a class." );
59
+ "Entity '${classElement .displayName }': annotated element must be a class." );
60
60
}
61
61
62
62
// process basic entity (note that allModels.createEntity is not used, as the entity will be merged)
@@ -65,8 +65,8 @@ class EntityResolver extends Builder {
65
65
final entity = ModelEntity .create (
66
66
IdUid (0 , entityUid.isNull ? 0 : entityUid.intValue),
67
67
entityRealClass.isNull
68
- ? classElement.name
69
- : entityRealClass.typeValue.element ! .name ! ,
68
+ ? classElement.displayName
69
+ : entityRealClass.typeValue.element3 ! .displayName ,
70
70
null ,
71
71
uidRequest: ! entityUid.isNull && entityUid.intValue == 0 );
72
72
@@ -85,43 +85,45 @@ class EntityResolver extends Builder {
85
85
86
86
log.info (entity);
87
87
88
- entity.constructorParams = constructorParams (findConstructor (classElement));
88
+ entity.constructorParams =
89
+ constructorParams (classElement.unnamedConstructor2);
89
90
90
91
// Make sure all stored fields are writable when reading object from DB.
91
92
// Let's filter read-only fields, i.e those that:
92
93
// * don't have a setter, and
93
94
// * don't have a corresponding argument in the constructor.
94
- // Note: `.correspondingSetter == null` is also true for ` final` fields.
95
+ // Note: the corresponding setter is also null for final fields.
95
96
final readOnlyFields = < String > {};
96
- for (var f in classElement.accessors) {
97
- if (f.isGetter &&
98
- f.correspondingSetter == null &&
97
+ for (var f in classElement.getters2) {
98
+ if (f.correspondingSetter2 == null &&
99
99
! entity.constructorParams
100
- .any ((String param) => param.startsWith ('${f .name } ' ))) {
101
- readOnlyFields.add (f.name );
100
+ .any ((String param) => param.startsWith ('${f .displayName } ' ))) {
101
+ readOnlyFields.add (f.displayName );
102
102
}
103
103
}
104
104
105
105
// read all suitable annotated properties
106
- for (var f in classElement.fields ) {
106
+ for (var f in classElement.fields2 ) {
107
107
// The field might be implicitly defined by a getter, aka it is synthetic
108
108
// and does not exist in code. So always resolve the actual non-synthetic
109
109
// element that exists in code (here a getter) as only it will have any
110
110
// annotations.
111
- final annotated = f.nonSynthetic ;
111
+ final annotated = f.nonSynthetic2 ;
112
112
113
113
if (_transientChecker.hasAnnotationOfExact (annotated)) {
114
- log.info (" Skipping property '${f .name }': annotated with @Transient." );
114
+ log.info (
115
+ " Skipping property '${f .displayName }': annotated with @Transient." );
115
116
continue ;
116
117
}
117
118
118
- if (readOnlyFields.contains (f.name) && ! isRelationField (f)) {
119
- log.info (" Skipping property '${f .name }': is read-only/getter." );
119
+ if (readOnlyFields.contains (f.name3) && ! isRelationField (f)) {
120
+ log.info (
121
+ " Skipping property '${f .displayName }': is read-only/getter." );
120
122
continue ;
121
123
}
122
124
123
125
if (f.isPrivate) {
124
- log.info (" Skipping property '${f .name }': is private." );
126
+ log.info (" Skipping property '${f .displayName }': is private." );
125
127
continue ;
126
128
}
127
129
@@ -153,10 +155,10 @@ class EntityResolver extends Builder {
153
155
if (isToManyRelationField (f)) {
154
156
isToManyRel = true ;
155
157
} else {
156
- fieldType = detectObjectBoxType (f, classElement.name );
158
+ fieldType = detectObjectBoxType (f, classElement.displayName );
157
159
if (fieldType == null ) {
158
160
log.warning (
159
- " Skipping property '${f .name }': type '${f .type }' not supported,"
161
+ " Skipping property '${f .displayName }': type '${f .type }' not supported,"
160
162
" consider creating a relation for @Entity types (https://docs.objectbox.io/relations),"
161
163
" or replace with getter/setter converting to a supported type (https://docs.objectbox.io/advanced/custom-types)." );
162
164
continue ;
@@ -167,12 +169,15 @@ class EntityResolver extends Builder {
167
169
String ? relTargetName;
168
170
if (isRelationField (f)) {
169
171
if (f.type is ! ParameterizedType ) {
170
- log.severe (" Skipping property '${f .name }': invalid relation type, "
172
+ log.severe (
173
+ " Skipping property '${f .displayName }': invalid relation type, "
171
174
"use a type like ToOne<TargetEntity> or ToMany<TargetEntity>." );
172
175
continue ;
173
176
}
174
- relTargetName =
175
- (f.type as ParameterizedType ).typeArguments[0 ].element! .name;
177
+ relTargetName = (f.type as ParameterizedType )
178
+ .typeArguments[0 ]
179
+ .element3!
180
+ .displayName;
176
181
}
177
182
178
183
final backlinkAnnotations =
@@ -181,13 +186,15 @@ class EntityResolver extends Builder {
181
186
// Handles ToMany based on other ToOne or ToMany relation (backlink)
182
187
if (! isToManyRel) {
183
188
log.severe (
184
- " Skipping property '${f .name }': @Backlink() may only be used with ToMany." );
189
+ " Skipping property '${f .displayName }': @Backlink() may only be used with ToMany." );
185
190
continue ;
186
191
}
187
192
final backlinkField =
188
193
backlinkAnnotations.first.getField ('to' )! .toStringValue ()! ;
189
194
final backlink = ModelBacklink (
190
- name: f.name, srcEntity: relTargetName! , srcField: backlinkField);
195
+ name: f.displayName,
196
+ srcEntity: relTargetName! ,
197
+ srcField: backlinkField);
191
198
entity.backlinks.add (backlink);
192
199
log.info (' $backlink ' );
193
200
} else if (isToManyRel) {
@@ -207,7 +214,7 @@ class EntityResolver extends Builder {
207
214
});
208
215
209
216
// create relation
210
- final rel = ModelRelation .create (IdUid (0 , propUid ?? 0 ), f.name ,
217
+ final rel = ModelRelation .create (IdUid (0 , propUid ?? 0 ), f.displayName ,
211
218
targetName: relTargetName,
212
219
uidRequest: propUid != null && propUid == 0 ,
213
220
externalName: externalName,
@@ -220,7 +227,7 @@ class EntityResolver extends Builder {
220
227
// Handles regular properties
221
228
// create property (do not use readEntity.createProperty in order to avoid generating new ids)
222
229
final prop = ModelProperty .create (
223
- IdUid (0 , propUid ?? 0 ), f.name , fieldType,
230
+ IdUid (0 , propUid ?? 0 ), f.displayName , fieldType,
224
231
flags: flags,
225
232
entity: entity,
226
233
uidRequest: propUid != null && propUid == 0 );
@@ -245,7 +252,7 @@ class EntityResolver extends Builder {
245
252
// errors, so no need to integrate with regular index processing.
246
253
if (fieldType != OBXPropertyType .FloatVector ) {
247
254
throw InvalidGenerationSourceError (
248
- "'${classElement .name }.${f .name }': @HnswIndex is only supported for float vector properties." ,
255
+ "'${classElement .displayName }.${f .displayName }': @HnswIndex is only supported for float vector properties." ,
249
256
element: f);
250
257
}
251
258
// Create an index
@@ -266,7 +273,7 @@ class EntityResolver extends Builder {
266
273
267
274
// for code generation
268
275
prop.dartFieldType =
269
- f.type.element ! .name ! + (isNullable (f.type) ? '?' : '' );
276
+ f.type.element3 ! .displayName + (isNullable (f.type) ? '?' : '' );
270
277
entity.properties.add (prop);
271
278
}
272
279
}
@@ -277,13 +284,13 @@ class EntityResolver extends Builder {
277
284
// for `setId()` won't compile. The only exception is when user uses
278
285
// self-assigned IDs, then a different setter will be generated - one that
279
286
// checks the ID being set is already the same, otherwise it must throw.
280
- final idField = classElement.fields
281
- . singleWhere (( FieldElement f) => f.name == entity.idProperty.name);
282
- if (idField.setter == null ) {
287
+ final idField = classElement.fields2. singleWhere (
288
+ ( FieldElement2 f) => f.displayName == entity.idProperty.name);
289
+ if (idField.setter2 == null ) {
283
290
if (! entity.idProperty.hasFlag (OBXPropertyFlags .ID_SELF_ASSIGNABLE )) {
284
291
throw InvalidGenerationSourceError (
285
- "@Id field '${idField .name }' must be writable: "
286
- " ObjectBox uses it to set the assigned ID after inserting a new object, "
292
+ "@Id field '${idField .displayName }' must be writable, "
293
+ " ObjectBox uses it to set the assigned ID after inserting a new object: "
287
294
" provide a setter or remove the 'final' keyword."
288
295
" If your code needs to assign IDs itself,"
289
296
" see https://docs.objectbox.io/advanced/object-ids#self-assigned-object-ids." ,
@@ -309,8 +316,8 @@ class EntityResolver extends Builder {
309
316
/// For fields that do not have a [Property.type] declared in their [Property]
310
317
/// annotation tries to determine the ObjectBox database type based on the
311
318
/// Dart type. May return null if no supported type is detected.
312
- int ? detectObjectBoxType (FieldElement f , String className ) {
313
- final dartType = f .type;
319
+ int ? detectObjectBoxType (FieldElement2 field , String classDisplayName ) {
320
+ final dartType = field .type;
314
321
315
322
if (dartType.isDartCoreInt) {
316
323
// Dart: 8 bytes
@@ -342,32 +349,36 @@ class EntityResolver extends Builder {
342
349
// List<String>
343
350
return OBXPropertyType .StringVector ;
344
351
}
345
- } else if (['Int8List' , 'Uint8List' ].contains (dartType.element! .name)) {
352
+ } else if (['Int8List' , 'Uint8List' ]
353
+ .contains (dartType.element3! .displayName)) {
346
354
return OBXPropertyType .ByteVector ;
347
- } else if (['Int16List' , 'Uint16List' ].contains (dartType.element! .name)) {
355
+ } else if (['Int16List' , 'Uint16List' ]
356
+ .contains (dartType.element3! .displayName)) {
348
357
return OBXPropertyType .ShortVector ;
349
- } else if (['Int32List' , 'Uint32List' ].contains (dartType.element! .name)) {
358
+ } else if (['Int32List' , 'Uint32List' ]
359
+ .contains (dartType.element3! .displayName)) {
350
360
return OBXPropertyType .IntVector ;
351
- } else if (['Int64List' , 'Uint64List' ].contains (dartType.element! .name)) {
361
+ } else if (['Int64List' , 'Uint64List' ]
362
+ .contains (dartType.element3! .displayName)) {
352
363
return OBXPropertyType .LongVector ;
353
- } else if (dartType.element ! .name == 'Float32List' ) {
364
+ } else if (dartType.element3 ! .displayName == 'Float32List' ) {
354
365
return OBXPropertyType .FloatVector ;
355
- } else if (dartType.element ! .name == 'Float64List' ) {
366
+ } else if (dartType.element3 ! .displayName == 'Float64List' ) {
356
367
return OBXPropertyType .DoubleVector ;
357
- } else if (dartType.element ! .name == 'DateTime' ) {
368
+ } else if (dartType.element3 ! .displayName == 'DateTime' ) {
358
369
log.warning (
359
- " DateTime property '${f . name }' in entity '$className ' is stored and read using millisecond precision. "
370
+ " DateTime property '${field . displayName }' in entity '$classDisplayName ' is stored and read using millisecond precision. "
360
371
'To silence this warning, add an explicit type using @Property(type: PropertyType.date) or @Property(type: PropertyType.dateNano) annotation.' );
361
372
return OBXPropertyType .Date ;
362
- } else if (isToOneRelationField (f )) {
373
+ } else if (isToOneRelationField (field )) {
363
374
return OBXPropertyType .Relation ;
364
375
}
365
376
366
377
// No supported Dart type recognized.
367
378
return null ;
368
379
}
369
380
370
- void processIdProperty (ModelEntity entity, ClassElement classElement) {
381
+ void processIdProperty (ModelEntity entity, ClassElement2 classElement) {
371
382
// check properties explicitly annotated with @Id()
372
383
final annotated =
373
384
entity.properties.where ((p) => p.hasFlag (OBXPropertyFlags .ID ));
@@ -405,8 +416,8 @@ class EntityResolver extends Builder {
405
416
idProperty.flags & = ~ OBXPropertyFlags .UNSIGNED ;
406
417
}
407
418
408
- void processAnnotationIndexUnique (FieldElement f, Element annotatedElement,
409
- int ? fieldType, Element elementBare, ModelProperty prop) {
419
+ void processAnnotationIndexUnique (FieldElement2 f, Element2 annotatedElement,
420
+ int ? fieldType, Element2 elementBare, ModelProperty prop) {
410
421
IndexType ? indexType;
411
422
412
423
final indexAnnotation =
@@ -427,13 +438,13 @@ class EntityResolver extends Builder {
427
438
fieldType == OBXPropertyType .DoubleVector ||
428
439
fieldType == OBXPropertyType .StringVector ) {
429
440
throw InvalidGenerationSourceError (
430
- "Entity '${elementBare .name }': @Index/@Unique is not supported for type '${f .type }' of field '${f .name }'." ,
441
+ "Entity '${elementBare .displayName }': @Index/@Unique is not supported for type '${f .type }' of field '${f .displayName }'." ,
431
442
element: f);
432
443
}
433
444
434
445
if (prop.hasFlag (OBXPropertyFlags .ID )) {
435
446
throw InvalidGenerationSourceError (
436
- "Entity '${elementBare .name }': @Index/@Unique is not supported for @Id field '${f .name }'."
447
+ "Entity '${elementBare .displayName }': @Index/@Unique is not supported for @Id field '${f .displayName }'."
437
448
" IDs are unique by definition and automatically indexed." ,
438
449
element: f);
439
450
}
@@ -459,7 +470,7 @@ class EntityResolver extends Builder {
459
470
if (! supportsHashIndex &&
460
471
(indexType == IndexType .hash || indexType == IndexType .hash64)) {
461
472
throw InvalidGenerationSourceError (
462
- "Entity '${elementBare .name }': a hash index is not supported for type '${f .type }' of field '${f .name }'" ,
473
+ "Entity '${elementBare .displayName }': a hash index is not supported for type '${f .type }' of field '${f .displayName }'" ,
463
474
element: f);
464
475
}
465
476
@@ -489,7 +500,7 @@ class EntityResolver extends Builder {
489
500
}
490
501
491
502
void ensureSingleUniqueReplace (
492
- ModelEntity entity, ClassElement classElement) {
503
+ ModelEntity entity, ClassElement2 classElement) {
493
504
final uniqueReplaceProps = entity.properties
494
505
.where ((p) => p.hasFlag (OBXPropertyFlags .UNIQUE_ON_CONFLICT_REPLACE ));
495
506
if (uniqueReplaceProps.length > 1 ) {
@@ -500,7 +511,7 @@ class EntityResolver extends Builder {
500
511
}
501
512
502
513
void ifSyncEnsureAllUniqueAreReplace (
503
- ModelEntity entity, ClassElement classElement) {
514
+ ModelEntity entity, ClassElement2 classElement) {
504
515
if (! entity.hasFlag (OBXEntityFlags .SYNC_ENABLED )) return ;
505
516
final uniqueButNotReplaceProps = entity.properties.where ((p) {
506
517
return p.hasFlag (OBXPropertyFlags .UNIQUE ) &&
@@ -541,28 +552,23 @@ class EntityResolver extends Builder {
541
552
return typeArgs.length == 1 ? typeArgs[0 ] : null ;
542
553
}
543
554
544
- bool isRelationField (FieldElement f) =>
555
+ bool isRelationField (FieldElement2 f) =>
545
556
isToOneRelationField (f) || isToManyRelationField (f);
546
557
547
- bool isToOneRelationField (FieldElement f) => f.type.element! .name == 'ToOne' ;
558
+ bool isToOneRelationField (FieldElement2 f) =>
559
+ f.type.element3! .name3 == 'ToOne' ;
548
560
549
- bool isToManyRelationField (FieldElement f) =>
550
- f.type.element ! .name == 'ToMany' ;
561
+ bool isToManyRelationField (FieldElement2 f) =>
562
+ f.type.element3 ! .name3 == 'ToMany' ;
551
563
552
564
bool isNullable (DartType type) =>
553
565
type.nullabilitySuffix == NullabilitySuffix .star ||
554
566
type.nullabilitySuffix == NullabilitySuffix .question;
555
567
556
- // Find an unnamed constructor we can use to initialize
557
- ConstructorElement ? findConstructor (ClassElement entity) {
558
- final index = entity.constructors.indexWhere ((c) => c.name.isEmpty);
559
- return index >= 0 ? entity.constructors[index] : null ;
560
- }
561
-
562
- List <String > constructorParams (ConstructorElement ? constructor) {
568
+ List <String > constructorParams (ConstructorElement2 ? constructor) {
563
569
if (constructor == null ) return List .empty ();
564
- return constructor.parameters .map ((param) {
565
- var info = StringBuffer (param.name );
570
+ return constructor.formalParameters .map ((param) {
571
+ var info = StringBuffer (param.displayName );
566
572
if (param.isRequiredPositional) info.write (' positional' );
567
573
if (param.isOptionalPositional) info.write (' optional' );
568
574
if (param.isRequiredNamed) info.write (' required-named' );
@@ -617,7 +623,7 @@ class EntityResolver extends Builder {
617
623
}
618
624
619
625
extension _TypeCheckerExtensions on TypeChecker {
620
- void runIfMatches (Element element, void Function (DartObject ) fn) {
626
+ void runIfMatches (Element2 element, void Function (DartObject ) fn) {
621
627
final annotations = annotationsOfExact (element);
622
628
if (annotations.isNotEmpty) fn (annotations.first);
623
629
}
0 commit comments