update json macro and macro code, to handle omitted types better and not crash the analyzer
Change-Id: I2b30568dd4163b0032624f1fd0db6d6a6246f16c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/365960 Auto-Submit: Jake Macdonald <jakemac@google.com> Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
+32
-18
@@ -310,19 +310,14 @@ macro class JsonCodable
|
||||
/// Returns a [Code] object which is an expression that converts a JSON map
|
||||
/// (referenced by [jsonReference]) into an instance of type [type].
|
||||
Future<Code> _convertTypeFromJson(
|
||||
TypeAnnotation type,
|
||||
TypeAnnotation rawType,
|
||||
Code jsonReference,
|
||||
DefinitionBuilder builder,
|
||||
_SharedIntrospectionData introspectionData) async {
|
||||
if (type is! NamedTypeAnnotation) {
|
||||
builder.report(Diagnostic(
|
||||
DiagnosticMessage(
|
||||
'Only fields with named types are allowed on serializable '
|
||||
'classes',
|
||||
target: type.asDiagnosticTarget),
|
||||
Severity.error));
|
||||
final type = _checkNamedType(rawType, builder);
|
||||
if (type == null) {
|
||||
return RawCode.fromString(
|
||||
"throw 'Unable to deserialize type ${type.code.debugString}'");
|
||||
"throw 'Unable to deserialize type ${rawType.code.debugString}'");
|
||||
}
|
||||
|
||||
// Follow type aliases until we reach an actual named type.
|
||||
@@ -407,6 +402,28 @@ macro class JsonCodable
|
||||
]);
|
||||
}
|
||||
|
||||
/// Returns [type] as a [NamedTypeAnnotation] if it is one, otherwise returns
|
||||
/// `null` and emits relevant error diagnostics.
|
||||
NamedTypeAnnotation? _checkNamedType(TypeAnnotation type, Builder builder) {
|
||||
if (type is NamedTypeAnnotation) return type;
|
||||
if (type is OmittedTypeAnnotation) {
|
||||
builder.report(Diagnostic(
|
||||
DiagnosticMessage(
|
||||
'Only fields with explicit types are allowed on serializable '
|
||||
'classes, please add a type.',
|
||||
target: type.asDiagnosticTarget),
|
||||
Severity.error));
|
||||
} else {
|
||||
builder.report(Diagnostic(
|
||||
DiagnosticMessage(
|
||||
'Only fields with named types are allowed on serializable '
|
||||
'classes.',
|
||||
target: type.asDiagnosticTarget),
|
||||
Severity.error));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Checks that [method] is a valid `toJson` method, and throws a
|
||||
/// [DiagnosticException] if not.
|
||||
Future<bool> _checkValidToJson(
|
||||
@@ -431,19 +448,14 @@ macro class JsonCodable
|
||||
/// Returns a [Code] object which is an expression that converts an instance
|
||||
/// of type [type] (referenced by [valueReference]) into a JSON map.
|
||||
Future<Code> _convertTypeToJson(
|
||||
TypeAnnotation type,
|
||||
TypeAnnotation rawType,
|
||||
Code valueReference,
|
||||
DefinitionBuilder builder,
|
||||
_SharedIntrospectionData introspectionData) async {
|
||||
if (type is! NamedTypeAnnotation) {
|
||||
builder.report(Diagnostic(
|
||||
DiagnosticMessage(
|
||||
'Only fields with named types are allowed on serializable '
|
||||
'classes',
|
||||
target: type.asDiagnosticTarget),
|
||||
Severity.error));
|
||||
final type = _checkNamedType(rawType, builder);
|
||||
if (type == null) {
|
||||
return RawCode.fromString(
|
||||
"throw 'Unable to serialize type ${type.code.debugString}'");
|
||||
"throw 'Unable to serialize type ${rawType.code.debugString}'");
|
||||
}
|
||||
|
||||
// Follow type aliases until we reach an actual named type.
|
||||
@@ -651,6 +663,8 @@ extension on Code {
|
||||
part._writeDebugString(buffer);
|
||||
case Identifier():
|
||||
buffer.write(part.name);
|
||||
case OmittedTypeAnnotation():
|
||||
buffer.write('<omitted>');
|
||||
default:
|
||||
buffer.write(part);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user