json_serializable.dart icon indicating copy to clipboard operation
json_serializable.dart copied to clipboard

Default values are not given the appropiate scope

Open refi64 opened this issue 4 years ago • 1 comments

Dart version

$ dart --version
Dart SDK version: 2.13.1 (stable) (Fri May 21 12:45:36 2021 +0200) on "linux_x64"

(I'm aware that this is slightly out of date, but I don't believe this should affect json_serializable).

Consider I create lib/tst.dart with the following:

import 'package:json_annotation/json_annotation.dart';

part 'tst.g.dart';

@JsonSerializable()
class Test {
  static const defaultValue = 'default';

  final String thing;
  Test({this.thing = defaultValue});
}

Trying to use this from anywhere results in:

lib/tst.g.dart:10:42: Error: Getter not found: 'defaultValue'.
      thing: json['thing'] as String? ?? defaultValue,
                                         ^^^^^^^^^^^^

The reason is evident if we examine tst.g.dart:

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'tst.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

Test _$TestFromJson(Map<String, dynamic> json) => Test(
      thing: json['thing'] as String? ?? defaultValue,
    );

Map<String, dynamic> _$TestToJson(Test instance) => <String, dynamic>{
      'thing': instance.thing,
    };

defaultValue is a member of the Test class, but the name is used bare here, and it should be Test.defaultValue.

This can be easily worked around by setting the default to Test.defaultValue in tst.dart, but I figured this is probably still a json_serializable bug that's worth filing.

refi64 avatar Jul 21 '21 18:07 refi64

The default value thing here is...tough. We just copy the content of the const as a String – in this case defaultValue. There is no information about the scope here.

It's annoying, I know. But you found the right work-around.

kevmoo avatar Jul 21 '21 18:07 kevmoo