Skip to content
This repository was archived by the owner on Apr 8, 2025. It is now read-only.

Commit 841505f

Browse files
add support for emitting typedefs (#387)
* add support for emittig typedefs * Apply suggestions from code review suggestions from code review Co-authored-by: Nate Bosch <nbosch@google.com> Co-authored-by: Nate Bosch <nbosch@google.com>
1 parent 4c32036 commit 841505f

File tree

8 files changed

+280
-1
lines changed

8 files changed

+280
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
* Mention how the `allocator` argument relates to imports in the `DartEmitter`
44
constructor doc.
5+
* Add support for emitting typedefs.
56

67
## 4.3.0
78

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ will be on a best-effort basis.
8585
> format this repository. You can run it simply from the command-line:
8686
>
8787
> ```sh
88-
> $ pub run dart_style:format -w .
88+
> $ dart pub run dart_style:format -w .
8989
> ```
9090
9191
[wiki]: https://github.com/dart-lang/code_builder/wiki

lib/code_builder.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,4 @@ export 'src/specs/mixin.dart' show Mixin, MixinBuilder;
5757
export 'src/specs/reference.dart' show refer, Reference;
5858
export 'src/specs/type_function.dart' show FunctionType, FunctionTypeBuilder;
5959
export 'src/specs/type_reference.dart' show TypeReference, TypeReferenceBuilder;
60+
export 'src/specs/typedef.dart' show TypeDef, TypeDefBuilder;

lib/src/emitter.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import 'specs/mixin.dart';
1818
import 'specs/reference.dart';
1919
import 'specs/type_function.dart';
2020
import 'specs/type_reference.dart';
21+
import 'specs/typedef.dart';
2122
import 'visitors.dart';
2223

2324
/// Helper method improving on [StringSink.writeAll].
@@ -514,6 +515,19 @@ class DartEmitter extends Object
514515
return out;
515516
}
516517

518+
@override
519+
StringSink visitTypeDef(TypeDef spec, [StringSink? output]) {
520+
final out = output ??= StringBuffer();
521+
spec.docs.forEach(out.writeln);
522+
for (var a in spec.annotations) {
523+
visitAnnotation(a, out);
524+
}
525+
out.write('typedef ${spec.name} = ');
526+
spec.definition.accept(this, out);
527+
out.writeln(';');
528+
return out;
529+
}
530+
517531
@override
518532
StringSink visitMethod(Method spec, [StringSink? output]) {
519533
output ??= StringBuffer();

lib/src/specs/typedef.dart

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:built_collection/built_collection.dart';
6+
import 'package:built_value/built_value.dart';
7+
import 'package:meta/meta.dart';
8+
9+
import '../base.dart';
10+
import '../mixins/annotations.dart';
11+
import '../mixins/dartdoc.dart';
12+
import '../visitors.dart';
13+
import 'expression.dart';
14+
15+
part 'typedef.g.dart';
16+
17+
@immutable
18+
abstract class TypeDef extends Object
19+
with HasAnnotations, HasDartDocs
20+
implements Built<TypeDef, TypeDefBuilder>, Spec {
21+
factory TypeDef([void Function(TypeDefBuilder)? updates]) = _$TypeDef;
22+
23+
TypeDef._();
24+
25+
/// Name of the typedef.
26+
String get name;
27+
28+
/// The right hand side of the typedef.
29+
///
30+
/// Typically a reference to a type, or a Function type.
31+
Expression get definition;
32+
33+
@override
34+
R accept<R>(
35+
SpecVisitor<R> visitor, [
36+
R? context,
37+
]) =>
38+
visitor.visitTypeDef(this, context);
39+
}
40+
41+
abstract class TypeDefBuilder extends Object
42+
with HasAnnotationsBuilder, HasDartDocsBuilder
43+
implements Builder<TypeDef, TypeDefBuilder> {
44+
factory TypeDefBuilder() = _$TypeDefBuilder;
45+
46+
TypeDefBuilder._();
47+
48+
@override
49+
ListBuilder<Expression> annotations = ListBuilder<Expression>();
50+
51+
@override
52+
ListBuilder<String> docs = ListBuilder<String>();
53+
54+
String? name;
55+
56+
Expression? definition;
57+
}

lib/src/specs/typedef.g.dart

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

lib/src/visitors.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import 'specs/mixin.dart';
1818
import 'specs/reference.dart';
1919
import 'specs/type_function.dart';
2020
import 'specs/type_reference.dart';
21+
import 'specs/typedef.dart';
2122

2223
@optionalTypeArgs
2324
abstract class SpecVisitor<T> {
@@ -43,6 +44,8 @@ abstract class SpecVisitor<T> {
4344

4445
T visitFunctionType(FunctionType spec, [T? context]);
4546

47+
T visitTypeDef(TypeDef spec, [T? context]);
48+
4649
T visitMethod(Method spec, [T? context]);
4750

4851
T visitReference(Reference spec, [T? context]);

test/specs/method_test.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,30 @@ void main() {
237237
);
238238
});
239239

240+
test('should create a typedef to a reference', () {
241+
expect(
242+
TypeDef((b) => b
243+
..name = 'i32'
244+
..definition = const Reference('int')),
245+
equalsDart(r'''
246+
typedef i32 = int;
247+
'''),
248+
);
249+
});
250+
251+
test('should create a typedef to a function type', () {
252+
expect(
253+
TypeDef((b) => b
254+
..name = 'MyMapper'
255+
..definition = FunctionType((b) => b
256+
..returnType = refer('String')
257+
..optionalParameters.add(refer('int')))),
258+
equalsDart(r'''
259+
typedef MyMapper = String Function([int]);
260+
'''),
261+
);
262+
});
263+
240264
test('should create a method with a nested function type return type', () {
241265
expect(
242266
Method((b) => b

0 commit comments

Comments
 (0)