Skip to content

Commit fedbb24

Browse files
committed
Updated for null safety
1 parent 9ad6814 commit fedbb24

File tree

7 files changed

+59
-64
lines changed

7 files changed

+59
-64
lines changed

example/example.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ abstract class Example
1717
// int get Bad;
1818

1919
// @Translate('Test')
20-
// String test;
20+
// String test = "";
2121

2222
// @Translate('NonAbstract')
2323
// String get NonAbstract => "Hi";
@@ -60,7 +60,7 @@ abstract class Example
6060

6161
class ExampleResources extends Resources
6262
{
63-
@override Future<Map<String, String>> GetModuleEntries(String module, String language) async
63+
@override Future<Map<String, String>> GetModuleEntries(String module, String? language) async
6464
{
6565
return {
6666
"replace": 'Replace "{1}", {0}',

example/example.g.dart

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/src/generator.dart

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,10 @@ String _key(KeyFormat format, String name, String override)
2424
switch (format)
2525
{
2626
case KeyFormat.None: return name;
27-
case KeyFormat.Kebab: return name.replaceAllMapped(_upperCase, (m) => m.start > 0
28-
? '-${m.group(0).toLowerCase()}'
29-
: m.group(0).toLowerCase()
27+
case KeyFormat.Kebab: return name.replaceAllMapped(_upperCase, (m) =>
28+
(m.start > 0 ? '-' : '') + (m[0]?.toLowerCase() ?? '?')
3029
);
3130
}
32-
33-
return name;
3431
}
3532

3633
// Retrieve the key from the annotation. If the
@@ -40,8 +37,8 @@ String _keyOverride(Element e)
4037
{
4138
return _translateChecker
4239
.firstAnnotationOfExact(e)
43-
.getField('key')
44-
.toStringValue();
40+
?.getField('key')
41+
?.toStringValue() ?? '';
4542
}
4643

4744

@@ -60,13 +57,12 @@ class TranslatableGenerator extends GeneratorForAnnotation<Translatable>
6057
);
6158
}
6259

63-
final classElement = element as ClassElement;
64-
final className = '_\$${classElement.name}';
60+
final className = '_\$${element.name}';
6561
final name = annotation.read('module').stringValue;
66-
final withMixin = annotation.read('withMixin').boolValue ? "with ${classElement.name}" : "";
67-
final fields = classElement.fields.where((f) => _translateChecker.hasAnnotationOfExact(f.getter) || _translateChecker.hasAnnotationOfExact(f));
68-
final methods = classElement.methods.where((m) => _translateChecker.hasAnnotationOfExact(m));
69-
final lookups = classElement.methods.where((m) => _lookupChecker.hasAnnotationOfExact(m));
62+
final withMixin = annotation.read('withMixin').boolValue ? "with ${element.name}" : "";
63+
final fields = element.fields.where((f) => _translateChecker.hasAnnotationOfExact(f.getter ?? f));// || _translateChecker.hasAnnotationOfExact(f));
64+
final methods = element.methods.where((m) => _translateChecker.hasAnnotationOfExact(m));
65+
final lookups = element.methods.where((m) => _lookupChecker.hasAnnotationOfExact(m));
7066
final format = KeyFormat.values.singleWhere(
7167
(v) => annotation.read('format').objectValue.getField(v.toString().split('.')[1]) != null
7268
);
@@ -76,19 +72,24 @@ class TranslatableGenerator extends GeneratorForAnnotation<Translatable>
7672

7773
for (var f in fields)
7874
{
79-
final key = _key(format, f.name, _keyOverride(f.getter));
75+
final getter = f.getter;
76+
77+
if (getter != null)
78+
{
79+
final key = _key(format, f.name, _keyOverride(getter));
8080

81-
IsAbstract(f.getter);
82-
ReturnsString(f.type, f);
83-
DoesNotContainKey(f.getter, values, key);
81+
IsAbstract(getter);
82+
ReturnsString(f.type, f);
83+
DoesNotContainKey(getter, values, key);
8484

85-
values[key] = _translateChecker
86-
.firstAnnotationOfExact(f.getter)
87-
.getField('source')
88-
.toStringValue()
89-
.replaceAll('"', '\\"');
85+
values[key] = _translateChecker
86+
.firstAnnotationOfExact(getter)
87+
?.getField('source')
88+
?.toStringValue()
89+
?.replaceAll('"', '\\"') ?? '';
9090

91-
buffer.write('String get ${f.name} => values["${key}"];\n');
91+
buffer.write('String get ${f.name} => values["${key}"] ?? "";\n');
92+
}
9293
}
9394

9495
for (var m in methods)
@@ -104,11 +105,11 @@ class TranslatableGenerator extends GeneratorForAnnotation<Translatable>
104105
final list = m.parameters.map((p) => p.name).join(', ');
105106
values[key] = _translateChecker
106107
.firstAnnotationOfExact(m)
107-
.getField('source')
108-
.toStringValue()
109-
.replaceAll('"', '\\"');
108+
?.getField('source')
109+
?.toStringValue()
110+
?.replaceAll('"', '\\"') ?? '';
110111

111-
buffer.write('String ${m.name}($parameters) => TranslatableModule.Substitute(values["${key}"], [ $list ]);\n');
112+
buffer.write('String ${m.name}($parameters) => TranslatableModule.Substitute(values["${key}"] ?? "", [ $list ]);\n');
112113
}
113114

114115
for (var l in lookups)
@@ -119,22 +120,20 @@ class TranslatableGenerator extends GeneratorForAnnotation<Translatable>
119120

120121
final table = _lookupChecker
121122
.firstAnnotationOfExact(l)
122-
.getField('table')
123-
.toMapValue()
124-
.map<String, String>((k, v) => MapEntry(
125-
k.toStringValue(),
126-
v.toStringValue().replaceAll('"', '\\"')
127-
));
123+
?.getField('table')
124+
?.toMapValue()
125+
?.map<String, String>((k, v) => MapEntry(
126+
k?.toStringValue() ?? '',
127+
v?.toStringValue()?.replaceAll('"', '\\"') ?? ''
128+
)) ?? {};
128129

129130
table.forEach((k, v) => DoesNotContainKey(l, values, k));
130131
values.addAll(table);
131-
buffer.write('String ${l.name}(String key) => values[key];\n');
132+
buffer.write('String ${l.name}(String key) => values[key] ?? "";\n');
132133
}
133134

134-
135-
136135
yield '''
137-
class $className extends TranslatableModule $withMixin implements ${classElement.name}
136+
class $className extends TranslatableModule $withMixin implements ${element.name}
138137
{
139138
$className(Resources resources) : super(resources, "$name", {
140139
${values.keys.map((k) => '"${k}": "${values[k]}"').join(',\n')}

lib/src/module.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ class TranslatableModule
2323

2424
static String Substitute(String text, List<String> values)
2525
{
26-
return text.replaceAllMapped(_matcher, (m) => values[int.parse(m[1])]);
26+
return text.replaceAllMapped(_matcher, (m) => values[int.parse(m[1] ?? '0')]);
2727
}
2828
}

lib/src/resources.dart

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ abstract class Resources
1515
}
1616

1717

18-
Future Initialise({ void onError(String) }) async
18+
Future Initialise({ void onError(String)? }) async
1919
{
2020
List<Future<TranslatableModule>> loading = [];
2121

@@ -43,25 +43,21 @@ abstract class Resources
4343
// is stored in your server-side application. If language is `null` then return
4444
// the values for the appropriate language based on the browser request header. If
4545
// language is a known code then return that language.
46-
Future<Map<String, String>> GetModuleEntries(String module, String language);
46+
Future<Map<String, String>> GetModuleEntries(String module, String? language);
4747

4848

4949
// Update a module with translations for a specific language or based on the browser
5050
// request header if language is `null`.
51-
Future<TranslatableModule> LoadModule(TranslatableModule module, String language) async
51+
Future<TranslatableModule> LoadModule(TranslatableModule module, String? language) async
5252
{
53-
var entries = await GetModuleEntries(module.name, language);
53+
var entries = await GetModuleEntries(module.name, language);
54+
module.orphaned = entries.keys.any((k) => !module.values.containsKey(k));
55+
module.missing = false;
5456

55-
if (entries != null)
57+
for (var k in module.values.keys)
5658
{
57-
module.orphaned = entries.keys.any((k) => !module.values.containsKey(k));
58-
module.missing = false;
59-
60-
for (var k in module.values.keys)
61-
{
62-
if (entries.containsKey(k)) module.values[k] = entries[k];
63-
else module.missing = true;
64-
}
59+
if (entries.containsKey(k)) module.values[k] = entries[k] ?? '';
60+
else module.missing = true;
6561
}
6662

6763
return module;

lib/src/type_checks.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ void IsAbstract(ExecutableElement e)
1616
}
1717

1818
// Deprecate this when type.isDartCoreString becomes available (analyzer 0.36.x)
19-
bool _IsString(DartType type) => type.element != null && type.element.library.isDartCore && type.element.name == "String";
19+
bool _IsString(DartType type) => (type.element?.library?.isDartCore ?? false) && type.element?.name == "String";
2020

2121
void ReturnsString(DartType type, Element e)
2222
{

pubspec.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
name: translatable
2-
version: 1.1.1
2+
version: 1.2.0
33
author: Dan Parnham <dan@emergent-design.co.uk>
44
homepage: https://github.com/emergent-design/translatable
55
description: >-
66
Generate translatable getters/functions that are mapped to allow
77
remote storage and modification of translations.
88
99
environment:
10-
sdk: '>=2.0.0 <3.0.0'
10+
sdk: '>=2.12.0 <3.0.0'
1111

1212
dependencies:
13-
build: ^1.2.1
14-
source_gen: ^0.9.4+6
13+
build: ^2.0.0
14+
source_gen: ^1.0.0
1515

1616
dev_dependencies:
17-
build_runner: ^1.9.0
17+
build_runner: ^1.12.2

0 commit comments

Comments
 (0)