@@ -13,7 +13,7 @@ import 'dartfuzz_api_table.dart';
13
13
// Version of DartFuzz. Increase this each time changes are made
14
14
// to preserve the property that a given version of DartFuzz yields
15
15
// the same fuzzed program for a deterministic random seed.
16
- const String version = '1.5 ' ;
16
+ const String version = '1.6 ' ;
17
17
18
18
// Restriction on statement and expression depths.
19
19
const int stmtDepth = 2 ;
@@ -101,10 +101,10 @@ class DartFuzz {
101
101
void emitClasses () {
102
102
assert (classFields.length == classMethods.length);
103
103
for (int i = 0 ; i < classFields.length; i++ ) {
104
- currentClass = i;
105
104
emitLn ('class X$i ${i == 0 ? "" : "extends X${i - 1 }" } {' );
106
105
indent += 2 ;
107
106
emitVarDecls ('$fieldName ${i }_' , classFields[i]);
107
+ currentClass = i;
108
108
emitMethods ('$methodName ${i }_' , classMethods[i]);
109
109
emitLn ('void run() {' );
110
110
indent += 2 ;
@@ -156,7 +156,7 @@ class DartFuzz {
156
156
for (int i = 0 ; i < vars.length; i++ ) {
157
157
DartType tp = vars[i];
158
158
emitLn ('${tp .name } $name $i = ' , newline: false );
159
- emitLiteral (tp);
159
+ emitLiteral (0 , tp);
160
160
emit (';' , newline: true );
161
161
}
162
162
emit ('' , newline: true );
@@ -534,39 +534,96 @@ class DartFuzz {
534
534
535
535
void emitString () {
536
536
emit ("'" );
537
- int l = rand.nextInt (8 );
538
- for (int i = 0 ; i < l; i++ ) {
537
+ for (int i = 0 , n = rand.nextInt (8 ); i < n; i++ ) {
539
538
emitChar ();
540
539
}
541
540
emit ("'" );
542
541
}
543
542
544
- void emitList (String open, String close) {
545
- emit ('$open ' );
546
- int l = 1 + rand.nextInt (4 );
547
- for (int i = 0 ; i < l; i++ ) {
548
- emitInt ();
549
- if (i != (l - 1 )) {
550
- emit (', ' );
551
- }
543
+ void emitElementExpr (int depth, DartType tp) {
544
+ if (currentMethod != null ) {
545
+ emitExpr (depth, tp);
546
+ } else {
547
+ emitLiteral (depth, tp);
552
548
}
553
- emit (' $close ' );
554
549
}
555
550
556
- void emitMap () {
557
- emit ('{ ' );
558
- int l = 1 + rand.nextInt (4 );
559
- for (int i = 0 ; i < l; i++ ) {
560
- emit ('$i : ' );
561
- emitString ();
562
- if (i != (l - 1 )) {
551
+ void emitElement (int depth, DartType tp) {
552
+ if (tp == DartType .INT_STRING_MAP ) {
553
+ emitSmallPositiveInt ();
554
+ emit (' : ' );
555
+ emitElementExpr (depth, DartType .STRING );
556
+ } else {
557
+ emitElementExpr (depth, DartType .INT );
558
+ }
559
+ }
560
+
561
+ void emitCollectionElement (int depth, DartType tp) {
562
+ int r = depth <= exprDepth ? rand.nextInt (10 ) : 10 ;
563
+ switch (r + 3 ) {
564
+ // TODO(ajcbik): enable when on by default
565
+ // Favors elements over control-flow collections.
566
+ case 0 :
567
+ emit ('...' ); // spread
568
+ emitCollection (depth + 1 , tp);
569
+ break ;
570
+ case 1 :
571
+ emit ('if (' );
572
+ emitElementExpr (depth + 1 , DartType .BOOL );
573
+ emit (') ' );
574
+ emitCollectionElement (depth + 1 , tp);
575
+ if (rand.nextBool ()) {
576
+ emit (' else ' );
577
+ emitCollectionElement (depth + 1 , tp);
578
+ }
579
+ break ;
580
+ case 2 :
581
+ {
582
+ int i = localVars.length;
583
+ emit ('for (int $localName $i ' );
584
+ // For-loop (induction, list, set).
585
+ switch (rand.nextInt (3 )) {
586
+ case 0 :
587
+ emit ('= 0; $localName $i < ' );
588
+ emitSmallPositiveInt ();
589
+ emit ('; $localName $i ++) ' );
590
+ break ;
591
+ case 1 :
592
+ emit ('in ' );
593
+ emitCollection (depth + 1 , DartType .INT_LIST );
594
+ emit (') ' );
595
+ break ;
596
+ default :
597
+ emit ('in ' );
598
+ emitCollection (depth + 1 , DartType .INT_SET );
599
+ emit (') ' );
600
+ break ;
601
+ }
602
+ nest++ ;
603
+ localVars.add (DartType .INT );
604
+ emitCollectionElement (depth + 1 , tp);
605
+ localVars.removeLast ();
606
+ nest-- ;
607
+ break ;
608
+ }
609
+ default :
610
+ emitElement (depth, tp);
611
+ break ;
612
+ }
613
+ }
614
+
615
+ void emitCollection (int depth, DartType tp) {
616
+ emit (tp == DartType .INT_LIST ? '[ ' : '{ ' );
617
+ for (int i = 0 , n = 1 + rand.nextInt (8 ); i < n; i++ ) {
618
+ emitCollectionElement (depth, tp);
619
+ if (i != (n - 1 )) {
563
620
emit (', ' );
564
621
}
565
622
}
566
- emit (' }' );
623
+ emit (tp == DartType . INT_LIST ? ' ]' : ' }' );
567
624
}
568
625
569
- void emitLiteral (DartType tp) {
626
+ void emitLiteral (int depth, DartType tp) {
570
627
if (tp == DartType .BOOL ) {
571
628
emitBool ();
572
629
} else if (tp == DartType .INT ) {
@@ -575,12 +632,10 @@ class DartFuzz {
575
632
emitDouble ();
576
633
} else if (tp == DartType .STRING ) {
577
634
emitString ();
578
- } else if (tp == DartType .INT_LIST ) {
579
- emitList ('[' , ']' );
580
- } else if (tp == DartType .INT_SET ) {
581
- emitList ('{' , '}' );
582
- } else if (tp == DartType .INT_STRING_MAP ) {
583
- emitMap ();
635
+ } else if (tp == DartType .INT_LIST ||
636
+ tp == DartType .INT_SET ||
637
+ tp == DartType .INT_STRING_MAP ) {
638
+ emitCollection (depth, tp);
584
639
} else {
585
640
assert (false );
586
641
}
@@ -642,7 +697,7 @@ class DartFuzz {
642
697
void emitTerminal (int depth, DartType tp) {
643
698
switch (rand.nextInt (2 )) {
644
699
case 0 :
645
- emitLiteral (tp);
700
+ emitLiteral (depth, tp);
646
701
break ;
647
702
default :
648
703
emitVar (depth, tp);
@@ -694,7 +749,7 @@ class DartFuzz {
694
749
emit ('(' );
695
750
emitExpr (depth + 1 , tp);
696
751
emitBinaryOp (tp);
697
- emitLiteral (tp);
752
+ emitLiteral (depth + 1 , tp);
698
753
emit (')' );
699
754
return ;
700
755
}
@@ -774,8 +829,9 @@ class DartFuzz {
774
829
void emitMethodCall (int depth, DartType tp) {
775
830
// Only call backward to avoid infinite recursion.
776
831
if (currentClass == null ) {
777
- // Outside a class: call backward in global methods.
778
- if (pickedCall (depth, tp, methodName, globalMethods, currentMethod)) {
832
+ // Outside a class but inside a method: call backward in global methods.
833
+ if (currentMethod != null &&
834
+ pickedCall (depth, tp, methodName, globalMethods, currentMethod)) {
779
835
return ;
780
836
}
781
837
} else {
@@ -996,17 +1052,15 @@ class DartFuzz {
996
1052
997
1053
List <DartType > fillTypes1 () {
998
1054
List <DartType > list = new List <DartType >();
999
- int n = 1 + rand.nextInt (4 );
1000
- for (int i = 0 ; i < n; i++ ) {
1055
+ for (int i = 0 , n = 1 + rand.nextInt (4 ); i < n; i++ ) {
1001
1056
list.add (getType ());
1002
1057
}
1003
1058
return list;
1004
1059
}
1005
1060
1006
1061
List <List <DartType >> fillTypes2 () {
1007
1062
List <List <DartType >> list = new List <List <DartType >>();
1008
- int n = 1 + rand.nextInt (4 );
1009
- for (int i = 0 ; i < n; i++ ) {
1063
+ for (int i = 0 , n = 1 + rand.nextInt (4 ); i < n; i++ ) {
1010
1064
list.add (fillTypes1 ());
1011
1065
}
1012
1066
return list;
0 commit comments