trphoenix
2018-11-12 29fbfc5dd1d55d189f23eb6d32f000252f92985f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
 
import 'package:analyzer/dart/element/type.dart';
 
import '../json_literal_generator.dart';
import '../type_helper.dart';
import '../utils.dart';
 
final simpleExpression = RegExp('^[a-zA-Z_]+\$');
 
class EnumHelper extends TypeHelper {
  const EnumHelper();
 
  @override
  String serialize(
      DartType targetType, String expression, TypeHelperContext context) {
    final memberContent = _enumValueMapFromType(targetType);
 
    if (memberContent == null) {
      return null;
    }
 
    context.addMember(memberContent);
 
    return '${_constMapName(targetType)}[$expression]';
  }
 
  @override
  String deserialize(
      DartType targetType, String expression, TypeHelperContext context) {
    final memberContent = _enumValueMapFromType(targetType);
 
    if (memberContent == null) {
      return null;
    }
 
    context.addMember(_enumDecodeHelper);
 
    if (context.nullable) {
      context.addMember(_enumDecodeHelperNullable);
    }
 
    context.addMember(memberContent);
 
    final functionName =
        context.nullable ? r'_$enumDecodeNullable' : r'_$enumDecode';
    return '$functionName(${_constMapName(targetType)}, '
        '$expression)';
  }
}
 
String _constMapName(DartType targetType) => '_\$${targetType.name}EnumMap';
 
String _enumValueMapFromType(DartType targetType) {
  final enumMap = enumFieldsMap(targetType);
 
  if (enumMap == null) {
    return null;
  }
 
  final items =
      enumMap.entries.map((e) => '  ${targetType.name}.${e.key.name}: '
          '${jsonLiteralAsDart(e.value)}');
 
  return 'const ${_constMapName(targetType)} = '
      '<${targetType.name}, dynamic>{\n${items.join(',\n')}\n};';
}
 
const _enumDecodeHelper = r'''
T _$enumDecode<T>(Map<T, dynamic> enumValues, dynamic source) {
  if (source == null) {
    throw ArgumentError('A value must be provided. Supported values: '
        '${enumValues.values.join(', ')}');
  }
  return enumValues.entries
      .singleWhere((e) => e.value == source,
          orElse: () => throw ArgumentError(
              '`$source` is not one of the supported values: '
              '${enumValues.values.join(', ')}'))
      .key;
}''';
 
const _enumDecodeHelperNullable = r'''
T _$enumDecodeNullable<T>(Map<T, dynamic> enumValues, dynamic source) {
  if (source == null) {
    return null;
  }
  return _$enumDecode<T>(enumValues, source);
}''';