Future build()

in source_gen/lib/builder.dart [77:142]


  Future 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
        '.', // `.` 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 partOf = nameOfPartial(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 output = '''
$defaultFileHeader
${languageOverrideForLibrary(inputLibrary)}$ignoreForFile
part of $partOf;

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