docrb 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|