Skip to content

Commit a78e447

Browse files
committed
Improve node docs
Currently I find them hard to follow because there are just so many methods. This groups them by topic instead so that the more unique methods appear first. I also added call-seqs because we have the type information, so why not.
1 parent 94e5525 commit a78e447

2 files changed

Lines changed: 199 additions & 63 deletions

File tree

templates/lib/prism/node.rb.erb

Lines changed: 129 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
# :markup: markdown
2+
13
module Prism
24
# This represents a node in the tree. It is the parent class of all of the
35
# various node types.
46
class Node
57
# A pointer to the source that this node was created from.
6-
attr_reader :source
8+
attr_reader :source # :nodoc:
79
private :source
810

911
# A unique identifier for this node. This is used in a very specific
@@ -30,99 +32,109 @@ module Prism
3032
repository.enter(node_id, :location)
3133
end
3234

33-
# Delegates to the start_line of the associated location object.
35+
36+
# --------------------------------------------------------------------------
37+
# :section: Location Delegators
38+
# These methods provide convenient access to the underlying Location object.
39+
# --------------------------------------------------------------------------
40+
41+
# Delegates to [`start_line`](rdoc-ref:Location#start_line) of the associated location object.
3442
def start_line
3543
location.start_line
3644
end
3745

38-
# Delegates to the end_line of the associated location object.
46+
# Delegates to [`end_line`](rdoc-ref:Location#end_line) of the associated location object.
3947
def end_line
4048
location.end_line
4149
end
4250

43-
# The start offset of the node in the source. This method is effectively a
44-
# delegate method to the location object.
51+
# Delegates to [`start_offset`](rdoc-ref:Location#start_offset) of the associated location object.
4552
def start_offset
4653
location = @location
4754
location.is_a?(Location) ? location.start_offset : location >> 32
4855
end
4956

50-
# The end offset of the node in the source. This method is effectively a
51-
# delegate method to the location object.
57+
# Delegates to [`end_offset`](rdoc-ref:Location#end_offset) of the associated location object.
5258
def end_offset
5359
location = @location
5460
location.is_a?(Location) ? location.end_offset : ((location >> 32) + (location & 0xFFFFFFFF))
5561
end
5662

57-
# Delegates to the start_character_offset of the associated location object.
63+
# Delegates to [`start_character_offset`](rdoc-ref:Location#start_character_offset)
64+
# of the associated location object.
5865
def start_character_offset
5966
location.start_character_offset
6067
end
6168

62-
# Delegates to the end_character_offset of the associated location object.
69+
# Delegates to [`end_character_offset`](rdoc-ref:Location#end_character_offset)
70+
# of the associated location object.
6371
def end_character_offset
6472
location.end_character_offset
6573
end
6674

67-
# Delegates to the cached_start_code_units_offset of the associated location
68-
# object.
75+
# Delegates to [`cached_start_code_units_offset`](rdoc-ref:Location#cached_start_code_units_offset)
76+
# of the associated location object.
6977
def cached_start_code_units_offset(cache)
7078
location.cached_start_code_units_offset(cache)
7179
end
7280

73-
# Delegates to the cached_end_code_units_offset of the associated location
74-
# object.
81+
# Delegates to [`cached_end_code_units_offset`](rdoc-ref:Location#cached_end_code_units_offset)
82+
# of the associated location object.
7583
def cached_end_code_units_offset(cache)
7684
location.cached_end_code_units_offset(cache)
7785
end
7886

79-
# Delegates to the start_column of the associated location object.
87+
# Delegates to [`start_column`](rdoc-ref:Location#start_column) of the associated location object.
8088
def start_column
8189
location.start_column
8290
end
8391

84-
# Delegates to the end_column of the associated location object.
92+
# Delegates to [`end_column`](rdoc-ref:Location#end_column) of the associated location object.
8593
def end_column
8694
location.end_column
8795
end
8896

89-
# Delegates to the start_character_column of the associated location object.
97+
# Delegates to [`start_character_column`](rdoc-ref:Location#start_character_column)
98+
# of the associated location object.
9099
def start_character_column
91100
location.start_character_column
92101
end
93102

94-
# Delegates to the end_character_column of the associated location object.
103+
# Delegates to [`end_character_column`](rdoc-ref:Location#end_character_column)
104+
# of the associated location object.
95105
def end_character_column
96106
location.end_character_column
97107
end
98108

99-
# Delegates to the cached_start_code_units_column of the associated location
100-
# object.
109+
# Delegates to [`cached_start_code_units_column`](rdoc-ref:Location#cached_start_code_units_column)
110+
# of the associated location object.
101111
def cached_start_code_units_column(cache)
102112
location.cached_start_code_units_column(cache)
103113
end
104114

105-
# Delegates to the cached_end_code_units_column of the associated location
106-
# object.
115+
# Delegates to [`cached_end_code_units_column`](rdoc-ref:Location#cached_end_code_units_column)
116+
# of the associated location object.
107117
def cached_end_code_units_column(cache)
108118
location.cached_end_code_units_column(cache)
109119
end
110120

111-
# Delegates to the leading_comments of the associated location object.
121+
# Delegates to [`leading_comments`](rdoc-ref:Location#leading_comments) of the associated location object.
112122
def leading_comments
113123
location.leading_comments
114124
end
115125

116-
# Delegates to the trailing_comments of the associated location object.
126+
# Delegates to [`trailing_comments`](rdoc-ref:Location#trailing_comments) of the associated location object.
117127
def trailing_comments
118128
location.trailing_comments
119129
end
120130

121-
# Delegates to the comments of the associated location object.
131+
# Delegates to [`comments`](rdoc-ref:Location#comments) of the associated location object.
122132
def comments
123133
location.comments
124134
end
125135

136+
# :section:
137+
126138
# Returns all of the lines of the source code associated with this node.
127139
def source_lines
128140
location.source_lines
@@ -146,7 +158,7 @@ module Prism
146158

147159
# An bitset of flags for this node. There are certain flags that are common
148160
# for all nodes, and then some nodes have specific flags.
149-
attr_reader :flags
161+
attr_reader :flags # :nodoc:
150162
protected :flags
151163

152164
# Returns true if the node has the newline flag set.
@@ -248,10 +260,9 @@ module Prism
248260
end
249261

250262
# --------------------------------------------------------------------------
251-
# :section: Node interface
252-
# These methods are effectively abstract methods that must be implemented by
253-
# the various subclasses of Node. They are here to make it easier to work
254-
# with typecheckers.
263+
# :section: Node Interface
264+
# These methods are effectively abstract methods that are implemented by
265+
# the various subclasses of Node.
255266
# --------------------------------------------------------------------------
256267

257268
# Accepts a visitor and calls back into the specialized visit function.
@@ -335,12 +346,23 @@ module Prism
335346
<%- end -%>
336347
end
337348

338-
# def accept: (Visitor visitor) -> void
349+
# ---------
350+
# :section: Repository
351+
# Methods related to Relocation.
352+
# ---------
353+
354+
# ----------------------------------------------------------------------------------
355+
# :section: Node Interface
356+
# These methods are present on all subclasses of Node.
357+
# Read the [node interface docs](rdoc-ref:Node@node-interface) for more information.
358+
# ----------------------------------------------------------------------------------
359+
360+
# See Node.accept.
339361
def accept(visitor)
340362
visitor.visit_<%= node.human %>(self)
341363
end
342364

343-
# def child_nodes: () -> Array[Node?]
365+
# See Node.child_nodes.
344366
def child_nodes
345367
[<%= node.fields.map { |field|
346368
case field
@@ -350,7 +372,7 @@ module Prism
350372
}.compact.join(", ") %>]
351373
end
352374

353-
# def each_child_node: () { (Prism::node) -> void } -> void | () -> Enumerator[Prism::node]
375+
# See Node.each_child_node.
354376
def each_child_node
355377
return to_enum(:each_child_node) unless block_given?
356378

@@ -366,7 +388,7 @@ module Prism
366388
<%- end -%>
367389
end
368390

369-
# def compact_child_nodes: () -> Array[Node]
391+
# See Node.compact_child_nodes.
370392
def compact_child_nodes
371393
<%- if node.fields.any? { |field| field.is_a?(Prism::Template::OptionalNodeField) } -%>
372394
compact = [] #: Array[Prism::node]
@@ -391,7 +413,7 @@ module Prism
391413
<%- end -%>
392414
end
393415

394-
# def comment_targets: () -> Array[Node | Location]
416+
# See Node.comment_targets.
395417
def comment_targets
396418
[<%= node.fields.map { |field|
397419
case field
@@ -401,49 +423,85 @@ module Prism
401423
}.compact.join(", ") %>] #: Array[Prism::node | Location]
402424
end
403425

404-
# def copy: (<%= (["?node_id: Integer", "?location: Location", "?flags: Integer"] + node.fields.map { |field| "?#{field.name}: #{field.rbs_class}" }).join(", ") %>) -> <%= node.name %>
426+
# :call-seq:
427+
# copy(**fields) -> <%= node.name %>
428+
#
429+
# Creates a copy of self with the given fields, using self as the template.
405430
def copy(<%= (["node_id", "location", "flags"] + node.fields.map(&:name)).map { |field| "#{field}: self.#{field}" }.join(", ") %>)
406431
<%= node.name %>.new(<%= ["source", "node_id", "location", "flags", *node.fields.map(&:name)].join(", ") %>)
407432
end
408433

409-
# def deconstruct: () -> Array[Node?]
410434
alias deconstruct child_nodes
411435

412436
def deconstruct_keys(keys) # :nodoc:
413437
{ <%= (["node_id: node_id", "location: location"] + node.fields.map { |field| "#{field.name}: #{field.name}" }).join(", ") %> }
414438
end
439+
440+
# See `Node#type`.
441+
def type
442+
:<%= node.human %>
443+
end
444+
445+
# See `Node.type`.
446+
def self.type
447+
:<%= node.human %>
448+
end
449+
450+
def inspect # :nodoc:
451+
InspectVisitor.compose(self)
452+
end
453+
454+
# :section:
415455
<%- if (node_flags = node.flags) -%>
416456
<%- node_flags.values.each do |value| -%>
417457

418-
# def <%= value.name.downcase %>?: () -> bool
458+
# :category: Flags
459+
# <%= value.comment %>
419460
def <%= value.name.downcase %>?
420461
flags.anybits?(<%= node_flags.name %>::<%= value.name %>)
421462
end
463+
422464
<%- end -%>
423465
<%- end -%>
424466
<%- node.fields.each do |field| -%>
425-
467+
<%- case field -%>
468+
<%- when Prism::Template::LocationField -%>
469+
# :category: Locations
470+
# :call-seq:
471+
# <%= field.name %> -> <%= field.call_seq_type %>
472+
#
426473
<%- if field.comment.nil? -%>
427-
# attr_reader <%= field.name %>: <%= field.rbs_class %>
474+
# Returns the Location represented by `<%= field.name %>`.
428475
<%- else -%>
429476
<%- field.each_comment_line do |line| -%>
430477
#<%= line %>
431478
<%- end -%>
432479
<%- end -%>
433-
<%- case field -%>
434-
<%- when Prism::Template::LocationField -%>
435480
def <%= field.name %>
436481
location = @<%= field.name %>
437482
return location if location.is_a?(Location)
438483
@<%= field.name %> = Location.new(source, location >> 32, location & 0xFFFFFFFF)
439484
end
440485

486+
# :category: Repository
441487
# Save the <%= field.name %> location using the given saved source so that
442488
# it can be retrieved later.
443489
def save_<%= field.name %>(repository)
444490
repository.enter(node_id, :<%= field.name %>)
445491
end
492+
446493
<%- when Prism::Template::OptionalLocationField -%>
494+
# :category: Locations
495+
# :call-seq:
496+
# <%= field.name %> -> <%= field.call_seq_type %>
497+
#
498+
<%- if field.comment.nil? -%>
499+
# Returns the Location represented by `<%= field.name %>`.
500+
<%- else -%>
501+
<%- field.each_comment_line do |line| -%>
502+
#<%= line %>
503+
<%- end -%>
504+
<%- end -%>
447505
def <%= field.name %>
448506
location = @<%= field.name %>
449507
case location
@@ -456,53 +514,61 @@ module Prism
456514
end
457515
end
458516

517+
# :category: Repository
459518
# Save the <%= field.name %> location using the given saved source so that
460519
# it can be retrieved later.
461520
def save_<%= field.name %>(repository)
462521
repository.enter(node_id, :<%= field.name %>) unless @<%= field.name %>.nil?
463522
end
464523
<%- else -%>
465-
attr_reader :<%= field.name %>
524+
# :call-seq:
525+
# <%= field.name %> -> <%= field.call_seq_type %>
526+
#
527+
<%- if field.comment.nil? -%>
528+
# Returns the `<%= field.name %>` attribute.
529+
<%- else -%>
530+
<%- field.each_comment_line do |line| -%>
531+
#<%= line %>
466532
<%- end -%>
467533
<%- end -%>
534+
def <%= field.name %>
535+
@<%= field.name %>
536+
end
537+
538+
<%- end -%>
539+
<%- end -%>
540+
541+
# :section: Slicing
542+
468543
<%- node.fields.each do |field| -%>
469544
<%- case field -%>
470545
<%- when Prism::Template::LocationField -%>
471546
<%- raise unless field.name.end_with?("_loc") -%>
472547
<%- next if node.fields.any? { |other| other.name == field.name.delete_suffix("_loc") } -%>
473-
474-
# def <%= field.name.delete_suffix("_loc") %>: () -> String
548+
# :call-seq:
549+
# <%= field.name.delete_suffix("_loc") %> -> String
550+
#
551+
# Slice the location of <%= field.name %> from the source.
475552
def <%= field.name.delete_suffix("_loc") %>
476553
<%= field.name %>.slice
477554
end
555+
478556
<%- when Prism::Template::OptionalLocationField -%>
479557
<%- raise unless field.name.end_with?("_loc") -%>
480558
<%- next if node.fields.any? { |other| other.name == field.name.delete_suffix("_loc") } -%>
481-
482-
# def <%= field.name.delete_suffix("_loc") %>: () -> String?
559+
# :call-seq:
560+
# <%= field.name.delete_suffix("_loc") %> -> String | nil
561+
#
562+
# Slice the location of <%= field.name %> from the source.
483563
def <%= field.name.delete_suffix("_loc") %>
484564
<%= field.name %>&.slice
485565
end
566+
486567
<%- end -%>
487568
<%- end -%>
569+
# :section:
488570

489-
def inspect # :nodoc:
490-
InspectVisitor.compose(self)
491-
end
492-
493-
# Return a symbol representation of this node type. See `Node#type`.
494-
def type
495-
:<%= node.human %>
496-
end
497-
498-
# Return a symbol representation of this node type. See `Node::type`.
499-
def self.type
500-
:<%= node.human %>
501-
end
502-
503-
# Implements case-equality for the node. This is effectively == but without
504-
# comparing the value of locations. Locations are checked only for presence.
505-
def ===(other)
571+
def ===(other) # :nodoc:
506572
other.is_a?(<%= node.name %>)<%= " &&" if (fields = [*node.flags, *node.fields]).any? %>
507573
<%- fields.each_with_index do |field, index| -%>
508574
<%- if field.is_a?(Prism::Template::LocationField) || field.is_a?(Prism::Template::OptionalLocationField) -%>

0 commit comments

Comments
 (0)