通过analyzer分析dart代码

比如有个需求:

通过分析注解,来生成一段dart代码。

 

dart上如果要自动生成代码,那么就需要用到代码生成器,code generator,这和Android里面apt类似。一般我们会引用source_gen声明一些generator,然后放在build.yaml里面,调用build_runner来生成代码。

如果不想使用框架,而是自己手写这个过程呢?

1.从dart文件读入代码

2.分析代码,读出里面的annotation对应的value值。

3.根据value值,自己再生成代码字符串content

4.把代码字符串写到一个dart文件中

如果是简单的第二个过程,可以想到一种,通过正则匹配来读出对应的annotation里面的值。然后用来生成代码字符串content。如果类很复杂,那么自己来手动分析就会比较繁琐。

dart中有一个工具analyzer,来分析代码。它会把一段代码内容导入进来,进行分析,然后生成一个ast抽象语法树。

我们现在利用它写一个demo读取出dart里面的注解内容。

我们先定义好一些注解类:

class SFLegoClass{
  final String host;
  final String source;

  const SFLegoClass(this.host,this.source);
}

class SFLegoField{
  final String fieldAlias;
  const SFLegoField(this.fieldAlias);
}

class SFLegoMethod{
  final String method;
  const SFLegoMethod(this.method);
}

@SFLegoClass("www.baidu.com", "dart")
class ExampleClass{
  @SFLegoField("mason")
  String name;

  @SFLegoMethod("method1")
  void myMethod(){
    
  }

我们的目标是,读出注解类上的值。

import 'dart:io';

import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';


main(List args) {
  read(File("annotation_example.dart"));
}

read(File file){
  // print(file.readAsStringSync());
  String content = file.readAsStringSync();
  // RegExp regExp = RegExp("");
  ParseStringResult result  = parseString(content: content);
  CompilationUnit unit = result.unit;
  unit.visitChildren(MyVisitor());
}

class MyVisitor extends RecursiveAstVisitor{
  @override
  visitAnnotation(Annotation node) {
    print("annotation node:"+node.toString()+",${node.name},${node.arguments}");
    return super.visitAnnotation(node);
  }
}

我们来分析一下上面的代码。

1.读出上面的类中的文件到一个字符串中

2.通过analyzer的静态方法parseString()来分析代码

3.取出其中的代码解析产物CompilationUnit

4.对其进行遍历

AstVistor里面定义了很多的方法,我们在遍历的过程中,就可以分别读到不通的内容。

abstract class AstVisitor {
  R visitAdjacentStrings(AdjacentStrings node);

  R visitAnnotation(Annotation node);

  R visitArgumentList(ArgumentList node);

  R visitAsExpression(AsExpression node);

  R visitAssertInitializer(AssertInitializer node);

  R visitAssertStatement(AssertStatement assertStatement);
  ...
}

analyzer定义了一些基本的vistor实现类。

通过analyzer分析dart代码_第1张图片

这里主要说一下RecursiveAstVisitor。

看名字就知道它会递归遍历整棵抽象语法树。我们可以用它来查找我们要的变量。运行一下上面的代码,得到如下结果。

我们就可以取出annotation里面的值了。本文仅借此例子来了解dart analyzer的用法。

此外,dart sdk还自带了dartAnalyzer工具,帮我们做静态代码分析。

比如在某个dart类中加入错误的一段代码。"A {"

它就能帮我们分析出其中错误的地方。

你可能感兴趣的:(dart,dart,flutter,ast,analyzer)