<commit_before>// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:io';
import 'dart:math';

import 'package:args/args.dart';

import 'dartfuzz_api_table.dart';
import 'dartfuzz_values.dart';

// Version of DartFuzz. Increase this each time changes are made
// to preserve the property that a given version of DartFuzz yields
// the same fuzzed program for a deterministic random seed.
const String version = '1.25';

// Restriction on statements and expressions.
const int stmtLength = 2;
const int stmtDepth = 1;
const int exprDepth = 2;

// Naming conventions.
const varName = 'var';
const paramName = 'par';
const localName = 'loc';
const fieldName = 'fld';
const methodName = 'foo';

/// Class that generates a random, but runnable Dart program for fuzz testing.
class DartFuzz {
  DartFuzz(this.seed, this.fp, this.ffi, this.file);

  void run() {
    // Initialize program variables.
    rand = Random(seed);
    indent = 0;
    nest = 0;
    currentClass = null;
    currentMethod = null;
    // Setup the types.
    localVars = <DartType>[];
    iterVars = <String>[];
    globalVars = fillTypes1();
    globalVars.addAll(DartType.allTypes); // always one each
    globalMethods = fillTypes2();
    classFields = fillTypes2();
    classMethods = fillTypes3(classFields.length);
    classParents = <int>[];
    // Setup optional ffi methods and types.
    final ffiStatus = <bool>[for (final _ in globalMethods) false];
    if (ffi) {
      List<List<DartType>> globalMethodsFfi = fillTypes2(isFfi: true);
      for (var m in globalMethodsFfi) {
        globalMethods.add(m);
        ffiStatus.add(true);
      }
    }
    // Generate.
    emitHeader();
    emitVarDecls(varName, globalVars);
    emitMethods(methodName, globalMethods, ffiStatus);
    emitClasses();
    emitMain();
    // Sanity.
    assert(currentClass == null);
    assert(currentMethod == null);
    assert(indent == 0);
    assert(nest == 0);
    assert(localVars.isEmpty);
  }

  //
  // Program components.
  //

  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');
    emitLn('');
    emitLn("import 'dart:async';");
    emitLn("import 'dart:cli';");
    emitLn("import 'dart:collection';");
    emitLn("import 'dart:convert';");
    emitLn("import 'dart:core';");
    emitLn("import 'dart:io';");
    emitLn("import 'dart:isolate';");
    emitLn("import 'dart:math';");
    emitLn("import 'dart:typed_data';");
    if (ffi) emitLn("import 'dart:ffi' as ffi;");
  }

  void emitFfiCast(String dartFuncName, String ffiFuncName, String typeName,
      List<DartType> pars) {
    emit("${pars[0].name} Function(");
    for (int i = 1; i < pars.length; i++) {
      DartType tp = pars[i];
      emit('${tp.name}');
      if (i != (pars.length - 1)) {
        emit(', ');
      }
    }
    emit(') ${dartFuncName} = ' +
        'ffi.Pointer.fromFunction<${typeName}>(${ffiFuncName}, ');
    emitLiteral(0, pars[0]);
    emitLn(').cast<ffi.NativeFunction<${typeName}>>().asFunction();');
  }

  void emitMethods(String name, List<List<DartType>> methods,
      [List<bool> ffiStatus]) {
    for (int i = 0; i < methods.length; i++) {
      List<DartType> method = methods[i];
      currentMethod = i;
      final bool isFfiMethod = ffiStatus != null && ffiStatus[i];
      if (isFfiMethod) {
        emitFfiTypedef("${name}Ffi${i}Type", method);
        emitLn('${method[0].name} ${name}Ffi$i(', newline: false);
      } else {
        emitLn('${method[0].name} $name$i(', newline: false);
      }
      emitParDecls(method);
      emit(') {', newline: true);
      indent += 2;
      assert(localVars.isEmpty);
      if (emitStatements(0)) {
        emitReturn();
      }
      assert(localVars.isEmpty);
      indent -= 2;
      emitLn('}');
      if (isFfiMethod) {
        emitFfiCast(<commit_msg>[vm/fuzzer] Add '=>' functions<commit_after>// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:io';
import 'dart:math';

import 'package:args/args.dart';

import 'dartfuzz_api_table.dart';
import 'dartfuzz_values.dart';

// Version of DartFuzz. Increase this each time changes are made
// to preserve the property that a given version of DartFuzz yields
// the same fuzzed program for a deterministic random seed.
const String version = '1.27';

// Restriction on statements and expressions.
const int stmtLength = 2;
const int stmtDepth = 1;
const int exprDepth = 2;

// Naming conventions.
const varName = 'var';
const paramName = 'par';
const localName = 'loc';
const fieldName = 'fld';
const methodName = 'foo';

/// Class that generates a random, but runnable Dart program for fuzz testing.
class DartFuzz {
  DartFuzz(this.seed, this.fp, this.ffi, this.file);

  void run() {
    // Initialize program variables.
    rand = Random(seed);
    indent = 0;
    nest = 0;
    currentClass = null;
    currentMethod = null;
    // Setup the types.
    localVars = <DartType>[];
    iterVars = <String>[];
    globalVars = fillTypes1();
    globalVars.addAll(DartType.allTypes); // always one each
    globalMethods = fillTypes2();
    classFields = fillTypes2();
    classMethods = fillTypes3(classFields.length);
    classParents = <int>[];
    // Setup optional ffi methods and types.
    final ffiStatus = <bool>[for (final _ in globalMethods) false];
    if (ffi) {
      List<List<DartType>> globalMethodsFfi = fillTypes2(isFfi: true);
      for (var m in globalMethodsFfi) {
        globalMethods.add(m);
        ffiStatus.add(true);
      }
    }
    // Generate.
    emitHeader();
    emitVarDecls(varName, globalVars);
    emitMethods(methodName, globalMethods, ffiStatus);
    emitClasses();
    emitMain();
    // Sanity.
    assert(currentClass == null);
    assert(currentMethod == null);
    assert(indent == 0);
    assert(nest == 0);
    assert(localVars.isEmpty);
  }

  //
  // Program components.
  //

  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');
    emitLn('');
    emitLn("import 'dart:async';");
    emitLn("import 'dart:cli';");
    emitLn("import 'dart:collection';");
    emitLn("import 'dart:convert';");
    emitLn("import 'dart:core';");
    emitLn("import 'dart:io';");
    emitLn("import 'dart:isolate';");
    emitLn("import 'dart:math';");
    emitLn("import 'dart:typed_data';");
    if (ffi) emitLn("import 'dart:ffi' as ffi;");
  }

  void emitFfiCast(String dartFuncName, String ffiFuncName, String typeName,
      List<DartType> pars) {
    emit("${pars[0].name} Function(");
    for (int i = 1; i < pars.length; i++) {
      DartType tp = pars[i];
      emit('${tp.name}');
      if (i != (pars.length - 1)) {
        emit(', ');
      }
    }
    emit(') ${dartFuncName} = ' +
        'ffi.Pointer.fromFunction<${typeName}>(${ffiFuncName}, ');
    emitLiteral(0, pars[0]);
    emitLn(').cast<ffi.NativeFunction<${typeName}>>().asFunction();');
  }

  void emitMethods(String name, List<List<DartType>> methods,
      [List<bool> ffiStatus]) {
    for (int i = 0; i < methods.length; i++) {
      List<DartType> method = methods[i];
      currentMethod = i;
      final bool isFfiMethod = ffiStatus != null && ffiStatus[i];
      if (isFfiMethod) {
        emitFfiTypedef("${name}Ffi${i}Type", method);
        emitLn('${method[0].name} ${name}Ffi$i(', newline: false);
      } else {
        emitLn('${method[0].name} $name$i(', newline: false);
      }
      emitParDecls(method);
      if (!isFfiMethod && rand.nextInt(10) == 0) {
        // Emit a method using "=>" syntax.
        emit(') => ');
        emitExpr(0, method[0]);
        emit(';', newline: true);
        currentMethod = null;
        continue;
      }
      emit(') {', newline: true);
      indent += 2;
      assert(localVars.isEmpty);
      if (emitStatements(0)) {
        emitReturn();
      }
      assert(localVars.isEmpty);
      indent -= 2;
      emitLn('}');
      if (isFfiMethod) {
        emitFfiCast(
{'fraction_non_alphanumeric': 0.16117688430430197, 'fraction_numerical': 0.007619270894385183, 'mean_word_length': 2.986915887850467, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '393096', 'n_tokens_mistral': 2937, 'n_tokens_neox': 2870, 'n_words': 721}