Class: Docscribe::InlineRewriter::Collector

Inherits:
Parser::AST::Processor
  • Object
show all
Defined in:
lib/docscribe/inline_rewriter/collector.rb

Overview

AST walker that collects documentation insertion targets.

This is where Docscribe models Ruby scoping and visibility semantics so the doc generator can:

  • know whether a method is an instance method or class/module method (# vs .)
  • add @private / @protected tags when appropriate
  • know the container name (A::B) to show in +A::B#foo+

In addition to private / protected / public handling, Collector supports:

  • module_function inside modules
  • extend self inside modules
  • receiver-based containers (def Foo.bar, class << Foo)
  • Sorbet-aware anchoring for methods with leading sig declarations

Defined Under Namespace

Classes: AttrInsertion, Insertion, VisibilityCtx

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(buffer) ⇒ void

Create a collector for the given source buffer.

Parameters:

  • buffer (Parser::Source::Buffer)

    source buffer for anchor location lookups



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/docscribe/inline_rewriter/collector.rb', line 210

def initialize(buffer)
  super()
  @buffer = buffer
  @insertions = []
  @attr_insertions = []
  @name_stack = []

  # Track module-level state across reopened modules within the same file pass.
  # Example:
  #   module M; extend self; end
  #   module M; def foo; end; end  # => should still document foo as M.foo
  #
  # @type [Hash{String=>Hash}]
  @module_states = {} # { "M" => { extend_self: true } }
end

Instance Attribute Details

#attr_insertionsObject (readonly)

Returns the value of attribute attr_insertions.



204
205
206
# File 'lib/docscribe/inline_rewriter/collector.rb', line 204

def attr_insertions
  @attr_insertions
end

#insertionsObject (readonly)

Returns the value of attribute insertions.



200
201
202
# File 'lib/docscribe/inline_rewriter/collector.rb', line 200

def insertions
  @insertions
end

Instance Method Details

#on_casgn(node) ⇒ Parser::AST::Node

Process a constant assignment (e.g. FOO = ... or Foo::BAR = ...).

If the value is a Struct.new call, extracts attribute insertions first. Then continues processing child nodes.

Parameters:

  • node (Parser::AST::Node)

    a :casgn node

Returns:

  • (Parser::AST::Node)

    the original node



277
278
279
280
281
282
283
284
285
# File 'lib/docscribe/inline_rewriter/collector.rb', line 277

def on_casgn(node)
  return node if process_struct_casgn?(node)

  node.children.each do |child|
    process(child) if child.is_a?(Parser::AST::Node)
  end

  node
end

#on_class(node) ⇒ Parser::AST::Node

Enter a class body and collect documentation targets from its contents.

Parameters:

  • node (Parser::AST::Node)

    an AST node

Returns:

  • (Parser::AST::Node)


230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/docscribe/inline_rewriter/collector.rb', line 230

def on_class(node)
  cname_node, super_node, body = *node
  @name_stack.push(const_name(cname_node))

  ctx = VisibilityCtx.new
  ctx.container_is_module = false

  process_struct_class(node, super_node)
  process_body(body, ctx)

  @name_stack.pop
  node
end

#on_def(node) ⇒ Parser::AST::Node

Enter a top-level method definition and collect it as a documentation target.

Top-level methods implicitly belong to Object. This handler ensures that def foo declared outside of any class or module is still picked up by the collector.

Parameters:

  • node (Parser::AST::Node)

    an AST node

Returns:

  • (Parser::AST::Node)


295
296
297
298
299
300
301
302
# File 'lib/docscribe/inline_rewriter/collector.rb', line 295

def on_def(node)
  return node unless @name_stack.empty?

  ctx = VisibilityCtx.new
  ctx.container_is_module = false
  process_stmt(node, ctx)
  node
end

#on_defs(node) ⇒ Parser::AST::Node

Enter a top-level singleton method definition and collect it as a documentation target.

Handles the case of def self.foo declared at the top level, outside of any class or module body.

Parameters:

  • node (Parser::AST::Node)

    an AST node

Returns:

  • (Parser::AST::Node)


311
312
313
314
315
316
317
318
# File 'lib/docscribe/inline_rewriter/collector.rb', line 311

def on_defs(node)
  return node unless @name_stack.empty?

  ctx = VisibilityCtx.new
  ctx.container_is_module = false
  process_stmt(node, ctx)
  node
end

#on_module(node) ⇒ Parser::AST::Node

Enter a module body and collect documentation targets from its contents.

This also carries extend self state across reopened modules in the same file.

Parameters:

  • node (Parser::AST::Node)

    an AST node

Returns:

  • (Parser::AST::Node)


251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/docscribe/inline_rewriter/collector.rb', line 251

def on_module(node)
  cname_node, body = *node
  @name_stack.push(const_name(cname_node))

  container = current_container

  ctx = VisibilityCtx.new
  ctx.container_is_module = true
  ctx.extend_self = !!@module_states.dig(container, :extend_self)

  process_body(body, ctx)

  # If `extend self` is active for this module, document all instance defs as module methods (M.foo).
  persist_extend_self_state(ctx, container)

  @name_stack.pop
  node
end