build method

  1. @override
Future<void> build(
  1. BuildStep buildStep
)

Generates the outputs for a given BuildStep.

Implementation

@override
Future<void> build(BuildStep buildStep) async {
  // Pattern used for `findAssets`, which must be glob-compatible
  final pattern = buildStep.inputId.changeExtension('.*$_partFiles').path;

  final inputBaseName =
      p.basenameWithoutExtension(buildStep.inputId.pathSegments.last);

  // Pattern used to ensure items are only considered if they match
  // [file name without extension].[valid part id].[part file extension]
  final restrictedPattern = RegExp(
    [
      '^', // start of string
      RegExp.escape(inputBaseName), // file name, without extension
      r'\.', // `.` character
      partIdRegExpLiteral, // A valid part ID
      RegExp.escape(_partFiles), // the ending part extension
      '\$', // end of string
    ].join(),
  );

  final assetIds = await buildStep
      .findAssets(Glob(pattern))
      .where((id) => restrictedPattern.hasMatch(id.pathSegments.last))
      .toList()
    ..sort();

  final assets = await Stream.fromIterable(assetIds)
      .asyncMap((id) async {
        var content = (await buildStep.readAsString(id)).trim();
        if (_includePartName) {
          content = '// Part: ${id.pathSegments.last}\n$content';
        }
        return content;
      })
      .where((s) => s.isNotEmpty)
      .join('\n\n');
  if (assets.isEmpty) return;

  final inputLibrary = await buildStep.inputLibrary;
  final outputId = buildStep.allowedOutputs.single;
  final partOfUri = uriOfPartial(inputLibrary, buildStep.inputId, outputId);

  // Ensure that the input has a correct `part` statement.
  final libraryUnit =
      await buildStep.resolver.compilationUnitFor(buildStep.inputId);
  final part = computePartUrl(buildStep.inputId, outputId);
  if (!hasExpectedPartDirective(libraryUnit, part)) {
    log.warning(
      '$part must be included as a part directive in '
      'the input library with:\n    part \'$part\';',
    );
    return;
  }

  final ignoreForFile = _ignoreForFile.isEmpty
      ? ''
      : '\n// ignore_for_file: ${_ignoreForFile.join(', ')}\n';

  final preamble = _preamble.isEmpty ? '' : '\n$_preamble\n';

  final output = '''
$defaultFileHeader
${languageOverrideForLibrary(inputLibrary)}$ignoreForFile$preamble
part of '$partOfUri';

$assets
''';
  await buildStep.writeAsString(outputId, output);
}