在dart中使用source_gen为解析文件列表生成一个文件 [英] Generate one file for a list of parsed files using source_gen in dart

查看:100
本文介绍了在dart中使用source_gen为解析文件列表生成一个文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个创建微型反射系统所需的模型列表.
我分析了Serializable软件包,并了解了如何为每个文件创建一个生成的文件,但是,我找不到如何为大量文件创建一个文件.

I have a list of models that I need to create a mini reflective system.
I analyzed the Serializable package and understood how to create one generated file per file, however, I couldn't find how can I create one file for a bulk of files.

那么,如何使用source_gen为文件列表动态生成一个文件?

So, how to dynamically generate one file, using source_gen, for a list of files?

示例:
文件
user.dart
category.dart

Example:
Files
user.dart
category.dart

生成:
info.dart(包含来自user.dart和category.dart的信息)

Generated:
info.dart (containg information from user.dart and category.dart)

推荐答案

了解了如何在Gitter人员的帮助下进行此操作.
您必须有一个文件(即使为空)才能调用生成器.在我的示例中,它是lib/batch.dart.

Found out how to do it with the help of people in Gitter.
You must have one file, even if empty, to call the generator. In my example, it is lib/batch.dart.

source_gen:^ 0.5.8

source_gen: ^0.5.8

这是工作代码:

tool/build.dart

The tool/build.dart

import 'package:build_runner/build_runner.dart';
import 'package:raoni_global/phase.dart';

main() async {
  PhaseGroup pg = new PhaseGroup()
    ..addPhase(batchModelablePhase(const ['lib/batch.dart']));

  await build(pg,
      deleteFilesByDefault: true);
}

阶段:

batchModelablePhase([Iterable<String> globs =
const ['bin/**.dart', 'web/**.dart', 'lib/**.dart']]) {
  return new Phase()
    ..addAction(
        new GeneratorBuilder(const
        [const BatchGenerator()], isStandalone: true
        ),
        new InputSet(new PackageGraph.forThisPackage().root.name, globs));
}

生成器:

import 'dart:async';

import 'package:analyzer/dart/element/element.dart';
import 'package:build/build.dart';
import 'package:source_gen/source_gen.dart';
import 'package:glob/glob.dart';
import 'package:build_runner/build_runner.dart';

class BatchGenerator extends Generator {
  final String path;

  const BatchGenerator({this.path: 'lib/models/*.dart'});

  @override
  Future<String> generate(Element element, BuildStep buildStep) async {
    // this makes sure we parse one time only
    if (element is! LibraryElement)
      return null;

    String libraryName = 'raoni_global', filePath = 'lib/src/model.dart';
    String className = 'Modelable';

    // find the files at the path designed
    var l = buildStep.findAssets(new Glob(path));

    // get the type of annotation that we will use to search classes
    var resolver = await buildStep.resolver;
    var assetWithAnnotationClass = new AssetId(libraryName, filePath);
    var annotationLibrary = resolver.getLibrary(assetWithAnnotationClass);
    var exposed = annotationLibrary.getType(className).type;

    // the caller library' name
    String libName = new PackageGraph.forThisPackage().root.name;

    await Future.forEach(l.toList(), (AssetId aid) async {
      LibraryElement lib;

      try {
        lib = resolver.getLibrary(aid);
      } catch (e) {}

      if (lib != null && Utils.isNotEmpty(lib.name)) {
        // all objects within the file
        lib.units.forEach((CompilationUnitElement unit) {
          // only the types, not methods
          unit.types.forEach((ClassElement el) {
            // only the ones annotated
            if (el.metadata.any((ElementAnnotation ea) =>
            ea.computeConstantValue().type == exposed)) {
              // use it
            }
          });
        });
      }
    });

    return '''
       $libName
    ''';
  }
}

这篇关于在dart中使用source_gen为解析文件列表生成一个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆