// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This script analyzes all the sample code in API docs in the Flutter source.
//
// It uses the following conventions:
//
// Code is denoted by markdown ```dart / ``` markers.
//
// Only code in "## Sample code" or "### Sample code" sections is examined.
// Subheadings can also be specified, as in "## Sample code: foo".
//
// Additionally, code inside of dartdoc snippet and sample blocks
// ({@tool snippet ...}{@end-tool}, and {@tool sample ...}{@end-tool})
// is recognized as sample code. Snippets are processed as separate programs,
// and samples are processed in the same way as "## Sample code" blocks are.
//
// There are several kinds of sample code you can specify:
//
// * Constructor calls, typically showing what might exist in a build method.
//   These start with "new" or "const", and will be inserted into an assignment
//   expression assigning to a variable of type "dynamic" and followed by a
//   semicolon, for the purposes of analysis.
//
// * Class definitions. These start with "class", and are analyzed verbatim.
//
// * Other code. It gets included verbatim, though any line that says "// ..."
//   is considered to separate the block into multiple blocks to be processed
//   individually.
//
// In addition, you can declare code that should be included in the analysis but
// not shown in the API docs by adding a comment "// Examples can assume:" to
// the file (usually at the top of the file, after the imports), following by
// one or more commented-out lines of code. That code is included verbatim in
// the analysis.
//
// All the sample code of every file is analyzed together. This means you can't
// have two pieces of sample code that define the same example class.
//
// Also, the above means that it's tricky to include verbatim imperative code
// (e.g. a call to a method), since it won't be valid to have such code at the
// top level. Instead, wrap it in a function or even a whole class, or make it a
// valid variable declaration.

import 'dart:io';

import 'package:path/path.dart' as path;

// To run this: bin/cache/dart-sdk/bin/dart dev/bots/analyze-sample-code.dart

final String _flutterRoot = path.dirname(path.dirname(path.dirname(path.fromUri(Platform.script))));
final String _defaultFlutterPackage = path.join(_flutterRoot, 'packages', 'flutter', 'lib');
final String _flutter = path.join(_flutterRoot, 'bin', Platform.isWindows ? 'flutter.bat' : 'flutter');

void main(List<String> arguments) {
  Directory flutterPackage;
  if (arguments.length == 1) {
    // Used for testing.
    flutterPackage = Directory(arguments.single);
  } else {
    flutterPackage = Directory(_defaultFlutterPackage);
  }
  exitCode = SampleChecker(flutterPackage).checkSamples();
}

/// Checks samples and code snippets for analysis errors.
///
/// Extracts dartdoc content from flutter package source code, identifies code
/// sections, and writes them to a temporary directory, where 'flutter analyze'
/// is used to analyze the sources for problems. If problems are found, the
/// error output from the analyzer is parsed for details, and the problem
/// locations are translated back to the source location.
///
/// For snippets, the snippets are generated using the snippets tool, and they
/// are analyzed with the samples. If errors are found in snippets, then the
/// line number of the start of the snippet is given instead of the actual error
/// line, since snippets get reformatted when written, and the line numbers
/// don't necessarily match. It does, however, print the source of the
/// problematic line.
class SampleChecker {
  SampleChecker(this._flutterPackage) {
    _tempDir = Directory.systemTemp.createTempSync('flutter_analyze_sample_code.');
  }

  /// The prefix of each comment line
  static const String _dartDocPrefix = '///';

  /// The prefix of each comment line with a space appended.
  static const String _dartDocPrefixWithSpace = '$_dartDocPrefix ';

  /// A RegExp that matches the beginning of a dartdoc snippet or sample.
  static final RegExp _dartDocSampleBeginRegex = RegExp(r'{@tool (sample|snippet)(?:| ([^}]*))}');

  /// A RegExp that matches the end of a dartdoc snippet or sample.
  static final RegExp _dartDocSampleEndRegex = RegExp(r'{@end-tool}');

  /// A RegExp that matches the start of a code block within dartdoc.
  static final RegExp _codeBlockStartRegex = RegExp(r'/// ```dart.*$');

  /// A RegExp that matches the end of a code block within dartdoc.
  static final RegExp _codeBlockEndRegex = RegExp(r'/// ```\s*$');

  /// A RegExp that matches a Dart constructor.
  static final RegExp _constructorRegExp = RegExp(r'[A-Z][a-zA-Z0-9<>.]*\(');

  /// The temporary directory where all output is written. This will be deleted
  /// automatically if there are no errors.
  Directory _tempDir;

  /// The package directory for the flutter package within the flutter root dir.
  final Directory _flutterPackage;

  /// A serial number so that we can create unique expression names when we
  /// generate them.
  int _expressionId = 0;

  /// The exit code from the analysis process.
  int _exitCode = 0;

  // Once the snippets tool has been precompiled by Dart, this contains the AOT
  // snapshot.
  String _snippetsSnapshotPath;

  /// Finds the location of the snippets script.
  String get _snippetsExecutable {
    final String platformScriptPath = path.dirname(path.fromUri(Platform.script));
    return path.canonicalize(path.join(platformScriptPath, '..', 'snippets', 'lib', 'main.dart'));
  }

  static List<File> _listDartFiles(Directory directory, {bool recursive = false}) {
    return directory.listSync(recursive: recursive, followLinks: false)
      .whereType<File>()
      .where((File file) => path.extension(file.path) == '.dart').toList();
  }

  /// Computes the headers needed for each sample file.
  List<Line> get headers {
    if (_headers == null) {
      final List<String> buffer = <String>[];
      buffer.add('// generated code');
      buffer.add('import \'dart:async\';');
      buffer.add('import \'dart:convert\';');
      buffer.add('import \'dart:math\' as math;');
      buffer.add('import \'dart:typed_data\';');
      buffer.add('import \'dart:ui\' as ui;');
      buffer.add('import \'package:flutter_test/flutter_test.dart\';');
      for (File file in _listDartFiles(Directory(_defaultFlutterPackage))) {
        buffer.add('');
        buffer.add('// ${file.path}');
        buffer.add('import \'package:flutter/${path.basename(file.path)}\';');
      }
      _headers = buffer.map<Line>((String code) => Line(code)).toList();
    }
    return _headers;
  }

  List<Line> _headers;

  /// Checks all the samples in the Dart files in [_flutterPackage] for errors.
  int checkSamples() {
    _exitCode = 0;
    Map<String, List<AnalysisError>> errors = <String, List<AnalysisError>>{};
    try {
      final Map<String, Section> sections = <String, Section>{};
      final Map<String, Snippet> snippets = <String, Snippet>{};
      _extractSamples(sections, snippets);
      errors = _analyze(_tempDir, sections, snippets);
    } finally {
      if (errors.isNotEmpty) {
        for (String filePath in errors.keys) {
          errors[filePath].forEach(stderr.writeln);
        }
        stderr.writeln('\nFound ${errors.length} sample code errors.');
      }
      try {
        _tempDir.deleteSync(recursive: true);
      } on FileSystemException catch (e) {
        stderr.writeln('Failed to delete ${_tempDir.path}: $e');
      }
      // If we made a snapshot, remove it (so as not to clutter up the tree).
      if (_snippetsSnapshotPath != null) {
        final File snapshot = File(_snippetsSnapshotPath);
        if (snapshot.existsSync()) {
          snapshot.deleteSync();
        }
      }
    }
    return _exitCode;
  }

  /// Creates a name for the snippets tool to use for the snippet ID from a
  /// filename and starting line number.
  String _createNameFromSource(String prefix, String filename, int start) {
    String snippetId = path.relative(filename, from: _flutterPackage.path);
    snippetId = path.split(snippetId).join('.');
    snippetId = path.basenameWithoutExtension(snippetId);
    snippetId = '$prefix.$snippetId.$start';
    return snippetId;
  }

  // Precompiles the snippets tool if _snippetsSnapshotPath isn't set yet, and
  // runs the precompiled version if it is set.
  ProcessResult _runSnippetsScript(List<String> args) {
    final String workingDirectory = path.join(_flutterRoot, 'dev', 'docs');
    if (_snippetsSnapshotPath == null) {
      _snippetsSnapshotPath = '$_snippetsExecutable.snapshot';
      return Process.runSync(
        path.canonicalize(Platform.executable),
        <String>[
          '--snapshot=$_snippetsSnapshotPath',
          '--snapshot-kind=app-jit',
          path.canonicalize(_snippetsExecutable),
        ]..addAll(args),
        workingDirectory: workingDirectory,
      );
    } else {
      return Process.runSync(
        path.canonicalize(Platform.executable),
        <String>[path.canonicalize(_snippetsSnapshotPath)]..addAll(args),
        workingDirectory: workingDirectory,
      );
    }
  }

  /// Writes out the given [snippet] to an output file in the [_tempDir] and
  /// returns the output file.
  File _writeSnippet(Snippet snippet) {
    // Generate the snippet.
    final String snippetId = _createNameFromSource('snippet', snippet.start.filename, snippet.start.line);
    final String inputName = '$snippetId.input';
    // Now we have a filename like 'lib.src.material.foo_widget.123.dart' for each snippet.
    final File inputFile = File(path.join(_tempDir.path, inputName))..createSync(recursive: true);
    inputFile.writeAsStringSync(snippet.input.join('\n'));
    final File outputFile = File(path.join(_tempDir.path, '$snippetId.dart'));
    final List<String> args = <String>[
      '--output=${outputFile.absolute.path}',
      '--input=${inputFile.absolute.path}',
    ]..addAll(snippet.args);
    print('Generating snippet for ${snippet.start?.filename}:${snippet.start?.line}');
    final ProcessResult process = _runSnippetsScript(args);
    if (process.exitCode != 0) {
      throw 'Unable to create snippet for ${snippet.start.filename}:${snippet.start.line} '
          '(using input from ${inputFile.path}):\n${process.stdout}\n${process.stderr}';
    }
    return outputFile;
  }

  /// Extracts the samples from the Dart files in [_flutterPackage], writes them
  /// to disk, and adds them to the appropriate [sectionMap] or [snippetMap].
  void _extractSamples(Map<String, Section> sectionMap, Map<String, Snippet> snippetMap) {
    final List<Section> sections = <Section>[];
    final List<Snippet> snippets = <Snippet>[];

    for (File file in _listDartFiles(_flutterPackage, recursive: true)) {
      final String relativeFilePath = path.relative(file.path, from: _flutterPackage.path);
      final List<String> sampleLines = file.readAsLinesSync();
      final List<Section> preambleSections = <Section>[];
      bool inPreamble = false;
      bool inSampleSection = false;
      bool inSnippet = false;
      bool inDart = false;
      bool foundDart = false;
      int lineNumber = 0;
      final List<String> block = <String>[];
      List<String> snippetArgs = <String>[];
      Line startLine;
      for (String line in sampleLines) {
        lineNumber += 1;
        final String trimmedLine = line.trim();
        if (inSnippet) {
          if (!trimmedLine.startsWith(_dartDocPrefix)) {
            throw '$relativeFilePath:$lineNumber: Snippet section unterminated.';
          }
          if (_dartDocSampleEndRegex.hasMatch(trimmedLine)) {
            snippets.add(
              Snippet(
                start: startLine,
                input: block,
                args: snippetArgs,
                serial: snippets.length,
              ),
            );
            snippetArgs = <String>[];
            block.clear();
            inSnippet = false;
            inSampleSection = false;
          } else {
            block.add(line.replaceFirst(RegExp(r'\s*/// ?'), ''));
          }
        } else if (inPreamble) {
          if (line.isEmpty) {
            inPreamble = false;
            preambleSections.add(_processBlock(startLine, block));
            block.clear();
          } else if (!line.startsWith('// ')) {
            throw '$relativeFilePath:$lineNumber: Unexpected content in sample code preamble.';
          } else {
            block.add(line.substring(3));
          }
        } else if (inSampleSection) {
          if (!trimmedLine.startsWith(_dartDocPrefix) || trimmedLine.startsWith('$_dartDocPrefix ## ')) {
            if (inDart) {
              throw '$relativeFilePath:$lineNumber: Dart section inexplicably unterminated.';
            }
            if (!foundDart) {
              throw '$relativeFilePath:$lineNumber: No dart block found in sample code section';
            }
            inSampleSection = false;
          } else {
            if (inDart) {
              if (_codeBlockEndRegex.hasMatch(trimmedLine)) {
                inDart = false;
                final Section processed = _processBlock(startLine, block);
                if (preambleSections.isEmpty) {
                  sections.add(processed);
                } else {
                  sections.add(Section.combine(preambleSections
                    ..toList()
                    ..add(processed)));
                }
                block.clear();
              } else if (trimmedLine == _dartDocPrefix) {
                block.add('');
              } else {
                final int index = line.indexOf(_dartDocPrefixWithSpace);
                if (index < 0) {
                  throw '$relativeFilePath:$lineNumber: Dart section inexplicably did not '
                      'contain "$_dartDocPrefixWithSpace" prefix.';
                }
                block.add(line.substring(index + 4));
              }
            } else if (_codeBlockStartRegex.hasMatch(trimmedLine)) {
              assert(block.isEmpty);
              startLine = Line(
                '',
                filename: relativeFilePath,
                line: lineNumber + 1,
                indent: line.indexOf(_dartDocPrefixWithSpace) + _dartDocPrefixWithSpace.length,
              );
              inDart = true;
              foundDart = true;
            }
          }
        }
        if (!inSampleSection) {
          final Match sampleMatch = _dartDocSampleBeginRegex.firstMatch(trimmedLine);
          if (line == '// Examples can assume:') {
            assert(block.isEmpty);
            startLine = Line('', filename: relativeFilePath, line: lineNumber + 1, indent: 3);
            inPreamble = true;
          } else if (trimmedLine == '/// ## Sample code' ||
              trimmedLine.startsWith('/// ## Sample code:') ||
              trimmedLine == '/// ### Sample code' ||
              trimmedLine.startsWith('/// ### Sample code:') ||
              sampleMatch != null) {
            inSnippet = sampleMatch != null ? sampleMatch[1] == 'snippet' : false;
            if (inSnippet) {
              startLine = Line(
                '',
                filename: relativeFilePath,
                line: lineNumber + 1,
                indent: line.indexOf(_dartDocPrefixWithSpace) + _dartDocPrefixWithSpace.length,
              );
              if (sampleMatch[2] != null) {
                // There are arguments to the snippet tool to keep track of.
                snippetArgs = _splitUpQuotedArgs(sampleMatch[2]).toList();
              } else {
                snippetArgs = <String>[];
              }
            }
            inSampleSection = !inSnippet;
            foundDart = false;
          }
        }
      }
    }
    print('Found ${sections.length} sample code sections.');
    for (Section section in sections) {
      sectionMap[_writeSection(section).path] = section;
    }
    for (Snippet snippet in snippets) {
      final File snippetFile = _writeSnippet(snippet);
      snippet.contents = snippetFile.readAsLinesSync();
      snippetMap[snippetFile.absolute.path] = snippet;
    }
  }

  /// Helper to process arguments given as a (possibly quoted) string.
  ///
  /// First, this will split the given [argsAsString] into separate arguments,
  /// taking any quoting (either ' or " are accepted) into account, including
  /// handling backslash-escaped quotes.
  ///
  /// Then, it will prepend "--" to any args that start with an identifier
  /// followed by an equals sign, allowing the argument parser to treat any
  /// "foo=bar" argument as "--foo=bar" (which is a dartdoc-ism).
  Iterable<String> _splitUpQuotedArgs(String argsAsString) {
    // Regexp to take care of splitting arguments, and handling the quotes
    // around arguments, if any.
    //
    // Match group 1 is the "foo=" (or "--foo=") part of the option, if any.
    // Match group 2 contains the quote character used (which is discarded).
    // Match group 3 is a quoted arg, if any, without the quotes.
    // Match group 4 is the unquoted arg, if any.
    final RegExp argMatcher = RegExp(r'([a-zA-Z\-_0-9]+=)?' // option name
        r'(?:' // Start a new non-capture group for the two possibilities.
        r'''(["'])((?:\\{2})*|(?:.*?[^\\](?:\\{2})*))\2|''' // with quotes.
        r'([^ ]+))'); // without quotes.
    final Iterable<Match> matches = argMatcher.allMatches(argsAsString);

    // Remove quotes around args, and if convertToArgs is true, then for any
    // args that look like assignments (start with valid option names followed
    // by an equals sign), add a "--" in front so that they parse as options.
    return matches.map<String>((Match match) {
      String option = '';
      if (match[1] != null && !match[1].startsWith('-')) {
        option = '--';
      }
      if (match[2] != null) {
        // This arg has quotes, so strip them.
        return '$option${match[1] ?? ''}${match[3] ?? ''}${match[4] ?? ''}';
      }
      return '$option${match[0]}';
    });
  }

  /// Creates the configuration files necessary for the analyzer to consider
  /// the temporary director a package, and sets which lint rules to enforce.
  void _createConfigurationFiles(Directory directory) {
    final File pubSpec = File(path.join(directory.path, 'pubspec.yaml'))..createSync(recursive: true);
    final File analysisOptions = File(path.join(directory.path, 'analysis_options.yaml'))..createSync(recursive: true);
    pubSpec.writeAsStringSync('''
name: analyze_sample_code
dependencies:
  flutter:
    sdk: flutter
  flutter_test:
    sdk: flutter
''');
    analysisOptions.writeAsStringSync('''
linter:
  rules:
    - unnecessary_const
    - unnecessary_new
''');
  }

  /// Writes out a sample section to the disk and returns the file.
  File _writeSection(Section section) {
    final String sectionId = _createNameFromSource('sample', section.start.filename, section.start.line);
    final File outputFile = File(path.join(_tempDir.path, '$sectionId.dart'))..createSync(recursive: true);
    final List<Line> mainContents = headers.toList();
    mainContents.add(const Line(''));
    mainContents.add(Line('// From: ${section.start.filename}:${section.start.line}'));
    mainContents.addAll(section.code);
    outputFile.writeAsStringSync(mainContents.map<String>((Line line) => line.code).join('\n'));
    return outputFile;
  }

  /// Invokes the analyzer on the given [directory] and returns the stdout.
  List<String> _runAnalyzer(Directory directory) {
    print('Starting analysis of samples.');
    _createConfigurationFiles(directory);
    final ProcessResult result = Process.runSync(
      _flutter,
      <String>['--no-wrap', 'analyze', '--no-preamble', '--no-congratulate', '.'],
      workingDirectory: directory.absolute.path,
    );
    final List<String> stderr = result.stderr.toString().trim().split('\n');
    final List<String> stdout = result.stdout.toString().trim().split('\n');
    // Check out the stderr to see if the analyzer had it's own issues.
    if (stderr.isNotEmpty && (stderr.first.contains(' issues found. (ran in ') || stderr.first.contains(' issue found. (ran in '))) {
      // The "23 issues found" message goes onto stderr, which is concatenated first.
      stderr.removeAt(0);
      // If there's an "issues found" message, we put a blank line on stdout before it.
      if (stderr.isNotEmpty && stderr.last.isEmpty) {
        stderr.removeLast();
      }
    }
    if (stderr.isNotEmpty) {
      throw 'Cannot analyze dartdocs; unexpected error output:\n$stderr';
    }
    if (stdout.isNotEmpty && stdout.first == 'Building flutter tool...') {
      stdout.removeAt(0);
    }
    if (stdout.isNotEmpty && stdout.first.startsWith('Running "flutter packages get" in ')) {
      stdout.removeAt(0);
    }
    _exitCode = result.exitCode;
    return stdout;
  }

  /// Starts the analysis phase of checking the samples by invoking the analyzer
  /// and parsing its output to create a map of filename to [AnalysisError]s.
  Map<String, List<AnalysisError>> _analyze(
    Directory directory,
    Map<String, Section> sections,
    Map<String, Snippet> snippets,
  ) {
    final List<String> errors = _runAnalyzer(directory);
    final Map<String, List<AnalysisError>> analysisErrors = <String, List<AnalysisError>>{};
    void addAnalysisError(File file, AnalysisError error) {
      if (analysisErrors.containsKey(file.path)) {
        analysisErrors[file.path].add(error);
      } else {
        analysisErrors[file.path] = <AnalysisError>[error];
      }
    }

    final String kBullet = Platform.isWindows ? ' - ' : ' • ';
    // RegExp to match an error output line of the analyzer.
    final RegExp errorPattern = RegExp(
      '^ +([a-z]+)$kBullet(.+)$kBullet(.+):([0-9]+):([0-9]+)$kBullet([-a-z_]+)\$',
      caseSensitive: false,
    );
    bool unknownAnalyzerErrors = false;
    final int headerLength = headers.length + 2;
    for (String error in errors) {
      final Match parts = errorPattern.matchAsPrefix(error);
      if (parts != null) {
        final String message = parts[2];
        final File file = File(path.join(_tempDir.path, parts[3]));
        final List<String> fileContents = file.readAsLinesSync();
        final bool isSnippet = path.basename(file.path).startsWith('snippet.');
        final bool isSample = path.basename(file.path).startsWith('sample.');
        final String line = parts[4];
        final String column = parts[5];
        final String errorCode = parts[6];
        final int lineNumber = int.parse(line, radix: 10) - (isSample ? headerLength : 0);
        final int columnNumber = int.parse(column, radix: 10);
        if (lineNumber < 0 && errorCode == 'unused_import') {
          // We don't care about unused imports.
          continue;
        }

        // For when errors occur outside of the things we're trying to analyze.
        if (!isSnippet && !isSample) {
          addAnalysisError(
            file,
            AnalysisError(
              lineNumber,
              columnNumber,
              message,
              errorCode,
              Line(
                '',
                filename: file.path,
                line: lineNumber,
              ),
            ),
          );
          throw 'Cannot analyze dartdocs; analysis errors exist in ${file.path}: $error';
        }

        if (errorCode == 'unused_element' || errorCode == 'unused_local_variable') {
          // We don't really care if sample code isn't used!
          continue;
        }

        if (isSnippet) {
          addAnalysisError(
            file,
            AnalysisError(
              lineNumber,
              columnNumber,
              message,
              errorCode,
              null,
              snippet: snippets[file.path],
            ),
          );
        } else {
          if (lineNumber < 1 || lineNumber > fileContents.length) {
            addAnalysisError(
              file,
              AnalysisError(
                lineNumber,
                columnNumber,
                message,
                errorCode,
                Line('', filename: file.path, line: lineNumber),
              ),
            );
            throw 'Failed to parse error message (read line number as $lineNumber; '
                'total number of lines is ${fileContents.length}): $error';
          }

          final Section actualSection = sections[file.path];
          final Line actualLine = actualSection.code[lineNumber - 1];

          if (actualLine.filename == null) {
            if (errorCode == 'missing_identifier' && lineNumber > 1) {
              if (fileContents[lineNumber - 2].endsWith(',')) {
                final Line actualLine = sections[file.path].code[lineNumber - 2];
                addAnalysisError(
                  file,
                  AnalysisError(
                    actualLine.line,
                    actualLine.indent + fileContents[lineNumber - 2].length - 1,
                    'Unexpected comma at end of sample code.',
                    errorCode,
                    actualLine,
                  ),
                );
              }
            } else {
              addAnalysisError(
                file,
                AnalysisError(
                  lineNumber - 1,
                  columnNumber,
                  message,
                  errorCode,
                  actualLine,
                ),
              );
            }
          } else {
            addAnalysisError(
              file,
              AnalysisError(
                actualLine.line,
                actualLine.indent + columnNumber,
                message,
                errorCode,
                actualLine,
              ),
            );
          }
        }
      } else {
        stderr.writeln('Analyzer output: $error');
        unknownAnalyzerErrors = true;
      }
    }
    if (_exitCode == 1 && analysisErrors.isEmpty && !unknownAnalyzerErrors) {
      _exitCode = 0;
    }
    if (_exitCode == 0) {
      print('No analysis errors in samples!');
      assert(analysisErrors.isEmpty);
    }
    return analysisErrors;
  }

  /// Process one block of sample code (the part inside of "```" markers).
  /// Splits any sections denoted by "// ..." into separate blocks to be
  /// processed separately. Uses a primitive heuristic to make sample blocks
  /// into valid Dart code.
  Section _processBlock(Line line, List<String> block) {
    if (block.isEmpty) {
      throw '$line: Empty ```dart block in sample code.';
    }
    if (block.first.startsWith('new ') || block.first.startsWith('const ') || block.first.startsWith(_constructorRegExp)) {
      _expressionId += 1;
      return Section.surround(line, 'dynamic expression$_expressionId = ', block.toList(), ';');
    } else if (block.first.startsWith('await ')) {
      _expressionId += 1;
      return Section.surround(line, 'Future<void> expression$_expressionId() async { ', block.toList(), ' }');
    } else if (block.first.startsWith('class ') || block.first.startsWith('enum ')) {
      return Section.fromStrings(line, block.toList());
    } else if ((block.first.startsWith('_') || block.first.startsWith('final ')) && block.first.contains(' = ')) {
      _expressionId += 1;
      return Section.surround(line, 'void expression$_expressionId() { ', block.toList(), ' }');
    } else {
      final List<String> buffer = <String>[];
      int subblocks = 0;
      Line subline;
      final List<Section> subsections = <Section>[];
      for (int index = 0; index < block.length; index += 1) {
        // Each section of the dart code that is either split by a blank line, or with '// ...' is
        // treated as a separate code block.
        if (block[index] == '' || block[index] == '// ...') {
          if (subline == null)
            throw '${Line('', filename: line.filename, line: line.line + index, indent: line.indent)}: '
                'Unexpected blank line or "// ..." line near start of subblock in sample code.';
          subblocks += 1;
          subsections.add(_processBlock(subline, buffer));
          buffer.clear();
          assert(buffer.isEmpty);
          subline = null;
        } else if (block[index].startsWith('// ')) {
          if (buffer.length > 1) // don't include leading comments
            buffer.add('/${block[index]}'); // so that it doesn't start with "// " and get caught in this again
        } else {
          subline ??= Line(
            block[index],
            filename: line.filename,
            line: line.line + index,
            indent: line.indent,
          );
          buffer.add(block[index]);
        }
      }
      if (subblocks > 0) {
        if (subline != null) {
          subsections.add(_processBlock(subline, buffer));
        }
        // Combine all of the subsections into one section, now that they've been processed.
        return Section.combine(subsections);
      } else {
        return Section.fromStrings(line, block.toList());
      }
    }
  }
}

/// A class to represent a line of input code.
class Line {
  const Line(this.code, {this.filename, this.line, this.indent});
  final String filename;
  final int line;
  final int indent;
  final String code;

  String toStringWithColumn(int column) {
    if (column != null && indent != null) {
      return '$filename:$line:${column + indent}: $code';
    }
    return toString();
  }

  @override
  String toString() => '$filename:$line: $code';
}

/// A class to represent a section of sample code, either marked by
/// "/// ## Sample code" in the comment, or by "{@tool sample}...{@end-tool}".
class Section {
  const Section(this.code);
  factory Section.combine(List<Section> sections) {
    final List<Line> code = <Line>[];
    for (Section section in sections) {
      code.addAll(section.code);
    }
    return Section(code);
  }
  factory Section.fromStrings(Line firstLine, List<String> code) {
    final List<Line> codeLines = <Line>[];
    for (int i = 0; i < code.length; ++i) {
      codeLines.add(
        Line(
          code[i],
          filename: firstLine.filename,
          line: firstLine.line + i,
          indent: firstLine.indent,
        ),
      );
    }
    return Section(codeLines);
  }
  factory Section.surround(Line firstLine, String prefix, List<String> code, String postfix) {
    assert(prefix != null);
    assert(postfix != null);
    final List<Line> codeLines = <Line>[];
    for (int i = 0; i < code.length; ++i) {
      codeLines.add(
        Line(
          code[i],
          filename: firstLine.filename,
          line: firstLine.line + i,
          indent: firstLine.indent,
        ),
      );
    }
    return Section(<Line>[Line(prefix)]
      ..addAll(codeLines)
      ..add(Line(postfix)));
  }
  Line get start => code.firstWhere((Line line) => line.filename != null);
  final List<Line> code;
}

/// A class to represent a snippet in the dartdoc comments, marked by
/// "{@tool snippet ...}...{@end-tool}". Snippets are processed separately from
/// regular samples, because they must be injected into templates in order to be
/// analyzed.
class Snippet {
  Snippet({this.start, List<String> input, List<String> args, this.serial}) {
    this.input = <String>[]..addAll(input);
    this.args = <String>[]..addAll(args);
  }
  final Line start;
  final int serial;
  List<String> input;
  List<String> args;
  List<String> contents;

  @override
  String toString() {
    final StringBuffer buf = StringBuffer('snippet ${args.join(' ')}\n');
    int count = start.line;
    for (String line in input) {
      buf.writeln(' ${count.toString().padLeft(4, ' ')}: $line');
      count++;
    }
    return buf.toString();
  }
}

/// A class representing an analysis error along with the context of the error.
///
/// Changes how it converts to a string based on the source of the error.
class AnalysisError {
  const AnalysisError(
    this.line,
    this.column,
    this.message,
    this.errorCode,
    this.source, {
    this.snippet,
  });

  final int line;
  final int column;
  final String message;
  final String errorCode;
  final Line source;
  final Snippet snippet;

  @override
  String toString() {
    if (source != null) {
      return '${source.toStringWithColumn(column)}\n>>> $message ($errorCode)';
    } else if (snippet != null) {
      return 'In snippet starting at '
          '${snippet.start.filename}:${snippet.start.line}:${snippet.contents[line - 1]}\n'
          '>>> $message ($errorCode)';
    } else {
      return '<source unknown>:$line:$column\n>>> $message ($errorCode)';
    }
  }
}
