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

import 'package:analyzer/dart/element/element.dart';
import 'package:build/build.dart';
import 'package:dart_style/src/dart_formatter.dart';

import 'generated_output.dart';
import 'generator.dart';
import 'utils.dart';

class GeneratorBuilder extends Builder {
  final List<Generator> generators;
  final String generatedExtension;
  final bool isStandalone;

  GeneratorBuilder(this.generators,
      {this.generatedExtension: '.g.dart', this.isStandalone: false}) {
    // TODO: validate that generatedExtension starts with a `.'
    //       not null, empty, etc
    if (this.isStandalone && this.generators.length > 1) {
      throw new ArgumentError(
          'Only one generator can be used to generate a standalone file.');
    }
  }

  @override
  Future build(BuildStep buildStep) async {
    var id = buildStep.input.id;
    var resolver = await buildStep.resolve(id, resolveAllConstants: false);
    try {
      var lib = resolver.getLibrary(id);
      if (lib == null) return;
      await _generateForLibrary(lib, buildStep);
    } finally {
      resolver.release();
    }
  }

  @override
  List<AssetId> declareOutputs(AssetId input) {
    if (input.extension != '.dart') return const [];
    return [_generatedFile(input)];
  }

  AssetId _generatedFile(AssetId input) =>
      input.changeExtension(generatedExtension);

  Future _generateForLibrary(
      LibraryElement library, BuildStep buildStep) async {
    buildStep.logger.fine('Running $generators for ${buildStep.input.id}');
    var generatedOutputs =
        await _generate(library, generators, buildStep).toList();

    // Don't outputs useless files.
    if (generatedOutputs.isEmpty) return;

    var contentBuffer = new StringBuffer();

    if (!isStandalone) {
      contentBuffer.writeln('part of ${library.name};');
      contentBuffer.writeln();
    }

    for (GeneratedOutput output in generatedOutputs) {
      contentBuffer.writeln('');
      contentBuffer.writeln(_headerLine);
      contentBuffer.writeln('// Generator: ${output.generator}');
      contentBuffer
          .writeln('// Target: ${friendlyNameForElement(output.sourceMember)}');
      contentBuffer.writeln(_headerLine);
      contentBuffer.writeln('');

      contentBuffer.writeln(output.output);
    }

    var genPartContent = contentBuffer.toString();

    var formatter = new DartFormatter();
    try {
      genPartContent = formatter.format(genPartContent);
    } catch (e, stack) {
      buildStep.logger.severe(
          """Error formatting the generated source code.
This may indicate an issue in the generated code or in the formatter.
Please check the generated code and file an issue on source_gen
if approppriate.""",
          e,
          stack);
    }

    var outputId = _generatedFile(buildStep.input.id);
    var output = new Asset(outputId, '$_topHeader$genPartContent');
    buildStep.writeAsString(output);
  }
}

Stream<GeneratedOutput> _generate(LibraryElement unit,
    List<Generator> generators, BuildStep buildStep) async* {
  for (var element in getElementsFromLibraryElement(unit)) {
    yield* _processUnitMember(element, generators, buildStep);
  }
}

Stream<GeneratedOutput> _processUnitMember(
    Element element, List<Generator> generators, BuildStep buildStep) async* {<commit_msg>Add toString() to GeneratorBuilder (#127)<commit_after>// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';

import 'package:analyzer/dart/element/element.dart';
import 'package:build/build.dart';
import 'package:dart_style/src/dart_formatter.dart';

import 'generated_output.dart';
import 'generator.dart';
import 'utils.dart';

class GeneratorBuilder extends Builder {
  final List<Generator> generators;
  final String generatedExtension;
  final bool isStandalone;

  GeneratorBuilder(this.generators,
      {this.generatedExtension: '.g.dart', this.isStandalone: false}) {
    // TODO: validate that generatedExtension starts with a `.'
    //       not null, empty, etc
    if (this.isStandalone && this.generators.length > 1) {
      throw new ArgumentError(
          'Only one generator can be used to generate a standalone file.');
    }
  }

  @override
  Future build(BuildStep buildStep) async {
    var id = buildStep.input.id;
    var resolver = await buildStep.resolve(id, resolveAllConstants: false);
    try {
      var lib = resolver.getLibrary(id);
      if (lib == null) return;
      await _generateForLibrary(lib, buildStep);
    } finally {
      resolver.release();
    }
  }

  @override
  List<AssetId> declareOutputs(AssetId input) {
    if (input.extension != '.dart') return const [];
    return [_generatedFile(input)];
  }

  AssetId _generatedFile(AssetId input) =>
      input.changeExtension(generatedExtension);

  Future _generateForLibrary(
      LibraryElement library, BuildStep buildStep) async {
    buildStep.logger.fine('Running $generators for ${buildStep.input.id}');
    var generatedOutputs =
        await _generate(library, generators, buildStep).toList();

    // Don't outputs useless files.
    if (generatedOutputs.isEmpty) return;

    var contentBuffer = new StringBuffer();

    if (!isStandalone) {
      contentBuffer.writeln('part of ${library.name};');
      contentBuffer.writeln();
    }

    for (GeneratedOutput output in generatedOutputs) {
      contentBuffer.writeln('');
      contentBuffer.writeln(_headerLine);
      contentBuffer.writeln('// Generator: ${output.generator}');
      contentBuffer
          .writeln('// Target: ${friendlyNameForElement(output.sourceMember)}');
      contentBuffer.writeln(_headerLine);
      contentBuffer.writeln('');

      contentBuffer.writeln(output.output);
    }

    var genPartContent = contentBuffer.toString();

    var formatter = new DartFormatter();
    try {
      genPartContent = formatter.format(genPartContent);
    } catch (e, stack) {
      buildStep.logger.severe(
          """Error formatting the generated source code.
This may indicate an issue in the generated code or in the formatter.
Please check the generated code and file an issue on source_gen
if approppriate.""",
          e,
          stack);
    }

    var outputId = _generatedFile(buildStep.input.id);
    var output = new Asset(outputId, '$_topHeader$genPartContent');
    buildStep.writeAsString(output);
  }

  @override
  String toString() => 'GeneratorBuilder:$generators';
}

Stream<GeneratedOutput> _generate(LibraryElement unit,
    List<Generator> generators, BuildStep buildStep) async* {
  for (var element in getElementsFromLibraryElement(unit)) {
    yield* _processUnitMember(element, generators, buildStep);
  }
}

Stream<GeneratedOutput> _processUnitMember(
    Element element, List<Generator> generators, BuildStep buildStep) async* {
{'fraction_non_alphanumeric': 0.10759140385152108, 'fraction_numerical': 0.001814122243929668, 'mean_word_length': 3.681254082299151, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7279396', 'n_tokens_mistral': 2056, 'n_tokens_neox': 1991, 'n_words': 556}