decode 0.20.2 → 0.21.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 133b0261b7fc97e74472573ccfe28b7526409627b7ebf60ee9674ff62348b0bc
4
- data.tar.gz: 79572a96b6c043d76093db8fac0835b6aeae69885f10d687e6ee18313a179e6d
3
+ metadata.gz: 6b8fbab2f6bbd8c5008a6a6de78b05846e7e102ae913c222a7c89410155c8585
4
+ data.tar.gz: ee07d9267e3d9ad7d84e0a72015e263465f1575fb8cb37942b4329e185ea54f8
5
5
  SHA512:
6
- metadata.gz: ad5a07fac459587b2a7c2630e4a368797ab8d7c6290134640a561b4b6acd9d1cc15fc310e752fd5895718c0b4f46c04e37facc457519d9a16f3f40d5cdd122fc
7
- data.tar.gz: a76d74f0eeb86f787dd6df5f859ce5235367a3e9ee2ab54aea1f22e2b5b980fac64f5620c239119406ee45492f5ed177959ccb49ade5ef58bf1ad0d676bb2bde
6
+ metadata.gz: 31004fbf090c9766bbec2b47c92a475a41b26e72641d040cf03e01c82ca038d9ed22daba05b9db9ac9ab484cca786f3f6adc727ba7cfcb62a710460a0ef9980a
7
+ data.tar.gz: ac3d6de5594d11b875c6c6befe2f01b2eea5a1dfa36e74e416697618a63f1c7b09ed6096e8981a4cfdbca6180aaa1b6d8ee75560bb3b7383272bd78bf1b99e8e
checksums.yaml.gz.sig CHANGED
Binary file
data/bake/decode/index.rb CHANGED
@@ -8,26 +8,51 @@
8
8
  def coverage(root)
9
9
  require 'build/files/glob'
10
10
  require 'decode/index'
11
+ require 'set'
11
12
 
12
13
  paths = Build::Files::Path.expand(root).glob("**/*")
13
14
 
14
15
  index = Decode::Index.new
15
16
  index.update(paths)
16
17
 
17
- total = 0
18
- documented = 0
18
+ documented = Set.new
19
+ missing = Set.new
19
20
 
20
- index.definitions.each do |name, definition|
21
- total += 1
21
+ index.trie.traverse do |path, node, descend|
22
+ public_definition = node.values.nil?
23
+
24
+ node.values&.each do |definition|
25
+ if definition.public?
26
+ level = path.size
27
+
28
+ if definition.comments.nil?
29
+ missing << definition.qualified_name
30
+ else
31
+ documented << definition.qualified_name
32
+ end
33
+
34
+ public_definition = true
35
+ end
36
+ end
22
37
 
23
- if comments = definition.comments
24
- documented += 1
25
- else
26
- $stderr.puts "#{name}"
38
+ # Don't descend into non-public definitions:
39
+ if public_definition
40
+ descend.call
27
41
  end
28
42
  end
29
43
 
30
- $stderr.puts "#{documented}/#{total} definitions have documentation."
44
+ documented_count = documented.size
45
+ public_count = documented_count + missing.size
46
+ $stderr.puts "#{documented_count} definitions have documentation, out of #{public_count} public definitions."
47
+
48
+ if documented_count < public_count
49
+ $stderr.puts nil, "Missing documentation for:"
50
+ missing.each do |name|
51
+ $stderr.puts "- #{name}"
52
+ end
53
+
54
+ raise RuntimeError, "Insufficient documentation!"
55
+ end
31
56
  end
32
57
 
33
58
  # Process the given source root and report on symbols.
@@ -48,6 +48,15 @@ module Decode
48
48
  # @attribute [Array(String)]
49
49
  attr :comments
50
50
 
51
+ # Whether the definition is considered part of the public interface.
52
+ #
53
+ # This is used to determine whether the definition should be documented for coverage purposes.
54
+ #
55
+ # @returns [Boolean]
56
+ def public?
57
+ true
58
+ end
59
+
51
60
  # The qualified name is an absolute name which includes any and all namespacing.
52
61
  # @returns [String]
53
62
  def qualified_name
data/lib/decode/index.rb CHANGED
@@ -37,7 +37,7 @@ module Decode
37
37
  attr :sources
38
38
 
39
39
  # All definitions which have been parsed.
40
- # @attribute [Array(Symbol)]
40
+ # @attribute [Hash(String, Definition)]
41
41
  attr :definitions
42
42
 
43
43
  # A (prefix) trie of lexically scoped definitions.
@@ -11,19 +11,27 @@ module Decode
11
11
  # A Ruby-specific definition.
12
12
  class Definition < Decode::Definition
13
13
  # Initialize the definition from the syntax tree node.
14
- def initialize(node, *arguments, **options)
14
+ def initialize(node, *arguments, visibility: nil, **options)
15
15
  super(*arguments, **options)
16
16
 
17
17
  @node = node
18
+ @visibility = visibility
18
19
  end
19
20
 
20
21
  def nested_name
21
22
  "\##{@name}"
22
23
  end
23
24
 
24
- # The parser syntax tree node.
25
+ # @attribute [Parser::AST::Node] The parser syntax tree node.
25
26
  attr :node
26
27
 
28
+ # @attribute [Symbol] The visibility of the definition.
29
+ attr_accessor :visibility
30
+
31
+ def public?
32
+ @visibility == :public
33
+ end
34
+
27
35
  def multiline?
28
36
  @node.location.line != @node.location.last_line
29
37
  end
@@ -25,6 +25,17 @@ module Decode
25
25
  class Parser
26
26
  def initialize(language)
27
27
  @language = language
28
+
29
+ @visibility = :public
30
+ @definitions = Hash.new.compare_by_identity
31
+ end
32
+
33
+ private def assign_definition(parent, definition)
34
+ (@definitions[parent] ||= {})[definition.name] = definition
35
+ end
36
+
37
+ private def lookup_definition(parent, name)
38
+ (@definitions[parent] ||= {})[name]
28
39
  end
29
40
 
30
41
  # Parse the given source object, can be a string or a Source instance.
@@ -71,6 +82,14 @@ module Decode
71
82
  end
72
83
  end
73
84
 
85
+ def with_visibility(visibility = :public, &block)
86
+ saved_visibility = @visibility
87
+ @visibility = visibility
88
+ yield
89
+ ensure
90
+ @visibility = saved_visibility
91
+ end
92
+
74
93
  # Walk over the syntax tree and extract relevant definitions with their associated comments.
75
94
  def walk_definitions(node, comments, parent = nil, &block)
76
95
  case node.type
@@ -79,32 +98,40 @@ module Decode
79
98
  node, nested_name_for(node.children[0]),
80
99
  comments: extract_comments_for(node, comments),
81
100
  parent: parent,
82
- language: @language
101
+ language: @language, visibility: :public
83
102
  )
84
103
 
104
+ assign_definition(parent, definition)
105
+
85
106
  yield definition
86
107
 
87
108
  if children = node.children[1]
88
- walk_definitions(children, comments, definition, &block)
109
+ with_visibility do
110
+ walk_definitions(children, comments, definition, &block)
111
+ end
89
112
  end
90
113
  when :class
91
114
  definition = Class.new(
92
115
  node, nested_name_for(node.children[0]),
93
116
  comments: extract_comments_for(node, comments),
94
- parent: parent, language: @language
117
+ parent: parent, language: @language, visibility: :public
95
118
  )
96
119
 
120
+ assign_definition(parent, definition)
121
+
97
122
  yield definition
98
123
 
99
124
  if children = node.children[2]
100
- walk_definitions(children, comments, definition, &block)
125
+ with_visibility do
126
+ walk_definitions(children, comments, definition, &block)
127
+ end
101
128
  end
102
129
  when :sclass
103
130
  if name = singleton_name_for(node.children[0])
104
131
  definition = Singleton.new(
105
132
  node, name,
106
133
  comments: extract_comments_for(node, comments),
107
- parent: parent, language: @language
134
+ parent: parent, language: @language, visibility: :public
108
135
  )
109
136
 
110
137
  yield definition
@@ -117,7 +144,7 @@ module Decode
117
144
  definition = Method.new(
118
145
  node, node.children[0],
119
146
  comments: extract_comments_for(node, comments),
120
- parent: parent, language: @language
147
+ parent: parent, language: @language, visibility: @visibility
121
148
  )
122
149
 
123
150
  yield definition
@@ -128,7 +155,7 @@ module Decode
128
155
  node, node.children[1],
129
156
  comments: extracted_comments,
130
157
  parent: scope_for(extracted_comments, parent, &block),
131
- language: @language
158
+ language: @language, visibility: @visibility
132
159
  )
133
160
 
134
161
  yield definition
@@ -144,6 +171,14 @@ module Decode
144
171
  name = node.children[1]
145
172
 
146
173
  case name
174
+ when :public, :protected, :private
175
+ @visibility = name
176
+ when :private_constant
177
+ constant_names_for(node.children[2..]) do |name|
178
+ if definition = lookup_definition(parent, name)
179
+ definition.visibility = :private
180
+ end
181
+ end
147
182
  when :attr, :attr_reader, :attr_writer, :attr_accessor
148
183
  definition = Attribute.new(
149
184
  node, name_for(node.children[2]),
@@ -263,6 +298,14 @@ module Decode
263
298
  return parent
264
299
  end
265
300
 
301
+ def constant_names_for(children)
302
+ children.each do |node|
303
+ if node.type == :sym
304
+ yield node.children[0]
305
+ end
306
+ end
307
+ end
308
+
266
309
  # Extract segments from the given input file.
267
310
  def segments_for(source, &block)
268
311
  top, comments = self.parse_source(source)
@@ -4,5 +4,5 @@
4
4
  # Copyright, 2020-2022, by Samuel Williams.
5
5
 
6
6
  module Decode
7
- VERSION = "0.20.2"
7
+ VERSION = "0.21.1"
8
8
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.2
4
+ version: 0.21.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -37,7 +37,7 @@ cert_chain:
37
37
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
38
38
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
39
39
  -----END CERTIFICATE-----
40
- date: 2023-12-04 00:00:00.000000000 Z
40
+ date: 2024-07-12 00:00:00.000000000 Z
41
41
  dependencies:
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: parser
@@ -125,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  - !ruby/object:Gem::Version
126
126
  version: '0'
127
127
  requirements: []
128
- rubygems_version: 3.4.22
128
+ rubygems_version: 3.5.9
129
129
  signing_key:
130
130
  specification_version: 4
131
131
  summary: Code analysis for documentation generation.
metadata.gz.sig CHANGED
Binary file