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