tag_ripper 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f55c43ce02431ffc69bd9284ec5875678d743e3c14544f3ebb0710e440921b8
4
- data.tar.gz: 10b1baa79118d897442fd87e49ee7da2b9259172802246f22e0ea5a3b3855d72
3
+ metadata.gz: 375a528cbf8942e0dd48c51ffe10c005a6b3672b414e82b5d768011f3355e350
4
+ data.tar.gz: f3e74892414a1587e5dfabeba4cda6839f2dd500f800bda6303fa2ea97f18042
5
5
  SHA512:
6
- metadata.gz: ab28505f7eb7784a4a90d7613960263251b43f9d8dcbca34570c360828f7c651e3b60d5e518b0d98e6722e0fc214a53e27f8280dfe3713962474c5914074fb5c
7
- data.tar.gz: c38bd4b3c85a1a6b02f7fe57ab61e69ea729f031d9f6a04fd40a85e71e978c820d7577d63a060079f3309a704452b779fa994d7fca6cc09d547dbcbdbb8622af
6
+ metadata.gz: 49ababa76c465f7fa6a691f968290a6668762d884e0be15ca3790e6b6b884853aa1ff1bbbe78c9afdeef293b85ab4f3470357d635c9dda531257f26e81d4700b
7
+ data.tar.gz: 07311f3a4768f8643c0fafcab84f3b6318392a5c1726bcfccf2fcfd1291db35e4039d4493adeb4e0241765b086e56bd2fbb3feee4e9065452c4880df3a9d88f9
data/.rubocop.yml CHANGED
@@ -8,7 +8,9 @@ AllCops:
8
8
  TargetRubyVersion: 3.1
9
9
  NewCops: enable
10
10
  SuggestExtensions: true
11
-
11
+ Exclude:
12
+ - bin/*
13
+ - test/fixtures/**/* # These files have particular styles that should be preserved
12
14
  Metrics/AbcSize:
13
15
  Exclude:
14
16
  - test/**/*
@@ -30,4 +32,3 @@ Style/TrivialAccessors:
30
32
 
31
33
  Style/StringLiteralsInInterpolation:
32
34
  EnforcedStyle: double_quotes
33
-
data/README.md CHANGED
@@ -17,15 +17,26 @@ class User
17
17
  end
18
18
 
19
19
  TagRipper.new(File.read('user.rb')).taggables
20
- # => [
21
- # <id=22040, @name=some_method_that_isnt_tested, tags={"warning" => #<Set: {"untested"}>},parent=#<TagRipper::TaggableEntity:0x00000001203bf468>>,
22
- # <id=22224, @name=User, tags={"domain" => #<Set: {"Auth"}>},parent=>nil
23
- # ]
20
+ # (Beautified output)
21
+ # ---
22
+ # -
23
+ # id: 2221
24
+ # name: some_method_that_isnt_tested
25
+ # tags:
26
+ # warning:
27
+ # - "untested
28
+ # parent: 22224,
29
+ # -
30
+ # id: 22224
31
+ # name: User
32
+ # tags:
33
+ # domain:
34
+ # - "Auth"
35
+ # parent: nil
24
36
  ```
25
37
 
26
38
  ## Installation
27
39
 
28
- TODO: Replace `tag_ripper` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
29
40
 
30
41
  Install the gem and add to the application's Gemfile by executing:
31
42
 
@@ -49,6 +49,10 @@ module TagRipper
49
49
  comment? && token.match?(TAG_REGEX)
50
50
  end
51
51
 
52
+ def double_colon?
53
+ token == "::"
54
+ end
55
+
52
56
  def keyword?
53
57
  type == :on_kw
54
58
  end
@@ -9,22 +9,42 @@ module TagRipper
9
9
  # entity is spawned. This creates a sort of recursion that allows a taggable
10
10
  # entity to be flexible to any amount of code nesting.
11
11
  class TaggableEntity
12
+ # Unable to move transition from one state to another
12
13
  class IllegalStateTransitionError < StandardError
13
14
  def initialize(from:, to:)
14
15
  super("Cannot transition from #{from} to #{to}")
15
16
  end
16
17
  end
17
18
 
19
+ # Attempting to set status to an unknown value
20
+ class InvalidStatusError < ArgumentError; end
21
+
22
+ # TODO: define naming state, to represent a partial name token
23
+ # The valid statuses that a TaggableEntity can move through.
24
+ # @return [Array<Symbol>]
25
+ VALID_STATUSES = %i[
26
+ pending
27
+ tagged
28
+ awaiting_name
29
+ named
30
+ closed
31
+ ].freeze
32
+
33
+ # Statuses that represent an open lexical scope.
34
+ # @return [Array<Symbol>]
35
+ OPENED_STATUSES = %i[tagged awaiting_name named].freeze
36
+
18
37
  def initialize(name: nil, parent: nil)
19
38
  @name = name
20
39
  @tags = Hash.new { |hash, key| hash[key] = Set.new }
21
40
  @parent = parent
22
41
  @type = nil
23
- @status = :pending
42
+ self.status = :pending
24
43
  end
25
44
 
45
+ alias id object_id
46
+
26
47
  def send_event(event_name, lex)
27
- puts "send_event: #{event_name} - #{lex} #(#{@status})"
28
48
  if respond_to?(event_name, true)
29
49
  send(event_name, lex)
30
50
  else
@@ -39,6 +59,9 @@ module TagRipper
39
59
  def type
40
60
  @type
41
61
  end
62
+
63
+ # The fully-qualified name of this entity (e.g. +"Foo::Bar::MyClass"+)
64
+ # @return [String]
42
65
  def fqn
43
66
  return nil unless named?
44
67
  return name if fqn_names.size == 1
@@ -51,14 +74,10 @@ module TagRipper
51
74
  end
52
75
  alias fully_qualified_name fqn
53
76
 
54
- def pending? = @status == :pending
55
-
56
- def tagged? = @status == :tagged
57
-
58
- def awaiting_name? = @status == :awaiting_name
59
-
60
- OPENED_STATUSES = %i[tagged awaiting_name named].freeze
61
-
77
+ # Have we opened a new lexical scope? (e.g. evaluating within the body
78
+ # of a class, rather than comments before the class)
79
+ #
80
+ # @return [Boolean]
62
81
  def open?
63
82
  OPENED_STATUSES.include?(@status)
64
83
  end
@@ -68,7 +87,7 @@ module TagRipper
68
87
  raise IllegalStateTransitionError.new(from: @status, to: :tagged)
69
88
  end
70
89
 
71
- @status = :tagged
90
+ self.status = :tagged
72
91
 
73
92
  add_tag(tag_name, tag_value)
74
93
  end
@@ -78,7 +97,7 @@ module TagRipper
78
97
  raise IllegalStateTransitionError.new(from: @status, to: :awaiting_name)
79
98
  end
80
99
 
81
- @status = :awaiting_name
100
+ self.status = :awaiting_name
82
101
  end
83
102
 
84
103
  def name=(name)
@@ -87,17 +106,19 @@ module TagRipper
87
106
  end
88
107
 
89
108
  @name = name.to_s
90
- @status = :named
109
+ self.status = :named
91
110
  end
92
111
 
93
112
  def close!
94
113
  @open = false
95
- @status = :closed
114
+ self.status = :closed
96
115
  freeze
97
116
  end
98
117
 
99
- def closed?
100
- @status == :closed
118
+ VALID_STATUSES.each do |status|
119
+ define_method(:"#{status}?") do
120
+ @status == status
121
+ end
101
122
  end
102
123
 
103
124
  def may_tag?
@@ -128,13 +149,28 @@ module TagRipper
128
149
  @name.to_s.dup
129
150
  end
130
151
 
131
- def type=(type)
132
- @type = type.to_sym
152
+ def parent
153
+ @parent
133
154
  end
134
155
 
135
156
  protected
136
157
 
137
- alias id object_id
158
+ def append_name!(string)
159
+ raise StandardError, "Cannot append #{string} to nil" unless @name
160
+
161
+ @name.concat(string.to_s)
162
+ end
163
+
164
+ def status=(status)
165
+ status = status.to_sym
166
+ raise InvalidStatusError unless VALID_STATUSES.include?(status)
167
+
168
+ @status = status
169
+ end
170
+
171
+ def type=(type)
172
+ @type = type.to_sym
173
+ end
138
174
 
139
175
  def fqn_names
140
176
  return [name] if parent.nil?
@@ -142,10 +178,6 @@ module TagRipper
142
178
  [*parent.fqn_names, name]
143
179
  end
144
180
 
145
- def parent
146
- @parent
147
- end
148
-
149
181
  def add_tag(name, value)
150
182
  @tags[name].add(value)
151
183
  end
@@ -178,6 +210,8 @@ module TagRipper
178
210
  send(event_token_method_name, lex)
179
211
  end
180
212
 
213
+ ##
214
+ # Lex is a keyword (e.g. def, class, module)
181
215
  def on_new_taggable_context_kw(lex)
182
216
  returnable_entity = named? ? build_child : self
183
217
 
@@ -191,21 +225,41 @@ module TagRipper
191
225
  alias on_kw_module on_new_taggable_context_kw
192
226
  alias on_kw_class on_new_taggable_context_kw
193
227
 
194
- IGNORED_IDENT_KEYWORDS = %w[require private class_eval instance_eval define_method].freeze
228
+ IGNORED_IDENT_KEYWORDS = %w[require private class_eval instance_eval
229
+ define_method].freeze
195
230
  private_constant :IGNORED_IDENT_KEYWORDS
196
231
 
197
- def name_from_lex(lex)
232
+ def name_from_lex(lex) # rubocop:disable Metrics
198
233
  return self if IGNORED_IDENT_KEYWORDS.include?(lex.token)
199
- return self if named?
200
- return self unless may_name?
234
+ # TODO: Simplify this logic
235
+ return self if named? && !@name.end_with?("::")
236
+ return self unless may_name? || @name.end_with?("::")
237
+
238
+ # self.status = :awaiting_name # TODO: Fix this with a proper state
239
+ if named? && @name.end_with?("::")
240
+ append_name!(lex.token)
241
+ else
242
+ self.name = "#{name}#{lex.token}"
243
+ end
201
244
 
202
- self.name = lex.token
203
245
  self
204
- end
246
+ end # rubocop:enable Metrics
205
247
 
248
+ ##
249
+ # Matches names of constants: module names, const names, etc.
206
250
  alias on_const name_from_lex
251
+
252
+ ##
253
+ # Matches tokens like: private, method names, argument names
207
254
  alias on_ident name_from_lex
208
255
 
256
+ def on_op(lex)
257
+ if lex.double_colon?
258
+ append_name!(lex.token)
259
+ end
260
+ self
261
+ end
262
+
209
263
  def on_kw_end(_lex)
210
264
  close!
211
265
  parent
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TagRipper
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tag_ripper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gavin Morrice
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-04-03 00:00:00.000000000 Z
10
+ date: 2025-06-19 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: Add tags to your Ruby code comments and then Rip the as lexical tokens
13
13
  email:
@@ -30,13 +30,13 @@ files:
30
30
  - lib/tag_ripper/ripper.rb
31
31
  - lib/tag_ripper/taggable_entity.rb
32
32
  - lib/tag_ripper/version.rb
33
- homepage: https://github.com/Bodacious/tag-ripper/
33
+ homepage: https://github.com/Bodacious/tag_ripper/
34
34
  licenses:
35
35
  - MIT
36
36
  metadata:
37
- homepage_uri: https://github.com/Bodacious/tag-ripper/
38
- source_code_uri: https://github.com/Bodacious/tag-ripper/
39
- changelog_uri: https://github.com/Bodacious/tag-ripper/
37
+ homepage_uri: https://github.com/Bodacious/tag_ripper/
38
+ source_code_uri: https://github.com/Bodacious/tag_ripper/
39
+ changelog_uri: https://github.com/Bodacious/tag_ripper/
40
40
  rubygems_mfa_required: 'true'
41
41
  rdoc_options: []
42
42
  require_paths: