[dartfuzz] Handle more types in minimized literal generation.
Previously, the minimizer only handled a small, handpicked set of types
when replacing expressions with minimized literals of the expression's
type. This CL adds minimal literal generation for any type that has a
known constructor and generalizes handling of lists, sets, and maps.
TEST=dartfuzz
Change-Id: Ifeaacfd4dec1ba8f66f4fee9cf8c7fb74193b0d2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/403861
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
index 2b73e28..1246d12 100644
--- a/runtime/tools/dartfuzz/dartfuzz.dart
+++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -42,13 +42,13 @@
ffiMethod,
instanceMethod,
callMethod,
- extensionMethod
+ extensionMethod,
}
/// Base class for all methods in the program generated by DartFuzz.
abstract class Method {
Method(this.name, this.parameters, this.fuzzer)
- : recursionAllowed = fuzzer.coinFlip() {
+ : recursionAllowed = fuzzer.coinFlip() {
if (recursionAllowed) {
// Add the recursion depth parameter.
parameters.add(DartType.INT);
@@ -58,12 +58,17 @@
String get recursionDepthParamName => '$paramName${parameters.length - 1}';
DartType get returnType => parameters[0];
- void emitCallParameters(int depth, bool isRecursiveCall,
- {RhsFilter? rhsFilter}) {
+ void emitCallParameters(
+ int depth,
+ bool isRecursiveCall, {
+ RhsFilter? rhsFilter,
+ }) {
if (isRecursiveCall && !recursionAllowed) {
throw StateError('Did not expect a recursive call in $name');
}
- fuzzer.emitParenWrapped(() => fuzzer.emitCommaSeparated((int i) {
+ fuzzer.emitParenWrapped(
+ () => fuzzer.emitCommaSeparated(
+ (int i) {
// If this function can be called recursively, the last parameter is the
// recursion depth parameter.
if (i == parameters.length - 1 && recursionAllowed) {
@@ -78,7 +83,11 @@
} else {
fuzzer.emitExpr(depth, parameters[i], rhsFilter: rhsFilter);
}
- }, parameters.length, start: 1));
+ },
+ parameters.length,
+ start: 1,
+ ),
+ );
}
void disableRecursionScope(Function callback) {
@@ -89,15 +98,18 @@
}
void emitRecursionBaseCase() {
- fuzzer.emitIfStatement(() {
- fuzzer.emit('$recursionDepthParamName >= ');
- fuzzer.emitSmallPositiveInt();
- }, () {
- // Temporarily set recursionAllowed to false so that we don't have a
- // recursive call in the return statement of the base case.
- disableRecursionScope(fuzzer.emitReturn);
- return false;
- });
+ fuzzer.emitIfStatement(
+ () {
+ fuzzer.emit('$recursionDepthParamName >= ');
+ fuzzer.emitSmallPositiveInt();
+ },
+ () {
+ // Temporarily set recursionAllowed to false so that we don't have a
+ // recursive call in the return statement of the base case.
+ disableRecursionScope(fuzzer.emitReturn);
+ return false;
+ },
+ );
}
void emitFunctionBody() {
@@ -150,10 +162,12 @@
fuzzer.emitNewline();
}
- String emitCall(int depth,
- {RhsFilter? rhsFilter,
- bool includeSemicolon = false,
- bool isRecursiveCall = false}) {
+ String emitCall(
+ int depth, {
+ RhsFilter? rhsFilter,
+ bool includeSemicolon = false,
+ bool isRecursiveCall = false,
+ }) {
var outputName = name;
fuzzer.emitLn(outputName, newline: false);
emitCallParameters(depth + 1, isRecursiveCall, rhsFilter: rhsFilter);
@@ -177,15 +191,18 @@
/// Class for global methods generated by DartFuzz.
class GlobalMethod extends Method {
GlobalMethod(String name, List<DartType> parameters, DartFuzz fuzzer)
- : super(name, parameters, fuzzer);
+ : super(name, parameters, fuzzer);
}
/// Class for ffi methods generated by DartFuzz.
class FfiMethod extends Method {
FfiMethod(
- String namePrefix, int index, List<DartType> parameters, DartFuzz fuzzer)
- : ffiCastName = '${namePrefix}FfiCast$index',
- super('${namePrefix}Ffi$index', parameters, fuzzer);
+ String namePrefix,
+ int index,
+ List<DartType> parameters,
+ DartFuzz fuzzer,
+ ) : ffiCastName = '${namePrefix}FfiCast$index',
+ super('${namePrefix}Ffi$index', parameters, fuzzer);
@override
void emitFunctionBody() {
@@ -216,14 +233,19 @@
/// Class for instance methods generated by DartFuzz.
class InstanceMethod extends Method {
InstanceMethod(
- String name, List<DartType> parameters, DartFuzz fuzzer, this.className)
- : super(name, parameters, fuzzer);
+ String name,
+ List<DartType> parameters,
+ DartFuzz fuzzer,
+ this.className,
+ ) : super(name, parameters, fuzzer);
@override
- String emitCall(int depth,
- {RhsFilter? rhsFilter,
- bool includeSemicolon = false,
- bool isRecursiveCall = false}) {
+ String emitCall(
+ int depth, {
+ RhsFilter? rhsFilter,
+ bool includeSemicolon = false,
+ bool isRecursiveCall = false,
+ }) {
var outputName = name;
if (fuzzer.currentClassIndex == null) {
// If we're calling an instance method from outside the class, then we
@@ -243,13 +265,15 @@
class CallMethod extends Method {
CallMethod(List<DartType> parameters, DartFuzz fuzzer, this.className)
- : super('call', parameters, fuzzer);
+ : super('call', parameters, fuzzer);
@override
- String emitCall(int depth,
- {RhsFilter? rhsFilter,
- bool includeSemicolon = false,
- bool isRecursiveCall = false}) {
+ String emitCall(
+ int depth, {
+ RhsFilter? rhsFilter,
+ bool includeSemicolon = false,
+ bool isRecursiveCall = false,
+ }) {
String outputName;
outputName = '$className()';
fuzzer.emitLn(outputName, newline: false);
@@ -273,9 +297,14 @@
// Class for extension methods generated by DartFuzz.
class ExtensionMethod extends Method {
- ExtensionMethod(String name, List<DartType> parameters, DartFuzz fuzzer,
- this.className, this.extensionName, this.type)
- : super(name, parameters, fuzzer);
+ ExtensionMethod(
+ String name,
+ List<DartType> parameters,
+ DartFuzz fuzzer,
+ this.className,
+ this.extensionName,
+ this.type,
+ ) : super(name, parameters, fuzzer);
@override
String emitCall(
int depth, {
@@ -291,9 +320,10 @@
// using a variable of the Dart type or using explicit extension
// application.
if (fuzzer.currentClassIndex == null || type != null) {
- var invokingObject = type != null
- ? fuzzer.pickScalarVar(type!.toNonNullable())
- : '$className()';
+ var invokingObject =
+ type != null
+ ? fuzzer.pickScalarVar(type!.toNonNullable())
+ : '$className()';
if (fuzzer.coinFlip()) {
outputName = '$extensionName($invokingObject).$name';
@@ -345,11 +375,16 @@
if (ffi) {
typeToLibraryMethods[DartType.INT] = [
...[
- DartLib('intComputation',
- [DartType.VOID, ...List<DartType>.filled(4, DartType.INT)], true),
+ DartLib('intComputation', [
+ DartType.VOID,
+ ...List<DartType>.filled(4, DartType.INT),
+ ], true),
DartLib('takeMaxUint16', [DartType.VOID, DartType.INT], true),
- DartLib(
- 'sumPlus42', [DartType.VOID, DartType.INT, DartType.INT], true),
+ DartLib('sumPlus42', [
+ DartType.VOID,
+ DartType.INT,
+ DartType.INT,
+ ], true),
DartLib('returnMaxUint8', [DartType.VOID, DartType.VOID], true),
DartLib('returnMaxUint16', [DartType.VOID, DartType.VOID], true),
DartLib('returnMaxUint32', [DartType.VOID, DartType.VOID], true),
@@ -358,10 +393,14 @@
DartLib('returnMinInt32', [DartType.VOID, DartType.VOID], true),
DartLib('takeMinInt16', [DartType.VOID, DartType.INT], true),
DartLib('takeMinInt32', [DartType.VOID, DartType.INT], true),
- DartLib('uintComputation',
- [DartType.VOID, ...List<DartType>.filled(4, DartType.INT)], true),
- DartLib('sumSmallNumbers',
- [DartType.VOID, ...List<DartType>.filled(6, DartType.INT)], true),
+ DartLib('uintComputation', [
+ DartType.VOID,
+ ...List<DartType>.filled(4, DartType.INT),
+ ], true),
+ DartLib('sumSmallNumbers', [
+ DartType.VOID,
+ ...List<DartType>.filled(6, DartType.INT),
+ ], true),
DartLib('takeMinInt8', [DartType.VOID, DartType.INT], true),
DartLib('takeMaxUint32', [DartType.VOID, DartType.INT], true),
DartLib('takeMaxUint8', [DartType.VOID, DartType.INT], true),
@@ -369,24 +408,33 @@
DartLib('minInt32', [DartType.VOID, DartType.VOID], true),
// Use small int to avoid overflow divergences due to size
// differences in intptr_t on 32-bit and 64-bit platforms.
- DartLib('sumManyIntsOdd',
- [DartType.VOID, ...List<DartType>.filled(11, DartType.INT)], true,
- restrictions: [
- Restriction.none,
- ...List<Restriction>.filled(11, Restriction.small)
- ]),
- DartLib('sumManyInts',
- [DartType.VOID, ...List<DartType>.filled(10, DartType.INT)], true,
- restrictions: [
- Restriction.none,
- ...List<Restriction>.filled(10, Restriction.small)
- ]),
- DartLib('regress37069',
- [DartType.VOID, ...List<DartType>.filled(11, DartType.INT)], true,
- restrictions: [
- Restriction.none,
- ...List<Restriction>.filled(11, Restriction.small)
- ]),
+ DartLib(
+ 'sumManyIntsOdd',
+ [DartType.VOID, ...List<DartType>.filled(11, DartType.INT)],
+ true,
+ restrictions: [
+ Restriction.none,
+ ...List<Restriction>.filled(11, Restriction.small),
+ ],
+ ),
+ DartLib(
+ 'sumManyInts',
+ [DartType.VOID, ...List<DartType>.filled(10, DartType.INT)],
+ true,
+ restrictions: [
+ Restriction.none,
+ ...List<Restriction>.filled(10, Restriction.small),
+ ],
+ ),
+ DartLib(
+ 'regress37069',
+ [DartType.VOID, ...List<DartType>.filled(11, DartType.INT)],
+ true,
+ restrictions: [
+ Restriction.none,
+ ...List<Restriction>.filled(11, Restriction.small),
+ ],
+ ),
],
...DartLib.intLibs,
];
@@ -394,37 +442,34 @@
typeToLibraryMethods[DartType.DOUBLE] = [
if (ffi) ...[
DartLib('times1_337Float', [DartType.VOID, DartType.DOUBLE], true),
- DartLib(
- 'sumManyDoubles',
- [DartType.VOID, ...List<DartType>.filled(10, DartType.DOUBLE)],
- true),
+ DartLib('sumManyDoubles', [
+ DartType.VOID,
+ ...List<DartType>.filled(10, DartType.DOUBLE),
+ ], true),
DartLib('times1_337Double', [DartType.VOID, DartType.DOUBLE], true),
- DartLib(
- 'sumManyNumbers',
- [
- DartType.VOID,
- DartType.INT,
- DartType.DOUBLE,
- DartType.INT,
- DartType.DOUBLE,
- DartType.INT,
- DartType.DOUBLE,
- DartType.INT,
- DartType.DOUBLE,
- DartType.INT,
- DartType.DOUBLE,
- DartType.INT,
- DartType.DOUBLE,
- DartType.INT,
- DartType.DOUBLE,
- DartType.INT,
- DartType.DOUBLE,
- DartType.INT,
- DartType.DOUBLE,
- DartType.INT,
- DartType.DOUBLE
- ],
- true),
+ DartLib('sumManyNumbers', [
+ DartType.VOID,
+ DartType.INT,
+ DartType.DOUBLE,
+ DartType.INT,
+ DartType.DOUBLE,
+ DartType.INT,
+ DartType.DOUBLE,
+ DartType.INT,
+ DartType.DOUBLE,
+ DartType.INT,
+ DartType.DOUBLE,
+ DartType.INT,
+ DartType.DOUBLE,
+ DartType.INT,
+ DartType.DOUBLE,
+ DartType.INT,
+ DartType.DOUBLE,
+ DartType.INT,
+ DartType.DOUBLE,
+ DartType.INT,
+ DartType.DOUBLE,
+ ], true),
DartLib('inventFloatValue', [DartType.VOID, DartType.VOID], true),
DartLib('smallDouble', [DartType.VOID, DartType.VOID], true),
],
@@ -438,8 +483,16 @@
/// Class that generates a random, but runnable Dart program for fuzz testing.
class DartFuzz {
- DartFuzz(this.seed, this.fp, this.ffi, this.flatTp, this.file,
- {this.minimize = false, this.smask, this.emask});
+ DartFuzz(
+ this.seed,
+ this.fp,
+ this.ffi,
+ this.flatTp,
+ this.file, {
+ this.minimize = false,
+ this.smask,
+ this.emask,
+ });
void run() {
// Initialize program variables.
@@ -459,19 +512,31 @@
globalVars = fillTypes1(limit: numGlobalVars);
globalVars.addAll(dartType.allTypes);
globalMethods = getMethods(
- numGlobalMethods, numMethodParams, MethodType.globalMethod,
- namePrefix: methodName);
+ numGlobalMethods,
+ numMethodParams,
+ MethodType.globalMethod,
+ namePrefix: methodName,
+ );
classFields = fillTypes2(limit2: numClasses, limit1: numLocalVars);
final numClassMethods = 1 + numClasses - classFields.length;
- classMethods = getClassMethods(classFields.length, numClassMethods,
- numMethodParams, fillTypes1(limit: numMethodParams));
+ classMethods = getClassMethods(
+ classFields.length,
+ numClassMethods,
+ numMethodParams,
+ fillTypes1(limit: numMethodParams),
+ );
virtualClassMethods = <Map<int, List<int>>>[];
classParents = <int>[];
// Setup optional ffi methods and types.
if (ffi) {
- globalMethods.addAll(getMethods(
- numGlobalMethods, numMethodParams, MethodType.ffiMethod,
- namePrefix: methodName));
+ globalMethods.addAll(
+ getMethods(
+ numGlobalMethods,
+ numMethodParams,
+ MethodType.ffiMethod,
+ namePrefix: methodName,
+ ),
+ );
}
// Generate.
emitHeader();
@@ -479,9 +544,13 @@
emitMethods(globalMethods);
for (var i = 0; i < numDartTypeExtensions; ++i) {
var type = oneOfSet(dartType.allTypes);
- emitAndAddExtensionMethods(globalMethods, type.name, '${methodName}E$i',
- '$methodName${i}_Extension',
- type: type);
+ emitAndAddExtensionMethods(
+ globalMethods,
+ type.name,
+ '${methodName}E$i',
+ '$methodName${i}_Extension',
+ type: type,
+ );
}
emitClasses();
emitMain();
@@ -494,15 +563,21 @@
assert(localVars.isEmpty);
}
- List<Method> getMethods(int maxMethods, int maxParams, MethodType methodType,
- {String? className,
- String? extensionName,
- String? namePrefix,
- DartType? type}) {
+ List<Method> getMethods(
+ int maxMethods,
+ int maxParams,
+ MethodType methodType, {
+ String? className,
+ String? extensionName,
+ String? namePrefix,
+ DartType? type,
+ }) {
final list = <Method>[];
for (var i = 0, n = chooseOneUpTo(maxMethods); i < n; i++) {
final params = fillTypes1(
- limit: maxParams, isFfi: methodType == MethodType.ffiMethod);
+ limit: maxParams,
+ isFfi: methodType == MethodType.ffiMethod,
+ );
switch (methodType) {
case MethodType.globalMethod:
list.add(GlobalMethod('$namePrefix$i', params, this));
@@ -514,8 +589,16 @@
list.add(InstanceMethod('$namePrefix$i', params, this, className!));
break;
case MethodType.extensionMethod:
- list.add(ExtensionMethod(
- '$namePrefix$i', params, this, className!, extensionName!, type));
+ list.add(
+ ExtensionMethod(
+ '$namePrefix$i',
+ params,
+ this,
+ className!,
+ extensionName!,
+ type,
+ ),
+ );
break;
default:
break;
@@ -524,13 +607,21 @@
return list;
}
- List<List<Method>> getClassMethods(int numClasses, int maxMethods,
- int maxParams, List<DartType> callMethodParams) {
+ List<List<Method>> getClassMethods(
+ int numClasses,
+ int maxMethods,
+ int maxParams,
+ List<DartType> callMethodParams,
+ ) {
final methodsForAllClasses = <List<Method>>[];
for (var i = 0; i < numClasses; i++) {
final methodsForCurrentClass = getMethods(
- maxMethods, maxParams, MethodType.instanceMethod,
- className: 'X$i', namePrefix: '$methodName${i}_');
+ maxMethods,
+ maxParams,
+ MethodType.instanceMethod,
+ className: 'X$i',
+ namePrefix: '$methodName${i}_',
+ );
// Add the call method for the current class. The prototype for the call
// method is pre-decided. This is because we are possibly overriding the
// parent class' call method, in which case the prototype should be the
@@ -566,8 +657,11 @@
void emitZero() => emit('0');
- void emitTryCatchFinally(Function tryBody, Function catchBody,
- {Function? finallyBody}) {
+ void emitTryCatchFinally(
+ Function tryBody,
+ Function catchBody, {
+ Function? finallyBody,
+ }) {
emitLn('try ', newline: false);
emitBraceWrapped(() => tryBody());
emit(' on OutOfMemoryError ');
@@ -582,8 +676,11 @@
}
}
- dynamic emitWrapped(List<String> pair, Function exprEmitter,
- {bool shouldIndent = true}) {
+ dynamic emitWrapped(
+ List<String> pair,
+ Function exprEmitter, {
+ bool shouldIndent = true,
+ }) {
assert(pair.length == 2);
emit(pair[0]);
if (shouldIndent) {
@@ -601,10 +698,15 @@
return result;
}
- dynamic emitParenWrapped(Function exprEmitter,
- {bool includeSemicolon = false}) {
- final result =
- emitWrapped(const ['(', ')'], exprEmitter, shouldIndent: false);
+ dynamic emitParenWrapped(
+ Function exprEmitter, {
+ bool includeSemicolon = false,
+ }) {
+ final result = emitWrapped(
+ const ['(', ')'],
+ exprEmitter,
+ shouldIndent: false,
+ );
if (includeSemicolon) {
emit(';');
}
@@ -617,8 +719,12 @@
dynamic emitSquareBraceWrapped(Function exprEmitter) =>
emitWrapped(const ['[', ']'], exprEmitter, shouldIndent: false);
- dynamic emitCommaSeparated(Function(int) elementBuilder, int length,
- {int start = 0, bool newline = false}) {
+ dynamic emitCommaSeparated(
+ Function(int) elementBuilder,
+ int length, {
+ int start = 0,
+ bool newline = false,
+ }) {
for (var i = start; i < length; ++i) {
elementBuilder(i);
if (i + 1 != length) {
@@ -642,8 +748,10 @@
}
bool emitIfStatement(
- Function ifConditionEmitter, bool Function() ifBodyEmitter,
- {bool Function()? elseBodyEmitter}) {
+ Function ifConditionEmitter,
+ bool Function() ifBodyEmitter, {
+ bool Function()? elseBodyEmitter,
+ }) {
emitLn('if ', newline: false);
emitParenWrapped(ifConditionEmitter);
emit(' ');
@@ -656,12 +764,17 @@
return ifMayFallThrough || elseMayFallThrough;
}
- void emitImport(String library, {String? asName}) => (asName == null)
- ? emitLn("import '$library';")
- : emitLn("import '$library' as $asName;");
+ void emitImport(String library, {String? asName}) =>
+ (asName == null)
+ ? emitLn("import '$library';")
+ : emitLn("import '$library' as $asName;");
- void emitBinaryComparison(Function e1, String op, Function e2,
- {bool includeSemicolon = false}) {
+ void emitBinaryComparison(
+ Function e1,
+ String op,
+ Function e2, {
+ bool includeSemicolon = false,
+ }) {
e1();
emit(' $op ');
e2();
@@ -688,34 +801,80 @@
skipExpr = false;
}
- void emitMinimizedLiteral(DartType tp) {
- switch (tp) {
- case DartType.BOOL:
- emit('true');
- break;
- case DartType.INT:
- emit('1');
- break;
- case DartType.DOUBLE:
- emit('1.0');
- break;
- case DartType.STRING:
- emit('"a"');
- break;
- case DartType.LIST_INT:
- emit('[1]');
- break;
- case DartType.SET_INT:
- emit('{1}');
- break;
- case DartType.MAP_INT_STRING:
- emit('{1: "a"}');
- break;
- default:
- throw 'Unknown DartType $tp';
+ void _emitMinimizedLiteralHelper(StringBuffer sb, DartType tp) {
+ // isListType returns true for types like Uint8List which can't be written
+ // simply with a list notation, so check this before the isListType check.
+ if (tp.hasConstructor(tp)) {
+ final constructorName = tp.constructors(tp).first;
+ if (constructorName.isNotEmpty) {
+ sb.write('${tp.name}.$constructorName');
+ } else {
+ sb.write(tp.name);
+ }
+ sb.write('(');
+ final paramTypes = tp.constructorParameters(tp, constructorName);
+ if (paramTypes.isNotEmpty) {
+ _emitMinimizedLiteralHelper(sb, paramTypes[0]);
+ for (int i = 1; i < paramTypes.length; i++) {
+ sb.write(',');
+ _emitMinimizedLiteralHelper(sb, paramTypes[i]);
+ }
+ }
+ sb.write(')');
+ } else if (DartType.isListType(tp)) {
+ sb.write('[');
+ _emitMinimizedLiteralHelper(sb, tp.elementType(tp));
+ sb.write(']');
+ } else if (DartType.isSetType(tp)) {
+ sb.write('{');
+ _emitMinimizedLiteralHelper(sb, tp.elementType(tp));
+ sb.write('}');
+ } else if (DartType.isMapType(tp)) {
+ sb.write('{');
+ _emitMinimizedLiteralHelper(sb, tp.indexType(tp));
+ sb.write(':');
+ _emitMinimizedLiteralHelper(sb, tp.elementType(tp));
+ sb.write('}');
+ } else {
+ switch (tp.toNonNullable()) {
+ case DartType.ENDIAN:
+ sb.write('Endian.little');
+ break;
+ case DartType.NUM:
+ if (coinFlip()) {
+ _emitMinimizedLiteralHelper(sb, DartType.INT);
+ } else {
+ _emitMinimizedLiteralHelper(sb, DartType.DOUBLE);
+ }
+ break;
+ case DartType.BOOL:
+ sb.write('true');
+ break;
+ case DartType.INT:
+ sb.write('1');
+ break;
+ case DartType.DOUBLE:
+ sb.write('1.0');
+ break;
+ case DartType.STRING:
+ sb.write('"a"');
+ break;
+ default:
+ if (!tp.isNullable) {
+ throw 'Unknown DartType $tp';
+ }
+ // Only fall back to null if an non-null element cannot be generated.
+ sb.write('null');
+ }
}
}
+ void emitMinimizedLiteral(DartType tp) {
+ final sb = StringBuffer();
+ _emitMinimizedLiteralHelper(sb, tp);
+ emit(sb.toString());
+ }
+
// Process the opening of a statement.
// Determine whether the statement should be skipped based on the
// statement index stored in stmtCntr and the statement mask stored
@@ -811,8 +970,10 @@
void emitHeader() {
emitLn('// The Dart Project Fuzz Tester ($version).');
emitLn('// Program generated as:');
- emitLn('// dart dartfuzz.dart --seed $seed --${fp ? "" : "no-"}fp '
- '--${ffi ? "" : "no-"}ffi --${flatTp ? "" : "no-"}flat');
+ emitLn(
+ '// dart dartfuzz.dart --seed $seed --${fp ? "" : "no-"}fp '
+ '--${ffi ? "" : "no-"}ffi --${flatTp ? "" : "no-"}flat',
+ );
emitLn('// @dart=2.14');
emitNewline();
emitImport('dart:async');
@@ -831,12 +992,20 @@
emitNewline();
}
- void emitFfiCast(String dartFuncName, String ffiFuncName, String typeName,
- List<DartType> pars) {
+ void emitFfiCast(
+ String dartFuncName,
+ String ffiFuncName,
+ String typeName,
+ List<DartType> pars,
+ ) {
emit('${pars[0].name} Function');
- emitParenWrapped(() => emitCommaSeparated(
- (int i) => emit('${pars[i].name}'), pars.length,
- start: 1));
+ emitParenWrapped(
+ () => emitCommaSeparated(
+ (int i) => emit('${pars[i].name}'),
+ pars.length,
+ start: 1,
+ ),
+ );
emit(' $dartFuncName = ffi.Pointer.fromFunction<$typeName>');
emitParenWrapped(() {
emit('$ffiFuncName, ');
@@ -924,25 +1093,35 @@
emitNewline();
emitNewline();
emitAndAddExtensionMethods(
- classMethods[currentClassIndex!],
- 'X$currentClassIndex',
- 'XE$currentClassIndex',
- '$methodName${currentClassIndex}_Extension');
+ classMethods[currentClassIndex!],
+ 'X$currentClassIndex',
+ 'XE$currentClassIndex',
+ '$methodName${currentClassIndex}_Extension',
+ );
currentClassIndex = null;
}
}
void emitAndAddExtensionMethods(
- List<Method> methodList, className, extensionName, namePrefix,
- {DartType? type}) {
+ List<Method> methodList,
+ className,
+ extensionName,
+ namePrefix, {
+ DartType? type,
+ }) {
var endIndex = methodList.length;
- methodList.addAll(getMethods(numExtensionMethodsPerClass, numMethodParams,
+ methodList.addAll(
+ getMethods(
+ numExtensionMethodsPerClass,
+ numMethodParams,
MethodType.extensionMethod,
className: className,
// Randomly select between named and anonymous extensions.
extensionName: coinFlip() ? extensionName : '',
namePrefix: namePrefix,
- type: type));
+ type: type,
+ ),
+ );
emit('extension $extensionName on $className ');
emitBraceWrapped(() {
// Emit the newly added methods.
@@ -960,74 +1139,93 @@
void emitLoadFfiLib() {
if (ffi) {
- emitLn('// The following throws an uncaught exception if the ffi library '
- 'is not found.');
- emitLn('// By not catching this exception, we terminate the program with '
- 'a full stack trace');
+ emitLn(
+ '// The following throws an uncaught exception if the ffi library '
+ 'is not found.',
+ );
+ emitLn(
+ '// By not catching this exception, we terminate the program with '
+ 'a full stack trace',
+ );
emitLn('// which, in turn, flags the problem prominently');
- emitIfStatement(() => emit('ffiTestFunctions == null'),
- () => emitPrint('Did not load ffi test functions'));
+ emitIfStatement(
+ () => emit('ffiTestFunctions == null'),
+ () => emitPrint('Did not load ffi test functions'),
+ );
emitNewline();
}
}
void emitMain() => emitFunctionDefinition('main', () {
- emitLoadFfiLib();
+ emitLoadFfiLib();
- // Call each global method once.
- for (var i = 0; i < globalMethods.length; i++) {
- late String outputName;
- emitTryCatchFinally(
- () => outputName =
- globalMethods[i].emitCall(1, includeSemicolon: true),
- () => emitPrint('${outputName}() throws'));
- emitNewline();
- }
+ // Call each global method once.
+ for (var i = 0; i < globalMethods.length; i++) {
+ late String outputName;
+ emitTryCatchFinally(
+ () => outputName = globalMethods[i].emitCall(1, includeSemicolon: true),
+ () => emitPrint('${outputName}() throws'),
+ );
+ emitNewline();
+ }
- // Call each class method once.
- for (var i = 0; i < classMethods.length; i++) {
- for (var j = 0; j < classMethods[i].length; j++) {
+ // Call each class method once.
+ for (var i = 0; i < classMethods.length; i++) {
+ for (var j = 0; j < classMethods[i].length; j++) {
+ late String outputName;
+ emitNewline();
+ emitTryCatchFinally(
+ () =>
+ outputName = classMethods[i][j].emitCall(
+ 1,
+ includeSemicolon: true,
+ ),
+ () => emitPrint('$outputName throws'),
+ );
+ }
+ // Call each virtual class method once.
+ var parentClass = classParents[i];
+ while (parentClass >= 0) {
+ if (virtualClassMethods[i].containsKey(parentClass)) {
+ for (
+ var j = 0;
+ j < virtualClassMethods[i][parentClass]!.length;
+ j++
+ ) {
late String outputName;
emitNewline();
emitTryCatchFinally(
- () => outputName =
- classMethods[i][j].emitCall(1, includeSemicolon: true),
- () => emitPrint('$outputName throws'));
- }
- // Call each virtual class method once.
- var parentClass = classParents[i];
- while (parentClass >= 0) {
- if (virtualClassMethods[i].containsKey(parentClass)) {
- for (var j = 0;
- j < virtualClassMethods[i][parentClass]!.length;
- j++) {
- late String outputName;
- emitNewline();
- emitTryCatchFinally(
- () => outputName = classMethods[parentClass][j]
- .emitCall(1, includeSemicolon: true),
- () => emitPrint('$outputName throws'));
- }
- }
- parentClass = classParents[parentClass];
+ () =>
+ outputName = classMethods[parentClass][j].emitCall(
+ 1,
+ includeSemicolon: true,
+ ),
+ () => emitPrint('$outputName throws'),
+ );
}
}
+ parentClass = classParents[parentClass];
+ }
+ }
- emitNewline();
- emitTryCatchFinally(() {
- emitLn('X${classFields.length - 1}().run();', newline: false);
- }, () {
- emitPrint('X${classFields.length - 1}().run() throws');
- });
+ emitNewline();
+ emitTryCatchFinally(
+ () {
+ emitLn('X${classFields.length - 1}().run();', newline: false);
+ },
+ () {
+ emitPrint('X${classFields.length - 1}().run() throws');
+ },
+ );
+ emitNewline();
+ emitTryCatchFinally(() {
+ for (var i = 0; i < globalVars.length; i++) {
+ emitPrint('$varName$i: \$$varName$i');
emitNewline();
- emitTryCatchFinally(() {
- for (var i = 0; i < globalVars.length; i++) {
- emitPrint('$varName$i: \$$varName$i');
- emitNewline();
- }
- }, () => emitPrint('print() throws'));
- });
+ }
+ }, () => emitPrint('print() throws'));
+ });
//
// Declarations.
@@ -1037,17 +1235,23 @@
for (var i = 0; i < vars.length; i++) {
var tp = vars[i];
final varName = '$name$i';
- emitVariableDeclaration(varName, tp,
- initializerEmitter: () => emitConstructorOrLiteral(0, tp));
+ emitVariableDeclaration(
+ varName,
+ tp,
+ initializerEmitter: () => emitConstructorOrLiteral(0, tp),
+ );
}
emitNewline();
}
- void emitVariableDeclaration(String name, DartType tp,
- {Function? initializerEmitter,
- bool indent = true,
- bool newline = true,
- bool includeSemicolon = true}) {
+ void emitVariableDeclaration(
+ String name,
+ DartType tp, {
+ Function? initializerEmitter,
+ bool indent = true,
+ bool newline = true,
+ bool includeSemicolon = true,
+ }) {
final typeName = tp.dartName;
if (indent) {
emitIndentation();
@@ -1062,10 +1266,14 @@
}
}
- void emitParDecls(List<DartType> pars) => emitCommaSeparated((int i) {
- var tp = pars[i];
- emit('${tp.dartName} $paramName$i');
- }, pars.length, start: 1);
+ void emitParDecls(List<DartType> pars) => emitCommaSeparated(
+ (int i) {
+ var tp = pars[i];
+ emit('${tp.dartName} $paramName$i');
+ },
+ pars.length,
+ start: 1,
+ );
//
// Comments (for FE and analysis tools).
@@ -1171,12 +1379,16 @@
// Emit a one-way if statement.
bool emitIf1(int depth) => emitIfStatement(
- () => emitExpr(0, DartType.BOOL), () => emitStatements(depth + 1));
+ () => emitExpr(0, DartType.BOOL),
+ () => emitStatements(depth + 1),
+ );
// Emit a two-way if statement.
bool emitIf2(int depth) => emitIfStatement(
- () => emitExpr(0, DartType.BOOL), () => emitStatements(depth + 1),
- elseBodyEmitter: () => emitStatements(depth + 1));
+ () => emitExpr(0, DartType.BOOL),
+ () => emitStatements(depth + 1),
+ elseBodyEmitter: () => emitStatements(depth + 1),
+ );
// Emit a simple increasing for-loop.
bool emitFor(int depth) {
@@ -1188,10 +1400,19 @@
emitLn('for ', newline: false);
emitParenWrapped(() {
final name = '$localName$i';
- emitVariableDeclaration(name, DartType.INT,
- initializerEmitter: emitZero, newline: false, indent: false);
- emitBinaryComparison(() => emit(name), '<', emitSmallPositiveInt,
- includeSemicolon: true);
+ emitVariableDeclaration(
+ name,
+ DartType.INT,
+ initializerEmitter: emitZero,
+ newline: false,
+ indent: false,
+ );
+ emitBinaryComparison(
+ () => emit(name),
+ '<',
+ emitSmallPositiveInt,
+ includeSemicolon: true,
+ );
emit('$name++');
});
emitBraceWrapped(() {
@@ -1284,11 +1505,15 @@
emitIndentation();
emitBraceWrapped(() {
final name = '$localName$i';
- emitVariableDeclaration(name, DartType.INT,
- initializerEmitter: () => emitSmallPositiveInt());
+ emitVariableDeclaration(
+ name,
+ DartType.INT,
+ initializerEmitter: () => emitSmallPositiveInt(),
+ );
emitLn('while ', newline: false);
emitParenWrapped(
- () => emitBinaryComparison(() => emit('--$name'), '>', emitZero));
+ () => emitBinaryComparison(() => emit('--$name'), '>', emitZero),
+ );
emitBraceWrapped(() {
nest++;
iterVars.add(name);
@@ -1325,9 +1550,13 @@
});
emit(' while ');
emitParenWrapped(
- () => emitBinaryComparison(
- () => emit('++$name'), '<', emitSmallPositiveInt),
- includeSemicolon: true);
+ () => emitBinaryComparison(
+ () => emit('++$name'),
+ '<',
+ emitSmallPositiveInt,
+ ),
+ includeSemicolon: true,
+ );
});
emitNewline();
return true;
@@ -1359,8 +1588,10 @@
emitBraceWrapped(() {
bodyEmitter();
emitNewline();
- emitLn('break;',
- newline: false); // always generate, avoid FE complaints
+ emitLn(
+ 'break;',
+ newline: false,
+ ); // always generate, avoid FE complaints
});
}
@@ -1371,8 +1602,10 @@
var step = chooseOneUpTo(10);
final maxCases = 3;
for (var i = 0; i < maxCases; i++, start += step) {
- emitCase(() => emitStatement(depth + 1),
- kase: (i == 2 && coinFlip()) ? null : start);
+ emitCase(
+ () => emitStatement(depth + 1),
+ kase: (i == 2 && coinFlip()) ? null : start,
+ );
if (i + 1 != maxCases) {
emitNewline();
}
@@ -1388,11 +1621,15 @@
var tp = oneOfSet(dartType.allTypes);
final i = localVars.length;
final name = '$localName$i';
- emitVariableDeclaration(name, tp, initializerEmitter: () {
- localVars.add(null); // declared, but don't use
- emitExpr(0, tp);
- localVars.removeLast(); // will get type
- });
+ emitVariableDeclaration(
+ name,
+ tp,
+ initializerEmitter: () {
+ localVars.add(null); // declared, but don't use
+ emitExpr(0, tp);
+ localVars.removeLast(); // will get type
+ },
+ );
localVars.add(tp);
emitStatements(depth + 1);
localVars.removeLast();
@@ -1562,8 +1799,12 @@
emit("'");
}
- void emitElementExpr(int depth, DartType tp,
- {RhsFilter? rhsFilter, bool isConst = false}) {
+ void emitElementExpr(
+ int depth,
+ DartType tp, {
+ RhsFilter? rhsFilter,
+ bool isConst = false,
+ }) {
// Inside a constant collection, keep collection elements constants too.
if (isConst) {
if (DartType.isCollectionType(tp)) {
@@ -1579,8 +1820,12 @@
}
}
- void emitElement(int depth, DartType tp,
- {RhsFilter? rhsFilter, bool isConst = false}) {
+ void emitElement(
+ int depth,
+ DartType tp, {
+ RhsFilter? rhsFilter,
+ bool isConst = false,
+ }) {
// Get the element type contained in type tp.
// E.g. element type of List<String> is String.
final elementType = dartType.elementType(tp);
@@ -1592,12 +1837,20 @@
emitElementExpr(depth, indexType, rhsFilter: rhsFilter, isConst: isConst);
emit(' : ');
// Emit construct for the map value type.
- emitElementExpr(depth, elementType,
- rhsFilter: rhsFilter, isConst: isConst);
+ emitElementExpr(
+ depth,
+ elementType,
+ rhsFilter: rhsFilter,
+ isConst: isConst,
+ );
} else {
// List and Set types.
- emitElementExpr(depth, elementType,
- rhsFilter: rhsFilter, isConst: isConst);
+ emitElementExpr(
+ depth,
+ elementType,
+ rhsFilter: rhsFilter,
+ isConst: isConst,
+ );
}
}
@@ -1605,8 +1858,11 @@
var r = (depth <= exprDepth) ? choose(10) : 10;
// TODO (felih): disable complex collection constructs for new types for
// now.
- if (!{DartType.MAP_INT_STRING, DartType.LIST_INT, DartType.SET_INT}
- .contains(tp)) {
+ if (!{
+ DartType.MAP_INT_STRING,
+ DartType.LIST_INT,
+ DartType.SET_INT,
+ }.contains(tp)) {
emitElement(depth, tp, rhsFilter: rhsFilter);
return;
}
@@ -1618,8 +1874,9 @@
break;
case 1:
emitLn('if ', newline: false);
- emitParenWrapped(() =>
- emitElementExpr(depth + 1, DartType.BOOL, rhsFilter: rhsFilter));
+ emitParenWrapped(
+ () => emitElementExpr(depth + 1, DartType.BOOL, rhsFilter: rhsFilter),
+ );
emitCollectionElement(depth + 1, tp, rhsFilter: rhsFilter);
if (coinFlip()) {
emitNewline();
@@ -1640,26 +1897,47 @@
localVars.add(null); // declared, but don't use
switch (choose(3)) {
case 0:
- emitVariableDeclaration(local, DartType.INT,
- initializerEmitter: emitZero, indent: false);
- emitBinaryComparison(() => emit(local), '<',
- () => emitSmallPositiveInt(limit: 16),
- includeSemicolon: true);
+ emitVariableDeclaration(
+ local,
+ DartType.INT,
+ initializerEmitter: emitZero,
+ indent: false,
+ );
+ emitBinaryComparison(
+ () => emit(local),
+ '<',
+ () => emitSmallPositiveInt(limit: 16),
+ includeSemicolon: true,
+ );
emit('$local++');
break;
case 1:
- emitVariableDeclaration(local, DartType.INT,
- includeSemicolon: false, indent: false);
+ emitVariableDeclaration(
+ local,
+ DartType.INT,
+ includeSemicolon: false,
+ indent: false,
+ );
emit(' in ');
- emitCollection(depth + 1, DartType.LIST_INT,
- rhsFilter: rhsFilter);
+ emitCollection(
+ depth + 1,
+ DartType.LIST_INT,
+ rhsFilter: rhsFilter,
+ );
break;
default:
- emitVariableDeclaration(local, DartType.INT,
- includeSemicolon: false, indent: false);
+ emitVariableDeclaration(
+ local,
+ DartType.INT,
+ includeSemicolon: false,
+ indent: false,
+ );
emit(' in ');
- emitCollection(depth + 1, DartType.SET_INT,
- rhsFilter: rhsFilter);
+ emitCollection(
+ depth + 1,
+ DartType.SET_INT,
+ rhsFilter: rhsFilter,
+ );
break;
}
localVars.removeLast(); // will get type
@@ -1701,9 +1979,10 @@
// Collection length decreases as depth increases.
var collectionLength = max(1, 8 - depth);
emitCommaSeparated(
- (int _) => emitCollectionElement(depth, tp, rhsFilter: rhsFilter),
- chooseOneUpTo(collectionLength),
- newline: DartType.isMapType(tp));
+ (int _) => emitCollectionElement(depth, tp, rhsFilter: rhsFilter),
+ chooseOneUpTo(collectionLength),
+ newline: DartType.isMapType(tp),
+ );
}, shouldIndent: DartType.isMapType(tp));
}
@@ -1719,14 +1998,16 @@
var elementType = dartType.elementType(tp);
l = 'const <${elementType.dartName}>{';
r = '}';
- canHaveElements = (elementType != DartType.DOUBLE) &&
+ canHaveElements =
+ (elementType != DartType.DOUBLE) &&
(elementType != DartType.DOUBLE_NULLABLE);
} else if (DartType.isMapType(tp)) {
var indexType = dartType.indexType(tp);
var elementType = dartType.elementType(tp);
l = 'const <${indexType.dartName},${elementType.dartName}>{';
r = '}';
- canHaveElements = (indexType != DartType.DOUBLE) &&
+ canHaveElements =
+ (indexType != DartType.DOUBLE) &&
(indexType != DartType.DOUBLE_NULLABLE);
} else {
throw "Unrecognized collection type $tp";
@@ -1739,13 +2020,19 @@
emit(r);
return;
}
- emitWrapped([l, r],
- () => emitElement(depth, tp, rhsFilter: rhsFilter, isConst: true),
- shouldIndent: DartType.isMapType(tp));
+ emitWrapped(
+ [l, r],
+ () => emitElement(depth, tp, rhsFilter: rhsFilter, isConst: true),
+ shouldIndent: DartType.isMapType(tp),
+ );
}
- void emitLiteral(int depth, DartType tp,
- {bool smallPositiveValue = false, RhsFilter? rhsFilter}) {
+ void emitLiteral(
+ int depth,
+ DartType tp, {
+ bool smallPositiveValue = false,
+ RhsFilter? rhsFilter,
+ }) {
if (tp.isNullable) {
if (choose(20) == 0) {
emitNull();
@@ -1793,8 +2080,12 @@
// Emit a constructor for a type, this can either be a trivial constructor
// (i.e. parsed from a literal) or an actual function invocation.
- void emitConstructorOrLiteral(int depth, DartType tp,
- {RhsFilter? rhsFilter, bool includeSemicolon = false}) {
+ void emitConstructorOrLiteral(
+ int depth,
+ DartType tp, {
+ RhsFilter? rhsFilter,
+ bool includeSemicolon = false,
+ }) {
// If there is at least one non trivial constructor for the type tp
// select one of these constructors.
if (dartType.hasConstructor(tp)) {
@@ -1812,14 +2103,20 @@
}
emitParenWrapped(() {
// Iterate over constructor parameters.
- var constructorParameters =
- dartType.constructorParameters(tp, constructor);
+ var constructorParameters = dartType.constructorParameters(
+ tp,
+ constructor,
+ );
emitCommaSeparated((int i) {
// If we are emitting a constructor parameter, we want to use small
// values to avoid programs that run out of memory.
// TODO (felih): maybe allow occasionally?
- emitLiteral(depth + 1, constructorParameters[i],
- smallPositiveValue: true, rhsFilter: rhsFilter);
+ emitLiteral(
+ depth + 1,
+ constructorParameters[i],
+ smallPositiveValue: true,
+ rhsFilter: rhsFilter,
+ );
}, constructorParameters.length);
});
} else {
@@ -1832,8 +2129,11 @@
}
// Pick an existing variable of the given type.
- String? pickScalarVar(DartType tp,
- {bool isLhs = false, RhsFilter? rhsFilter}) {
+ String? pickScalarVar(
+ DartType tp, {
+ bool isLhs = false,
+ RhsFilter? rhsFilter,
+ }) {
// Randomly specialize interface type, unless emitting left hand side.
if (!isLhs) tp = maybeSpecializeInterface(tp);
// Collect all choices from globals, fields, locals, and parameters.
@@ -1895,8 +2195,11 @@
return '${choices.elementAt(choose(choices.length))}';
}
- String? emitScalarVar(DartType tp,
- {bool isLhs = false, RhsFilter? rhsFilter}) {
+ String? emitScalarVar(
+ DartType tp, {
+ bool isLhs = false,
+ RhsFilter? rhsFilter,
+ }) {
final emittedVar = pickScalarVar(tp, isLhs: isLhs, rhsFilter: rhsFilter);
if (emittedVar != null) {
if (rhsFilter != null && (emittedVar == rhsFilter.lhsVar)) {
@@ -1907,8 +2210,13 @@
return emittedVar;
}
- String? emitSubscriptedVar(int depth, DartType tp,
- {bool isLhs = false, String? assignOp, RhsFilter? rhsFilter}) {
+ String? emitSubscriptedVar(
+ int depth,
+ DartType tp, {
+ bool isLhs = false,
+ String? assignOp,
+ RhsFilter? rhsFilter,
+ }) {
String? ret;
// Check if type tp is an indexable element of some other type.
if (dartType.isIndexableElementType(tp)) {
@@ -1926,33 +2234,48 @@
final indexType = dartType.indexType(iterType);
// Emit a variable of the selected list or map type.
ret = emitScalarVar(iterType, isLhs: isLhs, rhsFilter: rhsFilter);
- emitSquareBraceWrapped(() =>
- // Emit an expression resolving into the index type. For
- // collection type, only constant collections are used
- // to avoid rehashing the same value into many entries.
- DartType.isCollectionType(indexType)
- ? emitConstCollection(depth + 1, indexType)
- : emitExpr(depth + 1, indexType));
+ emitSquareBraceWrapped(
+ () =>
+ // Emit an expression resolving into the index type. For
+ // collection type, only constant collections are used
+ // to avoid rehashing the same value into many entries.
+ DartType.isCollectionType(indexType)
+ ? emitConstCollection(depth + 1, indexType)
+ : emitExpr(depth + 1, indexType),
+ );
// Map.[] and Expando.[] have a nullable result, but we should not write
// map[key]! = value.
if (!tp.isNullable && !isLhs) {
emit('!');
}
} else {
- ret = emitScalarVar(tp,
- isLhs: isLhs, rhsFilter: rhsFilter); // resort to scalar
+ ret = emitScalarVar(
+ tp,
+ isLhs: isLhs,
+ rhsFilter: rhsFilter,
+ ); // resort to scalar
}
return ret;
}
- String? emitVar(int depth, DartType tp,
- {bool isLhs = false, String? assignOp, RhsFilter? rhsFilter}) {
+ String? emitVar(
+ int depth,
+ DartType tp, {
+ bool isLhs = false,
+ String? assignOp,
+ RhsFilter? rhsFilter,
+ }) {
switch (choose(2)) {
case 0:
return emitScalarVar(tp, isLhs: isLhs, rhsFilter: rhsFilter);
default:
- return emitSubscriptedVar(depth, tp,
- isLhs: isLhs, assignOp: assignOp, rhsFilter: rhsFilter);
+ return emitSubscriptedVar(
+ depth,
+ tp,
+ isLhs: isLhs,
+ assignOp: assignOp,
+ rhsFilter: rhsFilter,
+ );
}
}
@@ -1976,7 +2299,8 @@
emit(oneOfSet(dartType.uniOps(tp)));
var uniOpParam = tp.toNonNullable();
emitParenWrapped(
- () => emitExpr(depth + 1, uniOpParam, rhsFilter: rhsFilter));
+ () => emitExpr(depth + 1, uniOpParam, rhsFilter: rhsFilter),
+ );
});
}
@@ -2059,8 +2383,12 @@
}
// Emit library call.
- void emitLibraryCall(int depth, DartType tp,
- {RhsFilter? rhsFilter, bool includeSemicolon = false}) {
+ void emitLibraryCall(
+ int depth,
+ DartType tp, {
+ RhsFilter? rhsFilter,
+ bool includeSemicolon = false,
+ }) {
var lib = getLibraryMethod(tp);
if (lib == null || (!fp && isTypedDataFloatType(lib.proto))) {
// We cannot find a library method, or we found a library method but its
@@ -2074,9 +2402,14 @@
var prototype = lib.proto;
// Receiver.
if (prototype[0] != DartType.VOID) {
- emitParenWrapped(() => emitArg(
- depth + 1, prototype[0], lib.getRestriction(0),
- rhsFilter: rhsFilter));
+ emitParenWrapped(
+ () => emitArg(
+ depth + 1,
+ prototype[0],
+ lib.getRestriction(0),
+ rhsFilter: rhsFilter,
+ ),
+ );
emit('.');
}
// Call.
@@ -2086,11 +2419,15 @@
emitParenWrapped(() {
if (prototype[1] != DartType.VOID) {
emitCommaSeparated(
- (int i) => emitArg(
- depth + 1, prototype[i], lib.getRestriction(i),
- rhsFilter: rhsFilter),
- prototype.length,
- start: 1);
+ (int i) => emitArg(
+ depth + 1,
+ prototype[i],
+ lib.getRestriction(i),
+ rhsFilter: rhsFilter,
+ ),
+ prototype.length,
+ start: 1,
+ );
}
});
}
@@ -2105,16 +2442,24 @@
}
// Helper for a method call.
- bool pickedCall(int depth, DartType tp, List<Method> methods, int m,
- {RhsFilter? rhsFilter}) {
+ bool pickedCall(
+ int depth,
+ DartType tp,
+ List<Method> methods,
+ int m, {
+ RhsFilter? rhsFilter,
+ }) {
for (var i = m - 1; i >= 0; i--) {
if (tp == methods[i].returnType) {
var isRecursiveCall = (currentMethod == methods[i]);
if (isRecursiveCall && !methods[i].recursionAllowed) {
continue;
}
- methods[i].emitCall(depth + 1,
- rhsFilter: rhsFilter, isRecursiveCall: isRecursiveCall);
+ methods[i].emitCall(
+ depth + 1,
+ rhsFilter: rhsFilter,
+ isRecursiveCall: isRecursiveCall,
+ );
return true;
}
}
@@ -2127,8 +2472,13 @@
if (currentClassIndex == null) {
// Outside a class but inside a method: call backward in global methods.
if (currentMethodIndex != null &&
- pickedCall(depth, tp, globalMethods, currentMethodIndex! + 1,
- rhsFilter: rhsFilter)) {
+ pickedCall(
+ depth,
+ tp,
+ globalMethods,
+ currentMethodIndex! + 1,
+ rhsFilter: rhsFilter,
+ )) {
return;
}
} else {
@@ -2155,8 +2505,13 @@
m1 = currentMethodIndex! + 1;
}
final m2 = globalMethods.length;
- if (pickedCall(depth, tp, classMethods[classIndex], m1,
- rhsFilter: rhsFilter) ||
+ if (pickedCall(
+ depth,
+ tp,
+ classMethods[classIndex],
+ m1,
+ rhsFilter: rhsFilter,
+ ) ||
pickedCall(depth, tp, globalMethods, m2, rhsFilter: rhsFilter)) {
return;
}
@@ -2165,8 +2520,12 @@
}
// Emit expression.
- void emitExpr(int depth, DartType tp,
- {RhsFilter? rhsFilter, bool includeSemicolon = false}) {
+ void emitExpr(
+ int depth,
+ DartType tp, {
+ RhsFilter? rhsFilter,
+ bool includeSemicolon = false,
+ }) {
final resetExprStmt = processExprOpen(tp);
// Continuing nested expressions becomes less likely as the depth grows.
if (choose(depth + 1) > exprDepth) {
@@ -2187,8 +2546,11 @@
emitPreOrPostExpr(depth, tp, rhsFilter: rhsFilter);
break;
case 4:
- emitLibraryCall(depth, tp,
- rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
+ emitLibraryCall(
+ depth,
+ tp,
+ rhsFilter: RhsFilter.cloneEmpty(rhsFilter),
+ );
break;
case 5:
emitMethodCall(depth, tp, rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
@@ -2234,8 +2596,12 @@
: null;
// Emit a library argument, possibly subject to restrictions.
- void emitArg(int depth, DartType type, Restriction restriction,
- {RhsFilter? rhsFilter}) {
+ void emitArg(
+ int depth,
+ DartType type,
+ Restriction restriction, {
+ RhsFilter? rhsFilter,
+ }) {
if ((type == DartType.INT) && (restriction == Restriction.small)) {
emitSmallPositiveInt();
} else if ((type == DartType.DOUBLE) && !fp) {
@@ -2265,8 +2631,11 @@
return list;
}
- List<List<DartType>> fillTypes2(
- {bool isFfi = false, int limit2 = 4, int limit1 = 4}) {
+ List<List<DartType>> fillTypes2({
+ bool isFfi = false,
+ int limit2 = 4,
+ int limit1 = 4,
+ }) {
final list = <List<DartType>>[];
for (var i = 0, n = chooseOneUpTo(limit2); i < n; i++) {
list.add(fillTypes1(limit: limit1, isFfi: isFfi));
@@ -2294,8 +2663,14 @@
void emitFfiType(DartType tp) {
if (tp == DartType.INT) {
- emit(oneOf(
- const <String>['ffi.Int8', 'ffi.Int16', 'ffi.Int32', 'ffi.Int64']));
+ emit(
+ oneOf(const <String>[
+ 'ffi.Int8',
+ 'ffi.Int16',
+ 'ffi.Int32',
+ 'ffi.Int64',
+ ]),
+ );
} else if (tp == DartType.DOUBLE) {
emit(oneOf(const <String>['ffi.Float', 'ffi.Double']));
} else {
@@ -2309,9 +2684,13 @@
emitFfiType(pars[0]);
emit(' Function');
emitParenWrapped(
- () => emitCommaSeparated((int i) => emitFfiType(pars[i]), pars.length,
- start: 1),
- includeSemicolon: true);
+ () => emitCommaSeparated(
+ (int i) => emitFfiType(pars[i]),
+ pars.length,
+ start: 1,
+ ),
+ includeSemicolon: true,
+ );
emitNewline();
emitNewline();
}
@@ -2459,7 +2838,7 @@
0xffffffff7fffffff,
0xffffffff80000000,
0xffffffff80000001,
- 0xffffffffffffffff
+ 0xffffffffffffffff,
];
}
@@ -2486,25 +2865,48 @@
const kMini = 'mini';
const kSMask = 'smask';
const kEMask = 'emask';
- final parser = ArgParser()
- ..addOption(kSeed,
- help: 'random seed (0 forces time-based seed)', defaultsTo: '0')
- ..addFlag(kFp, help: 'enables floating-point operations', defaultsTo: true)
- ..addFlag(kFfi,
- help: 'enables FFI method calls (default: off)', defaultsTo: false)
- ..addFlag(kFlat,
- help: 'enables flat types (default: off)', defaultsTo: false)
- // Minimization mode extensions.
- ..addFlag(kMini,
- help: 'enables minimization mode (default: off)', defaultsTo: false)
- ..addOption(kSMask,
- help: 'Bitmask indicating which statements to omit'
- '(Bit=1 omits)',
- defaultsTo: '0')
- ..addOption(kEMask,
- help: 'Bitmask indicating which expressions to omit'
- '(Bit=1 omits)',
- defaultsTo: '0');
+ final parser =
+ ArgParser()
+ ..addOption(
+ kSeed,
+ help: 'random seed (0 forces time-based seed)',
+ defaultsTo: '0',
+ )
+ ..addFlag(
+ kFp,
+ help: 'enables floating-point operations',
+ defaultsTo: true,
+ )
+ ..addFlag(
+ kFfi,
+ help: 'enables FFI method calls (default: off)',
+ defaultsTo: false,
+ )
+ ..addFlag(
+ kFlat,
+ help: 'enables flat types (default: off)',
+ defaultsTo: false,
+ )
+ // Minimization mode extensions.
+ ..addFlag(
+ kMini,
+ help: 'enables minimization mode (default: off)',
+ defaultsTo: false,
+ )
+ ..addOption(
+ kSMask,
+ help:
+ 'Bitmask indicating which statements to omit'
+ '(Bit=1 omits)',
+ defaultsTo: '0',
+ )
+ ..addOption(
+ kEMask,
+ help:
+ 'Bitmask indicating which expressions to omit'
+ '(Bit=1 omits)',
+ defaultsTo: '0',
+ );
final ArgResults results;
try {
results = parser.parse(arguments);
@@ -2521,8 +2923,16 @@
final minimize = results[kMini];
final smask = BigInt.parse(results[kSMask]);
final emask = BigInt.parse(results[kEMask]);
- final dartFuzz = DartFuzz(seed, fp, ffi, flatTp, file,
- minimize: minimize, smask: smask, emask: emask);
+ final dartFuzz = DartFuzz(
+ seed,
+ fp,
+ ffi,
+ flatTp,
+ file,
+ minimize: minimize,
+ smask: smask,
+ emask: emask,
+ );
dartFuzz.run();
file.closeSync();
// Print information that will be parsed by minimize.py
diff --git a/runtime/tools/dartfuzz/minimize.py b/runtime/tools/dartfuzz/minimize.py
index c9be86a..a54e440 100755
--- a/runtime/tools/dartfuzz/minimize.py
+++ b/runtime/tools/dartfuzz/minimize.py
@@ -139,7 +139,7 @@
p = subprocess.Popen(cmds, stdout=subprocess.PIPE)
p_stdout, p_stderr = p.communicate()
if p.returncode != 0:
- raise 'Invalid return code on generate %d' % p.returncode
+ raise RuntimeError('Invalid return code on generate %d' % p.returncode)
mask_new = 0
if do_expr:
mask_new = int(p_stdout.decode().splitlines()[EXPRESSION_MASK_LINE])