热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Flutter动态特性调研之——AstNode

在做Dart代码分析的时候,Flutter官方提供了analyzer库,通过analyzer可以配置并分析代码的规范性等;但analyzer不仅可以帮助开发者分析代码的规范性,还可以把Dar

在做Dart代码分析的时候,Flutter官方提供了analyzer库,通过analyzer可以配置并分析代码的规范性等;但analyzer不仅可以帮助开发者分析代码的规范性,还可以把Dart代码转换成抽象语法树(AST),这个过程有点类似编译器的分词,可以把Dart代码按关键词分解成对应的数据模型,并进一步转换成我们熟悉的json或xml格式。官方版本为analyzer 0.41.1
我们先来看看Dart的类Class转换后的最终效果:

  {
    "type": "ClassDeclaration",
    "id": {
      "type": "Identifier",
      "name": "AnalyzerDemo"
    },
    "superClause": {
      "type": "TypeName",
      "name": "SuperClass"
    },
    "implementsClause": {
      "type": "ImplementsClause",
      "implements": [
        {
          "type": "TypeName",
          "name": "ImplementClass"
        }
      ]
    },
    "mixinClause": null,
    "metadata": [],
    "body": []
  }

转换之前先来了解一下转换过程中用到的一个重要的类——AstNode,AstNode是AST转换过程中各种语法类型转换后数据模型的父节点,定义了该节点的基本信息:

abstract class AstNode implements SyntacticEntity {
  /// A comparator that can be used to sort AST nodes in lexical order.
  ///
  /// In other words, `compare` will return a negative value if the offset of
  /// the first node is less than the offset of the second node, zero (0) if
  /// the nodes have the same offset, and a positive value if the offset of the
  /// first node is greater than the offset of the second node.
  static Comparator LEXICAL_ORDER =
      (AstNode first, AstNode second) => first.offset - second.offset;

  /// Return the first token included in this node's source range.
  Token get beginToken;

  /// Return an iterator that can be used to iterate through all the entities
  /// (either AST nodes or tokens) that make up the contents of this node,
  /// including doc comments but excluding other comments.
  Iterable get childEntities;

  /// Return the offset of the character immediately following the last
  /// character of this node's source range.
  ///
  /// This is equivalent to `node.getOffset() + node.getLength()`. For a
  /// compilation unit this will be equal to the length of the unit's source.
  /// For synthetic nodes this will be equivalent to the node's offset (because
  /// the length is zero (0) by definition).
  @override
  int get end;

  /// Return the last token included in this node's source range.
  Token get endToken;

  /// Return `true` if this node is a synthetic node.
  ///
  /// A synthetic node is a node that was introduced by the parser in order to
  /// recover from an error in the code. Synthetic nodes always have a length
  /// of zero (`0`).
  bool get isSynthetic;

  @override
  int get length;

  @override
  int get offset;

  /// Return this node's parent node, or `null` if this node is the root of an
  /// AST structure.
  ///
  /// Note that the relationship between an AST node and its parent node may
  /// change over the lifetime of a node.
  AstNode get parent;

  /// Return the node at the root of this node's AST structure.
  ///
  /// Note that this method's performance is linear with respect to the depth
  /// of the node in the AST structure (O(depth)).
  AstNode get root;

  /// Use the given [visitor] to visit this node.
  ///
  /// Return the value returned by the visitor as a result of visiting this
  /// node.
  E accept(AstVisitor visitor);

  /// Return the token before [target] or `null` if it cannot be found.
  Token findPrevious(Token target);

  /// Return the value of the property with the given [name], or `null` if this
  /// node does not have a property with the given name.
  E getProperty(String name);

  /// Set the value of the property with the given [name] to the given [value].
  /// If the value is `null`, the property will effectively be removed.
  void setProperty(String name, Object value);

  /// Return either this node or the most immediate ancestor of this node for
  /// which the [predicate] returns `true`, or `null` if there is no such node.
  E thisOrAncestorMatching(Predicate predicate);

  /// Return either this node or the most immediate ancestor of this node that
  /// has the given type, or `null` if there is no such node.
  E thisOrAncestorOfType();

  /// Return a textual description of this node in a form approximating valid
  /// source.
  ///
  /// The returned string will not be valid source primarily in the case where
  /// the node itself is not well-formed.
  String toSource();

  /// Use the given [visitor] to visit all of the children of this node.
  ///
  /// The children will be visited in lexical order.
  void visitChildren(AstVisitor visitor);
}

AstNode描述了AST节点的基本信息:包括标识符(beginToken/endToken)、子元素(childEntities)、父节点(parent)、遍历方法(accept)、子元素遍历方法(visitChildren)等等,几乎所有的AST节点类型都继承于它;通过解释AstNode的衍生节点信息,我们可以把各种AST转换成我们想要的格式。


推荐阅读
author-avatar
工农大路店NOKIA客户服务中心
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有