Skip to content

Commit a395bf2

Browse files
authored
Api cleanup: remove Scope class and allow for unnamed types (#2013)
1 parent 315bf8a commit a395bf2

File tree

4 files changed

+56
-80
lines changed

4 files changed

+56
-80
lines changed

working/macros/api/builders.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,8 @@ abstract class ClassDeclarationBuilder
8383
/// The api used by [Macro] to get a [TypeDeclaration] for any given
8484
/// [TypeAnnotation].
8585
abstract class TypeIntrospector {
86-
/// TODO: Figure out how to deal with `FutureOr<T>`, function types, and
87-
/// other non-nominal types.
88-
Future<TypeDeclaration> resolve(TypeAnnotation annotation);
86+
/// Resolves a [NamedTypeAnnotation] to its declaration.
87+
Future<TypeDeclaration> resolve(NamedTypeAnnotation annotation);
8988
}
9089

9190
/// The base class for builders in the definition phase. These can convert

working/macros/api/code.dart

Lines changed: 18 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,36 @@
1-
/// A scope in which to resolve a chunk of code.
2-
///
3-
/// TODO: Specify more what these mean, what fields are available (if any), etc.
4-
abstract class Scope {}
5-
61
/// The base class representing an arbitrary chunk of Dart code, which may or
72
/// may not be syntactically or semantically valid yet.
83
class Code {
9-
/// The scope in which to resolve anything from [parts] that does not have its
10-
/// own scope already defined.
11-
final Scope? scope;
12-
134
/// All the chunks of [Code] or raw [String]s that comprise this [Code]
145
/// object.
156
final List<Object> parts;
167

17-
Code.fromString(String code, {this.scope}) : parts = [code];
8+
Code.fromString(String code) : parts = [code];
189

19-
Code.fromParts(this.parts, {this.scope});
10+
Code.fromParts(this.parts);
2011
}
2112

2213
/// A piece of code representing a syntactically valid declaration.
2314
class DeclarationCode extends Code {
24-
DeclarationCode.fromString(String code, {Scope? scope})
25-
: super.fromString(code, scope: scope);
15+
DeclarationCode.fromString(String code) : super.fromString(code);
2616

27-
DeclarationCode.fromParts(List<Object> parts, {Scope? scope})
28-
: super.fromParts(parts, scope: scope);
17+
DeclarationCode.fromParts(List<Object> parts) : super.fromParts(parts);
2918
}
3019

3120
/// A piece of code representing a syntactically valid element.
3221
///
3322
/// Should not include any trailing commas,
3423
class ElementCode extends Code {
35-
ElementCode.fromString(String code, {Scope? scope})
36-
: super.fromString(code, scope: scope);
24+
ElementCode.fromString(String code) : super.fromString(code);
3725

38-
ElementCode.fromParts(List<Object> parts, {Scope? scope})
39-
: super.fromParts(parts, scope: scope);
26+
ElementCode.fromParts(List<Object> parts) : super.fromParts(parts);
4027
}
4128

4229
/// A piece of code representing a syntactically valid expression.
4330
class ExpressionCode extends Code {
44-
ExpressionCode.fromString(String code, {Scope? scope})
45-
: super.fromString(code, scope: scope);
31+
ExpressionCode.fromString(String code) : super.fromString(code);
4632

47-
ExpressionCode.fromParts(List<Object> parts, {Scope? scope})
48-
: super.fromParts(parts, scope: scope);
33+
ExpressionCode.fromParts(List<Object> parts) : super.fromParts(parts);
4934
}
5035

5136
/// A piece of code representing a syntactically valid function body.
@@ -55,31 +40,25 @@ class ExpressionCode extends Code {
5540
///
5641
/// Both arrow and block function bodies are allowed.
5742
class FunctionBodyCode extends Code {
58-
FunctionBodyCode.fromString(String code, {Scope? scope})
59-
: super.fromString(code, scope: scope);
43+
FunctionBodyCode.fromString(String code) : super.fromString(code);
6044

61-
FunctionBodyCode.fromParts(List<Object> parts, {Scope? scope})
62-
: super.fromParts(parts, scope: scope);
45+
FunctionBodyCode.fromParts(List<Object> parts) : super.fromParts(parts);
6346
}
6447

6548
/// A piece of code representing a syntactically valid identifier.
6649
class IdentifierCode extends Code {
67-
IdentifierCode.fromString(String code, {Scope? scope})
68-
: super.fromString(code, scope: scope);
50+
IdentifierCode.fromString(String code) : super.fromString(code);
6951

70-
IdentifierCode.fromParts(List<Object> parts, {Scope? scope})
71-
: super.fromParts(parts, scope: scope);
52+
IdentifierCode.fromParts(List<Object> parts) : super.fromParts(parts);
7253
}
7354

7455
/// A piece of code identifying a named argument.
7556
///
7657
/// This should not include any trailing commas.
7758
class NamedArgumentCode extends Code {
78-
NamedArgumentCode.fromString(String code, {Scope? scope})
79-
: super.fromString(code, scope: scope);
59+
NamedArgumentCode.fromString(String code) : super.fromString(code);
8060

81-
NamedArgumentCode.fromParts(List<Object> parts, {Scope? scope})
82-
: super.fromParts(parts, scope: scope);
61+
NamedArgumentCode.fromParts(List<Object> parts) : super.fromParts(parts);
8362
}
8463

8564
/// A piece of code identifying a syntactically valid function parameter.
@@ -92,22 +71,18 @@ class NamedArgumentCode extends Code {
9271
/// construct and combine these together in a way that creates valid parameter
9372
/// lists.
9473
class ParameterCode extends Code {
95-
ParameterCode.fromString(String code, {Scope? scope})
96-
: super.fromString(code, scope: scope);
74+
ParameterCode.fromString(String code) : super.fromString(code);
9775

98-
ParameterCode.fromParts(List<Object> parts, {Scope? scope})
99-
: super.fromParts(parts, scope: scope);
76+
ParameterCode.fromParts(List<Object> parts) : super.fromParts(parts);
10077
}
10178

10279
/// A piece of code representing a syntactically valid statement.
10380
///
10481
/// Should always end with a semicolon.
10582
class StatementCode extends Code {
106-
StatementCode.fromString(String code, {Scope? scope})
107-
: super.fromString(code, scope: scope);
83+
StatementCode.fromString(String code) : super.fromString(code);
10884

109-
StatementCode.fromParts(List<Object> parts, {Scope? scope})
110-
: super.fromParts(parts, scope: scope);
85+
StatementCode.fromParts(List<Object> parts) : super.fromParts(parts);
11186
}
11287

11388
extension Join<T extends Code> on List<T> {

working/macros/api/introspection.dart

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,48 @@
11
import 'code.dart';
22

3-
/// An unresolved reference to a type.
3+
/// The base class for an unresolved reference to a type.
44
///
5-
/// These can be resolved to a [TypeDeclaration] using the `builder` classes
6-
/// depending on the phase a macro is running in.
5+
/// See the subtypes [FunctionTypeAnnotation] and [NamedTypeAnnotation].
76
abstract class TypeAnnotation {
87
/// Whether or not the type annotation is explicitly nullable (contains a
98
/// trailing `?`)
109
bool get isNullable;
1110

11+
/// A [Code] object representation of this type annotation.
12+
Code get code;
13+
}
14+
15+
/// The base class for function type declarations.
16+
abstract class FunctionTypeAnnotation implements TypeAnnotation {
17+
/// The return type of this function.
18+
TypeAnnotation get returnType;
19+
20+
/// The positional parameters for this function.
21+
Iterable<ParameterDeclaration> get positionalParameters;
22+
23+
/// The named parameters for this function.
24+
Iterable<ParameterDeclaration> get namedParameters;
25+
26+
/// The type parameters for this function.
27+
Iterable<TypeParameterDeclaration> get typeParameters;
28+
}
29+
30+
/// An unresolved reference to a type.
31+
///
32+
/// These can be resolved to a [TypeDeclaration] using the `builder` classes
33+
/// depending on the phase a macro is running in.
34+
abstract class NamedTypeAnnotation implements TypeAnnotation {
1235
/// The name of the type as it exists in the type annotation.
1336
String get name;
1437

15-
/// The scope in which the type annotation appeared in the program.
16-
///
17-
/// This can be used to construct an [IdentifierCode] that refers to this type
18-
/// regardless of the context in which it is emitted.
19-
Scope get scope;
20-
2138
/// The type arguments, if applicable.
2239
Iterable<TypeAnnotation> get typeArguments;
2340
}
2441

25-
//// The base class for all declarations.
42+
/// The base class for all declarations.
2643
abstract class Declaration {
27-
/// The name of this type declaration
44+
/// The name of this declaration.
2845
String get name;
29-
30-
/// The scope in which this type declaration is defined.
31-
///
32-
/// This can be used to construct an [IdentifierCode] that refers to this type
33-
/// regardless of the context in which it is emitted.
34-
Scope get scope;
3546
}
3647

3748
/// A declaration that defines a new type in the program.
@@ -128,10 +139,7 @@ abstract class FieldDeclaration implements VariableDeclaration {
128139
}
129140

130141
/// Parameter introspection information.
131-
abstract class ParameterDeclaration {
132-
/// The name of the parameter.
133-
String get name;
134-
142+
abstract class ParameterDeclaration implements Declaration {
135143
/// The type of this parameter.
136144
TypeAnnotation get type;
137145

@@ -148,7 +156,7 @@ abstract class ParameterDeclaration {
148156
}
149157

150158
/// Type parameter introspection information.
151-
abstract class TypeParameterDeclaration {
159+
abstract class TypeParameterDeclaration implements Declaration {
152160
/// The bounds for this type parameter, if it has any.
153161
TypeAnnotation? get bounds;
154162
}

working/macros/example/data_class.dart

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ macro class _AutoConstructor implements ClassDeclarationsMacro {
6868
? ''
6969
: Code.fromParts([' = ', param.defaultValue!]);
7070
parts.add(Code.fromParts([
71-
'\n$requiredKeyword${param.type.toCode()} ${param.name}',
71+
'\n$requiredKeyword${param.type.code} ${param.name}',
7272
defaultValue,
7373
',',
7474
]));
@@ -79,7 +79,7 @@ macro class _AutoConstructor implements ClassDeclarationsMacro {
7979
? ''
8080
: Code.fromParts([' = ', param.defaultValue!]);
8181
parts.add(Code.fromParts([
82-
'\n$requiredKeyword${param.type.toCode()} ${param.name}',
82+
'\n$requiredKeyword${param.type.code} ${param.name}',
8383
defaultValue,
8484
',',
8585
]));
@@ -122,22 +122,20 @@ macro class _CopyWith implements ClassDeclarationsMacro {
122122
var allFields = await clazz.allFields(builder).toList();
123123
var namedParams = [
124124
for (var field in allFields)
125-
ParameterCode.fromString(
126-
'${field.type.toCode()}${field.type.isNullable ? '?' : ''} '
127-
'${field.name}'),
125+
ParameterCode.fromString('${field.type.code} ${field.name}'),
128126
];
129127
var args = [
130128
for (var field in allFields)
131129
NamedArgumentCode.fromString(
132130
'${field.name}: ${field.name} ?? this.${field.name}'),
133131
];
134132
builder.declareInClass(DeclarationCode.fromParts([
135-
clazz.instantiate().toCode(),
133+
clazz.instantiate().code,
136134
' copyWith({',
137135
...namedParams.joinAsCode(', '),
138136
',})',
139137
// TODO: We assume this constructor exists, but should check
140-
'=> ', clazz.instantiate().toCode(), '(',
138+
'=> ', clazz.instantiate().code, '(',
141139
...args.joinAsCode(', '),
142140
', );',
143141
]));
@@ -195,7 +193,7 @@ external bool operator==(Object other);'''));
195193
ExpressionCode.fromString('this.${field.name} == other.${field.name}'),
196194
].joinAsCode(' && ');
197195
equalsBuilder.augment(FunctionBodyCode.fromParts([
198-
' => other is ${clazz.instantiate().toCode()} && ',
196+
' => other is ${clazz.instantiate().code} && ',
199197
...equalityExprs,
200198
';',
201199
]));
@@ -257,7 +255,3 @@ extension _<T> on Iterable<T> {
257255
}
258256
}
259257
}
260-
261-
extension _ToCode on TypeAnnotation {
262-
Code toCode() => Code.fromString(this.name, scope: this.scope);
263-
}

0 commit comments

Comments
 (0)