Flutter動態(tài)特性調(diào)研之——AstNode

在做Dart代碼分析的時候,F(xiàn)lutter官方提供了analyzer庫,通過analyzer可以配置并分析代碼的規(guī)范性等脖卖;但analyzer不僅可以幫助開發(fā)者分析代碼的規(guī)范性弥奸,還可以把Dart代碼轉(zhuǎn)換成抽象語法樹(AST)盛泡,這個過程有點(diǎn)類似編譯器的分詞捺癞,可以把Dart代碼按關(guān)鍵詞分解成對應(yīng)的數(shù)據(jù)模型夷蚊,并進(jìn)一步轉(zhuǎn)換成我們熟悉的json或xml格式。官方版本為analyzer 0.41.1
我們先來看看Dart的類Class轉(zhuǎn)換后的最終效果:

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

轉(zhuǎn)換之前先來了解一下轉(zhuǎn)換過程中用到的一個重要的類——AstNode髓介,AstNode是AST轉(zhuǎn)換過程中各種語法類型轉(zhuǎn)換后數(shù)據(jù)模型的父節(jié)點(diǎn)惕鼓,定義了該節(jié)點(diǎn)的基本信息:

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<AstNode> 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<SyntacticEntity> 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<E>(AstVisitor<E> 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<E>(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<E extends AstNode>(Predicate<AstNode> 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<E extends AstNode>();

  /// 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節(jié)點(diǎn)的基本信息:包括標(biāo)識符(beginToken/endToken)、子元素(childEntities)唐础、父節(jié)點(diǎn)(parent)箱歧、遍歷方法(accept)、子元素遍歷方法(visitChildren)等等一膨,幾乎所有的AST節(jié)點(diǎn)類型都繼承于它呀邢;通過解釋AstNode的衍生節(jié)點(diǎn)信息,我們可以把各種AST轉(zhuǎn)換成我們想要的格式豹绪。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末价淌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瞒津,更是在濱河造成了極大的恐慌蝉衣,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巷蚪,死亡現(xiàn)場離奇詭異病毡,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)屁柏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門浑娜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盲厌,“玉大人唧瘾,你說我怎么就攤上這事僚楞。” “怎么了似嗤?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵啸臀,是天一觀的道長。 經(jīng)常有香客問我烁落,道長乘粒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任伤塌,我火速辦了婚禮灯萍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘每聪。我一直安慰自己旦棉,他們只是感情好齿风,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著绑洛,像睡著了一般救斑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上真屯,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天脸候,我揣著相機(jī)與錄音,去河邊找鬼绑蔫。 笑死运沦,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的配深。 我是一名探鬼主播携添,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼凉馆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起亡资,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤澜共,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后锥腻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嗦董,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年瘦黑,在試婚紗的時候發(fā)現(xiàn)自己被綠了京革。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡幸斥,死狀恐怖匹摇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情甲葬,我是刑警寧澤廊勃,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站经窖,受9級特大地震影響坡垫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜画侣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一冰悠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧配乱,春花似錦溉卓、人聲如沸皮迟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽万栅。三九已至,卻和暖如春西疤,著一層夾襖步出監(jiān)牢的瞬間烦粒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工代赁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留扰她,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓芭碍,卻偏偏與公主長得像徒役,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子窖壕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容