4
4
5
5
import 'package:analyzer/dart/element/element.dart' ;
6
6
import 'package:build/build.dart' ;
7
+ import 'package:collection/collection.dart' ;
7
8
import 'package:source_gen/source_gen.dart' ;
8
9
9
10
import '../type_helper.dart' ;
@@ -48,13 +49,25 @@ class GeneratorHelper extends HelperCore with EncodeHelper, DecodeHelper {
48
49
);
49
50
}
50
51
51
- final sealedSuperClassesOrEmpty = sealedSuperClasses (element);
52
+ final sealedSupersAndConfigs = sealedSuperClasses (element).map (
53
+ (superClass) => (
54
+ classElement: superClass,
55
+ config: jsonSerializableConfig (superClass, _generator),
56
+ ),
57
+ );
52
58
53
- final sealedDiscriminators = sealedSuperClassesOrEmpty
54
- .map ((sealedClass) => jsonSerializableConfig (sealedClass, _generator))
55
- .map ((config) => config? .unionDiscriminator);
59
+ if (sealedSupersAndConfigs.isNotEmpty &&
60
+ sealedSupersAndConfigs.any ((e) => e.config == null )) {
61
+ throw InvalidGenerationSourceError (
62
+ 'The class `${element .displayName }` is annotated '
63
+ 'with `JsonSerializable` but its superclass is not annotated '
64
+ 'with `JsonSerializable`.' ,
65
+ todo: 'Add `@JsonSerializable` annotation to the sealed class.' ,
66
+ element: element,
67
+ );
68
+ }
56
69
57
- if ((sealedSuperClassesOrEmpty .isNotEmpty || element.isSealed) &&
70
+ if ((sealedSupersAndConfigs .isNotEmpty || element.isSealed) &&
58
71
config.genericArgumentFactories) {
59
72
throw InvalidGenerationSourceError (
60
73
'The class `${element .displayName }` is annotated '
@@ -68,32 +81,43 @@ class GeneratorHelper extends HelperCore with EncodeHelper, DecodeHelper {
68
81
);
69
82
}
70
83
84
+ if (sealedSupersAndConfigs.firstWhereOrNull (
85
+ (e) => e.config? .unionDiscriminator == config.unionDiscriminator,
86
+ )
87
+ case final conflictingSuper? when element.isSealed) {
88
+ throw InvalidGenerationSource (
89
+ 'The classes `${conflictingSuper .classElement .displayName }` and '
90
+ '${element .displayName } are nested sealed classes, but they have '
91
+ 'the same discriminator ${config .unionDiscriminator }.' ,
92
+ todo:
93
+ 'Rename one of the discriminators with `unionDiscriminator` '
94
+ 'field of `@JsonSerializable`.' ,
95
+ );
96
+ }
97
+
98
+ if (sealedSupersAndConfigs.firstWhereOrNull (
99
+ (e) => e.config? .createToJson != config.createToJson,
100
+ )
101
+ case final diffSuper? ) {
102
+ throw InvalidGenerationSourceError (
103
+ 'The class `${diffSuper .classElement .displayName }` is sealed but its '
104
+ 'subclass `${element .displayName }` has a different '
105
+ '`createToJson` option than the base class.' ,
106
+ element: element,
107
+ );
108
+ }
109
+
71
110
if (element.isSealed) {
72
- if (sealedDiscriminators.contains (config.unionDiscriminator)) {
73
- throw InvalidGenerationSource (
74
- 'Nested sealed classes cannot have the same discriminator.' ,
75
- todo:
76
- 'Rename one of the discriminators with `unionDiscriminator` '
77
- 'field in `@JsonSerializable`.' ,
78
- );
79
- }
80
- sealedClassImplementations (element).forEach ((impl) {
81
- final annotationConfig = jsonSerializableConfig (impl, _generator);
111
+ sealedSubClasses (element).forEach ((sub) {
112
+ final annotationConfig = jsonSerializableConfig (sub, _generator);
82
113
83
114
if (annotationConfig == null ) {
84
115
throw InvalidGenerationSourceError (
85
116
'The class `${element .displayName }` is sealed but its '
86
- 'implementation `${impl .displayName }` is not annotated with '
117
+ 'subclass `${sub .displayName }` is not annotated with '
87
118
'`JsonSerializable`.' ,
88
- todo: 'Add `@JsonSerializable` annotation to ${impl .displayName }.' ,
89
- );
90
- }
91
-
92
- if (annotationConfig.createToJson != config.createToJson) {
93
- throw InvalidGenerationSourceError (
94
- 'The class `${element .displayName }` is sealed but its '
95
- 'implementation `${impl .displayName }` has a different '
96
- '`createToJson` option than the base class.' ,
119
+ todo: 'Add `@JsonSerializable` annotation to ${sub .displayName }.' ,
120
+ element: sub,
97
121
);
98
122
}
99
123
});
@@ -165,7 +189,9 @@ class GeneratorHelper extends HelperCore with EncodeHelper, DecodeHelper {
165
189
..fold (< String > {}, (Set <String > set , fe) {
166
190
final jsonKey = nameAccess (fe);
167
191
168
- if (sealedDiscriminators.contains (jsonKey)) {
192
+ if (sealedSupersAndConfigs.any (
193
+ (e) => e.config? .unionDiscriminator == jsonKey,
194
+ )) {
169
195
throw InvalidGenerationSourceError (
170
196
'The JSON key "$jsonKey " is conflicting with the discriminator '
171
197
'of sealed superclass ' ,
0 commit comments