docrb 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +31 -41
- data/Gemfile +5 -1
- data/Gemfile.lock +28 -13
- data/docrb.gemspec +3 -5
- data/exe/docrb +39 -57
- data/lib/docrb/doc_compiler.rb +7 -47
- data/lib/docrb/version.rb +1 -1
- data/lib/docrb.rb +15 -54
- metadata +8 -55
- data/lib/docrb/comment_parser/code_example_block.rb +0 -36
- data/lib/docrb/comment_parser/code_example_parser.rb +0 -29
- data/lib/docrb/comment_parser/field_block.rb +0 -18
- data/lib/docrb/comment_parser/field_list_parser.rb +0 -90
- data/lib/docrb/comment_parser/text_block.rb +0 -43
- data/lib/docrb/comment_parser.rb +0 -272
- data/lib/docrb/doc_compiler/base_container/computations.rb +0 -178
- data/lib/docrb/doc_compiler/base_container.rb +0 -123
- data/lib/docrb/doc_compiler/doc_attribute.rb +0 -58
- data/lib/docrb/doc_compiler/doc_blocks.rb +0 -111
- data/lib/docrb/doc_compiler/doc_class.rb +0 -43
- data/lib/docrb/doc_compiler/doc_method.rb +0 -66
- data/lib/docrb/doc_compiler/doc_module.rb +0 -9
- data/lib/docrb/doc_compiler/file_ref.rb +0 -41
- data/lib/docrb/doc_compiler/object_container.rb +0 -68
- data/lib/docrb/markdown.rb +0 -62
- data/lib/docrb/module_extensions.rb +0 -13
- data/lib/docrb/resolvable.rb +0 -178
- data/lib/docrb/ruby_parser.rb +0 -630
@@ -1,178 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Docrb
|
4
|
-
class DocCompiler
|
5
|
-
class BaseContainer
|
6
|
-
# Module Computations implements utility methods to handle hierarchy and
|
7
|
-
# nesting.
|
8
|
-
module Computations
|
9
|
-
# Recursively computes all dependants of the receiver.
|
10
|
-
# This method expands all references into concrete representations.
|
11
|
-
def compute_dependants
|
12
|
-
return if @compute_dependants
|
13
|
-
|
14
|
-
@compute_dependants = true
|
15
|
-
|
16
|
-
classes.each(&:compute_dependants)
|
17
|
-
modules.each(&:compute_dependants)
|
18
|
-
|
19
|
-
extends.each do |ref|
|
20
|
-
resolve_ref(ref)&.compute_dependants
|
21
|
-
end
|
22
|
-
includes.each do |ref|
|
23
|
-
resolve_ref(ref)&.compute_dependants
|
24
|
-
end
|
25
|
-
|
26
|
-
return unless (parent_name = @inherits)
|
27
|
-
|
28
|
-
@parent_class = resolve(parent_name)
|
29
|
-
return unless @parent_class
|
30
|
-
|
31
|
-
@parent_class.compute_dependants
|
32
|
-
end
|
33
|
-
|
34
|
-
# Returns a Hash containing all methods for the container, along with
|
35
|
-
# inherited and included ones.
|
36
|
-
def merged_instance_methods
|
37
|
-
return @merged_instance_methods if @merged_instance_methods
|
38
|
-
|
39
|
-
compute_dependants
|
40
|
-
|
41
|
-
methods = {}
|
42
|
-
@parent_class&.merged_instance_methods&.each do |k, v|
|
43
|
-
methods[k] = { source: :inheritance, definition: v }
|
44
|
-
end
|
45
|
-
|
46
|
-
includes.each do |ref|
|
47
|
-
next unless (container = resolve_container(ref))
|
48
|
-
|
49
|
-
container.merged_instance_methods.each do |k, v|
|
50
|
-
methods[k] = { source: :inclusion, definition: v, overriding: methods[k] }
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
defs.each do |m|
|
55
|
-
methods[m.name] = { source: :source, definition: m, overriding: methods[m.name] }
|
56
|
-
end
|
57
|
-
|
58
|
-
methods
|
59
|
-
end
|
60
|
-
|
61
|
-
# Returns a hash containing all class methods for the container, along
|
62
|
-
# with inherited and extended ones.
|
63
|
-
def merged_class_methods
|
64
|
-
return @merged_class_methods if @merged_class_methods
|
65
|
-
|
66
|
-
compute_dependants
|
67
|
-
|
68
|
-
methods = {}
|
69
|
-
@parent_class&.merged_class_methods&.each do |k, v|
|
70
|
-
methods[k] = { source: :inheritance, definition: v }
|
71
|
-
end
|
72
|
-
|
73
|
-
includes.each do |ref|
|
74
|
-
next unless (container = resolve_container(ref))
|
75
|
-
|
76
|
-
container.merged_class_methods.each do |k, v|
|
77
|
-
methods[k] = { source: :extension, definition: v, overriding: methods[k] }
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
sdefs.each do |m|
|
82
|
-
methods[m.name] = { source: :source, definition: m, overriding: methods[m.name] }
|
83
|
-
end
|
84
|
-
|
85
|
-
methods
|
86
|
-
end
|
87
|
-
|
88
|
-
# Returns a hash containing all attributes for the container, along with
|
89
|
-
# inherited ones.
|
90
|
-
def merged_attributes
|
91
|
-
return @merged_attributes if @merged_attributes
|
92
|
-
|
93
|
-
compute_dependants
|
94
|
-
|
95
|
-
attrs = {}
|
96
|
-
@parent_class&.merged_attributes&.each do |k, v|
|
97
|
-
attrs[k] = { source: :inheritance, definition: v }
|
98
|
-
end
|
99
|
-
|
100
|
-
attributes.each do |m|
|
101
|
-
attrs[m.name] = { source: :source, definition: m, overriding: attrs[m.name] }
|
102
|
-
end
|
103
|
-
|
104
|
-
attrs
|
105
|
-
end
|
106
|
-
|
107
|
-
# Deprecated: Use #merged_instance_methods.
|
108
|
-
def all_defs
|
109
|
-
return @all_defs if @all_defs
|
110
|
-
|
111
|
-
compute_dependants
|
112
|
-
|
113
|
-
methods = {}
|
114
|
-
@parent_class&.all_defs&.each do |k, v|
|
115
|
-
methods[k] = v
|
116
|
-
end
|
117
|
-
|
118
|
-
includes.each do |ref|
|
119
|
-
resolve_ref(ref)&.all_defs&.each do |met|
|
120
|
-
if methods.key? met.name
|
121
|
-
methods[key].override! met
|
122
|
-
next
|
123
|
-
end
|
124
|
-
|
125
|
-
methods[met.name] = met
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
defs.each do |met|
|
130
|
-
if methods.key? met.name
|
131
|
-
methods[met.name].override! met
|
132
|
-
next
|
133
|
-
end
|
134
|
-
|
135
|
-
methods[met.name] = met
|
136
|
-
end
|
137
|
-
|
138
|
-
@all_defs = methods
|
139
|
-
end
|
140
|
-
|
141
|
-
# Deprecated: Use #merged_class_methods.
|
142
|
-
def all_sdefs
|
143
|
-
return @all_sdefs if @all_sdefs
|
144
|
-
|
145
|
-
compute_dependants
|
146
|
-
|
147
|
-
methods = {}
|
148
|
-
|
149
|
-
@parent_class&.all_sdefs&.each do |k, v|
|
150
|
-
methods[k] = v
|
151
|
-
end
|
152
|
-
|
153
|
-
extends.each do |ref|
|
154
|
-
resolve_ref(ref)&.all_defs&.each do |met|
|
155
|
-
if methods.key? met.name
|
156
|
-
methods[met.name].override! met
|
157
|
-
next
|
158
|
-
end
|
159
|
-
|
160
|
-
methods[met.name] = met
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
@sdefs.each do |met|
|
165
|
-
if methods.key? met.name
|
166
|
-
methods[met.name].override! met
|
167
|
-
next
|
168
|
-
end
|
169
|
-
|
170
|
-
methods[met.name] = met
|
171
|
-
end
|
172
|
-
|
173
|
-
@all_sdefs = methods
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
@@ -1,123 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Docrb
|
4
|
-
class DocCompiler
|
5
|
-
# BaseContainer represents a container for methods, classes, modules and
|
6
|
-
# attributes.
|
7
|
-
class BaseContainer < Resolvable
|
8
|
-
require_relative "./base_container/computations"
|
9
|
-
include Computations
|
10
|
-
|
11
|
-
attr_accessor :extends, :includes, :classes, :modules, :defs, :sdefs,
|
12
|
-
:type, :name, :defined_by, :parent, :doc
|
13
|
-
|
14
|
-
# Initialises a new BaseContainer instance with a provided parent,
|
15
|
-
# filename and represented object.
|
16
|
-
def initialize(parent, filename, obj)
|
17
|
-
super()
|
18
|
-
@parent = parent
|
19
|
-
@type = obj[:type]
|
20
|
-
@name = obj[:name]
|
21
|
-
@extends = []
|
22
|
-
@includes = []
|
23
|
-
@classes = ObjectContainer.new(self, DocClass)
|
24
|
-
@modules = ObjectContainer.new(self, DocModule)
|
25
|
-
@defs = ObjectContainer.new(self, DocMethod)
|
26
|
-
@sdefs = ObjectContainer.new(self, DocMethod)
|
27
|
-
@defined_by = ObjectContainer.new(nil, FileRef)
|
28
|
-
append(filename, obj)
|
29
|
-
end
|
30
|
-
|
31
|
-
# Appends a new object defined by the provided file to this container
|
32
|
-
def <<(filename, obj)
|
33
|
-
append(filename, obj)
|
34
|
-
end
|
35
|
-
|
36
|
-
# Appends a new class defined by the provided file to this container
|
37
|
-
def append_class(filename, cls)
|
38
|
-
@classes.push filename, cls
|
39
|
-
end
|
40
|
-
|
41
|
-
def inspect
|
42
|
-
ext = "#{extends.length} extend#{extends.length == 1 ? "" : "s"}"
|
43
|
-
inc = "#{includes.length} include#{includes.length == 1 ? "" : "s"}"
|
44
|
-
cls = "#{classes.length} class#{classes.length == 1 ? "" : "es"}"
|
45
|
-
mod = "#{modules.length} module#{modules.length == 1 ? "" : "s"}"
|
46
|
-
de = "#{defs.length} def#{defs.length == 1 ? "" : "s"}"
|
47
|
-
sde = "#{sdefs.length} sdef#{sdefs.length == 1 ? "" : "s"}"
|
48
|
-
|
49
|
-
"#<#{self.class.name}:#{format("0x%08x",
|
50
|
-
object_id * 2)} #{@type} #{@name} #{ext}, #{inc}, #{cls}, #{mod}, #{de}, #{sde}>"
|
51
|
-
end
|
52
|
-
|
53
|
-
# Attempts to append a given object defined in a provided filename.
|
54
|
-
# Raises ArgumentError in case the object can't be added to the container
|
55
|
-
# due to type contraints.
|
56
|
-
#
|
57
|
-
# filename - Filename defining the object being appended
|
58
|
-
# obj - The object definition to be appended to this container.
|
59
|
-
def append(filename, obj)
|
60
|
-
raise ArgumentError, "cannot append obj of type #{obj[:type]} into #{@name} (#{@type})" if obj[:type] != @type
|
61
|
-
|
62
|
-
raise ArgumentError, "cannot append obj named #{obj[:name]} into #{@name} (#{@type})" if obj[:name] != @name
|
63
|
-
|
64
|
-
unless (doc = obj[:doc]).nil?
|
65
|
-
@defined_by.push(filename, obj)
|
66
|
-
@doc = doc
|
67
|
-
end
|
68
|
-
|
69
|
-
obj.fetch(:classes, []).each { |c| @classes.push(filename, c) }
|
70
|
-
obj.fetch(:modules, []).each { |m| @modules.push(filename, m) }
|
71
|
-
obj.fetch(:extend, []).each { |e| @extends << e }
|
72
|
-
obj.fetch(:include, []).each { |i| @includes << i }
|
73
|
-
obj.fetch(:methods, []).each do |met|
|
74
|
-
if met[:type] == :def
|
75
|
-
@defs.push(filename, met)
|
76
|
-
else
|
77
|
-
@sdefs.push(filename, met)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
@inherits = obj.fetch(:inherits, nil) if obj[:type] == :class
|
82
|
-
|
83
|
-
appended(filename, obj)
|
84
|
-
end
|
85
|
-
|
86
|
-
# Courtesy method. This method is called whenever a new object is
|
87
|
-
# appended to the container. Inheriting classes can override it to perform
|
88
|
-
# further operations on the appended object.
|
89
|
-
def appended(filename, obj); end
|
90
|
-
|
91
|
-
# Intenral: Recursively unpacks a given element by checking its
|
92
|
-
# :definition and :overriding keys.
|
93
|
-
#
|
94
|
-
# Returns the updated element.
|
95
|
-
def unpack(elem)
|
96
|
-
return unless elem
|
97
|
-
|
98
|
-
elem.tap do |e|
|
99
|
-
inner = e[:definition]
|
100
|
-
e[:definition] = inner.is_a?(Hash) ? unpack(inner) : inner.to_h
|
101
|
-
e[:overriding] = unpack(e[:overriding])
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
# Returns a Hash representation of the current container along with its
|
106
|
-
# children.
|
107
|
-
def to_h
|
108
|
-
{
|
109
|
-
type:,
|
110
|
-
name:,
|
111
|
-
doc: DocBlocks.prepare(doc, parent: self),
|
112
|
-
defined_by: defined_by.map(&:to_h),
|
113
|
-
defs: merged_instance_methods.transform_values { |v| unpack(v) },
|
114
|
-
sdefs: merged_class_methods.transform_values { |v| unpack(v) },
|
115
|
-
classes: classes.map(&:to_h),
|
116
|
-
modules: modules.map(&:to_h),
|
117
|
-
includes: includes.map(&:to_h),
|
118
|
-
extends: extends.map(&:to_h)
|
119
|
-
}
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Docrb
|
4
|
-
class DocCompiler
|
5
|
-
# DocAttribute represents a single attribute defined on a class.
|
6
|
-
class DocAttribute < Resolvable
|
7
|
-
attr_reader :parent, :defined_by, :name, :docs, :type, :writer_visibility,
|
8
|
-
:reader_visibility
|
9
|
-
|
10
|
-
def initialize(parent, filename, obj)
|
11
|
-
super()
|
12
|
-
@parent = parent
|
13
|
-
@defined_by = [filename]
|
14
|
-
@name = obj[:name]
|
15
|
-
@docs = obj[:docs]
|
16
|
-
@type = nil
|
17
|
-
@writer_visibility = obj[:writer_visibility]
|
18
|
-
@reader_visibility = obj[:reader_visibility]
|
19
|
-
end
|
20
|
-
|
21
|
-
# Marks the current attribute as an accessor.
|
22
|
-
#
|
23
|
-
# Returns the attribute's instance for chaining.
|
24
|
-
def accessor!
|
25
|
-
@type = :accessor
|
26
|
-
self
|
27
|
-
end
|
28
|
-
|
29
|
-
# Marks the current attribute as an reader.
|
30
|
-
#
|
31
|
-
# Returns the attribute's instance for chaining.
|
32
|
-
def reader!
|
33
|
-
@type = :reader
|
34
|
-
self
|
35
|
-
end
|
36
|
-
|
37
|
-
# Marks the current attribute as an writer.
|
38
|
-
#
|
39
|
-
# Returns the attribute's instance for chaining.
|
40
|
-
def writer!
|
41
|
-
@type = :writer
|
42
|
-
self
|
43
|
-
end
|
44
|
-
|
45
|
-
# Returns a Hash representing this attribute
|
46
|
-
def to_h
|
47
|
-
{
|
48
|
-
defined_by:,
|
49
|
-
name:,
|
50
|
-
docs:,
|
51
|
-
type:,
|
52
|
-
writer_visibility:,
|
53
|
-
reader_visibility:
|
54
|
-
}
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,111 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Docrb
|
4
|
-
class DocCompiler
|
5
|
-
# DocBlocks provides utilities for annotating and formatting documentation
|
6
|
-
# blocks.
|
7
|
-
class DocBlocks
|
8
|
-
# Internal: Transforms a provided reference on a given parent by a
|
9
|
-
# ttempting to resolve it into a specific object.
|
10
|
-
#
|
11
|
-
# ref - Reference to be resolved
|
12
|
-
# parent - The reference's parent
|
13
|
-
#
|
14
|
-
# Returns the reference itself by augmenting it with :ref_type and
|
15
|
-
# :ref_path information.
|
16
|
-
def self.process_reference(ref, parent)
|
17
|
-
return process_method_reference(ref, parent) if ref[:ref_type] == :method
|
18
|
-
return ref if ref[:ref_type] != :ambiguous
|
19
|
-
|
20
|
-
resolved = parent.resolve_ref(ref)
|
21
|
-
if resolved.nil?
|
22
|
-
ref[:ref_type] = :not_found
|
23
|
-
return ref
|
24
|
-
end
|
25
|
-
ref[:ref_type] = resolved.type
|
26
|
-
ref[:ref_path] = resolved.path
|
27
|
-
ref
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.process_method_reference(ref, parent)
|
31
|
-
if (resolved = parent.resolve_ref(ref))
|
32
|
-
ref[:ref_path] = resolved.path
|
33
|
-
end
|
34
|
-
ref
|
35
|
-
end
|
36
|
-
|
37
|
-
# Internal: Processes a identifier on a provided parent. Returns an
|
38
|
-
# augmented reference with extra location information whenever it can
|
39
|
-
# be resolved.
|
40
|
-
#
|
41
|
-
# id - Identifier to be processed
|
42
|
-
# parent - Parent on which the identifier appeared.
|
43
|
-
def self.process_identifier(id, parent)
|
44
|
-
resolved = parent.resolve(id[:contents].to_sym)
|
45
|
-
if resolved.nil?
|
46
|
-
puts "Unresolved: #{id[:contents]} on #{parent.path}"
|
47
|
-
return {
|
48
|
-
type: :span,
|
49
|
-
contents: Markdown.inline("`#{id[:contents]}`")
|
50
|
-
}
|
51
|
-
end
|
52
|
-
{
|
53
|
-
type: :ref,
|
54
|
-
ref_type: resolved.type,
|
55
|
-
ref_path: resolved.path,
|
56
|
-
contents: id[:contents]
|
57
|
-
}
|
58
|
-
end
|
59
|
-
|
60
|
-
# Internal: Formats a given TextBlock object by expanding its contents
|
61
|
-
# into markdown annotations and attempting to resolve references and
|
62
|
-
# identifiers.
|
63
|
-
#
|
64
|
-
# Returns the updated block list.
|
65
|
-
def self.format_text_block(block, parent)
|
66
|
-
unless block[:contents].is_a? Array
|
67
|
-
block[:contents] = Markdown.inline(block[:contents])
|
68
|
-
return block
|
69
|
-
end
|
70
|
-
block[:contents].map! do |c|
|
71
|
-
case c[:type]
|
72
|
-
when :span
|
73
|
-
c[:contents] = Markdown.inline(c[:contents])
|
74
|
-
when :ref
|
75
|
-
c = process_reference(c, parent)
|
76
|
-
when :camelcase_identifier
|
77
|
-
c = process_identifier(c, parent)
|
78
|
-
end
|
79
|
-
c
|
80
|
-
end
|
81
|
-
block
|
82
|
-
end
|
83
|
-
|
84
|
-
# Public: Updates a given documentation block by augmenting markdown
|
85
|
-
# elements, references, fields and identifiers.
|
86
|
-
#
|
87
|
-
# doc - Documentation block to be processed
|
88
|
-
# parent - The parent container to which the block belongs to.
|
89
|
-
#
|
90
|
-
# Returns the updated block.
|
91
|
-
def self.prepare(doc, parent: nil)
|
92
|
-
return unless doc
|
93
|
-
|
94
|
-
doc[:contents].map! do |block|
|
95
|
-
case block[:type]
|
96
|
-
when :text_block
|
97
|
-
format_text_block(block, parent)
|
98
|
-
when :code_example
|
99
|
-
block[:contents] = Markdown.render_source(block[:contents])
|
100
|
-
when :field_block
|
101
|
-
block[:contents] = block[:contents].transform_values { |v| format_text_block(v, parent) }
|
102
|
-
else
|
103
|
-
puts "Skipped block with type #{block[:type]}"
|
104
|
-
end
|
105
|
-
block
|
106
|
-
end
|
107
|
-
doc
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Docrb
|
4
|
-
class DocCompiler
|
5
|
-
# DocClass represents a documented class
|
6
|
-
class DocClass < BaseContainer
|
7
|
-
attr_accessor :inherits, :attributes
|
8
|
-
|
9
|
-
# Initializes a new instance with the provided parent, file, and object.
|
10
|
-
#
|
11
|
-
# parent - The parent container holding this class definition.
|
12
|
-
# filename - The filename defining this class.
|
13
|
-
# obj - The parsed class data.
|
14
|
-
def initialize(parent, filename, obj)
|
15
|
-
@inherits = nil
|
16
|
-
@attributes = ObjectContainer.new(self, DocAttribute, always_append: true)
|
17
|
-
super
|
18
|
-
end
|
19
|
-
|
20
|
-
def appended(filename, obj)
|
21
|
-
obj.fetch(:attr_accessor, []).each do |att|
|
22
|
-
@attributes.push(filename, att).accessor!
|
23
|
-
end
|
24
|
-
|
25
|
-
obj.fetch(:attr_reader, []).each do |att|
|
26
|
-
@attributes.push(filename, att).reader!
|
27
|
-
end
|
28
|
-
|
29
|
-
obj.fetch(:attr_writer, []).each do |att|
|
30
|
-
@attributes.push(filename, att).writer!
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# Returns a Hash representation of this class definition
|
35
|
-
def to_h
|
36
|
-
super.to_h.merge({
|
37
|
-
inherits:,
|
38
|
-
attributes: merged_attributes.transform_values { |v| unpack(v) }
|
39
|
-
})
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Docrb
|
4
|
-
class DocCompiler
|
5
|
-
# DocMethod represents a documented method
|
6
|
-
class DocMethod < Resolvable
|
7
|
-
attr_reader :parent, :type, :name, :args, :doc, :visibility,
|
8
|
-
:overriden_by, :defined_by
|
9
|
-
|
10
|
-
# Initializes a new DocMethod instance with a given parent, path, and
|
11
|
-
# object.
|
12
|
-
#
|
13
|
-
# parent - The object holding the represented method
|
14
|
-
# filename - The filename on which the method is defined on
|
15
|
-
# obj - The method definition itself
|
16
|
-
def initialize(parent, filename, obj)
|
17
|
-
super()
|
18
|
-
@parent = parent
|
19
|
-
@type = obj[:type]
|
20
|
-
@name = obj[:name]
|
21
|
-
@args = obj[:args]
|
22
|
-
@doc = obj[:doc]
|
23
|
-
@visibility = obj[:visibility]
|
24
|
-
@overriden_by = nil
|
25
|
-
@defined_by = FileRef.new(nil, filename, obj)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Public: Marks this method as being overriden by a provided object in
|
29
|
-
# a given filename. This method initializes a new DocMethod instance using
|
30
|
-
# this instance's parent, the provided filename and object, and invokes
|
31
|
-
# #override! on it.
|
32
|
-
#
|
33
|
-
# filename - The filename defining the override for this method
|
34
|
-
# obj - The object representing the override for this method
|
35
|
-
def override(filename, obj)
|
36
|
-
override! DocMethod.new(@parent, filename, obj)
|
37
|
-
end
|
38
|
-
|
39
|
-
# Public: Marks this method as being overriden by the provided method
|
40
|
-
#
|
41
|
-
# method - DocMethod object overriding this method's implementation
|
42
|
-
def override!(method)
|
43
|
-
@overriden_by = method
|
44
|
-
end
|
45
|
-
|
46
|
-
def inspect
|
47
|
-
type = @type == :def ? "method" : "singleton method"
|
48
|
-
overriden = overriden_by.nil? ? "" : " overriden"
|
49
|
-
"#<DocMethod:#{format("0x%08x", object_id * 2)} #{visibility} #{type} #{name}#{overriden}>"
|
50
|
-
end
|
51
|
-
|
52
|
-
# Public: Returns a Hash representation of this method
|
53
|
-
def to_h
|
54
|
-
{
|
55
|
-
type:,
|
56
|
-
name:,
|
57
|
-
args:,
|
58
|
-
doc: DocBlocks.prepare(doc, parent: self),
|
59
|
-
visibility:,
|
60
|
-
overriden_by:,
|
61
|
-
defined_by: defined_by&.to_h
|
62
|
-
}
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Docrb
|
4
|
-
class DocCompiler
|
5
|
-
# FileRef represents a file reference. This class is used to represent
|
6
|
-
# definition metadata of objects in files. Instances of this class
|
7
|
-
# indicates filenames and boundaries for a represented object.
|
8
|
-
class FileRef
|
9
|
-
attr_reader :filename, :start_at, :end_at
|
10
|
-
|
11
|
-
# Initializes a new FileRef instance.
|
12
|
-
#
|
13
|
-
# _parent - Unused.
|
14
|
-
# filename - Path to the file being referenced
|
15
|
-
# obj - The object being referenced in the provided filename
|
16
|
-
#
|
17
|
-
def initialize(_parent, filename, obj)
|
18
|
-
@filename = filename
|
19
|
-
@start_at, @end_at = obj.values_at(:start_at, :end_at)
|
20
|
-
end
|
21
|
-
|
22
|
-
# Public: Returns the source code portion of the represented reference
|
23
|
-
def ruby_source
|
24
|
-
f = File.read(filename).split("\n")[start_at - 1..end_at - 1]
|
25
|
-
f.join("\n")
|
26
|
-
end
|
27
|
-
|
28
|
-
# Public: Returns the reference's Hash representation
|
29
|
-
def to_h
|
30
|
-
source = ruby_source
|
31
|
-
{
|
32
|
-
filename:,
|
33
|
-
start_at:,
|
34
|
-
end_at:,
|
35
|
-
source:,
|
36
|
-
markdown_source: Markdown.render_source(source)
|
37
|
-
}
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,68 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Docrb
|
4
|
-
class DocCompiler
|
5
|
-
# ObjectContainer implements utilities for representing a container of
|
6
|
-
# objects with a common type.
|
7
|
-
class ObjectContainer
|
8
|
-
extend Forwardable
|
9
|
-
|
10
|
-
attr_reader :objects
|
11
|
-
|
12
|
-
# Initializes a new container with a given parent, containing objects with
|
13
|
-
# a provided class and options.
|
14
|
-
#
|
15
|
-
# parent - The container's parent
|
16
|
-
# cls - The class of represented items
|
17
|
-
# **opts - Options list. Currently, only `always_append` is supported,
|
18
|
-
# which indicates that all objects provided to the instance must
|
19
|
-
# be appended regardless of their type.
|
20
|
-
def initialize(parent, cls, **opts)
|
21
|
-
@cls = cls
|
22
|
-
@objects = []
|
23
|
-
@opts = opts
|
24
|
-
@parent = parent
|
25
|
-
end
|
26
|
-
|
27
|
-
def_delegators :@objects, :length, :each, :map, :find, :filter, :first, :[], :to_json
|
28
|
-
|
29
|
-
# Pushes a new object into the container. May raise ArgumentError in case
|
30
|
-
# the object being pushed is not compatible with the container's base
|
31
|
-
# object.
|
32
|
-
#
|
33
|
-
# filename - Name of the file which defines the object being pushed
|
34
|
-
# obj - The object being pushed
|
35
|
-
#
|
36
|
-
# Returns the new instance representing the pushed object.
|
37
|
-
def push(filename, obj)
|
38
|
-
if @cls.method_defined?(:name) &&
|
39
|
-
(instance = @objects.find { |o| o.name == obj[:name] }) &&
|
40
|
-
!@opts.fetch(:always_append, false)
|
41
|
-
|
42
|
-
return instance.merge(filename, obj) if instance.respond_to? :merge
|
43
|
-
return instance.override(filename, obj) if instance.respond_to? :override
|
44
|
-
return instance.append(filename, obj) if instance.respond_to? :append
|
45
|
-
|
46
|
-
raise ArgumentError, "cannot handle existing object #{obj[:name]} for container of type #{@cls.name}"
|
47
|
-
end
|
48
|
-
|
49
|
-
inst = @cls.new(@parent, filename, obj)
|
50
|
-
@objects << inst
|
51
|
-
inst
|
52
|
-
end
|
53
|
-
|
54
|
-
def inspect
|
55
|
-
opts = []
|
56
|
-
opts << "always_append" if @opts[:always_append]
|
57
|
-
count = if @objects.count.zero?
|
58
|
-
"empty"
|
59
|
-
else
|
60
|
-
"#{@objects.length} object#{@objects.length == 1 ? "" : "s"}"
|
61
|
-
end
|
62
|
-
obj_id = format("0x%08x", object_id * 2)
|
63
|
-
opts_repr = opts.empty? ? "" : " #{opts.join(", ")}"
|
64
|
-
"#<ObjectContainer:#{obj_id} containing #{@cls.name}, #{count}#{opts_repr}>"
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|