@@ -13,6 +13,7 @@ import '../piece/adjacent.dart';
13
13
import '../piece/assign.dart' ;
14
14
import '../piece/block.dart' ;
15
15
import '../piece/chain.dart' ;
16
+ import '../piece/constructor.dart' ;
16
17
import '../piece/for.dart' ;
17
18
import '../piece/if.dart' ;
18
19
import '../piece/infix.dart' ;
@@ -130,7 +131,17 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
130
131
131
132
@override
132
133
Piece visitAssertInitializer (AssertInitializer node) {
133
- throw UnimplementedError ();
134
+ return buildPiece ((b) {
135
+ b.token (node.assertKeyword);
136
+ b.add (createList (
137
+ leftBracket: node.leftParenthesis,
138
+ [
139
+ node.condition,
140
+ if (node.message case var message? ) message,
141
+ ],
142
+ rightBracket: node.rightParenthesis,
143
+ ));
144
+ });
134
145
}
135
146
136
147
@override
@@ -343,18 +354,85 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
343
354
344
355
@override
345
356
Piece visitConstructorDeclaration (ConstructorDeclaration node) {
346
- throw UnimplementedError ();
357
+ var header = buildPiece ((b) {
358
+ b.modifier (node.externalKeyword);
359
+ b.modifier (node.constKeyword);
360
+ b.modifier (node.factoryKeyword);
361
+ b.visit (node.returnType);
362
+ b.token (node.period);
363
+ b.token (node.name);
364
+ });
365
+
366
+ var parameters = nodePiece (node.parameters);
367
+
368
+ Piece ? redirect;
369
+ Piece ? initializerSeparator;
370
+ Piece ? initializers;
371
+ if (node.redirectedConstructor case var constructor? ) {
372
+ redirect = AssignPiece (
373
+ tokenPiece (node.separator! ), nodePiece (constructor),
374
+ isValueDelimited: false );
375
+ } else if (node.initializers.isNotEmpty) {
376
+ initializerSeparator = tokenPiece (node.separator! );
377
+ initializers = createList (node.initializers,
378
+ style: const ListStyle (commas: Commas .nonTrailing));
379
+ }
380
+
381
+ var body = createFunctionBody (node.body);
382
+
383
+ return ConstructorPiece (header, parameters, body,
384
+ canSplitParameters: node.parameters.parameters
385
+ .canSplit (node.parameters.rightParenthesis),
386
+ hasOptionalParameter: node.parameters.rightDelimiter != null ,
387
+ redirect: redirect,
388
+ initializerSeparator: initializerSeparator,
389
+ initializers: initializers);
347
390
}
348
391
349
392
@override
350
393
Piece visitConstructorFieldInitializer (ConstructorFieldInitializer node) {
351
- throw UnimplementedError ();
394
+ return buildPiece ((b) {
395
+ b.token (node.thisKeyword);
396
+ b.token (node.period);
397
+ b.add (createAssignment (node.fieldName, node.equals, node.expression));
398
+ });
352
399
}
353
400
354
401
@override
355
402
Piece visitConstructorName (ConstructorName node) {
356
- throw UnsupportedError (
357
- 'This node is handled by visitInstanceCreationExpression().' );
403
+ // If there is an import prefix and/or constructor name, then allow
404
+ // splitting before the `.`. This doesn't look good, but is consistent with
405
+ // constructor calls that don't have `new` or `const`. We allow splitting
406
+ // in the latter because there is no way to distinguish syntactically
407
+ // between a named constructor call and any other kind of method call or
408
+ // property access.
409
+ var operations = < Piece > [];
410
+
411
+ var builder = AdjacentBuilder (this );
412
+ if (node.type.importPrefix case var importPrefix? ) {
413
+ builder.token (importPrefix.name);
414
+ operations.add (builder.build ());
415
+ builder.token (importPrefix.period);
416
+ }
417
+
418
+ // The name of the type being constructed.
419
+ var type = node.type;
420
+ builder.token (type.name2);
421
+ builder.visit (type.typeArguments);
422
+ builder.token (type.question);
423
+
424
+ // If this is a named constructor, the name.
425
+ if (node.name != null ) {
426
+ operations.add (builder.build ());
427
+ builder.token (node.period);
428
+ builder.visit (node.name);
429
+ }
430
+
431
+ // If there was a prefix or constructor name, then make a splittable piece.
432
+ // Otherwise, the current piece is a simple identifier for the name.
433
+ operations.add (builder.build ());
434
+ if (operations.length == 1 ) return operations.first;
435
+ return ChainPiece (operations);
358
436
}
359
437
360
438
@override
@@ -550,7 +628,30 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
550
628
551
629
@override
552
630
Piece visitFieldFormalParameter (FieldFormalParameter node) {
553
- throw UnimplementedError ();
631
+ if (node.parameters case var parameters? ) {
632
+ // A function-typed field formal like:
633
+ //
634
+ // ```
635
+ // C(this.fn(parameter));
636
+ // ```
637
+ return createFunctionType (
638
+ node.type,
639
+ fieldKeyword: node.thisKeyword,
640
+ period: node.period,
641
+ node.name,
642
+ node.typeParameters,
643
+ parameters,
644
+ node.question,
645
+ parameter: node);
646
+ } else {
647
+ return createFormalParameter (
648
+ node,
649
+ mutableKeyword: node.keyword,
650
+ fieldKeyword: node.thisKeyword,
651
+ period: node.period,
652
+ node.type,
653
+ node.name);
654
+ }
554
655
}
555
656
556
657
@override
@@ -736,7 +837,7 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
736
837
@override
737
838
Piece visitFunctionDeclaration (FunctionDeclaration node) {
738
839
return createFunction (
739
- externalKeyword : node.externalKeyword,
840
+ modifiers : [ node.externalKeyword] ,
740
841
returnType: node.returnType,
741
842
propertyKeyword: node.propertyKeyword,
742
843
name: node.name,
@@ -974,11 +1075,9 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
974
1075
@override
975
1076
Piece visitMethodDeclaration (MethodDeclaration node) {
976
1077
return createFunction (
977
- externalKeyword: node.externalKeyword,
978
- modifierKeyword: node.modifierKeyword,
1078
+ modifiers: [node.externalKeyword, node.modifierKeyword],
979
1079
returnType: node.returnType,
980
- operatorKeyword: node.operatorKeyword,
981
- propertyKeyword: node.propertyKeyword,
1080
+ propertyKeyword: node.operatorKeyword ?? node.propertyKeyword,
982
1081
name: node.name,
983
1082
typeParameters: node.typeParameters,
984
1083
parameters: node.parameters,
@@ -1166,7 +1265,12 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
1166
1265
@override
1167
1266
Piece visitRedirectingConstructorInvocation (
1168
1267
RedirectingConstructorInvocation node) {
1169
- throw UnimplementedError ();
1268
+ return buildPiece ((b) {
1269
+ b.token (node.thisKeyword);
1270
+ b.token (node.period);
1271
+ b.visit (node.constructorName);
1272
+ b.visit (node.argumentList);
1273
+ });
1170
1274
}
1171
1275
1172
1276
@override
@@ -1260,22 +1364,8 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
1260
1364
1261
1365
@override
1262
1366
Piece visitSimpleFormalParameter (SimpleFormalParameter node) {
1263
- var builder = AdjacentBuilder (this );
1264
- startFormalParameter (node, builder);
1265
- builder.modifier (node.keyword);
1266
-
1267
- if ((node.type, node.name) case (var _? , var name? )) {
1268
- // Have both a type and name, so allow splitting after the type.
1269
- builder.visit (node.type);
1270
- var typePiece = builder.build ();
1271
- var namePiece = tokenPiece (name);
1272
- return VariablePiece (typePiece, [namePiece], hasType: true );
1273
- } else {
1274
- // Don't have both a type and name, so just write whichever one we have.
1275
- builder.visit (node.type);
1276
- builder.token (node.name);
1277
- return builder.build ();
1278
- }
1367
+ return createFormalParameter (node, node.type, node.name,
1368
+ mutableKeyword: node.keyword);
1279
1369
}
1280
1370
1281
1371
@override
@@ -1300,7 +1390,12 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
1300
1390
1301
1391
@override
1302
1392
Piece visitSuperConstructorInvocation (SuperConstructorInvocation node) {
1303
- throw UnimplementedError ();
1393
+ return buildPiece ((b) {
1394
+ b.token (node.superKeyword);
1395
+ b.token (node.period);
1396
+ b.visit (node.constructorName);
1397
+ b.visit (node.argumentList);
1398
+ });
1304
1399
}
1305
1400
1306
1401
@override
@@ -1310,7 +1405,30 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
1310
1405
1311
1406
@override
1312
1407
Piece visitSuperFormalParameter (SuperFormalParameter node) {
1313
- throw UnimplementedError ();
1408
+ if (node.parameters case var parameters? ) {
1409
+ // A function-typed super parameter like:
1410
+ //
1411
+ // ```
1412
+ // C(super.fn(parameter));
1413
+ // ```
1414
+ return createFunctionType (
1415
+ node.type,
1416
+ fieldKeyword: node.superKeyword,
1417
+ period: node.period,
1418
+ node.name,
1419
+ node.typeParameters,
1420
+ parameters,
1421
+ node.question,
1422
+ parameter: node);
1423
+ } else {
1424
+ return createFormalParameter (
1425
+ node,
1426
+ mutableKeyword: node.keyword,
1427
+ fieldKeyword: node.superKeyword,
1428
+ period: node.period,
1429
+ node.type,
1430
+ node.name);
1431
+ }
1314
1432
}
1315
1433
1316
1434
@override
0 commit comments