PageRenderTime 60ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/syntax_tools/src/erl_syntax.erl

https://github.com/gebi/jungerl
Erlang | 6765 lines | 2507 code | 852 blank | 3406 comment | 47 complexity | 84f69af772a3237def0c3ccbbad9bdce MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. %% =====================================================================
  2. %% Abstract Erlang syntax trees (`erl_parse'-compatible).
  3. %%
  4. %% Copyright (C) 1997-2004 Richard Carlsson
  5. %%
  6. %% This library is free software; you can redistribute it and/or modify
  7. %% it under the terms of the GNU Lesser General Public License as
  8. %% published by the Free Software Foundation; either version 2 of the
  9. %% License, or (at your option) any later version.
  10. %%
  11. %% This library is distributed in the hope that it will be useful, but
  12. %% WITHOUT ANY WARRANTY; without even the implied warranty of
  13. %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. %% Lesser General Public License for more details.
  15. %%
  16. %% You should have received a copy of the GNU Lesser General Public
  17. %% License along with this library; if not, write to the Free Software
  18. %% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  19. %% USA
  20. %%
  21. %% Author contact: richardc@csd.uu.se
  22. %%
  23. %% $Id$
  24. %%
  25. %% =====================================================================
  26. %%
  27. %% @doc Abstract Erlang syntax trees.
  28. %%
  29. %% <p> This module defines an abstract data type for representing Erlang
  30. %% source code as syntax trees, in a way that is backwards compatible
  31. %% with the data structures created by the Erlang standard library
  32. %% parser module <code>erl_parse</code> (often referred to as "parse
  33. %% trees", which is a bit of a misnomer). This means that all
  34. %% <code>erl_parse</code> trees are valid abstract syntax trees, but the
  35. %% reverse is not true: abstract syntax trees can in general not be used
  36. %% as input to functions expecting an <code>erl_parse</code> tree.
  37. %% However, as long as an abstract syntax tree represents a correct
  38. %% Erlang program, the function <a
  39. %% href="#revert-1"><code>revert/1</code></a> should be able to
  40. %% transform it to the corresponding <code>erl_parse</code>
  41. %% representation.</p>
  42. %%
  43. %% <p>A recommended starting point for the first-time user is the
  44. %% documentation of the <a
  45. %% href="#type-syntaxTree"><code>syntaxTree()</code></a> data type, and
  46. %% the function <a href="#type-1"><code>type/1</code></a>.</p>
  47. %%
  48. %% <h3><b>NOTES:</b></h3>
  49. %%
  50. %% <p>This module deals with the composition and decomposition of
  51. %% <em>syntactic</em> entities (as opposed to semantic ones); its
  52. %% purpose is to hide all direct references to the data structures used
  53. %% to represent these entities. With few exceptions, the functions in
  54. %% this module perform no semantic interpretation of their inputs, and
  55. %% in general, the user is assumed to pass type-correct arguments - if
  56. %% this is not done, the effects are not defined.</p>
  57. %%
  58. %% <p>With the exception of the <code>erl_parse</code> data structures,
  59. %% the internal representations of abstract syntax trees are subject to
  60. %% change without notice, and should not be documented outside this
  61. %% module. Furthermore, we do not give any guarantees on how an abstract
  62. %% syntax tree may or may not be represented, <em>with the following
  63. %% exceptions</em>: no syntax tree is represented by a single atom, such
  64. %% as <code>none</code>, by a list constructor <code>[X | Y]</code>, or
  65. %% by the empty list <code>[]</code>. This can be relied on when writing
  66. %% functions that operate on syntax trees.</p>
  67. %%
  68. %% @type syntaxTree(). An abstract syntax tree. The
  69. %% <code>erl_parse</code> "parse tree" representation is a subset of the
  70. %% <code>syntaxTree()</code> representation.
  71. %%
  72. %% <p>Every abstract syntax tree node has a <em>type</em>, given by the
  73. %% function <a href="#type-1"><code>type/1</code></a>. Each node also
  74. %% has associated <em>attributes</em>; see <a
  75. %% href="#get_attrs-1"><code>get_attrs/1</code></a> for details. The
  76. %% functions <a href="#make_tree-2"><code>make_tree/2</code></a> and <a
  77. %% href="#subtrees-1"><code>subtrees/1</code></a> are generic
  78. %% constructor/decomposition functions for abstract syntax trees. The
  79. %% functions <a href="#abstract-1"><code>abstract/1</code></a> and <a
  80. %% href="#concrete-1"><code>concrete/1</code></a> convert between
  81. %% constant Erlang terms and their syntactic representations. The set of
  82. %% syntax tree nodes is extensible through the <a
  83. %% href="#tree-2"><code>tree/2</code></a> function.</p>
  84. %%
  85. %% <p>A syntax tree can be transformed to the <code>erl_parse</code>
  86. %% representation with the <a href="#revert-1"><code>revert/1</code></a>
  87. %% function.</p>
  88. %%
  89. %% @end
  90. %% =====================================================================
  91. -module(erl_syntax).
  92. -export([type/1,
  93. is_leaf/1,
  94. is_form/1,
  95. is_literal/1,
  96. abstract/1,
  97. concrete/1,
  98. revert/1,
  99. revert_forms/1,
  100. subtrees/1,
  101. make_tree/2,
  102. update_tree/2,
  103. meta/1,
  104. get_pos/1,
  105. set_pos/2,
  106. copy_pos/2,
  107. get_precomments/1,
  108. set_precomments/2,
  109. add_precomments/2,
  110. get_postcomments/1,
  111. set_postcomments/2,
  112. add_postcomments/2,
  113. has_comments/1,
  114. remove_comments/1,
  115. copy_comments/2,
  116. join_comments/2,
  117. get_ann/1,
  118. set_ann/2,
  119. add_ann/2,
  120. copy_ann/2,
  121. get_attrs/1,
  122. set_attrs/2,
  123. copy_attrs/2,
  124. flatten_form_list/1,
  125. cons/2,
  126. list_head/1,
  127. list_tail/1,
  128. is_list_skeleton/1,
  129. is_proper_list/1,
  130. list_elements/1,
  131. list_length/1,
  132. normalize_list/1,
  133. compact_list/1,
  134. application/2,
  135. application/3,
  136. application_arguments/1,
  137. application_operator/1,
  138. arity_qualifier/2,
  139. arity_qualifier_argument/1,
  140. arity_qualifier_body/1,
  141. atom/1,
  142. is_atom/2,
  143. atom_value/1,
  144. atom_literal/1,
  145. atom_name/1,
  146. attribute/1,
  147. attribute/2,
  148. attribute_arguments/1,
  149. attribute_name/1,
  150. binary/1,
  151. binary_field/1,
  152. binary_field/2,
  153. binary_field/3,
  154. binary_field_body/1,
  155. binary_field_types/1,
  156. binary_field_size/1,
  157. binary_fields/1,
  158. block_expr/1,
  159. block_expr_body/1,
  160. case_expr/2,
  161. case_expr_argument/1,
  162. case_expr_clauses/1,
  163. catch_expr/1,
  164. catch_expr_body/1,
  165. char/1,
  166. is_char/2,
  167. char_value/1,
  168. char_literal/1,
  169. clause/2,
  170. clause/3,
  171. clause_body/1,
  172. clause_guard/1,
  173. clause_patterns/1,
  174. comment/1,
  175. comment/2,
  176. comment_padding/1,
  177. comment_text/1,
  178. cond_expr/1,
  179. cond_expr_clauses/1,
  180. conjunction/1,
  181. conjunction_body/1,
  182. disjunction/1,
  183. disjunction_body/1,
  184. eof_marker/0,
  185. error_marker/1,
  186. error_marker_info/1,
  187. float/1,
  188. float_value/1,
  189. float_literal/1,
  190. form_list/1,
  191. form_list_elements/1,
  192. fun_expr/1,
  193. fun_expr_arity/1,
  194. fun_expr_clauses/1,
  195. function/2,
  196. function_arity/1,
  197. function_clauses/1,
  198. function_name/1,
  199. generator/2,
  200. generator_body/1,
  201. generator_pattern/1,
  202. if_expr/1,
  203. if_expr_clauses/1,
  204. implicit_fun/1,
  205. implicit_fun/2,
  206. implicit_fun_name/1,
  207. infix_expr/3,
  208. infix_expr_left/1,
  209. infix_expr_operator/1,
  210. infix_expr_right/1,
  211. integer/1,
  212. is_integer/2,
  213. integer_value/1,
  214. integer_literal/1,
  215. list/1,
  216. list/2,
  217. list_comp/2,
  218. list_comp_body/1,
  219. list_comp_template/1,
  220. list_prefix/1,
  221. list_suffix/1,
  222. macro/1,
  223. macro/2,
  224. macro_arguments/1,
  225. macro_name/1,
  226. match_expr/2,
  227. match_expr_body/1,
  228. match_expr_pattern/1,
  229. module_qualifier/2,
  230. module_qualifier_argument/1,
  231. module_qualifier_body/1,
  232. nil/0,
  233. operator/1,
  234. operator_literal/1,
  235. operator_name/1,
  236. parentheses/1,
  237. parentheses_body/1,
  238. prefix_expr/2,
  239. prefix_expr_argument/1,
  240. prefix_expr_operator/1,
  241. qualified_name/1,
  242. qualified_name_segments/1,
  243. query_expr/1,
  244. query_expr_body/1,
  245. receive_expr/1,
  246. receive_expr/3,
  247. receive_expr_action/1,
  248. receive_expr_clauses/1,
  249. receive_expr_timeout/1,
  250. record_access/2,
  251. record_access/3,
  252. record_access_argument/1,
  253. record_access_field/1,
  254. record_access_type/1,
  255. record_expr/2,
  256. record_expr/3,
  257. record_expr_argument/1,
  258. record_expr_fields/1,
  259. record_expr_type/1,
  260. record_field/1,
  261. record_field/2,
  262. record_field_name/1,
  263. record_field_value/1,
  264. record_index_expr/2,
  265. record_index_expr_field/1,
  266. record_index_expr_type/1,
  267. rule/2,
  268. rule_arity/1,
  269. rule_clauses/1,
  270. rule_name/1,
  271. size_qualifier/2,
  272. size_qualifier_argument/1,
  273. size_qualifier_body/1,
  274. string/1,
  275. is_string/2,
  276. string_value/1,
  277. string_literal/1,
  278. text/1,
  279. text_string/1,
  280. try_expr/2,
  281. try_expr/3,
  282. try_expr/4,
  283. try_after_expr/2,
  284. try_expr_body/1,
  285. try_expr_clauses/1,
  286. try_expr_handlers/1,
  287. try_expr_after/1,
  288. class_qualifier/2,
  289. class_qualifier_argument/1,
  290. class_qualifier_body/1,
  291. tuple/1,
  292. tuple_elements/1,
  293. tuple_size/1,
  294. underscore/0,
  295. variable/1,
  296. variable_name/1,
  297. variable_literal/1,
  298. warning_marker/1,
  299. warning_marker_info/1,
  300. tree/1,
  301. tree/2,
  302. data/1,
  303. is_tree/1]).
  304. %% =====================================================================
  305. %% IMPLEMENTATION NOTES:
  306. %%
  307. %% All nodes are represented by tuples of arity 2 or greater, whose
  308. %% first element is an atom which uniquely identifies the type of the
  309. %% node. (In the backwards-compatible representation, the interpretation
  310. %% is also often dependent on the context; the second element generally
  311. %% holds the position information - with a couple of exceptions; see
  312. %% `get_pos' and `set_pos' for details). In the documentation of this
  313. %% module, `Pos' is the source code position information associated with
  314. %% a node; usually, this is a positive integer indicating the original
  315. %% source code line, but no assumptions are made in this module
  316. %% regarding the format or interpretation of position information. When
  317. %% a syntax tree node is constructed, its associated position is by
  318. %% default set to the integer zero.
  319. %% =====================================================================
  320. -define(NO_UNUSED, true).
  321. %% =====================================================================
  322. %% Declarations of globally used internal data structures
  323. %% =====================================================================
  324. %% `com' records are used to hold comment information attached to a
  325. %% syntax tree node or a wrapper structure.
  326. %%
  327. %% #com{pre :: Pre, post :: Post}
  328. %%
  329. %% Pre = Post = [Com]
  330. %% Com = syntaxTree()
  331. %%
  332. %% type(Com) = comment
  333. -record(com, {pre = [],
  334. post = []}).
  335. %% `attr' records store node attributes as an aggregate.
  336. %%
  337. %% #attr{pos :: Pos, ann :: Ann, com :: Comments}
  338. %%
  339. %% Pos = term()
  340. %% Ann = [term()]
  341. %% Comments = none | #com{}
  342. %%
  343. %% where `Pos' `Ann' and `Comments' are the corresponding values of a
  344. %% `tree' or `wrapper' record.
  345. -record(attr, {pos = 0,
  346. ann = [],
  347. com = none}).
  348. %% `tree' records represent new-form syntax tree nodes.
  349. %%
  350. %% Tree = #tree{type :: Type, attr :: Attr, data :: Data}
  351. %%
  352. %% Type = atom()
  353. %% Attr = #attr{}
  354. %% Data = term()
  355. %%
  356. %% is_tree(Tree) = true
  357. -record(tree, {type,
  358. attr = #attr{},
  359. data}).
  360. %% `wrapper' records are used for attaching new-form node information to
  361. %% `erl_parse' trees.
  362. %%
  363. %% Wrapper = #wrapper{type :: Type, attr :: Attr, tree :: ParseTree}
  364. %%
  365. %% Type = atom()
  366. %% Attr = #attr{}
  367. %% ParseTree = term()
  368. %%
  369. %% is_tree(Wrapper) = false
  370. -record(wrapper, {type,
  371. attr = #attr{},
  372. tree}).
  373. %% =====================================================================
  374. %%
  375. %% Exported functions
  376. %%
  377. %% =====================================================================
  378. %% =====================================================================
  379. %% @spec type(Node::syntaxTree()) -> atom()
  380. %%
  381. %% @doc Returns the type tag of <code>Node</code>. If <code>Node</code>
  382. %% does not represent a syntax tree, evaluation fails with reason
  383. %% <code>badarg</code>. Node types currently defined by this module are:
  384. %% <p><center><table border="1">
  385. %% <tr>
  386. %% <td>application</td>
  387. %% <td>arity_qualifier</td>
  388. %% <td>atom</td>
  389. %% <td>attribute</td>
  390. %% </tr><tr>
  391. %% <td>binary</td>
  392. %% <td>binary_field</td>
  393. %% <td>block_expr</td>
  394. %% <td>case_expr</td>
  395. %% </tr><tr>
  396. %% <td>catch_expr</td>
  397. %% <td>char</td>
  398. %% <td>class_qualifier</td>
  399. %% <td>clause</td>
  400. %% </tr><tr>
  401. %% <td>comment</td>
  402. %% <td>cond_expr</td>
  403. %% <td>conjunction</td>
  404. %% <td>disjunction</td>
  405. %% </tr><tr>
  406. %% <td>eof_marker</td>
  407. %% <td>error_marker</td>
  408. %% <td>float</td>
  409. %% <td>form_list</td>
  410. %% </tr><tr>
  411. %% <td>fun_expr</td>
  412. %% <td>function</td>
  413. %% <td>generator</td>
  414. %% <td>if_expr</td>
  415. %% </tr><tr>
  416. %% <td>implicit_fun</td>
  417. %% <td>infix_expr</td>
  418. %% <td>integer</td>
  419. %% <td>list</td>
  420. %% </tr><tr>
  421. %% <td>list_comp</td>
  422. %% <td>macro</td>
  423. %% <td>match_expr</td>
  424. %% <td>module_qualifier</td>
  425. %% </tr><tr>
  426. %% <td>nil</td>
  427. %% <td>operator</td>
  428. %% <td>parentheses</td>
  429. %% <td>prefix_expr</td>
  430. %% </tr><tr>
  431. %% <td>qualified_name</td>
  432. %% <td>query_expr</td>
  433. %% <td>receive_expr</td>
  434. %% <td>record_access</td>
  435. %% </tr><tr>
  436. %% <td>record_expr</td>
  437. %% <td>record_field</td>
  438. %% <td>record_index_expr</td>
  439. %% <td>rule</td>
  440. %% </tr><tr>
  441. %% <td>size_qualifier</td>
  442. %% <td>string</td>
  443. %% <td>text</td>
  444. %% <td>try_expr</td>
  445. %% </tr><tr>
  446. %% <td>tuple</td>
  447. %% <td>underscore</td>
  448. %% <td>variable</td>
  449. %% <td>warning_marker</td>
  450. %% </tr>
  451. %% </table></center></p>
  452. %% <p>The user may (for special purposes) create additional nodes
  453. %% with other type tags, using the <code>tree/2</code> function.</p>
  454. %%
  455. %% <p>Note: The primary constructor functions for a node type should
  456. %% always have the same name as the node type itself.</p>
  457. %%
  458. %% @see tree/2
  459. %% @see application/3
  460. %% @see arity_qualifier/2
  461. %% @see atom/1
  462. %% @see attribute/2
  463. %% @see binary/1
  464. %% @see binary_field/2
  465. %% @see block_expr/1
  466. %% @see case_expr/2
  467. %% @see catch_expr/1
  468. %% @see char/1
  469. %% @see class_qualifier/2
  470. %% @see clause/3
  471. %% @see comment/2
  472. %% @see cond_expr/1
  473. %% @see conjunction/1
  474. %% @see disjunction/1
  475. %% @see eof_marker/0
  476. %% @see error_marker/1
  477. %% @see float/1
  478. %% @see form_list/1
  479. %% @see fun_expr/1
  480. %% @see function/2
  481. %% @see generator/2
  482. %% @see if_expr/1
  483. %% @see implicit_fun/2
  484. %% @see infix_expr/3
  485. %% @see integer/1
  486. %% @see list/2
  487. %% @see list_comp/2
  488. %% @see macro/2
  489. %% @see match_expr/2
  490. %% @see module_qualifier/2
  491. %% @see nil/0
  492. %% @see operator/1
  493. %% @see parentheses/1
  494. %% @see prefix_expr/2
  495. %% @see qualified_name/1
  496. %% @see query_expr/1
  497. %% @see receive_expr/3
  498. %% @see record_access/3
  499. %% @see record_expr/2
  500. %% @see record_field/2
  501. %% @see record_index_expr/2
  502. %% @see rule/2
  503. %% @see size_qualifier/2
  504. %% @see string/1
  505. %% @see text/1
  506. %% @see try_expr/3
  507. %% @see tuple/1
  508. %% @see underscore/0
  509. %% @see variable/1
  510. %% @see warning_marker/1
  511. type(#tree{type = T}) ->
  512. T;
  513. type(#wrapper{type = T}) ->
  514. T;
  515. type(Node) ->
  516. %% Check for `erl_parse'-compatible nodes, and otherwise fail.
  517. case Node of
  518. %% Leaf types
  519. {atom, _, _} -> atom;
  520. {char, _, _} -> char;
  521. {float, _, _} -> float;
  522. {integer, _, _} -> integer;
  523. {nil, _} -> nil;
  524. {string, _, _} -> string;
  525. {var, _, Name} ->
  526. if Name == '_' -> underscore;
  527. true -> variable
  528. end;
  529. {error, _} -> error_marker;
  530. {warning, _} -> warning_marker;
  531. {eof, _} -> eof_marker;
  532. %% Composite types
  533. {'case', _, _, _} -> case_expr;
  534. {'catch', _, _} -> catch_expr;
  535. {'cond', _, _} -> cond_expr;
  536. {'fun', _, {clauses, _}} -> fun_expr;
  537. {'fun', _, {function, _, _}} -> implicit_fun;
  538. {'if', _, _} -> if_expr;
  539. {'receive', _, _, _, _} -> receive_expr;
  540. {'receive', _, _} -> receive_expr;
  541. {attribute, _, _, _} -> attribute;
  542. {bin, _, _} -> binary;
  543. {bin_element, _, _, _, _} -> binary_field;
  544. {block, _, _} -> block_expr;
  545. {call, _, _, _} -> application;
  546. {clause, _, _, _, _} -> clause;
  547. {cons, _, _, _} -> list;
  548. {function, _, _, _, _} -> function;
  549. {generate, _, _, _} -> generator;
  550. {lc, _, _, _} -> list_comp;
  551. {match, _, _, _} -> match_expr;
  552. {op, _, _, _, _} -> infix_expr;
  553. {op, _, _, _} -> prefix_expr;
  554. {'query', _, _} -> query_expr;
  555. {record, _, _, _, _} -> record_expr;
  556. {record, _, _, _} -> record_expr;
  557. {record_field, _, _, _, _} -> record_access;
  558. {record_field, _, _, _} ->
  559. case is_qualified_name(Node) of
  560. true -> qualified_name;
  561. false -> record_access
  562. end;
  563. {record_index, _, _, _} -> record_index_expr;
  564. {remote, _, _, _} -> module_qualifier;
  565. {rule, _, _, _, _} -> rule;
  566. {'try', _, _, _, _, _} -> try_expr;
  567. {tuple, _, _} -> tuple;
  568. _ ->
  569. erlang:fault({badarg, Node})
  570. end.
  571. %% =====================================================================
  572. %% @spec is_leaf(Node::syntaxTree()) -> bool()
  573. %%
  574. %% @doc Returns <code>true</code> if <code>Node</code> is a leaf node,
  575. %% otherwise <code>false</code>. The currently recognised leaf node
  576. %% types are:
  577. %% <p><center><table border="1">
  578. %% <tr>
  579. %% <td><code>atom</code></td>
  580. %% <td><code>char</code></td>
  581. %% <td><code>comment</code></td>
  582. %% <td><code>eof_marker</code></td>
  583. %% <td><code>error_marker</code></td>
  584. %% </tr><tr>
  585. %% <td><code>float</code></td>
  586. %% <td><code>integer</code></td>
  587. %% <td><code>nil</code></td>
  588. %% <td><code>operator</code></td>
  589. %% <td><code>string</code></td>
  590. %% </tr><tr>
  591. %% <td><code>text</code></td>
  592. %% <td><code>underscore</code></td>
  593. %% <td><code>variable</code></td>
  594. %% <td><code>warning_marker</code></td>
  595. %% </tr>
  596. %% </table></center></p>
  597. %% <p>A node of type <code>tuple</code> is a leaf node if and only if
  598. %% its arity is zero.</p>
  599. %%
  600. %% <p>Note: not all literals are leaf nodes, and vice versa. E.g.,
  601. %% tuples with nonzero arity and nonempty lists may be literals, but are
  602. %% not leaf nodes. Variables, on the other hand, are leaf nodes but not
  603. %% literals.</p>
  604. %%
  605. %% @see type/1
  606. %% @see is_literal/1
  607. is_leaf(Node) ->
  608. case type(Node) of
  609. atom -> true;
  610. char -> true;
  611. comment -> true; % nonstandard type
  612. eof_marker -> true;
  613. error_marker -> true;
  614. float -> true;
  615. integer -> true;
  616. nil -> true;
  617. operator -> true; % nonstandard type
  618. string -> true;
  619. text -> true; % nonstandard type
  620. tuple ->
  621. case tuple_elements(Node) of
  622. [] -> true;
  623. _ -> false
  624. end;
  625. underscore -> true;
  626. variable -> true;
  627. warning_marker -> true;
  628. _ -> false
  629. end.
  630. %% =====================================================================
  631. %% @spec is_form(Node::syntaxTree()) -> bool()
  632. %%
  633. %% @doc Returns <code>true</code> if <code>Node</code> is a syntax tree
  634. %% representing a so-called "source code form", otherwise
  635. %% <code>false</code>. Forms are the Erlang source code units which,
  636. %% placed in sequence, constitute an Erlang program. Current form types
  637. %% are:
  638. %% <p><center><table border="1">
  639. %% <tr>
  640. %% <td><code>attribute</code></td>
  641. %% <td><code>comment</code></td>
  642. %% <td><code>error_marker</code></td>
  643. %% <td><code>eof_marker</code></td>
  644. %% </tr><tr>
  645. %% <td><code>form_list</code></td>
  646. %% <td><code>function</code></td>
  647. %% <td><code>rule</code></td>
  648. %% <td><code>warning_marker</code></td>
  649. %% </tr>
  650. %% </table></center></p>
  651. %% @see type/1
  652. %% @see attribute/2
  653. %% @see comment/2
  654. %% @see eof_marker/1
  655. %% @see error_marker/1
  656. %% @see form_list/1
  657. %% @see function/2
  658. %% @see rule/2
  659. %% @see warning_marker/1
  660. is_form(Node) ->
  661. case type(Node) of
  662. attribute -> true;
  663. comment -> true;
  664. function -> true;
  665. eof_marker -> true;
  666. error_marker -> true;
  667. form_list -> true;
  668. rule -> true;
  669. warning_marker -> true;
  670. _ -> false
  671. end.
  672. %% =====================================================================
  673. %% @spec get_pos(Node::syntaxTree()) -> term()
  674. %%
  675. %% @doc Returns the position information associated with
  676. %% <code>Node</code>. This is usually a nonnegative integer (indicating
  677. %% the source code line number), but may be any term. By default, all
  678. %% new tree nodes have their associated position information set to the
  679. %% integer zero.
  680. %%
  681. %% @see set_pos/2
  682. %% @see get_attrs/1
  683. %% All `erl_parse' tree nodes are represented by tuples whose second
  684. %% field is the position information (usually an integer), *with the
  685. %% exceptions of* `{error, ...}' (type `error_marker') and `{warning,
  686. %% ...}' (type `warning_marker'), which only contain the associated line
  687. %% number *of the error descriptor*; this is all handled transparently
  688. %% by `get_pos' and `set_pos'.
  689. get_pos(#tree{attr = Attr}) ->
  690. Attr#attr.pos;
  691. get_pos(#wrapper{attr = Attr}) ->
  692. Attr#attr.pos;
  693. get_pos({error, {Pos, _, _}}) ->
  694. Pos;
  695. get_pos({warning, {Pos, _, _}}) ->
  696. Pos;
  697. get_pos(Node) ->
  698. %% Here, we assume that we have an `erl_parse' node with position
  699. %% information in element 2.
  700. element(2, Node).
  701. %% =====================================================================
  702. %% @spec set_pos(Node::syntaxTree(), Pos::term()) -> syntaxTree()
  703. %%
  704. %% @doc Sets the position information of <code>Node</code> to
  705. %% <code>Pos</code>.
  706. %%
  707. %% @see get_pos/1
  708. %% @see copy_pos/2
  709. set_pos(Node, Pos) ->
  710. case Node of
  711. #tree{attr = Attr} ->
  712. Node#tree{attr = Attr#attr{pos = Pos}};
  713. #wrapper{attr = Attr} ->
  714. Node#wrapper{attr = Attr#attr{pos = Pos}};
  715. _ ->
  716. %% We then assume we have an `erl_parse' node, and create a
  717. %% wrapper around it to make things more uniform.
  718. set_pos(wrap(Node), Pos)
  719. end.
  720. %% =====================================================================
  721. %% @spec copy_pos(Source::syntaxTree(), Target::syntaxTree()) ->
  722. %% syntaxTree()
  723. %%
  724. %% @doc Copies the position information from <code>Source</code> to
  725. %% <code>Target</code>.
  726. %%
  727. %% <p>This is equivalent to <code>set_pos(Target,
  728. %% get_pos(Source))</code>, but potentially more efficient.</p>
  729. %%
  730. %% @see get_pos/1
  731. %% @see set_pos/2
  732. copy_pos(Source, Target) ->
  733. set_pos(Target, get_pos(Source)).
  734. %% =====================================================================
  735. %% `get_com' and `set_com' are for internal use only.
  736. get_com(#tree{attr = Attr}) -> Attr#attr.com;
  737. get_com(#wrapper{attr = Attr}) -> Attr#attr.com;
  738. get_com(_) -> none.
  739. set_com(Node, Com) ->
  740. case Node of
  741. #tree{attr = Attr} ->
  742. Node#tree{attr = Attr#attr{com = Com}};
  743. #wrapper{attr = Attr} ->
  744. Node#wrapper{attr = Attr#attr{com = Com}};
  745. _ ->
  746. set_com(wrap(Node), Com)
  747. end.
  748. %% =====================================================================
  749. %% @spec get_precomments(syntaxTree()) -> [syntaxTree()]
  750. %%
  751. %% @doc Returns the associated pre-comments of a node. This is a
  752. %% possibly empty list of abstract comments, in top-down textual order.
  753. %% When the code is formatted, pre-comments are typically displayed
  754. %% directly above the node. For example:
  755. %% <pre>
  756. %% % Pre-comment of function
  757. %% foo(X) -> {bar, X}.</pre>
  758. %%
  759. %% <p>If possible, the comment should be moved before any preceding
  760. %% separator characters on the same line. E.g.:
  761. %% <pre>
  762. %% foo([X | Xs]) ->
  763. %% % Pre-comment of 'bar(X)' node
  764. %% [bar(X) | foo(Xs)];
  765. %% ...</pre>
  766. %% (where the comment is moved before the "<code>[</code>").</p>
  767. %%
  768. %% @see comment/2
  769. %% @see set_precomments/2
  770. %% @see get_postcomments/1
  771. %% @see get_attrs/1
  772. get_precomments(#tree{attr = Attr}) -> get_precomments_1(Attr);
  773. get_precomments(#wrapper{attr = Attr}) -> get_precomments_1(Attr);
  774. get_precomments(_) -> [].
  775. get_precomments_1(#attr{com = none}) -> [];
  776. get_precomments_1(#attr{com = #com{pre = Cs}}) -> Cs.
  777. %% =====================================================================
  778. %% @spec set_precomments(Node::syntaxTree(),
  779. %% Comments::[syntaxTree()]) -> syntaxTree()
  780. %%
  781. %% @doc Sets the pre-comments of <code>Node</code> to
  782. %% <code>Comments</code>. <code>Comments</code> should be a possibly
  783. %% empty list of abstract comments, in top-down textual order.
  784. %%
  785. %% @see comment/2
  786. %% @see get_precomments/1
  787. %% @see add_precomments/2
  788. %% @see set_postcomments/2
  789. %% @see copy_comments/2
  790. %% @see remove_comments/1
  791. %% @see join_comments/2
  792. set_precomments(Node, Cs) ->
  793. case Node of
  794. #tree{attr = Attr} ->
  795. Node#tree{attr = set_precomments_1(Attr, Cs)};
  796. #wrapper{attr = Attr} ->
  797. Node#wrapper{attr = set_precomments_1(Attr, Cs)};
  798. _ ->
  799. set_precomments(wrap(Node), Cs)
  800. end.
  801. set_precomments_1(#attr{com = none} = Attr, Cs) ->
  802. Attr#attr{com = #com{pre = Cs}};
  803. set_precomments_1(#attr{com = Com} = Attr, Cs) ->
  804. Attr#attr{com = Com#com{pre = Cs}}.
  805. %% =====================================================================
  806. %% @spec add_precomments(Comments::[syntaxTree()],
  807. %% Node::syntaxTree()) -> syntaxTree()
  808. %%
  809. %% @doc Appends <code>Comments</code> to the pre-comments of
  810. %% <code>Node</code>.
  811. %%
  812. %% <p>Note: This is equivalent to <code>set_precomments(Node,
  813. %% get_precomments(Node) ++ Comments)</code>, but potentially more
  814. %% efficient.</p>
  815. %%
  816. %% @see comment/2
  817. %% @see get_precomments/1
  818. %% @see set_precomments/2
  819. %% @see add_postcomments/2
  820. %% @see join_comments/2
  821. add_precomments(Cs, Node) ->
  822. case Node of
  823. #tree{attr = Attr} ->
  824. Node#tree{attr = add_precomments_1(Cs, Attr)};
  825. #wrapper{attr = Attr} ->
  826. Node#wrapper{attr = add_precomments_1(Cs, Attr)};
  827. _ ->
  828. add_precomments(Cs, wrap(Node))
  829. end.
  830. add_precomments_1(Cs, #attr{com = none} = Attr) ->
  831. Attr#attr{com = #com{pre = Cs}};
  832. add_precomments_1(Cs, #attr{com = Com} = Attr) ->
  833. Attr#attr{com = Com#com{pre = Com#com.pre ++ Cs}}.
  834. %% =====================================================================
  835. %% @spec get_postcomments(syntaxTree()) -> [syntaxTree()]
  836. %%
  837. %% @doc Returns the associated post-comments of a node. This is a
  838. %% possibly empty list of abstract comments, in top-down textual order.
  839. %% When the code is formatted, post-comments are typically displayed to
  840. %% the right of and/or below the node. For example:
  841. %% <pre>
  842. %% {foo, X, Y} % Post-comment of tuple</pre>
  843. %%
  844. %% <p>If possible, the comment should be moved past any following
  845. %% separator characters on the same line, rather than placing the
  846. %% separators on the following line. E.g.:
  847. %% <pre>
  848. %% foo([X | Xs], Y) ->
  849. %% foo(Xs, bar(X)); % Post-comment of 'bar(X)' node
  850. %% ...</pre>
  851. %% (where the comment is moved past the rightmost "<code>)</code>" and
  852. %% the "<code>;</code>").</p>
  853. %%
  854. %% @see comment/2
  855. %% @see set_postcomments/2
  856. %% @see get_precomments/1
  857. %% @see get_attrs/1
  858. get_postcomments(#tree{attr = Attr}) -> get_postcomments_1(Attr);
  859. get_postcomments(#wrapper{attr = Attr}) -> get_postcomments_1(Attr);
  860. get_postcomments(_) -> [].
  861. get_postcomments_1(#attr{com = none}) -> [];
  862. get_postcomments_1(#attr{com = #com{post = Cs}}) -> Cs.
  863. %% =====================================================================
  864. %% @spec set_postcomments(Node::syntaxTree(),
  865. %% Comments::[syntaxTree()]) -> syntaxTree()
  866. %%
  867. %% @doc Sets the post-comments of <code>Node</code> to
  868. %% <code>Comments</code>. <code>Comments</code> should be a possibly
  869. %% empty list of abstract comments, in top-down textual order
  870. %%
  871. %% @see comment/2
  872. %% @see get_postcomments/1
  873. %% @see add_postcomments/2
  874. %% @see set_precomments/2
  875. %% @see copy_comments/2
  876. %% @see remove_comments/1
  877. %% @see join_comments/2
  878. set_postcomments(Node, Cs) ->
  879. case Node of
  880. #tree{attr = Attr} ->
  881. Node#tree{attr = set_postcomments_1(Attr, Cs)};
  882. #wrapper{attr = Attr} ->
  883. Node#wrapper{attr = set_postcomments_1(Attr, Cs)};
  884. _ ->
  885. set_postcomments(wrap(Node), Cs)
  886. end.
  887. set_postcomments_1(#attr{com = none} = Attr, Cs) ->
  888. Attr#attr{com = #com{post = Cs}};
  889. set_postcomments_1(#attr{com = Com} = Attr, Cs) ->
  890. Attr#attr{com = Com#com{post = Cs}}.
  891. %% =====================================================================
  892. %% @spec add_postcomments(Comments::[syntaxTree()],
  893. %% Node::syntaxTree()) -> syntaxTree()
  894. %%
  895. %% @doc Appends <code>Comments</code> to the post-comments of
  896. %% <code>Node</code>.
  897. %%
  898. %% <p>Note: This is equivalent to <code>set_postcomments(Node,
  899. %% get_postcomments(Node) ++ Comments)</code>, but potentially more
  900. %% efficient.</p>
  901. %%
  902. %% @see comment/2
  903. %% @see get_postcomments/1
  904. %% @see set_postcomments/2
  905. %% @see add_precomments/2
  906. %% @see join_comments/2
  907. add_postcomments(Cs, Node) ->
  908. case Node of
  909. #tree{attr = Attr} ->
  910. Node#tree{attr = add_postcomments_1(Cs, Attr)};
  911. #wrapper{attr = Attr} ->
  912. Node#wrapper{attr = add_postcomments_1(Cs, Attr)};
  913. _ ->
  914. add_postcomments(Cs, wrap(Node))
  915. end.
  916. add_postcomments_1(Cs, #attr{com = none} = Attr) ->
  917. Attr#attr{com = #com{post = Cs}};
  918. add_postcomments_1(Cs, #attr{com = Com} = Attr) ->
  919. Attr#attr{com = Com#com{post = Com#com.post ++ Cs}}.
  920. %% =====================================================================
  921. %% @spec has_comments(Node::syntaxTree()) -> bool()
  922. %%
  923. %% @doc Yields <code>false</code> if the node has no associated
  924. %% comments, and <code>true</code> otherwise.
  925. %%
  926. %% <p>Note: This is equivalent to <code>(get_precomments(Node) == [])
  927. %% and (get_postcomments(Node) == [])</code>, but potentially more
  928. %% efficient.</p>
  929. %%
  930. %% @see get_precomments/1
  931. %% @see get_postcomments/1
  932. %% @see remove_comments/1
  933. has_comments(#tree{attr = Attr}) ->
  934. case Attr#attr.com of
  935. none -> false;
  936. #com{pre = [], post = []} -> false;
  937. _ -> true
  938. end;
  939. has_comments(#wrapper{attr = Attr}) ->
  940. case Attr#attr.com of
  941. none -> false;
  942. #com{pre = [], post = []} -> false;
  943. _ -> true
  944. end;
  945. has_comments(_) -> false.
  946. %% =====================================================================
  947. %% @spec remove_comments(Node::syntaxTree()) -> syntaxTree()
  948. %%
  949. %% @doc Clears the associated comments of <code>Node</code>.
  950. %%
  951. %% <p>Note: This is equivalent to
  952. %% <code>set_precomments(set_postcomments(Node, []), [])</code>, but
  953. %% potentially more efficient.</p>
  954. %%
  955. %% @see set_precomments/2
  956. %% @see set_postcomments/2
  957. remove_comments(Node) ->
  958. case Node of
  959. #tree{attr = Attr} ->
  960. Node#tree{attr = Attr#attr{com = none}};
  961. #wrapper{attr = Attr} ->
  962. Node#wrapper{attr = Attr#attr{com = none}};
  963. _ ->
  964. Node
  965. end.
  966. %% =====================================================================
  967. %% @spec copy_comments(Source::syntaxTree(), Target::syntaxTree()) ->
  968. %% syntaxTree()
  969. %%
  970. %% @doc Copies the pre- and postcomments from <code>Source</code> to
  971. %% <code>Target</code>.
  972. %%
  973. %% <p>Note: This is equivalent to
  974. %% <code>set_postcomments(set_precomments(Target,
  975. %% get_precomments(Source)), get_postcomments(Source))</code>, but
  976. %% potentially more efficient.</p>
  977. %%
  978. %% @see comment/2
  979. %% @see get_precomments/1
  980. %% @see get_postcomments/1
  981. %% @see set_precomments/2
  982. %% @see set_postcomments/2
  983. copy_comments(Source, Target) ->
  984. set_com(Target, get_com(Source)).
  985. %% =====================================================================
  986. %% @spec join_comments(Source::syntaxTree(), Target::syntaxTree()) ->
  987. %% syntaxTree()
  988. %%
  989. %% @doc Appends the comments of <code>Source</code> to the current
  990. %% comments of <code>Target</code>.
  991. %%
  992. %% <p>Note: This is equivalent to
  993. %% <code>add_postcomments(get_postcomments(Source),
  994. %% add_precomments(get_precomments(Source), Target))</code>, but
  995. %% potentially more efficient.</p>
  996. %%
  997. %% @see comment/2
  998. %% @see get_precomments/1
  999. %% @see get_postcomments/1
  1000. %% @see add_precomments/2
  1001. %% @see add_postcomments/2
  1002. join_comments(Source, Target) ->
  1003. add_postcomments(
  1004. get_postcomments(Source),
  1005. add_precomments(get_precomments(Source), Target)).
  1006. %% =====================================================================
  1007. %% @spec get_ann(syntaxTree()) -> [term()]
  1008. %%
  1009. %% @doc Returns the list of user annotations associated with a syntax
  1010. %% tree node. For a newly created node, this is the empty list. The
  1011. %% annotations may be any terms.
  1012. %%
  1013. %% @see set_ann/2
  1014. %% @see get_attrs/1
  1015. get_ann(#tree{attr = Attr}) -> Attr#attr.ann;
  1016. get_ann(#wrapper{attr = Attr}) -> Attr#attr.ann;
  1017. get_ann(_) -> [].
  1018. %% =====================================================================
  1019. %% @spec set_ann(Node::syntaxTree(), Annotations::[term()]) ->
  1020. %% syntaxTree()
  1021. %%
  1022. %% @doc Sets the list of user annotations of <code>Node</code> to
  1023. %% <code>Annotations</code>.
  1024. %%
  1025. %% @see get_ann/1
  1026. %% @see add_ann/2
  1027. %% @see copy_ann/2
  1028. set_ann(Node, As) ->
  1029. case Node of
  1030. #tree{attr = Attr} ->
  1031. Node#tree{attr = Attr#attr{ann = As}};
  1032. #wrapper{attr = Attr} ->
  1033. Node#wrapper{attr = Attr#attr{ann = As}};
  1034. _ ->
  1035. %% Assume we have an `erl_parse' node and create a wrapper
  1036. %% structure to carry the annotation.
  1037. set_ann(wrap(Node), As)
  1038. end.
  1039. %% =====================================================================
  1040. %% @spec add_ann(Annotation::term(), Node::syntaxTree()) -> syntaxTree()
  1041. %%
  1042. %% @doc Appends the term <code>Annotation</code> to the list of user
  1043. %% annotations of <code>Node</code>.
  1044. %%
  1045. %% <p>Note: this is equivalent to <code>set_ann(Node, [Annotation |
  1046. %% get_ann(Node)])</code>, but potentially more efficient.</p>
  1047. %%
  1048. %% @see get_ann/1
  1049. %% @see set_ann/2
  1050. add_ann(A, Node) ->
  1051. case Node of
  1052. #tree{attr = Attr} ->
  1053. Node#tree{attr = Attr#attr{ann = [A | Attr#attr.ann]}};
  1054. #wrapper{attr = Attr} ->
  1055. Node#wrapper{attr = Attr#attr{ann = [A | Attr#attr.ann]}};
  1056. _ ->
  1057. %% Assume we have an `erl_parse' node and create a wrapper
  1058. %% structure to carry the annotation.
  1059. add_ann(A, wrap(Node))
  1060. end.
  1061. %% =====================================================================
  1062. %% @spec copy_ann(Source::syntaxTree(), Target::syntaxTree()) ->
  1063. %% syntaxTree()
  1064. %%
  1065. %% @doc Copies the list of user annotations from <code>Source</code> to
  1066. %% <code>Target</code>.
  1067. %%
  1068. %% <p>Note: this is equivalent to <code>set_ann(Target,
  1069. %% get_ann(Source))</code>, but potentially more efficient.</p>
  1070. %%
  1071. %% @see get_ann/1
  1072. %% @see set_ann/2
  1073. copy_ann(Source, Target) ->
  1074. set_ann(Target, get_ann(Source)).
  1075. %% =====================================================================
  1076. %% @spec get_attrs(syntaxTree()) -> syntaxTreeAttributes()
  1077. %%
  1078. %% @doc Returns a representation of the attributes associated with a
  1079. %% syntax tree node. The attributes are all the extra information that
  1080. %% can be attached to a node. Currently, this includes position
  1081. %% information, source code comments, and user annotations. The result
  1082. %% of this function cannot be inspected directly; only attached to
  1083. %% another node (cf. <code>set_attrs/2</code>).
  1084. %%
  1085. %% <p>For accessing individual attributes, see <code>get_pos/1</code>,
  1086. %% <code>get_ann/1</code>, <code>get_precomments/1</code> and
  1087. %% <code>get_postcomments/1</code>.</p>
  1088. %%
  1089. %% @type syntaxTreeAttributes(). This is an abstract representation of
  1090. %% syntax tree node attributes; see the function <a
  1091. %% href="#get_attrs-1"><code>get_attrs/1</code></a>.
  1092. %%
  1093. %% @see set_attrs/2
  1094. %% @see get_pos/1
  1095. %% @see get_ann/1
  1096. %% @see get_precomments/1
  1097. %% @see get_postcomments/1
  1098. get_attrs(#tree{attr = Attr}) -> Attr;
  1099. get_attrs(#wrapper{attr = Attr}) -> Attr;
  1100. get_attrs(Node) -> #attr{pos = get_pos(Node),
  1101. ann = get_ann(Node),
  1102. com = get_com(Node)}.
  1103. %% =====================================================================
  1104. %% @spec set_attrs(Node::syntaxTree(),
  1105. %% Attributes::syntaxTreeAttributes()) -> syntaxTree()
  1106. %%
  1107. %% @doc Sets the attributes of <code>Node</code> to
  1108. %% <code>Attributes</code>.
  1109. %%
  1110. %% @see get_attrs/1
  1111. %% @see copy_attrs/2
  1112. set_attrs(Node, Attr) ->
  1113. case Node of
  1114. #tree{} ->
  1115. Node#tree{attr = Attr};
  1116. #wrapper{} ->
  1117. Node#wrapper{attr = Attr};
  1118. _ ->
  1119. set_attrs(wrap(Node), Attr)
  1120. end.
  1121. %% =====================================================================
  1122. %% @spec copy_attrs(Source::syntaxTree(), Target::syntaxTree()) ->
  1123. %% syntaxTree()
  1124. %%
  1125. %% @doc Copies the attributes from <code>Source</code> to
  1126. %% <code>Target</code>.
  1127. %%
  1128. %% <p>Note: this is equivalent to <code>set_attrs(Target,
  1129. %% get_attrs(Source))</code>, but potentially more efficient.</p>
  1130. %%
  1131. %% @see get_attrs/1
  1132. %% @see set_attrs/2
  1133. copy_attrs(S, T) ->
  1134. set_attrs(T, get_attrs(S)).
  1135. %% =====================================================================
  1136. %% @spec comment(Strings) -> syntaxTree()
  1137. %% @equiv comment(none, Strings)
  1138. comment(Strings) ->
  1139. comment(none, Strings).
  1140. %% =====================================================================
  1141. %% @spec comment(Padding, Strings::[string()]) -> syntaxTree()
  1142. %% Padding = none | integer()
  1143. %%
  1144. %% @doc Creates an abstract comment with the given padding and text. If
  1145. %% <code>Strings</code> is a (possibly empty) list
  1146. %% <code>["<em>Txt1</em>", ..., "<em>TxtN</em>"]</code>, the result
  1147. %% represents the source code text
  1148. %% <pre>
  1149. %% %<em>Txt1</em>
  1150. %% ...
  1151. %% %<em>TxtN</em></pre>
  1152. %% <code>Padding</code> states the number of empty character positions
  1153. %% to the left of the comment separating it horizontally from
  1154. %% source code on the same line (if any). If <code>Padding</code> is
  1155. %% <code>none</code>, a default positive number is used. If
  1156. %% <code>Padding</code> is an integer less than 1, there should be no
  1157. %% separating space. Comments are in themselves regarded as source
  1158. %% program forms.
  1159. %%
  1160. %% @see comment/1
  1161. %% @see is_form/1
  1162. -record(comment, {pad, text}).
  1163. %% type(Node) = comment
  1164. %% data(Node) = #comment{pad :: Padding, text :: Strings}
  1165. %%
  1166. %% Padding = none | integer()
  1167. %% Strings = [string()]
  1168. comment(Pad, Strings) ->
  1169. tree(comment, #comment{pad = Pad, text = Strings}).
  1170. %% =====================================================================
  1171. %% @spec comment_text(Node::syntaxTree()) -> [string()]
  1172. %%
  1173. %% @doc Returns the lines of text of the abstract comment.
  1174. %%
  1175. %% @see comment/2
  1176. comment_text(Node) ->
  1177. (data(Node))#comment.text.
  1178. %% =====================================================================
  1179. %% @spec comment_padding(Node::syntaxTree()) -> none | integer()
  1180. %%
  1181. %% @doc Returns the amount of padding before the comment, or
  1182. %% <code>none</code>. The latter means that a default padding may be
  1183. %% used.
  1184. %%
  1185. %% @see comment/2
  1186. comment_padding(Node) ->
  1187. (data(Node))#comment.pad.
  1188. %% =====================================================================
  1189. %% @spec form_list(Forms::[syntaxTree()]) -> syntaxTree()
  1190. %%
  1191. %% @doc Creates an abstract sequence of "source code forms". If
  1192. %% <code>Forms</code> is <code>[F1, ..., Fn]</code>, where each
  1193. %% <code>Fi</code> is a form (cf. <code>is_form/1</code>, the result
  1194. %% represents
  1195. %% <pre>
  1196. %% <em>F1</em>
  1197. %% ...
  1198. %% <em>Fn</em></pre>
  1199. %% where the <code>Fi</code> are separated by one or more line breaks. A
  1200. %% node of type <code>form_list</code> is itself regarded as a source
  1201. %% code form; cf. <code>flatten_form_list/1</code>.
  1202. %%
  1203. %% <p>Note: this is simply a way of grouping source code forms as a
  1204. %% single syntax tree, usually in order to form an Erlang module
  1205. %% definition.</p>
  1206. %%
  1207. %% @see form_list_elements/1
  1208. %% @see is_form/1
  1209. %% @see flatten_form_list/1
  1210. %% type(Node) = form_list
  1211. %% data(Node) = [Form]
  1212. %%
  1213. %% Form = syntaxTree()
  1214. %% is_form(Form) = true
  1215. form_list(Forms) ->
  1216. tree(form_list, Forms).
  1217. %% =====================================================================
  1218. %% @spec form_list_elements(syntaxTree()) -> [syntaxTree()]
  1219. %%
  1220. %% @doc Returns the list of subnodes of a <code>form_list</code> node.
  1221. %%
  1222. %% @see form_list/1
  1223. form_list_elements(Node) ->
  1224. data(Node).
  1225. %% =====================================================================
  1226. %% @spec flatten_form_list(Node::syntaxTree()) -> syntaxTree()
  1227. %%
  1228. %% @doc Flattens sublists of a <code>form_list</code> node. Returns
  1229. %% <code>Node</code> with all subtrees of type <code>form_list</code>
  1230. %% recursively expanded, yielding a single "flat" abstract form
  1231. %% sequence.
  1232. %%
  1233. %% @see form_list/1
  1234. flatten_form_list(Node) ->
  1235. Fs = form_list_elements(Node),
  1236. Fs1 = lists:reverse(flatten_form_list_1(Fs, [])),
  1237. copy_attrs(Node, form_list(Fs1)).
  1238. flatten_form_list_1([F | Fs], As) ->
  1239. case type(F) of
  1240. form_list ->
  1241. As1 = flatten_form_list_1(form_list_elements(F), As),
  1242. flatten_form_list_1(Fs, As1);
  1243. _ ->
  1244. flatten_form_list_1(Fs, [F | As])
  1245. end;
  1246. flatten_form_list_1([], As) ->
  1247. As.
  1248. %% =====================================================================
  1249. %% @spec text(String::string()) -> syntaxTree()
  1250. %%
  1251. %% @doc Creates an abstract piece of source code text. The result
  1252. %% represents exactly the sequence of characters in <code>String</code>.
  1253. %% This is useful in cases when one wants full control of the resulting
  1254. %% output, e.g., for the appearance of floating-point numbers or macro
  1255. %% definitions.
  1256. %%
  1257. %% @see text_string/1
  1258. %% type(Node) = text
  1259. %% data(Node) = string()
  1260. text(String) ->
  1261. tree(text, String).
  1262. %% =====================================================================
  1263. %% @spec text_string(syntaxTree()) -> string()
  1264. %%
  1265. %% @doc Returns the character sequence represented by a
  1266. %% <code>text</code> node.
  1267. %%
  1268. %% @see text/1
  1269. text_string(Node) ->
  1270. data(Node).
  1271. %% =====================================================================
  1272. %% @spec variable(Name) -> syntaxTree()
  1273. %% Name = atom() | string()
  1274. %%
  1275. %% @doc Creates an abstract variable with the given name.
  1276. %% <code>Name</code> may be any atom or string that represents a
  1277. %% lexically valid variable name, but <em>not</em> a single underscore
  1278. %% character; cf. <code>underscore/0</code>.
  1279. %%
  1280. %% <p>Note: no checking is done whether the character sequence
  1281. %% represents a proper variable name, i.e., whether or not its first
  1282. %% character is an uppercase Erlang character, or whether it does not
  1283. %% contain control characters, whitespace, etc.</p>
  1284. %%
  1285. %% @see variable_name/1
  1286. %% @see variable_literal/1
  1287. %% @see underscore/0
  1288. %% type(Node) = variable
  1289. %% data(Node) = atom()
  1290. %%
  1291. %% `erl_parse' representation:
  1292. %%
  1293. %% {var, Pos, Name}
  1294. %%
  1295. %% Name = atom() \ '_'
  1296. variable(Name) when atom(Name) ->
  1297. tree(variable, Name);
  1298. variable(Name) ->
  1299. tree(variable, list_to_atom(Name)).
  1300. revert_variable(Node) ->
  1301. Pos = get_pos(Node),
  1302. Name = variable_name(Node),
  1303. {var, Pos, Name}.
  1304. %% =====================================================================
  1305. %% @spec variable_name(syntaxTree()) -> atom()
  1306. %%
  1307. %% @doc Returns the name of a <code>variable</code> node as an atom.
  1308. %%
  1309. %% @see variable/1
  1310. variable_name(Node) ->
  1311. case unwrap(Node) of
  1312. {var, _, Name} ->
  1313. Name;
  1314. Node1 ->
  1315. data(Node1)
  1316. end.
  1317. %% =====================================================================
  1318. %% @spec variable_literal(syntaxTree()) -> string()
  1319. %%
  1320. %% @doc Returns the name of a <code>variable</code> node as a string.
  1321. %%
  1322. %% @see variable/1
  1323. variable_literal(Node) ->
  1324. case unwrap(Node) of
  1325. {var, _, Name} ->
  1326. atom_to_list(Name);
  1327. Node1 ->
  1328. atom_to_list(data(Node1))
  1329. end.
  1330. %% =====================================================================
  1331. %% @spec underscore() -> syntaxTree()
  1332. %%
  1333. %% @doc Creates an abstract universal pattern ("<code>_</code>"). The
  1334. %% lexical representation is a single underscore character. Note that
  1335. %% this is <em>not</em> a variable, lexically speaking.
  1336. %%
  1337. %% @see variable/1
  1338. %% type(Node) = underscore
  1339. %% data(Node) = []
  1340. %%
  1341. %% `erl_parse' representation:
  1342. %%
  1343. %% {var, Pos, '_'}
  1344. underscore() ->
  1345. tree(underscore, []).
  1346. revert_underscore(Node) ->
  1347. Pos = get_pos(Node),
  1348. {var, Pos, '_'}.
  1349. %% =====================================================================
  1350. %% @spec integer(Value::integer()) -> syntaxTree()
  1351. %%
  1352. %% @doc Creates an abstract integer literal. The lexical representation
  1353. %% is the canonical decimal numeral of <code>Value</code>.
  1354. %%
  1355. %% @see integer_value/1
  1356. %% @see integer_literal/1
  1357. %% @see is_integer/2
  1358. %% type(Node) = integer
  1359. %% data(Node) = integer()
  1360. %%
  1361. %% `erl_parse' representation:
  1362. %%
  1363. %% {integer, Pos, Value}
  1364. %%
  1365. %% Value = integer()
  1366. integer(Value) ->
  1367. tree(integer, Value).
  1368. revert_integer(Node) ->
  1369. Pos = get_pos(Node),
  1370. {integer, Pos, integer_value(Node)}.
  1371. %% =====================================================================
  1372. %% @spec is_integer(Node::syntaxTree(), Value::integer()) -> bool()
  1373. %%
  1374. %% @doc Returns <code>true</code> if <code>Node</code> has type
  1375. %% <code>integer</code> and represents <code>Value</code>, otherwise
  1376. %% <code>false</code>.
  1377. %%
  1378. %% @see integer/1
  1379. is_integer(Node, Value) ->
  1380. case unwrap(Node) of
  1381. {integer, _, Value} ->
  1382. true;
  1383. #tree{type = integer, data = Value} ->
  1384. true;
  1385. _ ->
  1386. false
  1387. end.
  1388. %% =====================================================================
  1389. %% @spec integer_value(syntaxTree()) -> integer()
  1390. %%
  1391. %% @doc Returns the value represented by an <code>integer</code> node.
  1392. %%
  1393. %% @see integer/1
  1394. integer_value(Node) ->
  1395. case unwrap(Node) of
  1396. {integer, _, Value} ->
  1397. Value;
  1398. Node1 ->
  1399. data(Node1)
  1400. end.
  1401. %% =====================================================================
  1402. %% @spec integer_literal(syntaxTree()) -> string()
  1403. %%
  1404. %% @doc Returns the numeral string represented by an
  1405. %% <code>integer</code> node.
  1406. %%
  1407. %% @see integer/1
  1408. integer_literal(Node) ->
  1409. integer_to_list(integer_value(Node)).
  1410. %% =====================================================================
  1411. %% @spec float(Value::float()) -> syntaxTree()
  1412. %%
  1413. %% @doc Creates an abstract floating-point literal. The lexical
  1414. %% representation is the decimal floating-point numeral of
  1415. %% <code>Value</code>.
  1416. %%
  1417. %% @see float_value/1
  1418. %% @see float_literal/1
  1419. %% type(Node) = float
  1420. %% data(Node) = Value
  1421. %%
  1422. %% Value = float()
  1423. %%
  1424. %% `erl_parse' representation:
  1425. %%
  1426. %% {float, Pos, Value}
  1427. %%
  1428. %% Value = float()
  1429. %% Note that under current versions of Erlang, the name `float/1' cannot
  1430. %% be used for local calls (i.e., within the module) - it will be
  1431. %% overridden by the type conversion BIF of the same name, so always use
  1432. %% `make_float/1' for local calls.
  1433. float(Value) ->
  1434. make_float(Value).
  1435. make_float(Value) ->
  1436. tree(float, Value).
  1437. revert_float(Node) ->
  1438. Pos = get_pos(Node),
  1439. {float, Pos, float_value(Node)}.
  1440. %% =====================================================================
  1441. %% @spec float_value(syntaxTree()) -> float()
  1442. %%
  1443. %% @doc Returns the value represented by a <code>float</code> node. Note
  1444. %% that floating-point values should usually not be compared for
  1445. %% equality.
  1446. %%
  1447. %% @see float/1
  1448. float_value(Node) ->
  1449. case unwrap(Node) of
  1450. {float, _, Value} ->
  1451. Value;
  1452. Node1 ->
  1453. data(Node1)
  1454. end.
  1455. %% =====================================================================
  1456. %% @spec float_literal(syntaxTree()) -> string()
  1457. %%
  1458. %% @doc Returns the numeral string represented by a <code>float</code>
  1459. %% node.
  1460. %%
  1461. %% @see float/1
  1462. float_literal(Node) ->
  1463. float_to_list(float_value(Node)).
  1464. %% =====================================================================
  1465. %% @spec char(Value::char()) -> syntaxTree()
  1466. %%
  1467. %% @doc Creates an abstract character literal. The result represents
  1468. %% "<code>$<em>Name</em></code>", where <code>Name</code> corresponds to
  1469. %% <code>Value</code>.
  1470. %%
  1471. %% <p>Note: the literal corresponding to a particular character value is
  1472. %% not uniquely defined. E.g., the character "<code>a</code>" can be
  1473. %% written both as "<code>$a</code>" and "<code>$\141</code>", and a Tab
  1474. %% character can be written as "<code>$\11</code>", "<code>$\011</code>"
  1475. %% or "<code>$\t</code>".</p>
  1476. %%
  1477. %% @see char_value/1
  1478. %% @see char_literal/1
  1479. %% @see is_char/2
  1480. %% type(Node) = char
  1481. %% data(Node) = char()
  1482. %%
  1483. %% `erl_parse' representation:
  1484. %%
  1485. %% {char, Pos, Code}
  1486. %%
  1487. %% Code = integer()
  1488. char(Char) ->
  1489. tree(char, Char).
  1490. revert_char(Node) ->
  1491. Pos = get_pos(Node),
  1492. {char, Pos, char_value(Node)}.
  1493. %% =====================================================================
  1494. %% @spec is_char(Node::syntaxTree(), Value::char()) -> bool()
  1495. %%
  1496. %% @doc Returns <code>true</code> if <code>Node</code> has type
  1497. %% <code>char</code> and represents <code>Value</code>, otherwise
  1498. %% <code>false</code>.
  1499. %%
  1500. %% @see char/1
  1501. is_char(Node, Value) ->
  1502. case unwrap(Node) of
  1503. {char, _, Value} ->
  1504. true;
  1505. #tree{type = char, data = Value} ->
  1506. true;
  1507. _ ->
  1508. false
  1509. end.
  1510. %% =====================================================================
  1511. %% @spec char_value(syntaxTree()) -> char()
  1512. %%
  1513. %% @doc Returns the value represented by a <code>char</code> node.
  1514. %%
  1515. %% @see char/1
  1516. char_value(Node) ->
  1517. case unwrap(Node) of
  1518. {char, _, Char} ->
  1519. Char;
  1520. Node1 ->
  1521. data(Node1)
  1522. end.
  1523. %% =====================================================================
  1524. %% @spec char_literal(syntaxTree()) -> string()
  1525. %%
  1526. %% @doc Returns the literal string represented by a <code>char</code>
  1527. %% node. This includes the leading "<code>$</code>" character.
  1528. %%
  1529. %% @see char/1
  1530. char_literal(Node) ->
  1531. io_lib:write_char(char_value(Node)).
  1532. %% =====================================================================
  1533. %% @spec string(Value::string()) -> syntaxTree()
  1534. %%
  1535. %% @doc Creates an abstract string literal. The result represents
  1536. %% <code>"<em>Text</em>"</code> (including the surrounding
  1537. %% double-quotes), where <code>Text</code> corresponds to the sequence
  1538. %% of characters in <code>Value</code>, but not representing a
  1539. %% <em>specific</em> string literal. E.g., the result of
  1540. %% <code>string("x\ny")</code> represents any and all of
  1541. %% <code>"x\ny"</code>, <code>"x\12y"</code>, <code>"x\012y"</code> and
  1542. %% <code>"x\^Jy"</code>; cf. <code>char/1</code>.
  1543. %%
  1544. %% @see string_value/1
  1545. %% @see string_literal/1
  1546. %% @see is_string/2
  1547. %% @see char/1
  1548. %% type(Node) = string
  1549. %% data(Node) = string()
  1550. %%
  1551. %% `erl_parse' representation:
  1552. %%
  1553. %% {string, Pos, Chars}
  1554. %%
  1555. %% Chars = string()
  1556. string(String) ->
  1557. tree(string, String).
  1558. revert_string(Node) ->
  1559. Pos = get_pos(Node),
  1560. {string, Pos, string_value(Node)}.
  1561. %% =====================================================================
  1562. %% @spec is_string(Node::syntaxTree(), Value::string()) -> bool()
  1563. %%
  1564. %% @doc Returns <code>true</code> if <code>Node</code> has type
  1565. %% <code>string</code> and represents <code>Value</code>, otherwise
  1566. %% <code>false</code>.
  1567. %%
  1568. %% @see string/1
  1569. is_string(Node, Value) ->
  1570. case unwrap(Node) of
  1571. {string, _, Value} ->
  1572. true;
  1573. #tree{type = string, data = Value} ->
  1574. true;
  1575. _ ->
  1576. false
  1577. end.
  1578. %% =====================================================================
  1579. %% @spec string_value(syntaxTree()) -> string()
  1580. %%
  1581. %% @doc Returns the value represented by a <code>string</code> node.
  1582. %%
  1583. %% @see string/1
  1584. string_value(Node) ->
  1585. case unwrap(Node) of
  1586. {string, _, List} ->
  1587. List;
  1588. Node1 ->
  1589. data(Node1)
  1590. end.
  1591. %% =====================================================================
  1592. %% @spec string_literal(syntaxTree()) -> string()
  1593. %%
  1594. %% @doc Returns the literal string represented by a <code>string</code>
  1595. %% node. This includes surrounding double-quote characters.
  1596. %%
  1597. %% @see string/1
  1598. string_literal(Node) ->
  1599. io_lib:write_string(string_value(Node)).
  1600. %% =====================================================================
  1601. %% @spec atom(Name) -> syntaxTre

Large files files are truncated, but you can click here to view the full file