// Copyright 2014 The Flutter Authors. 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:convert';
import 'dart:core' hide print;
import 'dart:io' hide exit;
import 'dart:typed_data';

import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:collection/equality.dart';
import 'package:crypto/crypto.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;

import 'allowlist.dart';
import 'custom_rules/analyze.dart';
import 'custom_rules/avoid_future_catcherror.dart';
import 'custom_rules/no_double_clamp.dart';
import 'custom_rules/no_stop_watches.dart';
import 'custom_rules/protect_public_state_subtypes.dart';
import 'custom_rules/render_box_intrinsics.dart';
import 'run_command.dart';
import 'utils.dart';

final String flutterPackages = path.join(flutterRoot, 'packages');
final String flutterExamples = path.join(flutterRoot, 'examples');

/// The path to the `dart` executable; set at the top of `main`
late final String dart;

/// The path to the `pub` executable; set at the top of `main`
late final String pub;

/// When you call this, you can pass additional arguments to pass custom
/// arguments to flutter analyze. For example, you might want to call this
/// script with the parameter --dart-sdk to use custom dart sdk.
///
/// For example:
/// bin/cache/dart-sdk/bin/dart dev/bots/analyze.dart --dart-sdk=/tmp/dart-sdk
Future<void> main(List<String> arguments) async {
  final String dartSdk = path.join(
    Directory.current.absolute.path,
    _getDartSdkFromArguments(arguments) ?? path.join(flutterRoot, 'bin', 'cache', 'dart-sdk'),
  );
  dart = path.join(dartSdk, 'bin', Platform.isWindows ? 'dart.exe' : 'dart');
  pub = path.join(dartSdk, 'bin', Platform.isWindows ? 'pub.bat' : 'pub');
  printProgress('STARTING ANALYSIS');
  await run(arguments);
  if (hasError) {
    reportErrorsAndExit('${bold}Analysis failed.$reset');
  }
  reportSuccessAndExit('${bold}Analysis successful.$reset');
}

/// Scans [arguments] for an argument of the form `--dart-sdk` or
/// `--dart-sdk=...` and returns the configured SDK, if any.
String? _getDartSdkFromArguments(List<String> arguments) {
  String? result;
  for (var i = 0; i < arguments.length; i += 1) {
    if (arguments[i] == '--dart-sdk') {
      if (result != null) {
        foundError(<String>['The --dart-sdk argument must not be used more than once.']);
        return null;
      }
      if (i + 1 < arguments.length) {
        result = arguments[i + 1];
      } else {
        foundError(<String>['--dart-sdk must be followed by a path.']);
        return null;
      }
    }
    if (arguments[i].startsWith('--dart-sdk=')) {
      if (result != null) {
        foundError(<String>['The --dart-sdk argument must not be used more than once.']);
        return null;
      }
      result = arguments[i].substring('--dart-sdk='.length);
    }
  }
  return result;
}

void _printHelp(List<Validation> validations) {
  print('Usage: dart dev/bots/analyze.dart [arguments]');
  print('');
  print('Options:');
  print('  -h, --help                  Show this help message.');
  print('  --only=rule1,rule2,...      Run only the specified validations.');
  print('  --skip=rule1,rule2,...      Skip the specified validations.');
  print('');
  print('Available rules:');
  for (final validation in validations) {
    print('  ${validation.name.padRight(25)} ${validation.description}');
  }
}

/// Represents a specific validation step in the analyze script.
@visibleForTesting
class Validation {
  /// Creates a new validation step.
  const Validation(this.name, this.description, this.callback);

  /// The short name of the rule used for filtering with --only or --skip.
  final String name;

  /// A human-readable description of the validation step.
  final String description;

  /// The function that performs the validation.
  final Future<void> Function() callback;
}

Future<void> run(List<String> arguments, {List<Validation>? validationsForTesting}) async {
  var assertsEnabled = false;
  assert(() {
    assertsEnabled = true;
    return true;
  }());
  if (!assertsEnabled) {
    foundError(<String>['The analyze.dart script must be run with --enable-asserts.']);
  }

  CommandResult? dartAnalyzeResult;
  final passthroughArguments = <String>[];

  final List<Validation> validations =
      validationsForTesting ??
      _getValidations(
        passthroughArguments: passthroughArguments,
        getDartAnalyzeResult: () => dartAnalyzeResult,
        onDartAnalyzeResult: (CommandResult? result) => dartAnalyzeResult = result,
      );

  final seenNames = <String>{};
  for (final validation in validations) {
    if (!seenNames.add(validation.name)) {
      foundError(<String>['Duplicate validation name "${validation.name}" found in analyze.dart.']);
    }
  }

  var onlyRules = <String>[];
  var skipRules = <String>[];

  for (final arg in arguments) {
    if (arg == '-h' || arg == '--help') {
      _printHelp(validations);
      return;
    }
    if (arg.startsWith('--only=')) {
      if (onlyRules.isNotEmpty) {
        foundError(<String>['The --only argument must not be used more than once.']);
        return;
      }
      onlyRules = arg.substring('--only='.length).split(',');
      continue;
    }
    if (arg.startsWith('--skip=')) {
      if (skipRules.isNotEmpty) {
        foundError(<String>['The --skip argument must not be used more than once.']);
        return;
      }
      skipRules = arg.substring('--skip='.length).split(',');
      continue;
    }
    passthroughArguments.add(arg);
  }

  if (onlyRules.isNotEmpty && skipRules.isNotEmpty) {
    foundError(<String>['Cannot use both --only and --skip at the same time.']);
    return;
  }

  final Set<String> validNames = validations.map((Validation v) => v.name).toSet();

  for (final rule in onlyRules) {
    if (!validNames.contains(rule)) {
      foundError(<String>['Unknown rule "$rule" passed to --only.']);
      return;
    }
  }
  for (final rule in skipRules) {
    if (!validNames.contains(rule)) {
      foundError(<String>['Unknown rule "$rule" passed to --skip.']);
      return;
    }
  }

  for (final validation in validations) {
    final bool shouldRun = onlyRules.isNotEmpty
        ? onlyRules.contains(validation.name)
        : !skipRules.contains(validation.name);

    if (shouldRun) {
      printProgress('${validation.description} [${validation.name}]');
      await validation.callback();
    }
  }
}

List<Validation> _getValidations({
  required List<String> passthroughArguments,
  required CommandResult? Function() getDartAnalyzeResult,
  required void Function(CommandResult?) onDartAnalyzeResult,
}) {
  return <Validation>[
    Validation(
      'release-branch',
      'Release branch validation',
      () => verifyReleaseBranchState(flutterRoot),
    ),
    Validation(
      'target-platform',
      'TargetPlatform tool/framework consistency',
      () => verifyTargetPlatform(flutterRoot),
    ),
    Validation(
      'tool-end-to-end',
      'All tool test files end in _test.dart...',
      () => verifyToolTestsEndInTestDart(flutterRoot),
    ),
    Validation('no-sync-star-async-star', 'No sync*/async*', () async {
      await verifyNoSyncAsyncStar(flutterPackages);
      await verifyNoSyncAsyncStar(flutterExamples, minimumMatches: 200);
    }),
    Validation(
      'no-runtime-type',
      'No runtimeType in toString...',
      () => verifyNoRuntimeTypeInToString(flutterRoot),
    ),
    Validation(
      'no-checked-mode',
      'Debug mode instead of checked mode...',
      () => verifyNoCheckedMode(flutterRoot),
    ),
    Validation(
      'issue-links',
      'Links for creating GitHub issues...',
      () => verifyIssueLinks(flutterRoot),
    ),
    Validation(
      'repository-links',
      'Links to repositories...',
      () => verifyRepositoryLinks(flutterRoot),
    ),
    Validation('no-binaries', 'Unexpected binaries...', () => verifyNoBinaries(flutterRoot)),
    Validation(
      'no-trailing-spaces',
      'Trailing spaces...',
      () => verifyNoTrailingSpaces(flutterRoot),
    ),
    Validation(
      'spaces-after-flow',
      'Spaces after flow control statements...',
      () => verifySpacesAfterFlowControlStatements(flutterRoot),
    ),
    Validation('deprecations', 'Deprecations...', () => verifyDeprecations(flutterRoot)),
    Validation('golden-tags', 'Goldens...', () => verifyGoldenTags(flutterPackages)),
    Validation(
      'skip-test-comments',
      'Skip test comments...',
      () => verifySkipTestComments(flutterRoot),
    ),
    Validation('no-missing-license', 'Licenses...', () => verifyNoMissingLicense(flutterRoot)),
    Validation('no-test-imports', 'Test imports...', () => verifyNoTestImports(flutterRoot)),
    Validation(
      'no-bad-imports-flutter',
      'Bad imports (framework)...',
      () => verifyNoBadImportsInFlutter(flutterRoot),
    ),
    Validation(
      'no-bad-imports-tools',
      'Bad imports (tools)...',
      () => verifyNoBadImportsInFlutterTools(flutterRoot),
    ),
    Validation(
      'internationalization',
      'Internationalization...',
      () => verifyInternationalizations(flutterRoot, dart),
    ),
    Validation(
      'stock-app-localizations',
      'Localization files of stocks app...',
      () => verifyStockAppLocalizations(flutterRoot),
    ),
    Validation(
      'integration-timeouts',
      'Integration test timeouts...',
      () => verifyIntegrationTestTimeouts(flutterRoot),
    ),
    Validation(
      'null-fields',
      'null initialized debug fields...',
      () => verifyNullInitializedDebugExpensiveFields(flutterRoot),
    ),
    Validation('taboo', 'Taboo words...', () => verifyTabooDocumentation(flutterRoot)),
    Validation('lint-kotlin', 'Lint Kotlin files...', () => lintKotlinFiles(flutterRoot)),
    Validation(
      'lint-kotlin-templates',
      'Lint generated Kotlin files from templates...',
      () => lintKotlinTemplatedFiles(flutterRoot),
    ),
    Validation(
      'update-packages',
      'Package dependencies...',
      () => runCommand(flutter, <String>['update-packages'], workingDirectory: flutterRoot),
    ),
    Validation('package-allowlist', 'Package Allowlist...', () => _checkConsumerDependencies()),
    Validation('dart-analysis', 'Dart analysis...', () async {
      final CommandResult result = await _runFlutterAnalyze(
        flutterRoot,
        options: <String>['--flutter-repo', ...passthroughArguments],
      );
      onDartAnalyzeResult(result);
    }),
    // TODO(Piinks): Re-enable once formatting changes have rolled in and the repo has been reformatted,
    // https://github.com/flutter/flutter/issues/187204
    // Validation(
    //   'format',
    //   'Check formatting of Dart files...',
    //   () => runCommand(dart, <String>[
    //     '--enable-asserts',
    //     path.join(flutterRoot, 'dev', 'tools', 'bin', 'format.dart'),
    //   ], workingDirectory: flutterRoot),
    // ),
    Validation(
      'private-lints',
      'Private lints...',
      () => _verifyPrivateLints(flutterRoot, getDartAnalyzeResult()),
    ),
    Validation('executable-allowlist', 'Executable allowlist...', () => _checkForNewExecutables()),
    Validation(
      'dart-analysis-watch',
      'Dart analysis (with --watch)...',
      () => _runFlutterAnalyze(
        flutterRoot,
        failureMessage: 'Dart analyzer failed when --watch was used.',
        options: <String>['--flutter-repo', '--watch', '--benchmark', ...passthroughArguments],
      ),
    ),
    Validation(
      'snippets',
      'Snippet code...',
      () => runCommand(dart, <String>[
        '--enable-asserts',
        path.join(flutterRoot, 'dev', 'bots', 'analyze_snippet_code.dart'),
        '--verbose',
      ], workingDirectory: flutterRoot),
    ),
    Validation(
      'code-samples',
      'Code sample link validation...',
      () => runCommand(dart, <String>[
        '--enable-asserts',
        path.join(flutterRoot, 'dev', 'bots', 'check_code_samples.dart'),
      ], workingDirectory: flutterRoot),
    ),
    Validation(
      'mega-gallery',
      'Dart analysis (mega gallery)...',
      () => _verifyMegaGallery(flutterRoot, dart, passthroughArguments),
    ),
    Validation(
      'gen-defaults-names',
      'Correct file names in gen_defaults.dart...',
      () => verifyTokenTemplatesUpdateCorrectFiles(flutterRoot),
    ),
    Validation(
      'gen-defaults-up-to-date',
      'Material library files are up-to-date with token template files...',
      () => verifyMaterialFilesAreUpToDateWithTemplateFiles(flutterRoot, dart),
    ),
    Validation(
      'integration-templates',
      'Up to date integration test template files...',
      () => verifyIntegrationTestTemplateFiles(flutterRoot),
    ),
    Validation(
      'cross-imports',
      'Cross-import test validation...',
      () => runCommand(dart, <String>[
        '--enable-asserts',
        path.join(flutterRoot, 'dev', 'bots', 'check_tests_cross_imports.dart'),
      ], workingDirectory: flutterRoot),
    ),
  ];
}

// TESTS

FeatureSet _parsingFeatureSet() => FeatureSet.latestLanguageVersion();

_Line _getLine(ParseStringResult parseResult, int offset) {
  final int lineNumber = parseResult.lineInfo.getLocation(offset).lineNumber;
  final String content = parseResult.content.substring(
    parseResult.lineInfo.getOffsetOfLine(lineNumber - 1),
    parseResult.lineInfo.getOffsetOfLine(lineNumber) - 1,
  );
  return _Line(lineNumber, content);
}

Future<void> verifyReleaseBranchState(String workringDirerctory) async {
  final ProcessResult result = await Process.run(dart, <String>[
    'bin/check_engine_version.dart',
  ], workingDirectory: path.join(workringDirerctory, 'dev', 'tools'));
  if (result.exitCode != 0) {
    foundError(<String>['${result.stderr}']);
  }
}

Future<void> verifyTargetPlatform(String workingDirectory) async {
  final framework = File('$workingDirectory/packages/flutter/lib/src/foundation/platform.dart');
  final frameworkPlatforms = <String>{};
  List<String> lines = framework.readAsLinesSync();
  var index = 0;
  while (true) {
    if (index >= lines.length) {
      foundError(<String>['${framework.path}: Can no longer find TargetPlatform enum.']);
      return;
    }
    if (lines[index].startsWith('enum TargetPlatform {')) {
      index += 1;
      break;
    }
    index += 1;
  }
  while (true) {
    if (index >= lines.length) {
      foundError(<String>['${framework.path}: Could not find end of TargetPlatform enum.']);
      return;
    }
    String line = lines[index].trim();
    final int comment = line.indexOf('//');
    if (comment >= 0) {
      line = line.substring(0, comment);
    }
    if (line == '}') {
      break;
    }
    if (line.isNotEmpty) {
      if (line.endsWith(',')) {
        frameworkPlatforms.add(line.substring(0, line.length - 1));
      } else {
        foundError(<String>[
          '${framework.path}:$index: unparseable line when looking for TargetPlatform values',
        ]);
      }
    }
    index += 1;
  }
  final tool = File('$workingDirectory/packages/flutter_tools/lib/src/resident_runner.dart');
  final toolPlatforms = <String>{};
  lines = tool.readAsLinesSync();
  index = 0;
  while (true) {
    if (index >= lines.length) {
      foundError(<String>['${tool.path}: Can no longer find nextPlatform logic.']);
      return;
    }
    if (lines[index].trim().startsWith('const platforms = <String>[')) {
      index += 1;
      break;
    }
    index += 1;
  }
  while (true) {
    if (index >= lines.length) {
      foundError(<String>['${tool.path}: Could not find end of nextPlatform logic.']);
      return;
    }
    final String line = lines[index].trim();
    if (line.startsWith("'") && line.endsWith("',")) {
      toolPlatforms.add(line.substring(1, line.length - 2));
    } else if (line == '];') {
      break;
    } else {
      foundError(<String>[
        '${tool.path}:$index: unparseable line when looking for nextPlatform values',
      ]);
    }
    index += 1;
  }
  final Set<String> frameworkExtra = frameworkPlatforms.difference(toolPlatforms);
  if (frameworkExtra.isNotEmpty) {
    foundError(<String>[
      'TargetPlatform has some extra values not found in the tool: ${frameworkExtra.join(", ")}',
    ]);
  }
  final Set<String> toolExtra = toolPlatforms.difference(frameworkPlatforms);
  if (toolExtra.isNotEmpty) {
    foundError(<String>[
      'The nextPlatform logic in the tool has some extra values not found in TargetPlatform: ${toolExtra.join(", ")}',
    ]);
  }
}

/// Verify Token Templates are mapped to correct file names while generating
/// M3 defaults in /dev/tools/gen_defaults/bin/gen_defaults.dart.
Future<void> verifyTokenTemplatesUpdateCorrectFiles(String workingDirectory) async {
  final errors = <String>[];

  String getMaterialDirPath(List<String> lines) {
    final String line = lines.firstWhere((String line) => line.contains('String materialLib'));
    final String relativePath = line.substring(line.indexOf("'") + 1, line.lastIndexOf("'"));
    return path.join(workingDirectory, relativePath);
  }

  String getFileName(String line) {
    const materialLibString = r"'$materialLib/";
    final String leftClamp = line.substring(
      line.indexOf(materialLibString) + materialLibString.length,
    );
    return leftClamp.substring(0, leftClamp.indexOf("'"));
  }

  final genDefaultsBinDir = '$workingDirectory/dev/tools/gen_defaults/bin';
  final file = File(path.join(genDefaultsBinDir, 'gen_defaults.dart'));
  final List<String> lines = file.readAsLinesSync();
  final String materialDirPath = getMaterialDirPath(lines);
  var atLeastOneTargetLineExists = false;

  for (final line in lines) {
    if (line.contains('updateFile();')) {
      atLeastOneTargetLineExists = true;
      final String fileName = getFileName(line);
      final String filePath = path.join(materialDirPath, fileName);
      final file = File(filePath);

      if (!file.existsSync()) {
        errors.add('file $filePath does not exist.');
      }
    }
  }

  assert(
    atLeastOneTargetLineExists,
    'No lines exist that this test expects to '
    'verify. Check if the target file is correct or remove this test',
  );

  // Fail if any errors
  if (errors.isNotEmpty) {
    final s = errors.length > 1 ? 's' : '';
    final itThem = errors.length > 1 ? 'them' : 'it';
    foundError(<String>[
      ...errors,
      '${bold}Please correct the file name$s or remove $itThem from /dev/tools/gen_defaults/bin/gen_defaults.dart$reset',
    ]);
  }
}

/// Verify Material library files are up-to-date with the token template files
/// when running /dev/tools/gen_defaults/bin/gen_defaults.dart.
Future<void> verifyMaterialFilesAreUpToDateWithTemplateFiles(
  String workingDirectory,
  String dartExecutable,
) async {
  final errors = <String>[];
  const beginGeneratedComment = '// BEGIN GENERATED TOKEN PROPERTIES';

  String getMaterialDirPath(List<String> lines) {
    final String line = lines.firstWhere((String line) => line.contains('String materialLib'));
    final String relativePath = line.substring(line.indexOf("'") + 1, line.lastIndexOf("'"));
    return path.join(workingDirectory, relativePath);
  }

  String getFileName(String line) {
    const materialLibString = r"'$materialLib/";
    final String leftClamp = line.substring(
      line.indexOf(materialLibString) + materialLibString.length,
    );
    return leftClamp.substring(0, leftClamp.indexOf("'"));
  }

  // Get the template generated code from the file.
  List<String> getGeneratedCode(List<String> lines) {
    return lines.skipWhile((String line) => !line.contains(beginGeneratedComment)).toList();
  }

  final genDefaultsBinDir = '$workingDirectory/dev/tools/gen_defaults/bin';
  final file = File(path.join(genDefaultsBinDir, 'gen_defaults.dart'));
  final List<String> lines = file.readAsLinesSync();
  final String materialDirPath = getMaterialDirPath(lines);
  final beforeGeneratedCode = <String, List<String>>{};
  final afterGeneratedCode = <String, List<String>>{};

  for (final line in lines) {
    if (line.contains('updateFile();')) {
      final String fileName = getFileName(line);
      final String filePath = path.join(materialDirPath, fileName);
      final file = File(filePath);
      beforeGeneratedCode[fileName] = getGeneratedCode(file.readAsLinesSync());
    }
  }

  // Run gen_defaults.dart to generate the token template files.
  await runCommand(dartExecutable, <String>[
    '--enable-asserts',
    path.join('dev', 'tools', 'gen_defaults', 'bin', 'gen_defaults.dart'),
  ], workingDirectory: workingDirectory);

  for (final line in lines) {
    if (line.contains('updateFile();')) {
      final String fileName = getFileName(line);
      final String filePath = path.join(materialDirPath, fileName);
      final file = File(filePath);
      afterGeneratedCode[fileName] = getGeneratedCode(file.readAsLinesSync());
    }
  }

  // Compare the generated code before and after running gen_defaults.dart.
  for (final String fileName in beforeGeneratedCode.keys) {
    final List<String> before = beforeGeneratedCode[fileName]!;
    final List<String> after = afterGeneratedCode[fileName]!;
    if (!const IterableEquality<String>().equals(before, after)) {
      errors.add('$fileName is not up-to-date with the token template file.');
    }
  }

  // Fail if any errors.
  if (errors.isNotEmpty) {
    foundError(<String>[
      ...errors,
      '${bold}See: https://github.com/flutter/flutter/blob/main/dev/tools/gen_defaults to update the token template files.$reset',
    ]);
  }
}

/// Verify tool test files end in `_test.dart`.
///
/// The test runner will only recognize files ending in `_test.dart` as tests to
/// be run: https://github.com/dart-lang/test/tree/master/pkgs/test#running-tests
Future<void> verifyToolTestsEndInTestDart(String workingDirectory) async {
  final String toolsTestPath = path.join(workingDirectory, 'packages', 'flutter_tools', 'test');
  final violations = <String>[];

  // detect files that contains calls to test(), testUsingContext(), and testWithoutContext()
  final callsTestFunctionPattern = RegExp(
    r'^ *(test\(.*\)|testUsingContext\(.*\)|testWithoutContext\(.*\))',
  );

  await for (final File file in _allFiles(toolsTestPath, 'dart', minimumMatches: 300)) {
    final bool isValidTestFile = file.path.endsWith('_test.dart');
    if (isValidTestFile) {
      continue;
    }

    final bool isTestData = file.path.contains(r'test_data');
    if (isTestData) {
      continue;
    }

    final bool isInTestShard = file.path.contains(r'.shard/');
    if (!isInTestShard) {
      continue;
    }

    final bool callsTestFunction = file.readAsStringSync().contains(callsTestFunctionPattern);
    if (!callsTestFunction) {
      continue;
    }

    violations.add(file.path);
  }
  if (violations.isNotEmpty) {
    foundError(<String>[
      '${bold}Found flutter_tools tests that do not end in `_test.dart`; these will not be run by the test runner$reset',
      ...violations,
    ]);
  }
}

Future<void> verifyNoSyncAsyncStar(String workingDirectory, {int minimumMatches = 2000}) async {
  final syncPattern = RegExp(r'\s*?a?sync\*\s*?{');
  final ignorePattern = RegExp(r'^\s*?// The following uses a?sync\* because:? ');
  final commentPattern = RegExp(r'^\s*?//');
  final errors = <String>[];
  await for (final File file in _allFiles(
    workingDirectory,
    'dart',
    minimumMatches: minimumMatches,
  )) {
    if (file.path.contains('test')) {
      continue;
    }
    final List<String> lines = file.readAsLinesSync();
    for (var index = 0; index < lines.length; index += 1) {
      final String line = lines[index];
      if (line.startsWith(commentPattern)) {
        continue;
      }
      if (line.contains(syncPattern)) {
        int lookBehindIndex = index - 1;
        var hasExplanation = false;
        while (lookBehindIndex >= 0 && lines[lookBehindIndex].startsWith(commentPattern)) {
          if (lines[lookBehindIndex].startsWith(ignorePattern)) {
            hasExplanation = true;
            break;
          }
          lookBehindIndex -= 1;
        }
        if (!hasExplanation) {
          errors.add('${file.path}:$index: sync*/async* without an explanation.');
        }
      }
    }
  }
  if (errors.isNotEmpty) {
    foundError(<String>[
      '${bold}Do not use sync*/async* methods. See https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#avoid-syncasync for details.$reset',
      ...errors,
    ]);
  }
}

final RegExp _findGoldenTestPattern = RegExp(r'matchesGoldenFile\(');
final RegExp _findGoldenDefinitionPattern = RegExp(r'matchesGoldenFile\(Object');
final RegExp _leadingComment = RegExp(r'//');
final RegExp _goldenTagPattern1 = RegExp(r'@Tags\(');
final RegExp _goldenTagPattern2 = RegExp(r"'reduced-test-set'");

/// Only golden file tests in the flutter package are subject to reduced testing,
/// for example, invocations in flutter_test to validate comparator
/// functionality do not require tagging.
const String _ignoreGoldenTag = '// flutter_ignore: golden_tag (see analyze.dart)';
const String _ignoreGoldenTagForFile = '// flutter_ignore_for_file: golden_tag (see analyze.dart)';

Future<void> verifyGoldenTags(String workingDirectory, {int minimumMatches = 2000}) async {
  final errors = <String>[];
  await for (final File file in _allFiles(
    workingDirectory,
    'dart',
    minimumMatches: minimumMatches,
  )) {
    var needsTag = false;
    var hasTagNotation = false;
    var hasReducedTag = false;
    var ignoreForFile = false;
    final List<String> lines = file.readAsLinesSync();
    for (final line in lines) {
      if (line.contains(_goldenTagPattern1)) {
        hasTagNotation = true;
      }
      if (line.contains(_goldenTagPattern2)) {
        hasReducedTag = true;
      }
      if (line.contains(_findGoldenTestPattern) &&
          !line.contains(_findGoldenDefinitionPattern) &&
          !line.contains(_leadingComment) &&
          !line.contains(_ignoreGoldenTag)) {
        needsTag = true;
      }
      if (line.contains(_ignoreGoldenTagForFile)) {
        ignoreForFile = true;
      }
      // If the file is being ignored or a reduced test tag is already accounted
      // for, skip parsing the rest of the lines for golden file tests.
      if (ignoreForFile || (hasTagNotation && hasReducedTag)) {
        break;
      }
    }
    // If a reduced test tag is already accounted for, move on to the next file.
    if (ignoreForFile || (hasTagNotation && hasReducedTag)) {
      continue;
    }
    // If there are golden file tests, ensure they are tagged for all reduced
    // test environments.
    if (needsTag) {
      if (!hasTagNotation) {
        errors.add(
          '${file.path}: Files containing golden tests must be tagged using '
          "@Tags(<String>['reduced-test-set']) at the top of the file before import statements.",
        );
      } else if (!hasReducedTag) {
        errors.add(
          '${file.path}: Files containing golden tests must be tagged with '
          "'reduced-test-set'.",
        );
      }
    }
  }
  if (errors.isNotEmpty) {
    foundError(<String>[
      ...errors,
      '${bold}See: https://github.com/flutter/flutter/blob/main/docs/contributing/testing/Writing-a-golden-file-test-for-package-flutter.md$reset',
    ]);
  }
}

class _DeprecationMessagesVisitor extends RecursiveAstVisitor<void> {
  _DeprecationMessagesVisitor(this.parseResult, this.filePath);

  final ParseStringResult parseResult;
  final String filePath;
  final List<String> errors = <String>[];

  /// Some deprecation notices are special, for example they're used to annotate members that
  /// will never go away and were never allowed but which we are trying to show messages for.
  /// (One example would be a library that intentionally conflicts with a member in another
  /// library to indicate that it is incompatible with that other library. Another would be
  /// the regexp just above...)
  static const Pattern ignoreDeprecration =
      '// flutter_ignore: deprecation_syntax (see analyze.dart)';

  /// Some deprecation notices are exempt for historical reasons. They must have an issue listed.
  static final RegExp legacyDeprecation = RegExp(
    r'// flutter_ignore: deprecation_syntax, https://github.com/flutter/flutter/issues/\d+',
  );

  static final RegExp deprecationVersionPattern = RegExp(
    r'This feature was deprecated after v(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(?<build>-\d+\.\d+\.pre)?\.$',
  );

  void _addErrorWithLineInfo(AstNode node, {required String error}) {
    final int lineNumber = parseResult.lineInfo.getLocation(node.offset).lineNumber;
    errors.add('$filePath:$lineNumber: $error');
  }

  @override
  void visitAnnotation(Annotation node) {
    super.visitAnnotation(node);
    final bool shouldCheckAnnotation =
        node.name.name == 'Deprecated' &&
        !hasInlineIgnore(node, parseResult, ignoreDeprecration) &&
        !hasInlineIgnore(node, parseResult, legacyDeprecation);
    if (!shouldCheckAnnotation) {
      return;
    }
    final NodeList<Expression>? arguments = node.arguments?.arguments;
    if (arguments == null || arguments.length != 1) {
      _addErrorWithLineInfo(
        node,
        error: 'A @Deprecation annotation must have exactly one deprecation notice String.',
      );
      return;
    }
    final Expression deprecationNotice = arguments.first;
    if (deprecationNotice is! AdjacentStrings) {
      _addErrorWithLineInfo(node, error: 'Deprecation notice must be an adjacent string.');
      return;
    }
    final List<StringLiteral> strings = deprecationNotice.strings;
    final Iterator<StringLiteral> deprecationMessageIterator = strings.iterator;
    final bool isNotEmpty = deprecationMessageIterator.moveNext();
    assert(isNotEmpty); // An AdjacentString always has 2 or more string literals.

    final [...List<StringLiteral> messageLiterals, StringLiteral versionLiteral] = strings;

    // Verify the version literal has the correct pattern.
    final RegExpMatch? versionMatch = versionLiteral is SimpleStringLiteral
        ? deprecationVersionPattern.firstMatch(versionLiteral.value)
        : null;
    if (versionMatch == null) {
      _addErrorWithLineInfo(
        versionLiteral,
        error:
            'Deprecation notice must end with a line saying "This feature was deprecated after v<version>.".',
      );
      return;
    }

    final int major = int.parse(versionMatch.namedGroup('major')!);
    final int minor = int.parse(versionMatch.namedGroup('minor')!);
    final int patch = int.parse(versionMatch.namedGroup('patch')!);
    final hasBuild = versionMatch.namedGroup('build') != null;
    // There was a beta release that was mistakenly labeled 3.1.0 without a build.
    final bool specialBeta = major == 3 && minor == 1 && patch == 0;
    if (!specialBeta && (major > 1 || (major == 1 && minor >= 20))) {
      if (!hasBuild) {
        _addErrorWithLineInfo(
          versionLiteral,
          error:
              'Deprecation notice does not accurately indicate a beta branch version number; please see https://docs.flutter.dev/install/archive to find the latest beta build version number.',
        );
        return;
      }
    }

    // Verify the version literal has the correct pattern.
    assert(messageLiterals.isNotEmpty); // An AdjacentString always has 2 or more string literals.
    for (final message in messageLiterals) {
      if (message is! SingleStringLiteral) {
        _addErrorWithLineInfo(
          message,
          error: 'Deprecation notice does not match required pattern.',
        );
        return;
      }
      if (!message.isSingleQuoted) {
        _addErrorWithLineInfo(
          message,
          error:
              'Deprecation notice does not match required pattern. You might have used double quotes (") for the string instead of single quotes (\').',
        );
        return;
      }
    }
    final String fullExplanation = messageLiterals
        .map((StringLiteral message) => message.stringValue ?? '')
        .join()
        .trimRight();
    if (fullExplanation.isEmpty) {
      _addErrorWithLineInfo(
        messageLiterals.last,
        error:
            'Deprecation notice should be a grammatically correct sentence and end with a period; There might not be an explanatory message.',
      );
      return;
    }
    final firstChar = String.fromCharCode(fullExplanation.runes.first);
    if (firstChar.toUpperCase() != firstChar) {
      _addErrorWithLineInfo(
        messageLiterals.first,
        error:
            'Deprecation notice should be a grammatically correct sentence and start with a capital letter; see style guide: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md',
      );
      return;
    }
    if (!fullExplanation.endsWith('.') &&
        !fullExplanation.endsWith('?') &&
        !fullExplanation.endsWith('!')) {
      _addErrorWithLineInfo(
        messageLiterals.last,
        error:
            'Deprecation notice should be a grammatically correct sentence and end with a period; notice appears to be "$fullExplanation".',
      );
      return;
    }
  }
}

Future<void> verifyDeprecations(String workingDirectory, {int minimumMatches = 2000}) async {
  final errors = <String>[];
  await for (final File file in _allFiles(
    workingDirectory,
    'dart',
    minimumMatches: minimumMatches,
  )) {
    final ParseStringResult parseResult = parseFile(
      featureSet: _parsingFeatureSet(),
      path: file.absolute.path,
    );
    final visitor = _DeprecationMessagesVisitor(parseResult, file.path);
    visitor.visitCompilationUnit(parseResult.unit);
    errors.addAll(visitor.errors);
  }
  // Fail if any errors
  if (errors.isNotEmpty) {
    foundError(<String>[
      ...errors,
      '${bold}See: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes$reset',
    ]);
  }
}

String _generateLicense(String prefix) {
  return '${prefix}Copyright 2014 The Flutter Authors. All rights reserved.\n'
      '${prefix}Use of this source code is governed by a BSD-style license that can be\n'
      '${prefix}found in the LICENSE file.';
}

Future<void> verifyNoMissingLicense(String workingDirectory, {bool checkMinimums = true}) async {
  final int? overrideMinimumMatches = checkMinimums ? null : 0;
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'dart',
    overrideMinimumMatches ?? 2000,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'java',
    overrideMinimumMatches ?? 1,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'h',
    overrideMinimumMatches ?? 30,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'm',
    overrideMinimumMatches ?? 30,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'cc',
    overrideMinimumMatches ?? 10,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'cpp',
    overrideMinimumMatches ?? 0,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'swift',
    overrideMinimumMatches ?? 10,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'gradle',
    overrideMinimumMatches ?? 80,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'gn',
    overrideMinimumMatches ?? 0,
    _generateLicense('# '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'sh',
    overrideMinimumMatches ?? 1,
    _generateLicense('# '),
    header: r'#!/usr/bin/env bash\n',
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'bat',
    overrideMinimumMatches ?? 1,
    _generateLicense('REM '),
    header: r'@ECHO off\n',
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'ps1',
    overrideMinimumMatches ?? 1,
    _generateLicense('# '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'html',
    overrideMinimumMatches ?? 1,
    '<!-- ${_generateLicense('')} -->',
    trailingBlank: false,
    header: r'<!DOCTYPE HTML>\n',
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'xml',
    overrideMinimumMatches ?? 1,
    '<!-- ${_generateLicense('')} -->',
    header: r'(<\?xml version="1.0" encoding="utf-8"\?>\n)?',
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'frag',
    overrideMinimumMatches ?? 1,
    _generateLicense('// '),
    header: r'#version 320 es(\n)+',
  );
}

Future<void> _verifyNoMissingLicenseForExtension(
  String workingDirectory,
  String extension,
  int minimumMatches,
  String license, {
  bool trailingBlank = true,
  // The "header" is a regular expression matching the header that comes before
  // the license in some files.
  String header = '',
}) async {
  assert(!license.endsWith('\n'));
  final String licensePattern = RegExp.escape('$license\n${trailingBlank ? '\n' : ''}');
  final errors = <String>[];
  await for (final File file in _allFiles(
    workingDirectory,
    extension,
    minimumMatches: minimumMatches,
  )) {
    final String contents = file.readAsStringSync().replaceAll('\r\n', '\n');
    if (contents.isEmpty) {
      continue; // let's not go down the /bin/true rabbit hole
    }
    if (path.basename(file.path) == 'Package.swift') {
      continue;
    }
    if (!contents.startsWith(RegExp(header + licensePattern))) {
      errors.add(file.path);
    }
  }
  // Fail if any errors
  if (errors.isNotEmpty) {
    final fileDoes = errors.length == 1 ? 'file does' : '${errors.length} files do';
    foundError(<String>[
      '${bold}The following $fileDoes not have the right license header for $extension files:$reset',
      ...errors.map<String>((String error) => '  $error'),
      'The expected license header is:',
      if (header.isNotEmpty) 'A header matching the regular expression "$header",',
      if (header.isNotEmpty) 'followed by the following license text:',
      license,
      if (trailingBlank) '...followed by a blank line.',
    ]);
  }
}

class _Line {
  _Line(this.line, this.content);

  final int line;
  final String content;
}

Iterable<_Line> _getTestSkips(File file) {
  final ParseStringResult parseResult = parseFile(
    featureSet: _parsingFeatureSet(),
    path: file.absolute.path,
  );
  final visitor = _TestSkipLinesVisitor<CompilationUnit>(parseResult);
  visitor.visitCompilationUnit(parseResult.unit);
  return visitor.skips;
}

class _TestSkipLinesVisitor<T> extends RecursiveAstVisitor<T> {
  _TestSkipLinesVisitor(this.parseResult) : skips = <_Line>{};

  final ParseStringResult parseResult;
  final Set<_Line> skips;

  static bool isTestMethod(String name) {
    return name.startsWith('test') || name == 'group' || name == 'expect';
  }

  static final Pattern _skipTestIntentionalPattern = RegExp(r'// .*[intended]');
  static final Pattern _skipTestTrackingBugPattern = RegExp(
    r'// .*https+?://github.com/.*/issues/\d+',
  );
  bool _hasValidJustificationComment(Label skipLabel) {
    return hasInlineIgnore(skipLabel, parseResult, _skipTestIntentionalPattern) ||
        hasInlineIgnore(skipLabel, parseResult, _skipTestTrackingBugPattern);
  }

  @override
  T? visitMethodInvocation(MethodInvocation node) {
    if (isTestMethod(node.methodName.toString())) {
      for (final Expression argument in node.argumentList.arguments) {
        if (argument is NamedExpression &&
            argument.name.label.name == 'skip' &&
            !_hasValidJustificationComment(argument.name)) {
          skips.add(_getLine(parseResult, argument.beginToken.charOffset));
        }
      }
    }
    return super.visitMethodInvocation(node);
  }
}

Future<void> verifySkipTestComments(String workingDirectory) async {
  final errors = <String>[];
  final Stream<File> testFiles = _allFiles(
    workingDirectory,
    'dart',
    minimumMatches: 1500,
  ).where((File f) => f.path.endsWith('_test.dart'));

  await for (final File file in testFiles) {
    for (final _Line skip in _getTestSkips(file)) {
      errors.add('${file.path}:${skip.line}: skip test without a justification comment.');
    }
  }

  // Fail if any errors
  if (errors.isNotEmpty) {
    foundError(<String>[
      ...errors,
      '\n${bold}See: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#skipped-tests$reset',
    ]);
  }
}

final RegExp _testImportPattern = RegExp(r'''import (['"])([^'"]+_test\.dart)\1''');
const Set<String> _exemptTestImports = <String>{
  'package:flutter_test/flutter_test.dart',
  'hit_test.dart',
  'package:test_api/src/backend/live_test.dart',
  'package:integration_test/integration_test.dart',
};

Future<void> verifyNoTestImports(String workingDirectory) async {
  final errors = <String>[];
  assert("// foo\nimport 'binding_test.dart' as binding;\n'".contains(_testImportPattern));
  final List<File> dartFiles = await _allFiles(
    path.join(workingDirectory, 'packages'),
    'dart',
    minimumMatches: 1500,
  ).toList();
  for (final file in dartFiles) {
    for (final String line in file.readAsLinesSync()) {
      final Match? match = _testImportPattern.firstMatch(line);
      if (match != null && !_exemptTestImports.contains(match.group(2))) {
        errors.add(file.path);
      }
    }
  }
  // Fail if any errors
  if (errors.isNotEmpty) {
    foundError(<String>[
      '${bold}The following file(s) import a test directly. Test utilities should be in their own file.$reset',
      ...errors,
    ]);
  }
}

Future<void> verifyNoBadImportsInFlutter(String workingDirectory) async {
  final errors = <String>[];
  final String libPath = path.join(workingDirectory, 'packages', 'flutter', 'lib');
  final String srcPath = path.join(workingDirectory, 'packages', 'flutter', 'lib', 'src');
  // Verify there's one libPath/*.dart for each srcPath/*/.
  final List<String> packages =
      Directory(libPath)
          .listSync()
          .where(
            (FileSystemEntity entity) => entity is File && path.extension(entity.path) == '.dart',
          )
          .map<String>((FileSystemEntity entity) => path.basenameWithoutExtension(entity.path))
          .toList()
        ..sort();
  final List<String> directories =
      Directory(srcPath)
          .listSync()
          .whereType<Directory>()
          .map<String>((Directory entity) => path.basename(entity.path))
          .toList()
        ..sort();
  if (!_listEquals<String>(packages, directories)) {
    errors.add(
      <String>[
        'flutter/lib/*.dart does not match flutter/lib/src/*/:',
        'These are the exported packages:',
        ...packages.map<String>((String path) => '  lib/$path.dart'),
        'These are the directories:',
        ...directories.map<String>((String path) => '  lib/src/$path/'),
      ].join('\n'),
    );
  }
  // Verify that the imports are well-ordered.
  final dependencyMap = <String, Set<String>>{};
  for (final directory in directories) {
    dependencyMap[directory] = await _findFlutterDependencies(
      path.join(srcPath, directory),
      errors,
      checkForMeta: directory != 'foundation',
    );
  }
  assert(
    dependencyMap['material']!.contains('widgets') &&
        dependencyMap['widgets']!.contains('rendering') &&
        dependencyMap['rendering']!.contains('painting'),
  ); // to make sure we're convinced _findFlutterDependencies is finding some
  for (final String package in dependencyMap.keys) {
    if (dependencyMap[package]!.contains(package)) {
      errors.add(
        'One of the files in the $yellow$package$reset package imports that package recursively.',
      );
    }
  }

  for (final String key in dependencyMap.keys) {
    for (final String dependency in dependencyMap[key]!) {
      if (dependencyMap[dependency] != null) {
        continue;
      }
      // Sanity check before performing _deepSearch, to ensure there's no rogue
      // dependencies.
      final String validFilenames = dependencyMap.keys
          .map((String name) => '$name.dart')
          .join(', ');
      errors.add(
        '$key imported package:flutter/$dependency.dart '
        'which is not one of the valid exports { $validFilenames }.\n'
        'Consider changing $dependency.dart to one of them.',
      );
    }
  }

  for (final String package in dependencyMap.keys) {
    final List<String>? loop = _deepSearch<String>(dependencyMap, package);
    if (loop != null) {
      errors.add('${yellow}Dependency loop:$reset ${loop.join(' depends on ')}');
    }
  }
  // Fail if any errors
  if (errors.isNotEmpty) {
    foundError(<String>[
      if (errors.length == 1)
        '${bold}An error was detected when looking at import dependencies within the Flutter package:$reset'
      else
        '${bold}Multiple errors were detected when looking at import dependencies within the Flutter package:$reset',
      ...errors,
    ]);
  }
}

Future<void> verifyNoBadImportsInFlutterTools(String workingDirectory) async {
  final errors = <String>[];
  final List<File> files = await _allFiles(
    path.join(workingDirectory, 'packages', 'flutter_tools', 'lib'),
    'dart',
    minimumMatches: 200,
  ).toList();
  for (final file in files) {
    if (file.readAsStringSync().contains('package:flutter_tools/')) {
      errors.add('$yellow${file.path}$reset imports flutter_tools.');
    }
  }
  // Fail if any errors
  if (errors.isNotEmpty) {
    foundError(<String>[
      if (errors.length == 1)
        '${bold}An error was detected when looking at import dependencies within the flutter_tools package:$reset'
      else
        '${bold}Multiple errors were detected when looking at import dependencies within the flutter_tools package:$reset',
      ...errors.map((String paragraph) => '$paragraph\n'),
    ]);
  }
}

Future<void> verifyIntegrationTestTimeouts(String workingDirectory) async {
  final errors = <String>[];
  final String dev = path.join(workingDirectory, 'dev');
  final List<File> files = await _allFiles(dev, 'dart', minimumMatches: 1)
      .where(
        (File file) =>
            file.path.contains('test_driver') &&
            (file.path.endsWith('_test.dart') || file.path.endsWith('util.dart')),
      )
      .toList();
  for (final file in files) {
    final String contents = file.readAsStringSync();
    final int testCount = ' test('.allMatches(contents).length;
    final int timeoutNoneCount = 'timeout: Timeout.none'.allMatches(contents).length;
    if (testCount != timeoutNoneCount) {
      errors.add(
        '$yellow${file.path}$reset has at least $testCount test(s) but only $timeoutNoneCount `Timeout.none`(s).',
      );
    }
  }
  if (errors.isNotEmpty) {
    foundError(<String>[
      if (errors.length == 1)
        '${bold}An error was detected when looking at integration test timeouts:$reset'
      else
        '${bold}Multiple errors were detected when looking at integration test timeouts:$reset',
      ...errors.map((String paragraph) => '$paragraph\n'),
    ]);
  }
}

Future<void> verifyInternationalizations(String workingDirectory, String dartExecutable) async {
  final EvalResult materialGenResult = await _evalCommand(dartExecutable, <String>[
    path.join('dev', 'tools', 'localization', 'bin', 'gen_localizations.dart'),
    '--material',
    '--remove-undefined',
  ], workingDirectory: workingDirectory);
  final EvalResult cupertinoGenResult = await _evalCommand(dartExecutable, <String>[
    path.join('dev', 'tools', 'localization', 'bin', 'gen_localizations.dart'),
    '--cupertino',
    '--remove-undefined',
  ], workingDirectory: workingDirectory);

  final String materialLocalizationsFile = path.join(
    workingDirectory,
    'packages',
    'flutter_localizations',
    'lib',
    'src',
    'l10n',
    'generated_material_localizations.dart',
  );
  final String cupertinoLocalizationsFile = path.join(
    workingDirectory,
    'packages',
    'flutter_localizations',
    'lib',
    'src',
    'l10n',
    'generated_cupertino_localizations.dart',
  );
  final String expectedMaterialResult = await File(materialLocalizationsFile).readAsString();
  final String expectedCupertinoResult = await File(cupertinoLocalizationsFile).readAsString();

  if (materialGenResult.stdout.trim() != expectedMaterialResult.trim()) {
    foundError(<String>[
      '<<<<<<< $materialLocalizationsFile',
      expectedMaterialResult.trim(),
      '=======',
      materialGenResult.stdout.trim(),
      '>>>>>>> gen_localizations',
      'The contents of $materialLocalizationsFile are different from that produced by gen_localizations.',
      '',
      'Did you forget to run gen_localizations.dart after updating a .arb file?',
    ]);
  }
  if (cupertinoGenResult.stdout.trim() != expectedCupertinoResult.trim()) {
    foundError(<String>[
      '<<<<<<< $cupertinoLocalizationsFile',
      expectedCupertinoResult.trim(),
      '=======',
      cupertinoGenResult.stdout.trim(),
      '>>>>>>> gen_localizations',
      'The contents of $cupertinoLocalizationsFile are different from that produced by gen_localizations.',
      '',
      'Did you forget to run gen_localizations.dart after updating a .arb file?',
    ]);
  }
}

Future<void> verifyStockAppLocalizations(String workingDirectory) async {
  final appRoot = Directory(
    path.join(workingDirectory, 'dev', 'benchmarks', 'test_apps', 'stocks'),
  );
  if (!appRoot.existsSync()) {
    foundError(<String>['Stocks app does not exist at expected location: ${appRoot.path}']);
  }

  // Regenerate the localizations.
  final String flutterExecutable = path.join(
    workingDirectory,
    'bin',
    'flutter${Platform.isWindows ? '.bat' : ''}',
  );
  await _evalCommand(flutterExecutable, const <String>['gen-l10n'], workingDirectory: appRoot.path);
  final i10nDirectory = Directory(path.join(appRoot.path, 'lib', 'i18n'));
  if (!i10nDirectory.existsSync()) {
    foundError(<String>[
      'Localization files for stocks app not found at expected location: ${i10nDirectory.path}',
    ]);
  }

  // Check that regeneration did not dirty the tree.
  final EvalResult result = await _evalCommand('git', <String>[
    'diff',
    '--name-only',
    '--exit-code',
    i10nDirectory.path,
  ], workingDirectory: workingDirectory);
  if (result.exitCode == 1) {
    foundError(<String>[
      'The following localization files for the stocks app appear to be out of date:',
      ...(const LineSplitter().convert(result.stdout).map((String line) => ' * $line')),
      'Run "flutter gen-l10n" in "${path.relative(appRoot.path, from: workingDirectory)}" to regenerate.',
    ]);
  } else if (result.exitCode != 0) {
    foundError(<String>[
      'Failed to run "git diff" on localization files of stocks app:',
      result.stderr,
    ]);
  }
}

/// Verifies that all instances of "checked mode" have been migrated to "debug mode".
Future<void> verifyNoCheckedMode(String workingDirectory) async {
  final String flutterPackages = path.join(workingDirectory, 'packages');
  final List<File> files = await _allFiles(
    flutterPackages,
    'dart',
    minimumMatches: 400,
  ).where((File file) => path.extension(file.path) == '.dart').toList();
  final problems = <String>[];
  for (final file in files) {
    var lineCount = 0;
    for (final String line in file.readAsLinesSync()) {
      if (line.toLowerCase().contains('checked mode')) {
        problems.add(
          '${file.path}:$lineCount uses deprecated "checked mode" instead of "debug mode".',
        );
      }
      lineCount += 1;
    }
  }
  if (problems.isNotEmpty) {
    foundError(problems);
  }
}

Future<void> verifyNoRuntimeTypeInToString(String workingDirectory) async {
  final String flutterLib = path.join(workingDirectory, 'packages', 'flutter', 'lib');
  final excludedFiles = <String>{
    path.join(flutterLib, 'src', 'foundation', 'object.dart'), // Calls this from within an assert.
  };
  final List<File> files = await _allFiles(
    flutterLib,
    'dart',
    minimumMatches: 400,
  ).where((File file) => !excludedFiles.contains(file.path)).toList();
  final toStringRegExp = RegExp(r'^\s+String\s+to(.+?)?String(.+?)?\(\)\s+(\{|=>)');
  final problems = <String>[];
  for (final file in files) {
    final List<String> lines = file.readAsLinesSync();
    for (var index = 0; index < lines.length; index++) {
      if (toStringRegExp.hasMatch(lines[index])) {
        final int sourceLine = index + 1;
        bool checkForRuntimeType(String line) {
          if (line.contains(r'$runtimeType') || line.contains('runtimeType.toString()')) {
            problems.add('${file.path}:$sourceLine}: toString calls runtimeType.toString');
            return true;
          }
          return false;
        }

        if (checkForRuntimeType(lines[index])) {
          continue;
        }
        if (lines[index].contains('=>')) {
          while (!lines[index].contains(';')) {
            index++;
            assert(index < lines.length, 'Source file $file has unterminated toString method.');
            if (checkForRuntimeType(lines[index])) {
              break;
            }
          }
        } else {
          int openBraceCount =
              '{'.allMatches(lines[index]).length - '}'.allMatches(lines[index]).length;
          while (!lines[index].contains('}') && openBraceCount > 0) {
            index++;
            assert(
              index < lines.length,
              'Source file $file has unbalanced braces in a toString method.',
            );
            if (checkForRuntimeType(lines[index])) {
              break;
            }
            openBraceCount += '{'.allMatches(lines[index]).length;
            openBraceCount -= '}'.allMatches(lines[index]).length;
          }
        }
      }
    }
  }
  if (problems.isNotEmpty) {
    foundError(problems);
  }
}

Future<void> verifyNoTrailingSpaces(String workingDirectory, {int minimumMatches = 4000}) async {
  final List<File> files = await _allFiles(workingDirectory, null, minimumMatches: minimumMatches)
      .where((File file) => path.basename(file.path) != 'serviceaccount.enc')
      .where((File file) => path.basename(file.path) != 'Ahem.ttf')
      .where((File file) => path.extension(file.path) != '.snapshot')
      .where((File file) => path.extension(file.path) != '.png')
      .where((File file) => path.extension(file.path) != '.jpg')
      .where((File file) => path.extension(file.path) != '.ico')
      .where((File file) => path.extension(file.path) != '.jar')
      .where((File file) => path.extension(file.path) != '.swp')
      .toList();
  final problems = <String>[];
  for (final file in files) {
    final List<String> lines = file.readAsLinesSync();
    for (var index = 0; index < lines.length; index += 1) {
      if (lines[index].endsWith(' ')) {
        problems.add('${file.path}:${index + 1}: trailing U+0020 space character');
      } else if (lines[index].endsWith('\t')) {
        problems.add('${file.path}:${index + 1}: trailing U+0009 tab character');
      }
    }
    if (lines.isNotEmpty && lines.last == '') {
      problems.add('${file.path}:${lines.length}: trailing blank line');
    }
  }
  if (problems.isNotEmpty) {
    foundError(problems);
  }
}

final RegExp _flowControlStatementWithoutSpace = RegExp(
  r'(^|[ \t])(if|switch|for|do|while|catch)\(',
  multiLine: true,
);

Future<void> verifySpacesAfterFlowControlStatements(
  String workingDirectory, {
  int minimumMatches = 4000,
}) async {
  const extensions = <String>{
    // .dart omitted from this list because the Dart auto formatter ensures
    // spaces after flow control statements.
    '.java',
    '.js',
    '.kt',
    '.swift',
    '.c',
    '.cc',
    '.cpp',
    '.h',
    '.m',
  };
  final List<File> files = await _allFiles(
    workingDirectory,
    null,
    minimumMatches: minimumMatches,
  ).where((File file) => extensions.contains(path.extension(file.path))).toList();
  final problems = <String>[];
  for (final file in files) {
    final List<String> lines = file.readAsLinesSync();
    for (var index = 0; index < lines.length; index += 1) {
      if (lines[index].contains(_flowControlStatementWithoutSpace)) {
        problems.add('${file.path}:${index + 1}: no space after flow control statement');
      }
    }
  }
  if (problems.isNotEmpty) {
    foundError(problems);
  }
}

String _bullets(String value) => ' * $value';

Future<void> verifyIssueLinks(String workingDirectory) async {
  const issueLinkPrefix = 'https://github.com/flutter/flutter/issues/new';
  const stops = <String>{'\n', ' ', "'", '"', r'\', ')', '>'};
  assert(
    !stops.contains('.'),
  ); // instead of "visit https://foo." say "visit: https://foo", it copy-pastes better
  const kGiveTemplates =
      'Prefer to provide a link either to $issueLinkPrefix/choose (the list of issue '
      'templates) or to a specific template directly ($issueLinkPrefix?template=...).\n';
  final Set<String> templateNames =
      Directory(path.join(workingDirectory, '.github', 'ISSUE_TEMPLATE'))
          .listSync()
          .whereType<File>()
          .where(
            (File file) =>
                path.extension(file.path) == '.md' || path.extension(file.path) == '.yml',
          )
          .map<String>((File file) => path.basename(file.path))
          .toSet();
  final kTemplates = 'The available templates are:\n${templateNames.map(_bullets).join("\n")}';
  final problems = <String>[];
  final suggestions = <String>{};
  final List<File> files = await _gitFiles(workingDirectory);
  for (final file in files) {
    if (path.basename(file.path).endsWith('_test.dart') ||
        path.basename(file.path) == 'analyze.dart' ||
        FileSystemEntity.isLinkSync(file.path)) {
      continue; // Skip tests, they're not public-facing. Skip symlinks.
    }
    final Uint8List bytes = file.readAsBytesSync();
    // We allow invalid UTF-8 here so that binaries don't trip us up.
    // There's a separate test in this file that verifies that all text
    // files are actually valid UTF-8 (see verifyNoBinaries below).
    final String contents = utf8.decode(bytes, allowMalformed: true);
    var start = 0;
    while ((start = contents.indexOf(issueLinkPrefix, start)) >= 0) {
      int end = start + issueLinkPrefix.length;
      while (end < contents.length && !stops.contains(contents[end])) {
        end += 1;
      }
      final String url = contents.substring(start, end);
      if (url == issueLinkPrefix) {
        if (file.path != path.join(workingDirectory, 'dev', 'bots', 'analyze.dart')) {
          problems.add('${file.path} contains a direct link to $issueLinkPrefix.');
          suggestions.add(kGiveTemplates);
          suggestions.add(kTemplates);
        }
      } else if (url.startsWith('$issueLinkPrefix?')) {
        final Uri parsedUrl = Uri.parse(url);
        final List<String>? templates = parsedUrl.queryParametersAll['template'];
        if (templates == null) {
          problems.add('${file.path} contains $url, which has no "template" argument specified.');
          suggestions.add(kGiveTemplates);
          suggestions.add(kTemplates);
        } else if (templates.length != 1) {
          problems.add(
            '${file.path} contains $url, which has ${templates.length} templates specified.',
          );
          suggestions.add(kGiveTemplates);
          suggestions.add(kTemplates);
        } else if (!templateNames.contains(templates.single)) {
          problems.add(
            '${file.path} contains $url, which specifies a non-existent template ("${templates.single}").',
          );
          suggestions.add(kTemplates);
        } else if (parsedUrl.queryParametersAll.keys.length > 1) {
          problems.add(
            '${file.path} contains $url, which the analyze.dart script is not sure how to handle.',
          );
          suggestions.add(
            'Update analyze.dart to handle the URLs above, or change them to the expected pattern.',
          );
        }
      } else if (url != '$issueLinkPrefix/choose') {
        problems.add(
          '${file.path} contains $url, which the analyze.dart script is not sure how to handle.',
        );
        suggestions.add(
          'Update analyze.dart to handle the URLs above, or change them to the expected pattern.',
        );
      }
      start = end;
    }
  }
  assert(problems.isEmpty == suggestions.isEmpty);
  if (problems.isNotEmpty) {
    foundError(<String>[...problems, ...suggestions]);
  }
}

Future<void> verifyRepositoryLinks(String workingDirectory) async {
  const stops = <String>{'\n', ' ', "'", '"', r'\', ')', '>'};
  assert(
    !stops.contains('.'),
  ); // instead of "visit https://foo." say "visit: https://foo", it copy-pastes better

  // Repos whose default branch is still 'master'
  const repoExceptions = <String>{
    'chromium/chromium',
    'clojure/clojure',
    'dart-lang/test', // TODO(guidezpl): remove when https://github.com/dart-lang/test/issues/2209 is closed
    'eseidelGoogle/bezier_perf',
    'flutter/devtools', // TODO(guidezpl): remove when https://github.com/flutter/devtools/issues/7551 is closed
    'flutter/flutter-intellij', // TODO(guidezpl): remove when https://github.com/flutter/flutter-intellij/issues/7342 is closed
    'flutter/platform_tests', // TODO(guidezpl): remove when subtask in https://github.com/flutter/flutter/issues/121564 is complete
    'flutter/web_installers',
    'glfw/glfw',
    'GoogleCloudPlatform/artifact-registry-maven-tools',
    'material-components/material-components-android', // TODO(guidezpl): remove when https://github.com/material-components/material-components-android/issues/4144 is closed
    'ninja-build/ninja',
    'torvalds/linux',
    'tpn/winsdk-10',
  };

  // See dev/bots/test/analyze-test-input/root/packages/foo/bad_repository_links.dart
  // for examples of repository links that are not allowed.
  final pattern = RegExp(
    r'^(https:\/\/(?:cs\.opensource\.google|github|raw\.githubusercontent|source\.chromium|([a-z0-9\-]+)\.googlesource)\.)',
  );

  final problems = <String>[];
  final suggestions = <String>{};
  final List<File> files = await _allFiles(workingDirectory, null, minimumMatches: 10).toList();
  for (final file in files) {
    final Uint8List bytes = file.readAsBytesSync();
    // We allow invalid UTF-8 here so that binaries don't trip us up.
    // There's a separate test in this file that verifies that all text
    // files are actually valid UTF-8 (see verifyNoBinaries below).
    final String contents = utf8.decode(bytes, allowMalformed: true);
    var start = 0;
    while ((start = contents.indexOf('https://', start)) >= 0) {
      // Find all 'https://' links
      int end = start + 8; // Length of 'https://'
      while (end < contents.length && !stops.contains(contents[end])) {
        end += 1;
      }
      final String url = contents.substring(start, end).replaceAll('\r', '');

      if (pattern.hasMatch(url) && !repoExceptions.any(url.contains)) {
        if (url.contains('master')) {
          problems.add('${file.path} contains $url, which uses the banned "master" branch.');
          suggestions.add(
            'Change the URLs above to the expected pattern by '
            'using the "main" branch if it exists, otherwise adding the '
            'repository to the list of exceptions in analyze.dart.',
          );
        }
      }
      start = end;
    }
  }
  assert(problems.isEmpty == suggestions.isEmpty);
  if (problems.isNotEmpty) {
    foundError(<String>[...problems, ...suggestions]);
  }
}

@immutable
class Hash256 {
  const Hash256(this.a, this.b, this.c, this.d);

  factory Hash256.fromDigest(Digest digest) {
    assert(digest.bytes.length == 32);
    return Hash256(
      digest.bytes[0] << 56 |
          digest.bytes[1] << 48 |
          digest.bytes[2] << 40 |
          digest.bytes[3] << 32 |
          digest.bytes[4] << 24 |
          digest.bytes[5] << 16 |
          digest.bytes[6] << 8 |
          digest.bytes[7] << 0,
      digest.bytes[8] << 56 |
          digest.bytes[9] << 48 |
          digest.bytes[10] << 40 |
          digest.bytes[11] << 32 |
          digest.bytes[12] << 24 |
          digest.bytes[13] << 16 |
          digest.bytes[14] << 8 |
          digest.bytes[15] << 0,
      digest.bytes[16] << 56 |
          digest.bytes[17] << 48 |
          digest.bytes[18] << 40 |
          digest.bytes[19] << 32 |
          digest.bytes[20] << 24 |
          digest.bytes[21] << 16 |
          digest.bytes[22] << 8 |
          digest.bytes[23] << 0,
      digest.bytes[24] << 56 |
          digest.bytes[25] << 48 |
          digest.bytes[26] << 40 |
          digest.bytes[27] << 32 |
          digest.bytes[28] << 24 |
          digest.bytes[29] << 16 |
          digest.bytes[30] << 8 |
          digest.bytes[31] << 0,
    );
  }

  final int a;
  final int b;
  final int c;
  final int d;

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is Hash256 && other.a == a && other.b == b && other.c == c && other.d == d;
  }

  @override
  int get hashCode => Object.hash(a, b, c, d);
}

// DO NOT ADD ANY ENTRIES TO THIS LIST.
// We have a policy of not checking in binaries into this repository.
// If you are adding/changing template images, use the flutter_template_images
// package and a .img.tmpl placeholder instead.
// If you have other binaries to add, please consult johnmccutchan for advice.
final Set<Hash256> _legacyBinaries = <Hash256>{
  // DEFAULT ICON IMAGES

  // packages/flutter_tools/templates/app/android.tmpl/app/src/main/res/mipmap-hdpi/ic_launcher.png
  // packages/flutter_tools/templates/module/android/host_app_common/app.tmpl/src/main/res/mipmap-hdpi/ic_launcher.png
  // (also used by many examples)
  const Hash256(0x6A7C8F0D703E3682, 0x108F9662F8133022, 0x36240D3F8F638BB3, 0x91E32BFB96055FEF),

  // packages/flutter_tools/templates/app/android.tmpl/app/src/main/res/mipmap-mdpi/ic_launcher.png
  // (also used by many examples)
  const Hash256(0xC7C0C0189145E4E3, 0x2A401C61C9BDC615, 0x754B0264E7AFAE24, 0xE834BB81049EAF81),

  // packages/flutter_tools/templates/app/android.tmpl/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  // (also used by many examples)
  const Hash256(0xE14AA40904929BF3, 0x13FDED22CF7E7FFC, 0xBF1D1AAC4263B5EF, 0x1BE8BFCE650397AA),

  // packages/flutter_tools/templates/app/android.tmpl/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  // (also used by many examples)
  const Hash256(0x4D470BF22D5C17D8, 0x4EDC5F82516D1BA8, 0xA1C09559CD761CEF, 0xB792F86D9F52B540),

  // packages/flutter_tools/templates/app/android.tmpl/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  // (also used by many examples)
  const Hash256(0x3C34E1F298D0C9EA, 0x3455D46DB6B7759C, 0x8211A49E9EC6E44B, 0x635FC5C87DFB4180),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  // (also used by a few examples)
  const Hash256(0x7770183009E91411, 0x2DE7D8EF1D235A6A, 0x30C5834424858E0D, 0x2F8253F6B8D31926),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
  // (also used by many examples)
  const Hash256(0x5925DAB509451F9E, 0xCBB12CE8A625F9D4, 0xC104718EE20CAFF8, 0xB1B51032D1CD8946),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
  // (also used by many examples)
  const Hash256(0xC4D9A284C12301D0, 0xF50E248EC53ED51A, 0x19A10147B774B233, 0x08399250B0D44C55),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
  // (also used by many examples)
  const Hash256(0xBF97F9D3233F33E1, 0x389B09F7B8ADD537, 0x41300CB834D6C7A5, 0xCA32CBED363A4FB2),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
  // (also used by many examples)
  const Hash256(0x285442F69A06B45D, 0x9D79DF80321815B5, 0x46473548A37B7881, 0x9B68959C7B8ED237),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
  // (also used by many examples)
  const Hash256(0x2AB64AF8AC727EA9, 0x9C6AB9EAFF847F46, 0xFBF2A9A0A78A0ABC, 0xBF3180F3851645B4),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
  // (also used by many examples)
  const Hash256(0x9DCA09F4E5ED5684, 0xD3C4DFF41F4E8B7C, 0xB864B438172D72BE, 0x069315FA362930F9),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
  // (also used by many examples)
  const Hash256(0xD5AD04DE321EF37C, 0xACC5A7B960AFCCE7, 0x1BDCB96FA020C482, 0x49C1545DD1A0F497),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
  // (also used by many examples)
  const Hash256(0x809ABFE75C440770, 0xC13C4E2E46D09603, 0xC22053E9D4E0E227, 0x5DCB9C1DCFBB2C75),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
  // (also used by many examples)
  const Hash256(0x3DB08CB79E7B01B9, 0xE81F956E3A0AE101, 0x48D0FAFDE3EA7AA7, 0x0048DF905AA52CFD),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
  // (also used by many examples)
  const Hash256(0x23C13D463F5DCA5C, 0x1F14A14934003601, 0xC29F1218FD461016, 0xD8A22CEF579A665F),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
  // (also used by many examples)
  const Hash256(0x6DB7726530D71D3F, 0x52CB59793EB69131, 0x3BAA04796E129E1E, 0x043C0A58A1BFFD2F),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
  // (also used by many examples)
  const Hash256(0xCEE565F5E6211656, 0x9B64980B209FD5CA, 0x4B3D3739011F5343, 0x250B33A1A2C6EB65),

  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
  // packages/flutter_tools/templates/app/ios.tmpl/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
  // packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
  // (also used by many examples)
  const Hash256(0x93AE7D494FAD0FB3, 0x0CBF3AE746A39C4B, 0xC7A0F8BBF87FBB58, 0x7A3F3C01F3C5CE20),

  // packages/flutter_tools/templates/app/macos.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
  // (also used by a few examples)
  const Hash256(0xB18BEBAAD1AD6724, 0xE48BCDF699BA3927, 0xDF3F258FEBE646A3, 0xAB5C62767C6BAB40),

  // packages/flutter_tools/templates/app/macos.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
  // (also used by a few examples)
  const Hash256(0xF90D839A289ECADB, 0xF2B0B3400DA43EB8, 0x08B84908335AE4A0, 0x07457C4D5A56A57C),

  // packages/flutter_tools/templates/app/macos.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
  // (also used by a few examples)
  const Hash256(0x592C2ABF84ADB2D3, 0x91AED8B634D3233E, 0x2C65369F06018DCD, 0x8A4B27BA755EDCBE),

  // packages/flutter_tools/templates/app/macos.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
  // (also used by a few examples)
  const Hash256(0x75D9A0C034113CA8, 0xA1EC11C24B81F208, 0x6630A5A5C65C7D26, 0xA5DC03A1C0A4478C),

  // packages/flutter_tools/templates/app/macos.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
  // (also used by a few examples)
  const Hash256(0xA896E65745557732, 0xC72BD4EE3A10782F, 0xE2AA95590B5AF659, 0x869E5808DB9C01C1),

  // packages/flutter_tools/templates/app/macos.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
  // (also used by a few examples)
  const Hash256(0x3A69A8A1AAC5D9A8, 0x374492AF4B6D07A4, 0xCE637659EB24A784, 0x9C4DFB261D75C6A3),

  // packages/flutter_tools/templates/app/macos.tmpl/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
  // (also used by a few examples)
  const Hash256(0xD29D4E0AF9256DC9, 0x2D0A8F8810608A5E, 0x64A132AD8B397CA2, 0xC4DDC0B1C26A68C3),

  // packages/flutter_tools/templates/app/web/icons/Icon-192.png.copy.tmpl
  // dev/integration_tests/flutter_gallery/web/icons/Icon-192.png
  const Hash256(0x3DCE99077602F704, 0x21C1C6B2A240BC9B, 0x83D64D86681D45F2, 0x154143310C980BE3),

  // packages/flutter_tools/templates/app/web/icons/Icon-512.png.copy.tmpl
  // dev/integration_tests/flutter_gallery/web/icons/Icon-512.png
  const Hash256(0xBACCB205AE45f0B4, 0x21BE1657259B4943, 0xAC40C95094AB877F, 0x3BCBE12CD544DCBE),

  // packages/flutter_tools/templates/app/web/favicon.png.copy.tmpl
  // dev/integration_tests/flutter_gallery/web/favicon.png
  const Hash256(0x7AB2525F4B86B65D, 0x3E4C70358A17E5A1, 0xAAF6F437f99CBCC0, 0x46DAD73d59BB9015),

  // GALLERY ICONS

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-hdpi/ic_background.png
  const Hash256(0x03CFDE53C249475C, 0x277E8B8E90AC8A13, 0xE5FC13C358A94CCB, 0x67CA866C9862A0DD),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-hdpi/ic_foreground.png
  const Hash256(0x86A83E23A505EFCC, 0x39C358B699EDE12F, 0xC088EE516A1D0C73, 0xF3B5D74DDAD164B1),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  const Hash256(0xD813B1A77320355E, 0xB68C485CD47D0F0F, 0x3C7E1910DCD46F08, 0x60A6401B8DC13647),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xhdpi/ic_background.png
  const Hash256(0x35AFA76BD5D6053F, 0xEE927436C78A8794, 0xA8BA5F5D9FC9653B, 0xE5B96567BB7215ED),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xhdpi/ic_foreground.png
  const Hash256(0x263CE9B4F1F69B43, 0xEBB08AE9FE8F80E7, 0x95647A59EF2C040B, 0xA8AEB246861A7DFF),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  const Hash256(0x5E1A93C3653BAAFF, 0x1AAC6BCEB8DCBC2F, 0x2AE7D68ECB07E507, 0xCB1FA8354B28313A),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xxhdpi/ic_background.png
  const Hash256(0xA5C77499151DDEC6, 0xDB40D0AC7321FD74, 0x0646C0C0F786743F, 0x8F3C3C408CAC5E8C),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xxhdpi/ic_foreground.png
  const Hash256(0x33DE450980A2A16B, 0x1982AC7CDC1E7B01, 0x919E07E0289C2139, 0x65F85BCED8895FEF),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  const Hash256(0xC3B8577F4A89BA03, 0x830944FB06C3566B, 0x4C99140A2CA52958, 0x089BFDC3079C59B7),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xxxhdpi/ic_background.png
  const Hash256(0xDEBC241D6F9C5767, 0x8980FDD46FA7ED0C, 0x5B8ACD26BCC5E1BC, 0x473C89B432D467AD),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xxxhdpi/ic_foreground.png
  const Hash256(0xBEFE5F7E82BF8B64, 0x148D869E3742004B, 0xF821A9F5A1BCDC00, 0x357D246DCC659DC2),

  // dev/integration_tests/flutter_gallery/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  const Hash256(0xC385404341FF9EDD, 0x30FBE76F0EC99155, 0x8EA4F4AFE8CC0C60, 0x1CA3EDEF177E1DA8),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-1024.png
  const Hash256(0x6BE5751A29F57A80, 0x36A4B31CC542C749, 0x984E49B22BD65CAA, 0x75AE8B2440848719),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-120.png
  const Hash256(0x9972A2264BFA8F8D, 0x964AFE799EADC1FA, 0x2247FB31097F994A, 0x1495DC32DF071793),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-152.png
  const Hash256(0x4C7CC9B09BEEDA24, 0x45F57D6967753910, 0x57D68E1A6B883D2C, 0x8C52701A74F1400F),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-167.png
  const Hash256(0x66DACAC1CFE4D349, 0xDBE994CB9125FFD7, 0x2D795CFC9CF9F739, 0xEDBB06CE25082E9C),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-180.png
  const Hash256(0x5188621015EBC327, 0xC9EF63AD76E60ECE, 0xE82BDC3E4ABF09E2, 0xEE0139FA7C0A2BE5),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-20.png
  const Hash256(0x27D2752D04EE9A6B, 0x78410E208F74A6CD, 0xC90D9E03B73B8C60, 0xD05F7D623E790487),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-29.png
  const Hash256(0xBB20556B2826CF85, 0xD5BAC73AA69C2AC3, 0x8E71DAD64F15B855, 0xB30CB73E0AF89307),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-40.png
  const Hash256(0x623820FA45CDB0AC, 0x808403E34AD6A53E, 0xA3E9FDAE83EE0931, 0xB020A3A4EF2CDDE7),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-58.png
  const Hash256(0xC6D631D1E107215E, 0xD4A58FEC5F3AA4B5, 0x0AE9724E07114C0C, 0x453E5D87C2CAD3B3),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-60.png
  const Hash256(0x4B6F58D1EB8723C6, 0xE717A0D09FEC8806, 0x90C6D1EF4F71836E, 0x618672827979B1A2),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-76.png
  const Hash256(0x0A1744CC7634D508, 0xE85DD793331F0C8A, 0x0B7C6DDFE0975D8F, 0x29E91C905BBB1BED),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-80.png
  const Hash256(0x24032FBD1E6519D6, 0x0BA93C0D5C189554, 0xF50EAE23756518A2, 0x3FABACF4BD5DAF08),

  // dev/integration_tests/flutter_gallery/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-87.png
  const Hash256(0xC17BAE6DF6BB234A, 0xE0AF4BEB0B805F12, 0x14E74EB7AA9A30F1, 0x5763689165DA7DDF),

  // STOCKS ICONS

  // dev/benchmarks/test_apps/stocks/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  const Hash256(0x74052AB5241D4418, 0x7085180608BC3114, 0xD12493C50CD8BBC7, 0x56DED186C37ACE84),

  // dev/benchmarks/test_apps/stocks/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
  const Hash256(0xE37947332E3491CB, 0x82920EE86A086FEA, 0xE1E0A70B3700A7DA, 0xDCAFBDD8F40E2E19),

  // dev/benchmarks/test_apps/stocks/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  const Hash256(0xE608CDFC0C8579FB, 0xE38873BAAF7BC944, 0x9C9D2EE3685A4FAE, 0x671EF0C8BC41D17C),

  // dev/benchmarks/test_apps/stocks/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  const Hash256(0xBD53D86977DF9C54, 0xF605743C5ABA114C, 0x9D51D1A8BB917E1A, 0x14CAA26C335CAEBD),

  // dev/benchmarks/test_apps/stocks/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  const Hash256(0x64E4D02262C4F3D0, 0xBB4FDC21CD0A816C, 0x4CD2A0194E00FB0F, 0x1C3AE4142FAC0D15),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png
  const Hash256(0x5BA3283A76918FC0, 0xEE127D0F22D7A0B6, 0xDF03DAED61669427, 0x93D89DDD87A08117),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
  const Hash256(0xCD7F26ED31DEA42A, 0x535D155EC6261499, 0x34E6738255FDB2C4, 0xBD8D4BDDE9A99B05),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-76.png
  const Hash256(0x3FA1225FC9A96A7E, 0xCD071BC42881AB0E, 0x7747EB72FFB72459, 0xA37971BBAD27EE24),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png
  const Hash256(0xCD867001ACD7BBDB, 0x25CDFD452AE89FA2, 0x8C2DC980CAF55F48, 0x0B16C246CFB389BC),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png
  const Hash256(0x848E9736E5C4915A, 0x7945BCF6B32FD56B, 0x1F1E7CDDD914352E, 0xC9681D38EF2A70DA),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Notification.png
  const Hash256(0x654BA7D6C4E05CA0, 0x7799878884EF8F11, 0xA383E1F24CEF5568, 0x3C47604A966983C8),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Notification@2x.png
  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small-40.png
  const Hash256(0x743056FE7D83FE42, 0xA2990825B6AD0415, 0x1AF73D0D43B227AA, 0x07EBEA9B767381D9),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Notification@3x.png
  const Hash256(0xA7E1570812D119CF, 0xEF4B602EF28DD0A4, 0x100D066E66F5B9B9, 0x881765DC9303343B),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png
  const Hash256(0xB4102839A1E41671, 0x62DACBDEFA471953, 0xB1EE89A0AB7594BE, 0x1D9AC1E67DC2B2CE),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small.png
  const Hash256(0x70AC6571B593A967, 0xF1CBAEC9BC02D02D, 0x93AD766D8290ADE6, 0x840139BF9F219019),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png
  const Hash256(0x5D87A78386DA2C43, 0xDDA8FEF2CA51438C, 0xE5A276FE28C6CF0A, 0xEBE89085B56665B6),

  // dev/benchmarks/test_apps/stocks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png
  const Hash256(0x4D9F5E81F668DA44, 0xB20A77F8BF7BA2E1, 0xF384533B5AD58F07, 0xB3A2F93F8635CD96),

  // LEGACY ICONS

  // dev/benchmarks/complex_layout/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@3x.png
  // dev/benchmarks/microbenchmarks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@3x.png
  // examples/flutter_view/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@3x.png
  // (not really sure where this came from, or why neither the template nor most examples use them)
  const Hash256(0x6E645DC9ED913AAD, 0xB50ED29EEB16830D, 0xB32CA12F39121DB9, 0xB7BC1449DDDBF8B8),

  // dev/benchmarks/macrobenchmarks/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  // dev/integration_tests/codegen/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  // dev/integration_tests/ios_add2app/ios_add2app/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  // dev/integration_tests/release_smoke_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  const Hash256(0xDEFAC77E08EC71EC, 0xA04CCA3C95D1FC33, 0xB9F26E1CB15CB051, 0x47DEFC79CDD7C158),

  // examples/flutter_view/ios/Runner/ic_add.png
  // examples/platform_view/ios/Runner/ic_add.png
  const Hash256(0x3CCE7450334675E2, 0xE3AABCA20B028993, 0x127BE82FE0EB3DFF, 0x8B027B3BAF052F2F),

  // examples/image_list/images/coast.jpg
  const Hash256(0xDA957FD30C51B8D2, 0x7D74C2C918692DC4, 0xD3C5C99BB00F0D6B, 0x5EBB30395A6EDE82),

  // examples/image_list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  const Hash256(0xB5792CA06F48A431, 0xD4379ABA2160BD5D, 0xE92339FC64C6A0D3, 0x417AA359634CD905),

  // TEST ASSETS

  // dev/benchmarks/macrobenchmarks/assets/999x1000.png
  const Hash256(0x553E9C36DFF3E610, 0x6A608BDE822A0019, 0xDE4F1769B6FBDB97, 0xBC3C20E26B839F59),

  // dev/bots/test/analyze-test-input/root/packages/foo/serviceaccount.enc
  const Hash256(0xA8100AE6AA1940D0, 0xB663BB31CD466142, 0xEBBDBD5187131B92, 0xD93818987832EB89),

  // dev/automated_tests/icon/test.png
  const Hash256(0xE214B4A0FEEEC6FA, 0x8E7AA8CC9BFBEC40, 0xBCDAC2F2DEBC950F, 0x75AF8EBF02BCE459),

  // dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/android/app/src/main/res/drawable-land-xxhdpi/flutter_splash_screen.png
  // dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/android/app/src/main/res/mipmap-land-xxhdpi/flutter_splash_screen.png
  const Hash256(0x2D4F8D7A3DFEF9D3, 0xA0C66938E169AB58, 0x8C6BBBBD1973E34E, 0x03C428416D010182),

  // dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/android/app/src/main/res/drawable-xxhdpi/flutter_splash_screen.png
  // dev/integration_tests/android_splash_screens/splash_screen_kitchen_sink/android/app/src/main/res/mipmap-xxhdpi/flutter_splash_screen.png
  const Hash256(0xCD46C01BAFA3B243, 0xA6AA1645EEDDE481, 0x143AC8ABAB1A0996, 0x22CAA9D41F74649A),

  // dev/integration_tests/flutter_driver_screenshot_test/assets/red_square.png
  const Hash256(0x40054377E1E084F4, 0x4F4410CE8F44C210, 0xABA945DFC55ED0EF, 0x23BDF9469E32F8D3),

  // dev/integration_tests/flutter_driver_screenshot_test/test_driver/goldens/red_square_image/iPhone7,2.png
  const Hash256(0x7F9D27C7BC418284, 0x01214E21CA886B2F, 0x40D9DA2B31AE7754, 0x71D68375F9C8A824),

  // examples/flutter_view/assets/flutter-mark-square-64.png
  // examples/platform_view/assets/flutter-mark-square-64.png
  const Hash256(0xF416B0D8AC552EC8, 0x819D1F492D1AB5E6, 0xD4F20CF45DB47C22, 0x7BB431FEFB5B67B2),

  // packages/flutter_tools/test/data/intellij/plugins/Dart/lib/Dart.jar
  const Hash256(0x576E489D788A13DB, 0xBF40E4A39A3DAB37, 0x15CCF0002032E79C, 0xD260C69B29E06646),

  // packages/flutter_tools/test/data/intellij/plugins/flutter-intellij.jar
  const Hash256(0x4C67221E25626CB2, 0x3F94E1F49D34E4CF, 0x3A9787A514924FC5, 0x9EF1E143E5BC5690),

  // MISCELLANEOUS

  // dev/bots/serviceaccount.enc
  const Hash256(0x1F19ADB4D80AFE8C, 0xE61899BA776B1A8D, 0xCA398C75F5F7050D, 0xFB0E72D7FBBBA69B),

  // dev/docs/favicon.ico
  const Hash256(0x67368CA1733E933A, 0xCA3BC56EF0695012, 0xE862C371AD4412F0, 0x3EC396039C609965),

  // dev/snippets/assets/code_sample.png
  const Hash256(0xAB2211A47BDA001D, 0x173A52FD9C75EBC7, 0xE158942FFA8243AD, 0x2A148871990D4297),

  // dev/snippets/assets/code_snippet.png
  const Hash256(0xDEC70574DA46DFBB, 0xFA657A771F3E1FBD, 0xB265CFC6B2AA5FE3, 0x93BA4F325D1520BA),

  // packages/flutter_tools/static/Ahem.ttf
  const Hash256(0x63D2ABD0041C3E3B, 0x4B52AD8D382353B5, 0x3C51C6785E76CE56, 0xED9DACAD2D2E31C4),
};

Future<void> verifyNoBinaries(String workingDirectory, {Set<Hash256>? legacyBinaries}) async {
  // Please do not add anything to the _legacyBinaries set above.
  // We have a policy of not checking in binaries into this repository.
  // If you are adding/changing template images, use the flutter_template_images
  // package and a .img.tmpl placeholder instead.
  // If you have other binaries to add, please consult johnmccutchan for advice.
  assert(
    _legacyBinaries
            .expand<int>((Hash256 hash) => <int>[hash.a, hash.b, hash.c, hash.d])
            .reduce((int value, int element) => value ^ element) ==
        0x606B51C908B40BFA, // Please do not modify this line.
  );
  legacyBinaries ??= _legacyBinaries;
  if (!Platform.isWindows) {
    // TODO(ianh): Port this to Windows
    final List<File> files = await _gitFiles(workingDirectory);
    final problems = <String>[];
    for (final file in files) {
      if (FileSystemEntity.isLinkSync(file.path)) {
        continue; // Skip symlinks.
      }
      final Uint8List bytes = file.readAsBytesSync();
      try {
        utf8.decode(bytes);
      } on FormatException catch (error) {
        final Digest digest = sha256.convert(bytes);
        if (!legacyBinaries.contains(Hash256.fromDigest(digest))) {
          problems.add('${file.path}:${error.offset}: file is not valid UTF-8');
        }
      }
    }
    if (problems.isNotEmpty) {
      foundError(<String>[
        ...problems,
        'All files in this repository must be UTF-8. In particular, images and other binaries',
        'must not be checked into this repository. This is because we are very sensitive to the',
        'size of the repository as it is distributed to all our developers. If you have a binary',
        'to which you need access, you should consider how to fetch it from another repository;',
        'for example, the "assets-for-api-docs" repository is used for images in API docs.',
        'To add assets to flutter_tools templates, see the instructions in the wiki:',
        'https://github.com/flutter/flutter/blob/main/docs/tool/Managing-template-image-assets.md',
      ]);
    }
  }
}

// UTILITY FUNCTIONS

bool _listEquals<T>(List<T> a, List<T> b) {
  if (a.length != b.length) {
    return false;
  }
  for (var index = 0; index < a.length; index += 1) {
    if (a[index] != b[index]) {
      return false;
    }
  }
  return true;
}

Future<List<File>> _gitFiles(String workingDirectory, {bool runSilently = true}) async {
  final EvalResult evalResult = await _evalCommand(
    'git',
    <String>['ls-files', '-z'],
    workingDirectory: workingDirectory,
    runSilently: runSilently,
  );
  if (evalResult.exitCode != 0) {
    foundError(<String>[
      'git ls-files failed with exit code ${evalResult.exitCode}',
      '${bold}stdout:$reset',
      evalResult.stdout,
      '${bold}stderr:$reset',
      evalResult.stderr,
    ]);
  }
  final List<String> filenames = evalResult.stdout.split('\x00');
  assert(filenames.last.isEmpty); // git ls-files gives a trailing blank 0x00
  filenames.removeLast();
  return filenames
      .where((String filename) => !filename.startsWith('engine/'))
      .map<File>((String filename) => File(path.join(workingDirectory, filename)))
      .toList();
}

Stream<File> _allFiles(
  String workingDirectory,
  String? extension, {
  required int minimumMatches,
}) async* {
  assert(
    extension == null || !extension.startsWith('.'),
    'Extension argument should not start with a period.',
  );

  final List<File> gitFiles = [
    for (final File f in await _gitFiles(workingDirectory)) File(path.normalize(f.path)),
  ];

  final Set<String> dartIgnoreDirectories = gitFiles
      .where((File f) => path.basename(f.path) == '.dartignore')
      .map((File f) => path.dirname(f.path))
      .toSet();

  const skipDirectories = {'.git', '.idea', '.gradle', '.dart_tool', 'build'};

  var matches = 0;
  for (final file in gitFiles) {
    if (extension != null && path.extension(file.path) != '.$extension') {
      continue;
    }
    if (dartIgnoreDirectories.any((String d) => path.isWithin(d, file.path))) {
      continue;
    }
    final String relativePath = path.relative(file.path, from: workingDirectory);
    final List<String> components = path.split(relativePath);
    if (components.any((String c) => skipDirectories.contains(c) || c.endsWith('.tmpl'))) {
      continue;
    }
    if (_isGeneratedPluginRegistrant(file)) {
      continue;
    }
    switch (path.basename(file.path)) {
      case 'flutter_export_environment.sh' || 'gradlew.bat' || '.DS_Store':
        continue;
    }
    final FileStat stat = file.statSync();
    if (stat.type != FileSystemEntityType.file) {
      continue;
    }
    matches += 1;
    yield file;
  }

  assert(
    matches >= minimumMatches,
    'Expected to find at least $minimumMatches files with extension ".$extension" in "$workingDirectory", but only found $matches.',
  );
}

class EvalResult {
  EvalResult({required this.stdout, required this.stderr, this.exitCode = 0});

  static const kNotFoundExitCode = 127;

  final String stdout;
  final String stderr;
  final int exitCode;
}

// TODO(ianh): Refactor this to reuse the code in run_command.dart
Future<EvalResult> _evalCommand(
  String executable,
  List<String> arguments, {
  required String workingDirectory,
  Map<String, String>? environment,
  bool allowNonZeroExit = false,
  bool runSilently = false,
}) async {
  final commandDescription =
      '${path.relative(executable, from: workingDirectory)} ${arguments.join(' ')}';
  final String relativeWorkingDir = path.relative(workingDirectory);

  if (!runSilently) {
    print('RUNNING: cd $cyan$relativeWorkingDir$reset; $green$commandDescription$reset');
  }

  final time = Stopwatch()..start();
  final Process process;

  try {
    process = await Process.start(
      executable,
      arguments,
      workingDirectory: workingDirectory,
      environment: environment,
    );
  } on ProcessException catch (e) {
    return EvalResult(stdout: '', stderr: e.toString(), exitCode: EvalResult.kNotFoundExitCode);
  }

  final Future<List<List<int>>> savedStdout = process.stdout.toList();
  final Future<List<List<int>>> savedStderr = process.stderr.toList();
  final int exitCode = await process.exitCode;
  final result = EvalResult(
    stdout: utf8.decode((await savedStdout).expand<int>((List<int> ints) => ints).toList()),
    stderr: utf8.decode((await savedStderr).expand<int>((List<int> ints) => ints).toList()),
    exitCode: exitCode,
  );

  if (!runSilently) {
    print(
      'ELAPSED TIME: $bold${prettyPrintDuration(time.elapsed)}$reset for $commandDescription in $relativeWorkingDir',
    );
  }

  if (exitCode != 0 && !allowNonZeroExit) {
    foundError(<String>[
      result.stderr,
      '${bold}ERROR:$red Last command exited with $exitCode.$reset',
      '${bold}Command:$red $commandDescription$reset',
      '${bold}Relative working directory:$red $relativeWorkingDir$reset',
    ]);
  }

  return result;
}

Future<void> _checkConsumerDependencies() async {
  const kCorePackages = <String>[
    'flutter',
    'flutter_test',
    'flutter_driver',
    'flutter_localizations',
    'integration_test',
    'fuchsia_remote_debug_protocol',
  ];
  final dependencies = <String>{};

  // Parse the output of pub deps --json to determine all of the
  // current packages used by the core set of flutter packages.
  for (final package in kCorePackages) {
    final ProcessResult result = await Process.run(flutter, <String>[
      'pub',
      'deps',
      '--json',
      '--directory=${path.join(flutterRoot, 'packages', package)}',
    ]);
    if (result.exitCode != 0) {
      foundError(<String>[result.stdout.toString(), result.stderr.toString()]);
      return;
    }
    final rawJson = json.decode(result.stdout as String) as Map<String, Object?>;
    final dependencyTree = <String, Map<String, Object?>>{
      for (final Map<String, Object?> package
          in (rawJson['packages']! as List<Object?>).cast<Map<String, Object?>>())
        package['name']! as String: package,
    };
    final workset = <Map<String, Object?>>[];
    workset.add(dependencyTree[package]!);

    while (workset.isNotEmpty) {
      final Map<String, Object?> currentPackage = workset.removeLast();
      if (currentPackage['kind'] == 'dev') {
        continue;
      }
      dependencies.add(currentPackage['name']! as String);

      final List<String> currentDependencies =
          (currentPackage['directDependencies']! as List<Object?>).cast<String>();
      for (final dependency in currentDependencies) {
        // Don't add dependencies we've already seen or we will get stuck
        // forever if there are any circular references.
        // TODO(dantup): Consider failing gracefully with the names of the
        //  packages once the cycle between test_api and matcher is resolved.
        //  https://github.com/dart-lang/test/issues/1979
        if (!dependencies.contains(dependency)) {
          workset.add(dependencyTree[dependency]!);
        }
      }
    }
  }

  final Set<String> removed = kCorePackageAllowList.difference(dependencies);
  final Set<String> added = dependencies.difference(kCorePackageAllowList);

  String plural(int n, String s, String p) => n == 1 ? s : p;

  if (added.isNotEmpty) {
    foundError(<String>[
      'The transitive closure of package dependencies contains ${plural(added.length, "a non-allowlisted package", "non-allowlisted packages")}:',
      '  ${added.join(', ')}',
      'We strongly desire to keep the number of dependencies to a minimum and',
      'therefore would much prefer not to add new dependencies.',
      'See dev/bots/allowlist.dart for instructions on how to update the package',
      'allowlist if you nonetheless believe this is a necessary addition.',
    ]);
  }

  if (removed.isNotEmpty) {
    foundError(<String>[
      'Excellent news! ${plural(removed.length, "A package dependency has been removed!", "Multiple package dependencies have been removed!")}',
      '  ${removed.join(', ')}',
      'To make sure we do not accidentally add ${plural(removed.length, "this dependency", "these dependencies")} back in the future,',
      'please remove ${plural(removed.length, "this", "these")} packages from the allow-list in dev/bots/allowlist.dart.',
      'Thanks!',
    ]);
  }
}

class _DebugOnlyFieldVisitor extends RecursiveAstVisitor<void> {
  _DebugOnlyFieldVisitor(this.parseResult);

  final ParseStringResult parseResult;
  final List<AstNode> errors = <AstNode>[];

  static const String _kDebugOnlyAnnotation = '_debugOnly';
  static final RegExp _nullInitializedField = RegExp(r'kDebugMode \? [\w<> ,{}()]+ : null;');

  @override
  void visitFieldDeclaration(FieldDeclaration node) {
    super.visitFieldDeclaration(node);
    if (node.metadata.any(
      (Annotation annotation) => annotation.name.name == _kDebugOnlyAnnotation,
    )) {
      if (!node.toSource().contains(_nullInitializedField)) {
        errors.add(node.fields); // Use the fields node for line number.
      }
    }
  }
}

Future<void> verifyNullInitializedDebugExpensiveFields(
  String workingDirectory, {
  int minimumMatches = 400,
}) async {
  final String flutterLib = path.join(workingDirectory, 'packages', 'flutter', 'lib');
  final List<File> files = await _allFiles(
    flutterLib,
    'dart',
    minimumMatches: minimumMatches,
  ).toList();
  final errors = <String>[];
  for (final file in files) {
    final ParseStringResult parsedFile = parseFile(
      featureSet: _parsingFeatureSet(),
      path: file.absolute.path,
    );
    final visitor = _DebugOnlyFieldVisitor(parsedFile);
    visitor.visitCompilationUnit(parsedFile.unit);
    for (final AstNode badNode in visitor.errors) {
      errors.add(
        '${file.path}:${parsedFile.lineInfo.getLocation(badNode.offset).lineNumber}: fields annotated with @_debugOnly must null initialize.',
      );
    }
  }
  if (errors.isNotEmpty) {
    foundError(<String>[
      ...errors,
      '',
      '$bold${red}Fields annotated with @_debugOnly must null initialize,$reset',
      'to ensure both the field and initializer are removed from profile/release mode.',
      'These fields should be written as:',
      'field = kDebugMode ? <DebugValue> : null;',
    ]);
  }
}

final RegExp tabooPattern = RegExp(r'^ *///.*\b(simply|note:|note that)\b', caseSensitive: false);

Future<void> verifyTabooDocumentation(String workingDirectory, {int minimumMatches = 100}) async {
  final errors = <String>[];
  await for (final File file in _allFiles(
    workingDirectory,
    'dart',
    minimumMatches: minimumMatches,
  )) {
    final List<String> lines = file.readAsLinesSync();
    for (var index = 0; index < lines.length; index += 1) {
      final String line = lines[index];
      final Match? match = tabooPattern.firstMatch(line);
      if (match != null) {
        errors.add(
          '${file.path}:${index + 1}: Found use of the taboo word "${match.group(1)}" in documentation string.',
        );
      }
    }
  }
  if (errors.isNotEmpty) {
    foundError(<String>[
      ...errors,
      '',
      '${bold}Avoid the word "simply" in documentation. See https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#use-the-passive-voice-recommend-do-not-require-never-say-things-are-simple for details.$reset',
      '${bold}In many cases these words can be omitted without loss of generality; in other cases it may require a bit of rewording to avoid implying that the task is simple.$reset',
      '${bold}Similarly, avoid using "note:" or the phrase "note that". See https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#avoid-empty-prose for details.$reset',
    ]);
  }
}

final Map<String, String> _kKotlinTemplateKeys = <String, String>{
  'androidIdentifier': 'dummyPackage',
  'pluginClass': 'PluginClass',
  'projectName': 'dummy',
  'agpVersion': '0.0.0.1',
  'kotlinVersion': '0.0.0.1',
};

final String _kKotlinTemplateRelativePath = path.join('packages', 'flutter_tools', 'templates');

const List<String> _kKotlinExtList = <String>['.kt.tmpl', '.kts.tmpl'];
const String _kKotlinTmplExt = '.tmpl';
final RegExp _kKotlinTemplatePattern = RegExp(r'{{(.*?)}}');

/// Copy kotlin template files from [_kKotlinTemplateRelativePath] into a system tmp folder
/// then replace template values with values from [_kKotlinTemplateKeys] or "'dummy'" if an
/// unknown key is found. Then run ktlint on the tmp folder to check for lint errors in the
/// generated Kotlin files.
Future<void> lintKotlinTemplatedFiles(String workingDirectory) async {
  final String templatePath = path.join(workingDirectory, _kKotlinTemplateRelativePath);
  final Iterable<File> files = Directory(templatePath)
      .listSync(recursive: true)
      .toList()
      .whereType<File>()
      .where((File file) => _kKotlinExtList.contains(path.extension(file.path, 2)));

  if (files.isEmpty) {
    foundError(<String>['No Kotlin template files found']);
    return;
  }

  final Directory tempDir = Directory.systemTemp.createTempSync('template_output');
  for (final templateFile in files) {
    final String inputContent = await templateFile.readAsString();
    final String modifiedContent = inputContent.replaceAllMapped(
      _kKotlinTemplatePattern,
      (Match match) => _kKotlinTemplateKeys[match[1]] ?? 'dummy',
    );

    String outputFilename = path.basename(templateFile.path);
    outputFilename = outputFilename.substring(
      0,
      outputFilename.length - _kKotlinTmplExt.length,
    ); // Remove '.tmpl' from file path

    // Ensure the first letter of the generated class is uppercase (instead of pluginClass)
    outputFilename = outputFilename.substring(0, 1).toUpperCase() + outputFilename.substring(1);

    final String relativePath = path.dirname(path.relative(templateFile.path, from: templatePath));
    final String outputDir = path.join(tempDir.path, relativePath);
    await Directory(outputDir).create(recursive: true);
    final String outputFile = path.join(outputDir, outputFilename);
    final output = File(outputFile);
    await output.writeAsString(modifiedContent);
  }
  return lintKotlinFiles(tempDir.path).whenComplete(() {
    tempDir.deleteSync(recursive: true);
  });
}

Future<void> lintKotlinFiles(String workingDirectory) async {
  const baselineRelativePath = 'dev/bots/test/analyze-test-input/ktlint-baseline.xml';
  const editorConfigRelativePath = 'dev/bots/test/analyze-test-input/.editorconfig';
  final EvalResult lintResult = await _evalCommand('ktlint', <String>[
    '--baseline=$flutterRoot/$baselineRelativePath',
    '--editorconfig=$flutterRoot/$editorConfigRelativePath',
  ], workingDirectory: workingDirectory);
  if (lintResult.exitCode == EvalResult.kNotFoundExitCode) {
    foundError(<String>['Failed to find ktlint on PATH. Kotlin code analysis failed.']);
  } else if (lintResult.exitCode != 0) {
    final errorMessage =
        'Found lint violations in Kotlin files:\n ${lintResult.stdout}\n\n'
        'To reproduce this lint locally:\n'
        '1. Identify the CIPD version tag used to resolve this particular version of ktlint (check the dependencies section of this shard in the ci.yaml). \n'
        '2. Download that version from https://chrome-infra-packages.appspot.com/p/flutter/ktlint/linux-amd64/+/<version_tag>\n'
        '3. From the repository root, run `<path_to_ktlint>/ktlint --editorconfig=$editorConfigRelativePath --baseline=$baselineRelativePath`\n'
        'Alternatively, if you use Android Studio, follow the docs at docs/platforms/android/Kotlin-android-studio-formatting.md to enable auto formatting.';
    foundError(<String>[errorMessage]);
  }
}

const List<String> _kIgnoreList = <String>['Runner.rc.tmpl', 'flutter_window.cpp'];
final String _kIntegrationTestsRelativePath = path.join('dev', 'integration_tests');
final String _kTemplateRelativePath = path.join(
  'packages',
  'flutter_tools',
  'templates',
  'app',
  'windows.tmpl',
  'runner',
);
final String _kWindowsRunnerSubPath = path.join('windows', 'runner');
const String _kProjectNameKey = '{{projectName}}';
const String _kTmplExt = '.tmpl';

const String _kFlutterLicense =
    '// Copyright 2014 The Flutter Authors. All rights reserved.\n'
    '// Use of this source code is governed by a BSD-style license that can be\n'
    '// found in the LICENSE file.\n'
    '\n';

const String _kFlutterLicenseHtml = '''
<!-- Copyright 2014 The Flutter Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
''';

String _removeLicenseIfPresent(String fileContents) {
  if (fileContents.startsWith(_kFlutterLicense)) {
    return fileContents.substring(_kFlutterLicense.length);
  }
  if (fileContents.contains(_kFlutterLicenseHtml)) {
    return fileContents.replaceFirst(_kFlutterLicenseHtml, '');
  }
  return fileContents;
}

Future<void> verifyIntegrationTestTemplateFiles(String flutterRoot) async {
  final errors = <String>[];
  final String integrationTestsPath = path.join(flutterRoot, _kIntegrationTestsRelativePath);
  final String templatePath = path.join(flutterRoot, _kTemplateRelativePath);
  final Iterable<Directory> subDirs = Directory(
    integrationTestsPath,
  ).listSync().toList().whereType<Directory>();
  for (final testPath in subDirs) {
    final String projectName = path.basename(testPath.path);
    final String runnerPath = path.join(testPath.path, _kWindowsRunnerSubPath);
    final runner = Directory(runnerPath);
    if (!runner.existsSync()) {
      continue;
    }
    final Iterable<File> files = Directory(templatePath).listSync().toList().whereType<File>();
    for (final templateFile in files) {
      final String fileName = path.basename(templateFile.path);
      if (_kIgnoreList.contains(fileName)) {
        continue;
      }
      String templateFileContents = templateFile.readAsLinesSync().join('\n');
      String appFilePath = path.join(runnerPath, fileName);
      if (fileName.endsWith(_kTmplExt)) {
        appFilePath = appFilePath.substring(
          0,
          appFilePath.length - _kTmplExt.length,
        ); // Remove '.tmpl' from app file path
        templateFileContents = templateFileContents.replaceAll(
          _kProjectNameKey,
          projectName,
        ); // Substitute template project name
      }
      String appFileContents = File(appFilePath).readAsLinesSync().join('\n');
      appFileContents = _removeLicenseIfPresent(appFileContents);
      if (appFileContents != templateFileContents) {
        int indexOfDifference;
        for (
          indexOfDifference = 0;
          indexOfDifference < appFileContents.length;
          indexOfDifference++
        ) {
          if (indexOfDifference >= templateFileContents.length ||
              templateFileContents.codeUnitAt(indexOfDifference) !=
                  appFileContents.codeUnitAt(indexOfDifference)) {
            break;
          }
        }
        final error =
            '''
Error: file $fileName mismatched for integration test $testPath
Verify the integration test has been migrated to the latest app template.
=====$appFilePath======
$appFileContents
=====${templateFile.path}======
$templateFileContents
==========
Diff at character #$indexOfDifference
        ''';
        errors.add(error);
      }
    }
  }
  if (errors.isNotEmpty) {
    foundError(errors);
  }
}

Future<CommandResult> _runFlutterAnalyze(
  String workingDirectory, {
  List<String> options = const <String>[],
  String? failureMessage,
}) async {
  return runCommand(
    flutter,
    <String>['analyze', ...options],
    workingDirectory: workingDirectory,
    failureMessage: failureMessage,
  );
}

// These files legitimately require executable permissions
const Set<String> kExecutableAllowlist = <String>{
  '.autoroller-preupload.sh',
  '.claude/skills',
  'bin/dart',
  'bin/flutter',
  'bin/flutter-dev',
  'bin/internal/last_engine_commit.sh',
  'bin/internal/update_dart_sdk.sh',
  'bin/internal/update_engine_version.sh',
  'bin/internal/content_aware_hash.sh',

  'dev/bots/codelabs_build_test.sh',
  'dev/bots/docs.sh',

  'dev/checks',

  'dev/customer_testing/ci.sh',

  'dev/integration_tests/flutter_gallery/tool/run_instrumentation_test.sh',

  'dev/integration_tests/ios_add2app_life_cycle/build_and_test.sh',

  'dev/integration_tests/deferred_components_test/download_assets.sh',
  'dev/integration_tests/deferred_components_test/run_release_test.sh',

  'dev/packages_autoroller/run',

  'dev/tools/gen_keycodes/bin/gen_keycodes',
  'dev/tools/repackage_gradle_wrapper.sh',
  'dev/tools/bin/engine_hash.sh',
  'dev/tools/format.sh',
  'dev/tools/test/mock_git.sh',

  'packages/flutter_tools/bin/macos_assemble.sh',
  'packages/flutter_tools/bin/tool_backend.sh',
  'packages/flutter_tools/bin/xcode_backend.sh',
};

Future<void> _checkForNewExecutables() async {
  // 0b001001001
  const executableBitMask = 0x49;
  final List<File> files = await _gitFiles(flutterRoot);
  final errors = <String>[];
  for (final file in files) {
    final String relativePath = path.relative(file.path, from: flutterRoot);
    final FileStat stat = file.statSync();
    final isExecutable = stat.mode & executableBitMask != 0x0;
    if (isExecutable && !kExecutableAllowlist.contains(relativePath)) {
      errors.add('$relativePath is executable: ${(stat.mode & 0x1FF).toRadixString(2)}');
    }
  }
  if (errors.isNotEmpty) {
    throw Exception(
      '${errors.join('\n')}\n'
      'found ${errors.length} unexpected executable file'
      '${errors.length == 1 ? '' : 's'}! If this was intended, you '
      'must add this file to kExecutableAllowlist in dev/bots/analyze.dart',
    );
  }
}

final RegExp _importPattern = RegExp(r'''^\s*import (['"])package:flutter/([^.]+)\.dart\1''');
final RegExp _importMetaPattern = RegExp(r'''^\s*import (['"])package:meta/meta\.dart\1''');

Future<Set<String>> _findFlutterDependencies(
  String srcPath,
  List<String> errors, {
  bool checkForMeta = false,
}) async {
  return _allFiles(srcPath, 'dart', minimumMatches: 1)
      .map<Set<String>>((File file) {
        final result = <String>{};
        for (final String line in file.readAsLinesSync()) {
          Match? match = _importPattern.firstMatch(line);
          if (match != null) {
            result.add(match.group(2)!);
          }
          if (checkForMeta) {
            match = _importMetaPattern.firstMatch(line);
            if (match != null) {
              errors.add(
                '${file.path}\nThis package imports the ${yellow}meta$reset package.\n'
                'You should instead import the "foundation.dart" library.',
              );
            }
          }
        }
        return result;
      })
      .reduce((Set<String>? value, Set<String> element) {
        value ??= <String>{};
        value.addAll(element);
        return value;
      });
}

List<T>? _deepSearch<T>(Map<T, Set<T>> map, T start, [Set<T>? seen]) {
  if (map[start] == null) {
    return null; // We catch these separately.
  }

  for (final T key in map[start]!) {
    if (key == start) {
      continue; // we catch these separately
    }
    if (seen != null && seen.contains(key)) {
      return <T>[start, key];
    }
    final List<T>? result = _deepSearch<T>(map, key, <T>{
      if (seen == null) start else ...seen,
      key,
    });
    if (result != null) {
      result.insert(0, start);
      // Only report the shortest chains.
      // For example a->b->a, rather than c->a->b->a.
      // Since we visit every node, we know the shortest chains are those
      // that start and end on the loop.
      if (result.first == result.last) {
        return result;
      }
    }
  }
  return null;
}

bool _isGeneratedPluginRegistrant(File file) {
  final String filename = path.basename(file.path);
  return !file.path.contains('.pub-cache') &&
      (filename == 'GeneratedPluginRegistrant.java' ||
          filename == 'GeneratedPluginRegistrant.swift' ||
          filename == 'GeneratedPluginRegistrant.h' ||
          filename == 'GeneratedPluginRegistrant.m' ||
          filename == 'generated_plugin_registrant.dart' ||
          filename == 'generated_plugin_registrant.h' ||
          filename == 'generated_plugin_registrant.cc');
}

Future<void> _verifyPrivateLints(String flutterRoot, CommandResult? dartAnalyzeResult) async {
  if (dartAnalyzeResult == null) {
    foundError(<String>[
      'The "dart-analysis" rule must run before "private-lints".',
      'Ensure "dart-analysis" is not skipped and is included in --only if used.',
    ]);
    return;
  }
  // Only run the private lints when the code is free of type errors. The
  // lints are easier to write when they can assume, for example, there is no
  // inheritance cycles.
  if (dartAnalyzeResult.exitCode == 0) {
    final rules = <AnalyzeRule>[
      noDoubleClamp,
      noStopwatches,
      renderBoxIntrinsicCalculation,
      protectPublicStateSubtypes,
    ];
    final String ruleNames = rules.map((AnalyzeRule rule) => '\n * $rule').join();
    printProgress('Analyzing code in the framework with the following rules:$ruleNames');
    await analyzeWithRules(
      flutterRoot,
      rules,
      includePaths: const <String>['packages/flutter/lib'],
      excludePaths: const <String>['packages/flutter/lib/fix_data'],
    );
    final testRules = <AnalyzeRule>[noStopwatches];
    final String testRuleNames = testRules.map((AnalyzeRule rule) => '\n * $rule').join();
    printProgress('Analyzing code in the test folder with the following rules:$testRuleNames');
    await analyzeWithRules(flutterRoot, testRules, includePaths: <String>['packages/flutter/test']);
    final toolRules = <AnalyzeRule>[AvoidFutureCatchError()];
    final String toolRuleNames = toolRules.map((AnalyzeRule rule) => '\n * $rule').join();
    printProgress('Analyzing code in the tool with the following rules:$toolRuleNames');
    await analyzeWithRules(
      flutterRoot,
      toolRules,
      includePaths: const <String>['packages/flutter_tools/lib', 'packages/flutter_tools/test'],
    );
  }
}

Future<void> _verifyMegaGallery(
  String flutterRoot,
  String dart,
  List<String> passthroughArguments,
) async {
  final Directory outDir = Directory.systemTemp.createTempSync('flutter_mega_gallery.');
  try {
    await runCommand(dart, <String>[
      path.join(flutterRoot, 'dev', 'tools', 'mega_gallery.dart'),
      '--out',
      outDir.path,
    ], workingDirectory: flutterRoot);
    await _runFlutterAnalyze(
      outDir.path,
      failureMessage: 'Dart analyzer failed on mega_gallery benchmark.',
      options: <String>['--watch', '--benchmark', ...passthroughArguments],
    );
  } finally {
    outDir.deleteSync(recursive: true);
  }
}
