@@ -2,7 +2,7 @@ import 'dart:async';
22import 'dart:convert' ;
33
44import 'package:analyzer/dart/constant/value.dart' ;
5- import 'package:analyzer/dart/element/element .dart' ;
5+ import 'package:analyzer/dart/element/element2 .dart' ;
66import 'package:analyzer/dart/element/nullability_suffix.dart' ;
77import 'package:analyzer/dart/element/type.dart' ;
88import 'package:build/build.dart' ;
@@ -53,10 +53,10 @@ class EntityResolver extends Builder {
5353 }
5454
5555 ModelEntity generateForAnnotatedElement (
56- Element classElement, ConstantReader annotation) {
57- if (classElement is ! ClassElement ) {
56+ Element2 classElement, ConstantReader annotation) {
57+ if (classElement is ! ClassElement2 ) {
5858 throw InvalidGenerationSourceError (
59- "Entity '${classElement .name }': annotated element must be a class." );
59+ "Entity '${classElement .displayName }': annotated element must be a class." );
6060 }
6161
6262 // process basic entity (note that allModels.createEntity is not used, as the entity will be merged)
@@ -65,8 +65,8 @@ class EntityResolver extends Builder {
6565 final entity = ModelEntity .create (
6666 IdUid (0 , entityUid.isNull ? 0 : entityUid.intValue),
6767 entityRealClass.isNull
68- ? classElement.name
69- : entityRealClass.typeValue.element ! .name ! ,
68+ ? classElement.displayName
69+ : entityRealClass.typeValue.element3 ! .displayName ,
7070 null ,
7171 uidRequest: ! entityUid.isNull && entityUid.intValue == 0 );
7272
@@ -85,43 +85,46 @@ class EntityResolver extends Builder {
8585
8686 log.info (entity);
8787
88- entity.constructorParams = constructorParams (findConstructor (classElement));
88+ // Note: if there is no unnamed constructor this list will just be empty
89+ entity.constructorParams =
90+ constructorParams (classElement.unnamedConstructor2);
8991
9092 // Make sure all stored fields are writable when reading object from DB.
9193 // Let's filter read-only fields, i.e those that:
9294 // * don't have a setter, and
9395 // * don't have a corresponding argument in the constructor.
94- // Note: `.correspondingSetter == null` is also true for ` final` fields.
96+ // Note: the corresponding setter is also null for final fields.
9597 final readOnlyFields = < String > {};
96- for (var f in classElement.accessors) {
97- if (f.isGetter &&
98- f.correspondingSetter == null &&
98+ for (var f in classElement.getters2) {
99+ if (f.correspondingSetter2 == null &&
99100 ! entity.constructorParams
100- .any ((String param) => param.startsWith ('${f .name } ' ))) {
101- readOnlyFields.add (f.name );
101+ .any ((String param) => param.startsWith ('${f .displayName } ' ))) {
102+ readOnlyFields.add (f.displayName );
102103 }
103104 }
104105
105106 // read all suitable annotated properties
106- for (var f in classElement.fields ) {
107+ for (var f in classElement.fields2 ) {
107108 // The field might be implicitly defined by a getter, aka it is synthetic
108109 // and does not exist in code. So always resolve the actual non-synthetic
109110 // element that exists in code (here a getter) as only it will have any
110111 // annotations.
111- final annotated = f.nonSynthetic ;
112+ final annotated = f.nonSynthetic2 ;
112113
113114 if (_transientChecker.hasAnnotationOfExact (annotated)) {
114- log.info (" Skipping property '${f .name }': annotated with @Transient." );
115+ log.info (
116+ " Skipping property '${f .displayName }': annotated with @Transient." );
115117 continue ;
116118 }
117119
118- if (readOnlyFields.contains (f.name) && ! isRelationField (f)) {
119- log.info (" Skipping property '${f .name }': is read-only/getter." );
120+ if (readOnlyFields.contains (f.name3) && ! isRelationField (f)) {
121+ log.info (
122+ " Skipping property '${f .displayName }': is read-only/getter." );
120123 continue ;
121124 }
122125
123126 if (f.isPrivate) {
124- log.info (" Skipping property '${f .name }': is private." );
127+ log.info (" Skipping property '${f .displayName }': is private." );
125128 continue ;
126129 }
127130
@@ -153,10 +156,10 @@ class EntityResolver extends Builder {
153156 if (isToManyRelationField (f)) {
154157 isToManyRel = true ;
155158 } else {
156- fieldType = detectObjectBoxType (f, classElement.name );
159+ fieldType = detectObjectBoxType (f, classElement.displayName );
157160 if (fieldType == null ) {
158161 log.warning (
159- " Skipping property '${f .name }': type '${f .type }' not supported,"
162+ " Skipping property '${f .displayName }': type '${f .type }' not supported,"
160163 " consider creating a relation for @Entity types (https://docs.objectbox.io/relations),"
161164 " or replace with getter/setter converting to a supported type (https://docs.objectbox.io/advanced/custom-types)." );
162165 continue ;
@@ -167,12 +170,15 @@ class EntityResolver extends Builder {
167170 String ? relTargetName;
168171 if (isRelationField (f)) {
169172 if (f.type is ! ParameterizedType ) {
170- log.severe (" Skipping property '${f .name }': invalid relation type, "
173+ log.severe (
174+ " Skipping property '${f .displayName }': invalid relation type, "
171175 "use a type like ToOne<TargetEntity> or ToMany<TargetEntity>." );
172176 continue ;
173177 }
174- relTargetName =
175- (f.type as ParameterizedType ).typeArguments[0 ].element! .name;
178+ relTargetName = (f.type as ParameterizedType )
179+ .typeArguments[0 ]
180+ .element3!
181+ .displayName;
176182 }
177183
178184 final backlinkAnnotations =
@@ -181,13 +187,15 @@ class EntityResolver extends Builder {
181187 // Handles ToMany based on other ToOne or ToMany relation (backlink)
182188 if (! isToManyRel) {
183189 log.severe (
184- " Skipping property '${f .name }': @Backlink() may only be used with ToMany." );
190+ " Skipping property '${f .displayName }': @Backlink() may only be used with ToMany." );
185191 continue ;
186192 }
187193 final backlinkField =
188194 backlinkAnnotations.first.getField ('to' )! .toStringValue ()! ;
189195 final backlink = ModelBacklink (
190- name: f.name, srcEntity: relTargetName! , srcField: backlinkField);
196+ name: f.displayName,
197+ srcEntity: relTargetName! ,
198+ srcField: backlinkField);
191199 entity.backlinks.add (backlink);
192200 log.info (' $backlink ' );
193201 } else if (isToManyRel) {
@@ -207,7 +215,7 @@ class EntityResolver extends Builder {
207215 });
208216
209217 // create relation
210- final rel = ModelRelation .create (IdUid (0 , propUid ?? 0 ), f.name ,
218+ final rel = ModelRelation .create (IdUid (0 , propUid ?? 0 ), f.displayName ,
211219 targetName: relTargetName,
212220 uidRequest: propUid != null && propUid == 0 ,
213221 externalName: externalName,
@@ -220,7 +228,7 @@ class EntityResolver extends Builder {
220228 // Handles regular properties
221229 // create property (do not use readEntity.createProperty in order to avoid generating new ids)
222230 final prop = ModelProperty .create (
223- IdUid (0 , propUid ?? 0 ), f.name , fieldType,
231+ IdUid (0 , propUid ?? 0 ), f.displayName , fieldType,
224232 flags: flags,
225233 entity: entity,
226234 uidRequest: propUid != null && propUid == 0 );
@@ -245,7 +253,7 @@ class EntityResolver extends Builder {
245253 // errors, so no need to integrate with regular index processing.
246254 if (fieldType != OBXPropertyType .FloatVector ) {
247255 throw InvalidGenerationSourceError (
248- "'${classElement .name }.${f .name }': @HnswIndex is only supported for float vector properties." ,
256+ "'${classElement .displayName }.${f .displayName }': @HnswIndex is only supported for float vector properties." ,
249257 element: f);
250258 }
251259 // Create an index
@@ -266,7 +274,7 @@ class EntityResolver extends Builder {
266274
267275 // for code generation
268276 prop.dartFieldType =
269- f.type.element ! .name ! + (isNullable (f.type) ? '?' : '' );
277+ f.type.element3 ! .displayName + (isNullable (f.type) ? '?' : '' );
270278 entity.properties.add (prop);
271279 }
272280 }
@@ -277,13 +285,13 @@ class EntityResolver extends Builder {
277285 // for `setId()` won't compile. The only exception is when user uses
278286 // self-assigned IDs, then a different setter will be generated - one that
279287 // 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 ) {
288+ final idField = classElement.fields2. singleWhere (
289+ ( FieldElement2 f) => f.displayName == entity.idProperty.name);
290+ if (idField.setter2 == null ) {
283291 if (! entity.idProperty.hasFlag (OBXPropertyFlags .ID_SELF_ASSIGNABLE )) {
284292 throw InvalidGenerationSourceError (
285- "@Id field '${idField .name }' must be writable: "
286- " ObjectBox uses it to set the assigned ID after inserting a new object, "
293+ "@Id field '${idField .displayName }' must be writable, "
294+ " ObjectBox uses it to set the assigned ID after inserting a new object: "
287295 " provide a setter or remove the 'final' keyword."
288296 " If your code needs to assign IDs itself,"
289297 " see https://docs.objectbox.io/advanced/object-ids#self-assigned-object-ids." ,
@@ -309,8 +317,8 @@ class EntityResolver extends Builder {
309317 /// For fields that do not have a [Property.type] declared in their [Property]
310318 /// annotation tries to determine the ObjectBox database type based on the
311319 /// Dart type. May return null if no supported type is detected.
312- int ? detectObjectBoxType (FieldElement f , String className ) {
313- final dartType = f .type;
320+ int ? detectObjectBoxType (FieldElement2 field , String classDisplayName ) {
321+ final dartType = field .type;
314322
315323 if (dartType.isDartCoreInt) {
316324 // Dart: 8 bytes
@@ -342,32 +350,36 @@ class EntityResolver extends Builder {
342350 // List<String>
343351 return OBXPropertyType .StringVector ;
344352 }
345- } else if (['Int8List' , 'Uint8List' ].contains (dartType.element! .name)) {
353+ } else if (['Int8List' , 'Uint8List' ]
354+ .contains (dartType.element3! .displayName)) {
346355 return OBXPropertyType .ByteVector ;
347- } else if (['Int16List' , 'Uint16List' ].contains (dartType.element! .name)) {
356+ } else if (['Int16List' , 'Uint16List' ]
357+ .contains (dartType.element3! .displayName)) {
348358 return OBXPropertyType .ShortVector ;
349- } else if (['Int32List' , 'Uint32List' ].contains (dartType.element! .name)) {
359+ } else if (['Int32List' , 'Uint32List' ]
360+ .contains (dartType.element3! .displayName)) {
350361 return OBXPropertyType .IntVector ;
351- } else if (['Int64List' , 'Uint64List' ].contains (dartType.element! .name)) {
362+ } else if (['Int64List' , 'Uint64List' ]
363+ .contains (dartType.element3! .displayName)) {
352364 return OBXPropertyType .LongVector ;
353- } else if (dartType.element ! .name == 'Float32List' ) {
365+ } else if (dartType.element3 ! .displayName == 'Float32List' ) {
354366 return OBXPropertyType .FloatVector ;
355- } else if (dartType.element ! .name == 'Float64List' ) {
367+ } else if (dartType.element3 ! .displayName == 'Float64List' ) {
356368 return OBXPropertyType .DoubleVector ;
357- } else if (dartType.element ! .name == 'DateTime' ) {
369+ } else if (dartType.element3 ! .displayName == 'DateTime' ) {
358370 log.warning (
359- " DateTime property '${f . name }' in entity '$className ' is stored and read using millisecond precision. "
371+ " DateTime property '${field . displayName }' in entity '$classDisplayName ' is stored and read using millisecond precision. "
360372 'To silence this warning, add an explicit type using @Property(type: PropertyType.date) or @Property(type: PropertyType.dateNano) annotation.' );
361373 return OBXPropertyType .Date ;
362- } else if (isToOneRelationField (f )) {
374+ } else if (isToOneRelationField (field )) {
363375 return OBXPropertyType .Relation ;
364376 }
365377
366378 // No supported Dart type recognized.
367379 return null ;
368380 }
369381
370- void processIdProperty (ModelEntity entity, ClassElement classElement) {
382+ void processIdProperty (ModelEntity entity, ClassElement2 classElement) {
371383 // check properties explicitly annotated with @Id()
372384 final annotated =
373385 entity.properties.where ((p) => p.hasFlag (OBXPropertyFlags .ID ));
@@ -405,8 +417,8 @@ class EntityResolver extends Builder {
405417 idProperty.flags & = ~ OBXPropertyFlags .UNSIGNED ;
406418 }
407419
408- void processAnnotationIndexUnique (FieldElement f, Element annotatedElement,
409- int ? fieldType, Element elementBare, ModelProperty prop) {
420+ void processAnnotationIndexUnique (FieldElement2 f, Element2 annotatedElement,
421+ int ? fieldType, Element2 elementBare, ModelProperty prop) {
410422 IndexType ? indexType;
411423
412424 final indexAnnotation =
@@ -427,13 +439,13 @@ class EntityResolver extends Builder {
427439 fieldType == OBXPropertyType .DoubleVector ||
428440 fieldType == OBXPropertyType .StringVector ) {
429441 throw InvalidGenerationSourceError (
430- "Entity '${elementBare .name }': @Index/@Unique is not supported for type '${f .type }' of field '${f .name }'." ,
442+ "Entity '${elementBare .displayName }': @Index/@Unique is not supported for type '${f .type }' of field '${f .displayName }'." ,
431443 element: f);
432444 }
433445
434446 if (prop.hasFlag (OBXPropertyFlags .ID )) {
435447 throw InvalidGenerationSourceError (
436- "Entity '${elementBare .name }': @Index/@Unique is not supported for @Id field '${f .name }'."
448+ "Entity '${elementBare .displayName }': @Index/@Unique is not supported for @Id field '${f .displayName }'."
437449 " IDs are unique by definition and automatically indexed." ,
438450 element: f);
439451 }
@@ -459,7 +471,7 @@ class EntityResolver extends Builder {
459471 if (! supportsHashIndex &&
460472 (indexType == IndexType .hash || indexType == IndexType .hash64)) {
461473 throw InvalidGenerationSourceError (
462- "Entity '${elementBare .name }': a hash index is not supported for type '${f .type }' of field '${f .name }'" ,
474+ "Entity '${elementBare .displayName }': a hash index is not supported for type '${f .type }' of field '${f .displayName }'" ,
463475 element: f);
464476 }
465477
@@ -489,7 +501,7 @@ class EntityResolver extends Builder {
489501 }
490502
491503 void ensureSingleUniqueReplace (
492- ModelEntity entity, ClassElement classElement) {
504+ ModelEntity entity, ClassElement2 classElement) {
493505 final uniqueReplaceProps = entity.properties
494506 .where ((p) => p.hasFlag (OBXPropertyFlags .UNIQUE_ON_CONFLICT_REPLACE ));
495507 if (uniqueReplaceProps.length > 1 ) {
@@ -500,7 +512,7 @@ class EntityResolver extends Builder {
500512 }
501513
502514 void ifSyncEnsureAllUniqueAreReplace (
503- ModelEntity entity, ClassElement classElement) {
515+ ModelEntity entity, ClassElement2 classElement) {
504516 if (! entity.hasFlag (OBXEntityFlags .SYNC_ENABLED )) return ;
505517 final uniqueButNotReplaceProps = entity.properties.where ((p) {
506518 return p.hasFlag (OBXPropertyFlags .UNIQUE ) &&
@@ -541,28 +553,23 @@ class EntityResolver extends Builder {
541553 return typeArgs.length == 1 ? typeArgs[0 ] : null ;
542554 }
543555
544- bool isRelationField (FieldElement f) =>
556+ bool isRelationField (FieldElement2 f) =>
545557 isToOneRelationField (f) || isToManyRelationField (f);
546558
547- bool isToOneRelationField (FieldElement f) => f.type.element! .name == 'ToOne' ;
559+ bool isToOneRelationField (FieldElement2 f) =>
560+ f.type.element3! .name3 == 'ToOne' ;
548561
549- bool isToManyRelationField (FieldElement f) =>
550- f.type.element ! .name == 'ToMany' ;
562+ bool isToManyRelationField (FieldElement2 f) =>
563+ f.type.element3 ! .name3 == 'ToMany' ;
551564
552565 bool isNullable (DartType type) =>
553566 type.nullabilitySuffix == NullabilitySuffix .star ||
554567 type.nullabilitySuffix == NullabilitySuffix .question;
555568
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) {
569+ List <String > constructorParams (ConstructorElement2 ? constructor) {
563570 if (constructor == null ) return List .empty ();
564- return constructor.parameters .map ((param) {
565- var info = StringBuffer (param.name );
571+ return constructor.formalParameters .map ((param) {
572+ var info = StringBuffer (param.displayName );
566573 if (param.isRequiredPositional) info.write (' positional' );
567574 if (param.isOptionalPositional) info.write (' optional' );
568575 if (param.isRequiredNamed) info.write (' required-named' );
@@ -617,7 +624,7 @@ class EntityResolver extends Builder {
617624}
618625
619626extension _TypeCheckerExtensions on TypeChecker {
620- void runIfMatches (Element element, void Function (DartObject ) fn) {
627+ void runIfMatches (Element2 element, void Function (DartObject ) fn) {
621628 final annotations = annotationsOfExact (element);
622629 if (annotations.isNotEmpty) fn (annotations.first);
623630 }
0 commit comments