Skip to content

Commit f5831de

Browse files
johnniwintherCommit Bot
authored andcommitted
[cfe] Support arguments in macro applications
Change-Id: I87281598b18443778bdfe8444b455cd80da5155a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/240544 Reviewed-by: Chloe Stefantsova <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent 2a3d3eb commit f5831de

File tree

14 files changed

+307
-98
lines changed

14 files changed

+307
-98
lines changed

pkg/front_end/lib/src/fasta/kernel/macro/annotation_parser.dart

Lines changed: 152 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'package:_fe_analyzer_shared/src/macros/executor.dart' as macro;
56
import 'package:_fe_analyzer_shared/src/messages/codes.dart';
67
import 'package:_fe_analyzer_shared/src/parser/parser.dart';
8+
import 'package:_fe_analyzer_shared/src/parser/quote.dart';
79
import 'package:_fe_analyzer_shared/src/scanner/error_token.dart';
810
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
911

@@ -15,7 +17,6 @@ import '../../builder/prefix_builder.dart';
1517
import '../../scope.dart';
1618
import '../../source/diet_parser.dart';
1719
import '../../source/source_library_builder.dart';
18-
1920
import 'macro.dart';
2021

2122
List<MacroApplication>? prebuildAnnotations(
@@ -78,7 +79,35 @@ class _NoArgumentsNode implements _Node {
7879
}
7980

8081
class _ArgumentsNode implements _Node {
81-
_ArgumentsNode();
82+
final List<Object?> positionalArguments;
83+
final Map<String, Object?> namedArguments;
84+
85+
_ArgumentsNode(this.positionalArguments, this.namedArguments);
86+
}
87+
88+
class _PrimitiveValueNode implements _Node {
89+
final Object? value;
90+
91+
_PrimitiveValueNode(this.value);
92+
}
93+
94+
class _TokenNode implements _Node {
95+
final Token token;
96+
97+
_TokenNode(this.token);
98+
}
99+
100+
class _NamedArgumentIdentifierNode implements _Node {
101+
final String name;
102+
103+
_NamedArgumentIdentifierNode(this.name);
104+
}
105+
106+
class _NamedArgumentNode implements _Node {
107+
final String name;
108+
final Object? value;
109+
110+
_NamedArgumentNode(this.name, this.value);
82111
}
83112

84113
class _MacroListener implements Listener {
@@ -154,8 +183,11 @@ class _MacroListener implements Listener {
154183
if (macroClass != null &&
155184
constructorName != null &&
156185
argumentsNode is _ArgumentsNode) {
157-
push(new _MacroApplicationNode(
158-
new MacroApplication(macroClass, constructorName)));
186+
push(new _MacroApplicationNode(new MacroApplication(
187+
macroClass,
188+
constructorName,
189+
new macro.Arguments(argumentsNode.positionalArguments,
190+
argumentsNode.namedArguments))));
159191
return;
160192
}
161193
}
@@ -211,6 +243,9 @@ class _MacroListener implements Listener {
211243
pushUnsupported();
212244
}
213245
break;
246+
case IdentifierContext.namedArgumentReference:
247+
push(new _NamedArgumentIdentifierNode(token.lexeme));
248+
break;
214249
default:
215250
pushUnsupported();
216251
break;
@@ -224,11 +259,27 @@ class _MacroListener implements Listener {
224259

225260
@override
226261
void endArguments(int count, Token beginToken, Token endToken) {
227-
if (count == 0) {
228-
push(new _ArgumentsNode());
229-
} else {
230-
// TODO(johnniwinther): Handle arguments.
262+
if (unrecognized) {
263+
pushUnsupported();
264+
return;
265+
}
266+
List<Object?> positionalArguments = [];
267+
Map<String, Object?> namedArguments = {};
268+
for (int i = 0; i < count; i++) {
269+
_Node node = pop();
270+
if (node is _PrimitiveValueNode) {
271+
positionalArguments.add(node.value);
272+
} else if (node is _NamedArgumentNode &&
273+
!namedArguments.containsKey(node.name)) {
274+
namedArguments[node.name] = node.value;
275+
} else {
276+
_unsupported();
277+
}
278+
}
279+
if (unrecognized) {
231280
pushUnsupported();
281+
} else {
282+
push(new _ArgumentsNode(positionalArguments, namedArguments));
232283
}
233284
}
234285

@@ -248,6 +299,99 @@ class _MacroListener implements Listener {
248299
// context.
249300
}
250301

302+
@override
303+
void handleNamedArgument(Token colon) {
304+
if (unrecognized) {
305+
pushUnsupported();
306+
} else {
307+
_Node value = pop();
308+
_Node name = pop();
309+
if (name is _NamedArgumentIdentifierNode &&
310+
value is _PrimitiveValueNode) {
311+
push(new _NamedArgumentNode(name.name, value.value));
312+
} else {
313+
pushUnsupported();
314+
}
315+
}
316+
}
317+
318+
@override
319+
void handleLiteralNull(Token token) {
320+
push(new _PrimitiveValueNode(null));
321+
}
322+
323+
@override
324+
void handleLiteralBool(Token token) {
325+
push(new _PrimitiveValueNode(token.lexeme == 'true'));
326+
}
327+
328+
@override
329+
void handleLiteralDouble(Token token) {
330+
push(new _PrimitiveValueNode(double.parse(token.lexeme)));
331+
}
332+
333+
@override
334+
void handleLiteralInt(Token token) {
335+
push(new _PrimitiveValueNode(int.parse(token.lexeme)));
336+
}
337+
338+
@override
339+
void beginLiteralString(Token token) {
340+
push(new _TokenNode(token));
341+
}
342+
343+
@override
344+
void endLiteralString(int interpolationCount, Token endToken) {
345+
if (unrecognized) {
346+
pushUnsupported();
347+
return;
348+
}
349+
if (interpolationCount == 0) {
350+
_Node node = pop();
351+
if (node is _TokenNode) {
352+
String text = unescapeString(node.token.lexeme, node.token, this);
353+
if (unrecognized) {
354+
pushUnsupported();
355+
} else {
356+
push(new _PrimitiveValueNode(text));
357+
}
358+
} else {
359+
pushUnsupported();
360+
}
361+
} else {
362+
// TODO(johnniwinther): Should we support this?
363+
pushUnsupported();
364+
}
365+
}
366+
367+
@override
368+
void handleStringPart(Token token) {
369+
// TODO(johnniwinther): Should we support this?
370+
_unhandled();
371+
}
372+
373+
@override
374+
void handleStringJuxtaposition(Token startToken, int literalCount) {
375+
if (unrecognized) {
376+
pushUnsupported();
377+
} else {
378+
List<String> values = [];
379+
for (int i = 0; i < literalCount; i++) {
380+
_Node node = pop();
381+
if (node is _PrimitiveValueNode && node.value is String) {
382+
values.add(node.value as String);
383+
} else {
384+
_unsupported();
385+
}
386+
}
387+
if (unrecognized) {
388+
pushUnsupported();
389+
} else {
390+
push(new _PrimitiveValueNode(values.reversed.join()));
391+
}
392+
}
393+
}
394+
251395
//////////////////////////////////////////////////////////////////////////////
252396
// Stub implementation
253397
//////////////////////////////////////////////////////////////////////////////
@@ -552,11 +696,6 @@ class _MacroListener implements Listener {
552696
_unexpected();
553697
}
554698

555-
@override
556-
void beginLiteralString(Token token) {
557-
_unhandled();
558-
}
559-
560699
@override
561700
void beginLiteralSymbol(Token token) {
562701
_unhandled();
@@ -1125,11 +1264,6 @@ class _MacroListener implements Listener {
11251264
_unexpected();
11261265
}
11271266

1128-
@override
1129-
void endLiteralString(int interpolationCount, Token endToken) {
1130-
_unhandled();
1131-
}
1132-
11331267
@override
11341268
void endLiteralSymbol(Token hashToken, int identifierCount) {
11351269
_unhandled();
@@ -1636,21 +1770,6 @@ class _MacroListener implements Listener {
16361770
_unsupported();
16371771
}
16381772

1639-
@override
1640-
void handleLiteralBool(Token token) {
1641-
_unhandled();
1642-
}
1643-
1644-
@override
1645-
void handleLiteralDouble(Token token) {
1646-
_unhandled();
1647-
}
1648-
1649-
@override
1650-
void handleLiteralInt(Token token) {
1651-
_unhandled();
1652-
}
1653-
16541773
@override
16551774
void handleLiteralList(
16561775
int count, Token leftBracket, Token? constKeyword, Token rightBracket) {
@@ -1662,11 +1781,6 @@ class _MacroListener implements Listener {
16621781
_unhandled();
16631782
}
16641783

1665-
@override
1666-
void handleLiteralNull(Token token) {
1667-
_unhandled();
1668-
}
1669-
16701784
@override
16711785
void handleLiteralSetOrMap(int count, Token leftBrace, Token? constKeyword,
16721786
Token rightBrace, bool hasSetEntry) {
@@ -1683,11 +1797,6 @@ class _MacroListener implements Listener {
16831797
_unexpected();
16841798
}
16851799

1686-
@override
1687-
void handleNamedArgument(Token colon) {
1688-
_unhandled();
1689-
}
1690-
16911800
@override
16921801
void handleNamedMixinApplicationWithClause(Token withKeyword) {
16931802
_unexpected();
@@ -1839,16 +1948,6 @@ class _MacroListener implements Listener {
18391948
_unsupported();
18401949
}
18411950

1842-
@override
1843-
void handleStringJuxtaposition(Token startToken, int literalCount) {
1844-
_unhandled();
1845-
}
1846-
1847-
@override
1848-
void handleStringPart(Token token) {
1849-
_unhandled();
1850-
}
1851-
18521951
@override
18531952
void handleSuperExpression(Token token, IdentifierContext context) {
18541953
_unsupported();

pkg/front_end/lib/src/fasta/kernel/macro/macro.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,11 @@ class MacroDeclarationData {
6565
class MacroApplication {
6666
final ClassBuilder classBuilder;
6767
final String constructorName;
68+
final macro.Arguments arguments;
6869

6970
// TODO(johnniwinther): Add support for arguments.
7071

71-
MacroApplication(this.classBuilder, this.constructorName);
72+
MacroApplication(this.classBuilder, this.constructorName, this.arguments);
7273

7374
late macro.MacroInstanceIdentifier instanceIdentifier;
7475

@@ -152,8 +153,7 @@ class MacroApplications {
152153
libraryUri,
153154
macroClassName,
154155
application.constructorName,
155-
// TODO(johnniwinther): Support macro arguments.
156-
new macro.Arguments([], {}));
156+
application.arguments);
157157
benchmarker?.endSubdivide();
158158
} catch (e) {
159159
throw "Error instantiating macro `${application}`: $e";

pkg/front_end/test/macros/declaration/data/pkgs/macro/lib/macro.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,10 @@ macro class Macro3<T> implements Macro {
2525
class NonMacro {
2626
const NonMacro();
2727
}
28+
29+
macro class Macro4 implements Macro {
30+
final field;
31+
final named;
32+
33+
const Macro4(this.field, {this.named});
34+
}

pkg/front_end/test/macros/declaration/data/tests/all_precompiled.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010

1111
import 'package:precompiled_macro/precompiled_macro.dart';
1212

13-
/*member: main:appliedMacros=[PrecompiledMacro.new]*/
13+
/*member: main:appliedMacros=[PrecompiledMacro.new()]*/
1414
@PrecompiledMacro()
1515
void main() {}

0 commit comments

Comments
 (0)