[ruby/win32ole] Undefine allocator of WIN32OLE_VARIABLE to get rid of warning
[ruby-80x24.org.git] / ast.rb
blobf866bd23e5ad73b27035cecd1759d19d7bc8ab8a
1 # for ast.c
3 # AbstractSyntaxTree provides methods to parse Ruby code into
4 # abstract syntax trees. The nodes in the tree
5 # are instances of RubyVM::AbstractSyntaxTree::Node.
7 # This module is MRI specific as it exposes implementation details
8 # of the MRI abstract syntax tree.
10 # This module is experimental and its API is not stable, therefore it might
11 # change without notice. As examples, the order of children nodes is not
12 # guaranteed, the number of children nodes might change, there is no way to
13 # access children nodes by name, etc.
15 # If you are looking for a stable API or an API working under multiple Ruby
16 # implementations, consider using the _parser_ gem or Ripper. If you would
17 # like to make RubyVM::AbstractSyntaxTree stable, please join the discussion
18 # at https://bugs.ruby-lang.org/issues/14844.
20 module RubyVM::AbstractSyntaxTree
22   #  call-seq:
23   #     RubyVM::AbstractSyntaxTree.parse(string) -> RubyVM::AbstractSyntaxTree::Node
24   #
25   #  Parses the given _string_ into an abstract syntax tree,
26   #  returning the root node of that tree.
27   #
28   #  SyntaxError is raised if the given _string_ is invalid syntax.
29   #
30   #    RubyVM::AbstractSyntaxTree.parse("x = 1 + 2")
31   #    # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-1:9>
32   def self.parse string, keep_script_lines: false
33     Primitive.ast_s_parse string, keep_script_lines
34   end
36   #  call-seq:
37   #     RubyVM::AbstractSyntaxTree.parse_file(pathname) -> RubyVM::AbstractSyntaxTree::Node
38   #
39   #   Reads the file from _pathname_, then parses it like ::parse,
40   #   returning the root node of the abstract syntax tree.
41   #
42   #   SyntaxError is raised if _pathname_'s contents are not
43   #   valid Ruby syntax.
44   #
45   #     RubyVM::AbstractSyntaxTree.parse_file("my-app/app.rb")
46   #     # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-31:3>
47   def self.parse_file pathname, keep_script_lines: false
48     Primitive.ast_s_parse_file pathname, keep_script_lines
49   end
51   #  call-seq:
52   #     RubyVM::AbstractSyntaxTree.of(proc)   -> RubyVM::AbstractSyntaxTree::Node
53   #     RubyVM::AbstractSyntaxTree.of(method) -> RubyVM::AbstractSyntaxTree::Node
54   #
55   #   Returns AST nodes of the given _proc_ or _method_.
56   #
57   #     RubyVM::AbstractSyntaxTree.of(proc {1 + 2})
58   #     # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:35-1:42>
59   #
60   #     def hello
61   #       puts "hello, world"
62   #     end
63   #
64   #     RubyVM::AbstractSyntaxTree.of(method(:hello))
65   #     # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-3:3>
66   def self.of body, keep_script_lines: false
67     Primitive.ast_s_of body, keep_script_lines
68   end
70   # RubyVM::AbstractSyntaxTree::Node instances are created by parse methods in
71   # RubyVM::AbstractSyntaxTree.
72   #
73   # This class is MRI specific.
74   #
75   class Node
77     #  call-seq:
78     #     node.type -> symbol
79     #
80     #  Returns the type of this node as a symbol.
81     #
82     #    root = RubyVM::AbstractSyntaxTree.parse("x = 1 + 2")
83     #    root.type # => :SCOPE
84     #    lasgn = root.children[2]
85     #    lasgn.type # => :LASGN
86     #    call = lasgn.children[1]
87     #    call.type # => :OPCALL
88     def type
89       Primitive.ast_node_type
90     end
92     #  call-seq:
93     #     node.first_lineno -> integer
94     #
95     #  The line number in the source code where this AST's text began.
96     def first_lineno
97       Primitive.ast_node_first_lineno
98     end
100     #  call-seq:
101     #     node.first_column -> integer
102     #
103     #  The column number in the source code where this AST's text began.
104     def first_column
105       Primitive.ast_node_first_column
106     end
108     #  call-seq:
109     #     node.last_lineno -> integer
110     #
111     #  The line number in the source code where this AST's text ended.
112     def last_lineno
113       Primitive.ast_node_last_lineno
114     end
116     #  call-seq:
117     #     node.last_column -> integer
118     #
119     #  The column number in the source code where this AST's text ended.
120     def last_column
121       Primitive.ast_node_last_column
122     end
124     #  call-seq:
125     #     node.children -> array
126     #
127     #  Returns AST nodes under this one.  Each kind of node
128     #  has different children, depending on what kind of node it is.
129     #
130     #  The returned array may contain other nodes or <code>nil</code>.
131     def children
132       Primitive.ast_node_children
133     end
135     #  call-seq:
136     #     node.inspect -> string
137     #
138     #  Returns debugging information about this node as a string.
139     def inspect
140       Primitive.ast_node_inspect
141     end
143     #  call-seq:
144     #     node.node_id -> integer
145     #
146     #  Returns an internal node_id number.
147     #  Note that this is an API for ruby internal use, debugging,
148     #  and research. Do not use this for any other purpose.
149     #  The compatibility is not guaranteed.
150     def node_id
151       Primitive.ast_node_node_id
152     end
154     #  call-seq:
155     #     node.script_lines -> array
156     #
157     #  Returns the original source code as an array of lines.
158     #
159     #  Note that this is an API for ruby internal use, debugging,
160     #  and research. Do not use this for any other purpose.
161     #  The compatibility is not guaranteed.
162     def script_lines
163       Primitive.ast_node_script_lines
164     end
166     #  call-seq:
167     #     node.source -> string
168     #
169     #  Returns the code fragment that corresponds to this AST.
170     #
171     #  Note that this is an API for ruby internal use, debugging,
172     #  and research. Do not use this for any other purpose.
173     #  The compatibility is not guaranteed.
174     #
175     #  Also note that this API may return an incomplete code fragment
176     #  that does not parse; for example, a here document following
177     #  an expression may be dropped.
178     def source
179       lines = script_lines
180       if lines
181         lines = lines[first_lineno - 1 .. last_lineno - 1]
182         lines[-1] = lines[-1][0...last_column]
183         lines[0] = lines[0][first_column..-1]
184         lines.join
185       else
186         nil
187       end
188     end
189   end