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

Commit 0ff897d

Browse files
authored
Make Reference.type return Reference (#175)
Fixes #174 While these changes are technically breaking we expect clients won't be impacted. - Add a test which fails before this change and passes after - Add tests for nested function types since that was untested previously - Make `Reference.type` return `Reference`, update call sites. - Return `this` from the `type` getter.
1 parent db564b1 commit 0ff897d

File tree

6 files changed

+60
-10
lines changed

6 files changed

+60
-10
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ void main() {
8787
* Added `nullSafeProperty` to `Expression` to access properties with `?.`
8888
* Added `conditional` to `Expression` to use the ternary operator `? : `
8989
* Methods taking `positionalArguments` accept `Iterable<Expression>`
90+
* **BUG FIX**: Parameters can take a `FunctionType` as a `type`.
91+
`Reference.type` now returns a `Reference`. Note that this change is
92+
technically breaking but should not impacts most clients.
9093

9194
## 2.2.0
9295

lib/src/emitter.dart

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,19 @@ class DartEmitter extends Object
100100
visitTypeParameters(spec.types.map((r) => r.type), output);
101101
if (spec.extend != null) {
102102
output.write(' extends ');
103-
visitType(spec.extend.type, output);
103+
spec.extend.type.accept(this, output);
104104
}
105105
if (spec.mixins.isNotEmpty) {
106106
output
107107
..write(' with ')
108-
..writeAll(spec.mixins.map<StringSink>((m) => visitType(m.type)), ',');
108+
..writeAll(
109+
spec.mixins.map<StringSink>((m) => m.type.accept(this)), ',');
109110
}
110111
if (spec.implements.isNotEmpty) {
111112
output
112113
..write(' implements ')
113114
..writeAll(
114-
spec.implements.map<StringSink>((m) => visitType(m.type)), ',');
115+
spec.implements.map<StringSink>((m) => m.type.accept(this)), ',');
115116
}
116117
output.write(' {');
117118
spec.constructors.forEach((c) {
@@ -198,7 +199,7 @@ class DartEmitter extends Object
198199
}
199200
if (spec.redirect != null) {
200201
output.write(' = ');
201-
visitType(spec.redirect.type, output);
202+
spec.redirect.type.accept(this, output);
202203
output.write(';');
203204
} else if (spec.body != null) {
204205
if (_isLambdaConstructor(spec)) {
@@ -484,12 +485,12 @@ class DartEmitter extends Object
484485
}
485486

486487
@override
487-
visitTypeParameters(Iterable<TypeReference> specs, [StringSink output]) {
488+
visitTypeParameters(Iterable<Reference> specs, [StringSink output]) {
488489
output ??= new StringBuffer();
489490
if (specs.isNotEmpty) {
490491
output
491492
..write('<')
492-
..writeAll(specs.map<StringSink>(visitType), ',')
493+
..writeAll(specs.map<StringSink>((s) => s.accept(this)), ',')
493494
..write('>');
494495
}
495496
return output;

lib/src/specs/reference.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class Reference extends Expression implements Spec {
123123
.toString();
124124

125125
/// Returns as a [TypeReference], which allows adding generic type parameters.
126-
TypeReference get type => new TypeReference((b) => b
126+
Reference get type => new TypeReference((b) => b
127127
..url = url
128128
..symbol = symbol);
129129
}

lib/src/specs/type_function.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import '../visitors.dart';
1414
import 'code.dart';
1515
import 'expression.dart';
1616
import 'reference.dart';
17-
import 'type_reference.dart';
1817

1918
part 'type_function.g.dart';
2019

@@ -58,7 +57,7 @@ abstract class FunctionType extends Expression
5857
String get symbol => null;
5958

6059
@override
61-
TypeReference get type => null;
60+
Reference get type => this;
6261

6362
@override
6463
Expression newInstance(

lib/src/visitors.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,5 @@ abstract class SpecVisitor<T> {
4545

4646
T visitType(TypeReference spec, [T context]);
4747

48-
T visitTypeParameters(Iterable<TypeReference> specs, [T context]);
48+
T visitTypeParameters(Iterable<Reference> specs, [T context]);
4949
}

test/specs/method_test.dart

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,53 @@ void main() {
145145
);
146146
});
147147

148+
test('should create a method with a nested function type return type', () {
149+
expect(
150+
new Method((b) => b
151+
..name = 'foo'
152+
..returns = new FunctionType((b) => b
153+
..returnType = new FunctionType((b) => b
154+
..returnType = refer('String')
155+
..requiredParameters.add(refer('String')))
156+
..requiredParameters.addAll([
157+
refer('int'),
158+
]))),
159+
equalsDart(r'''
160+
String Function(String) Function(int) foo();
161+
'''),
162+
);
163+
});
164+
165+
test('should create a method with a function type argument', () {
166+
expect(
167+
new Method((b) => b
168+
..name = 'foo'
169+
..requiredParameters.add(new Parameter((b) => b
170+
..type = new FunctionType((b) => b
171+
..returnType = refer('String')
172+
..requiredParameters.add(refer('int')))
173+
..name = 'argument'))),
174+
equalsDart(r'''
175+
foo(String Function(int) argument);
176+
'''));
177+
});
178+
179+
test('should create a method with a nested function type argument', () {
180+
expect(
181+
new Method((b) => b
182+
..name = 'foo'
183+
..requiredParameters.add(new Parameter((b) => b
184+
..type = new FunctionType((b) => b
185+
..returnType = new FunctionType((b) => b
186+
..returnType = refer('String')
187+
..requiredParameters.add(refer('String')))
188+
..requiredParameters.add(refer('int')))
189+
..name = 'argument'))),
190+
equalsDart(r'''
191+
foo(String Function(String) Function(int) argument);
192+
'''));
193+
});
194+
148195
test('should create a method with generic types', () {
149196
expect(
150197
new Method((b) => b

0 commit comments

Comments
 (0)