tcepsni 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3695b6a1a12979fa76824819d4f839ce4e3b9a2af040f97eca9e474609c5c1f2
4
- data.tar.gz: 373da53b2e230d3510f2043f25b8ae7cf017fae689fdfbaa92a388be4155ebcd
3
+ metadata.gz: 3c7e2dad3ee934784b32e2263cfd23a6a478ec4d648b7e02f1a02267238296e5
4
+ data.tar.gz: 5db7c50e53eea93481004efd7d2f359db19fe8099356bfd980564f3b861d52d1
5
5
  SHA512:
6
- metadata.gz: f646aecf1094e4e171581b52ca0e48dccddc4464bf158f4c30b93e8df7ef7b8989b240e9c61abf25a7cb65c2c9a29ec6978529f627a1c360f0fede299624d297
7
- data.tar.gz: 573e5e82c5c7a0b476ee93255fe6b6fc7992febcee911e54ee1b852c9acacca29950bc67183ec01cbed7c3cf3cfcce3edd21137f1c04400bff42959d6f1d72c8
6
+ metadata.gz: fc943477c66e694f76a6711ec01a2f82893c756fe7e30b1f00e8ef82d04c63699899b28252e2d046d148af68195a049bf2ca79b8b90bde359474ac610d9d3804
7
+ data.tar.gz: 8daf45aa53eb860b306357831c0c86a17d0e847fba6cfa8a051fe932a6d355ccfee936aee3ef48949b05a418013b7e140ce37ff57108ae653f768c97359c2f94
data/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.3.0 - 2023-11-18
6
+
7
+ ### Changed
8
+
9
+ - Introduced plugin system.
10
+ For example, if the source contains `Pathname` objects, use the `vendors` option like `Tcepsni.parse(str, vendors: [::Tcepsni::Vendor::Pathname])`.
11
+
12
+ ### Removed
13
+
14
+ - `Tcepsni::Class#string_scanner?`, `Tcepsni::Class#pathname?`, `Tcepsni::Class#ipaddr?`, `Tcepsni::Class#active_support_ordered_options?`, and `Tcepsni::Class#rails_paths_root?`.
15
+
5
16
  ## 0.2.0 - 2023-10-20
6
17
 
7
18
  ### Added
@@ -0,0 +1,161 @@
1
+ require 'strscan'
2
+ require 'forwardable'
3
+
4
+ module Tcepsni
5
+ class Parser
6
+ def initialize(source, vendors:)
7
+ @scanner = ::StringScanner.new(source)
8
+ @vendors = vendors.flat_map { |vendor| [*vendor.dependencies, vendor] }.uniq
9
+ end
10
+
11
+ # If it returned nil when failed, it collides with normal nil value.
12
+ def parse_expression
13
+ if @scanner.skip(/nil\b/)
14
+ nil
15
+ elsif @scanner.skip(/true\b/)
16
+ true
17
+ elsif @scanner.skip(/false\b/)
18
+ false
19
+ elsif @scanner.skip(':')
20
+ parse_identifier
21
+ elsif @scanner.skip('"')
22
+ parse_string
23
+ elsif @scanner.skip('[')
24
+ parse_array
25
+ elsif @scanner.skip('{')
26
+ parse_hash
27
+ elsif @scanner.skip('#<')
28
+ pos = @scanner.pos
29
+ @vendors.select { |vendor| vendor.object? }.each do |vendor|
30
+ begin
31
+ @scanner.pos = pos
32
+ return vendor.parse(self)
33
+ rescue Error
34
+ next
35
+ end
36
+ end
37
+ @scanner.pos = pos
38
+ parse_object
39
+ else
40
+ if (digits = @scanner.scan(/\d+/))
41
+ int = Integer(digits)
42
+ if @scanner.skip('.')
43
+ int2 = parse_integer
44
+ Float("#{int}.#{int2}")
45
+ elsif digits.size == 4 && @scanner.skip(/-(?<month>[01]\d)-(?<day>\d\d) (?<hour>[012]\d):(?<minute>[0-5]\d):(?<second>[0-5]\d) (?<zone>[+-]\d\d\d\d)/)
46
+ Time.new(Integer(int), @scanner[:month], @scanner[:day],
47
+ @scanner[:hour], @scanner[:minute], @scanner[:second],
48
+ @scanner[:zone])
49
+ else
50
+ int
51
+ end
52
+ else
53
+ parse_class
54
+ end
55
+ end
56
+ end
57
+
58
+ alias parse parse_expression
59
+
60
+ def parse_integer
61
+ int = @scanner.scan(/\d+/) or raise Error, 'no digits'
62
+ Integer(int)
63
+ end
64
+
65
+ def parse_identifier
66
+ id = @scanner.scan(/[A-Za-z_][A-Za-z0-9_]*/) or raise Error, 'no identifier'
67
+ id.intern
68
+ end
69
+
70
+ def parse_string
71
+ result = ''
72
+ until @scanner.eos?
73
+ if @scanner.skip('"')
74
+ return result
75
+ elsif @scanner.skip('\\"')
76
+ result << '"'
77
+ else
78
+ result << @scanner.getch
79
+ end
80
+ end
81
+ result
82
+ end
83
+
84
+ def parse_array
85
+ result = []
86
+ until @scanner.eos?
87
+ result << parse_expression rescue break
88
+ @scanner.skip(', ') or break
89
+ end
90
+ @scanner.skip(']') or raise Error, "no array closer: #{@scanner.inspect}"
91
+ result
92
+ end
93
+
94
+ def parse_hash
95
+ result = {}
96
+ until @scanner.eos?
97
+ key = parse_expression rescue break
98
+ @scanner.skip('=>') or raise Error, 'no hash arrow'
99
+ value = parse_expression
100
+ result[key] = value
101
+ @scanner.skip(', ') or break
102
+ end
103
+ @scanner.skip('}') or raise Error, 'no hash closer'
104
+ result
105
+ end
106
+
107
+ def parse_class
108
+ namespaces = [parse_capitalized_identifier]
109
+ until @scanner.eos?
110
+ @scanner.skip('::') or break
111
+ @scanner.eos? and raise Error, 'incomplete class'
112
+ namespaces << parse_capitalized_identifier
113
+ end
114
+ *namespaces, name = namespaces
115
+ Tcepsni::Class.new(name: name, namespaces: namespaces)
116
+ end
117
+
118
+ def parse_capitalized_identifier
119
+ id = @scanner.scan(/[A-Z][A-Za-z0-9_]*/) or raise Error, "no capitalized identifier: #{@scanner.inspect}"
120
+ id.intern
121
+ end
122
+
123
+ def parse_object
124
+ klass = parse_class
125
+ if klass.encoding?
126
+ @scanner.skip(':') or raise Error, 'no colon separator in encoding object'
127
+ @scanner.skip(/(?<name>[^>]+)>/) or raise Error, 'invalid encoding name'
128
+ Encoding.find(@scanner[:name])
129
+ else
130
+ memory_reference = parse_memory_reference
131
+ attributes = parse_attributes
132
+ Tcepsni::Object.new(klass: klass, memory_reference: memory_reference, attributes: attributes)
133
+ end
134
+ end
135
+
136
+ def parse_attributes
137
+ attributes = {}
138
+ unless @scanner.skip('>')
139
+ until @scanner.eos?
140
+ @scanner.skip(' @') or break
141
+ key = parse_identifier
142
+ @scanner.skip('=') or raise Error, 'no attribute keyval equal char'
143
+ attributes[key.intern] = parse_expression
144
+ unless @scanner.skip(',')
145
+ @scanner.skip('>') or raise Error, "no object closer: #{@scanner.inspect}"
146
+ break
147
+ end
148
+ end
149
+ end
150
+ attributes
151
+ end
152
+
153
+ def parse_memory_reference
154
+ @scanner.skip(/:(?<memory_reference>0x[0-9a-f]{16})/) or raise Error, "no memory reference: #{@scanner.inspect}"
155
+ Integer(@scanner[:memory_reference])
156
+ end
157
+
158
+ extend Forwardable
159
+ def_delegators :@scanner, :skip, :[]
160
+ end
161
+ end
@@ -0,0 +1,28 @@
1
+ require 'active_support/ordered_options'
2
+
3
+ module Tcepsni
4
+ module Vendor
5
+ module ActiveSupport
6
+ class OrderedOptions
7
+ def self.parse(parser)
8
+ parser.skip('ActiveSupport::OrderedOptions {') or raise Error, 'no space between ActiveSupport::OrderedOptions class name and hash opener'
9
+ hash = parser.parse_hash
10
+ parser.skip('>') or raise Error, "no ActiveSupport ordered options closer: #{parser.scanner.inspect}"
11
+ options = ::ActiveSupport::OrderedOptions.new
12
+ hash.each do |key, val|
13
+ options[key] = val
14
+ end
15
+ options
16
+ end
17
+
18
+ def self.dependencies
19
+ []
20
+ end
21
+
22
+ def self.object?
23
+ true
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ require 'ipaddr'
2
+
3
+ module Tcepsni
4
+ module Vendor
5
+ class IPAddr
6
+ def self.parse(parser)
7
+ parser.skip(/IPAddr: IPv[46]:(?<addr>[^>]+)>/) or raise Error, 'invalid IP address format error'
8
+ ::IPAddr.new(parser[:addr])
9
+ end
10
+
11
+ def self.object?
12
+ true
13
+ end
14
+
15
+ def self.dependencies
16
+ []
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ require 'pathname'
2
+
3
+ module Tcepsni
4
+ module Vendor
5
+ class Pathname
6
+ def self.parse(parser)
7
+ parser.skip('Pathname:') or raise Error, 'no colon between Pathname class name and path string'
8
+ parser.skip(/(?<path>[^>]+)>/) or raise Error, 'invalid path string and closer'
9
+ ::Pathname.new(parser[:path])
10
+ end
11
+
12
+ def self.object?
13
+ true
14
+ end
15
+
16
+ def self.dependencies
17
+ []
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,37 @@
1
+ require 'rails/paths'
2
+
3
+ module Tcepsni
4
+ module Vendor
5
+ module Rails
6
+ module Paths
7
+ class Root
8
+ attr_reader :memory_reference, :attributes
9
+
10
+ def initialize(memory_reference, attributes)
11
+ @memory_reference = memory_reference
12
+ @attributes = attributes
13
+ end
14
+
15
+ def self.parse(parser)
16
+ parser.skip('Rails::Paths::Root') or raise Error, 'this is not Rails::Paths::Root'
17
+ memory_reference = parser.parse_memory_reference
18
+ if parser.skip(' ...>')
19
+ attributes = {}
20
+ else
21
+ attributes = parser.parse_attributes
22
+ end
23
+ Tcepsni::Vendor::Rails::Paths::Root.new(memory_reference, attributes)
24
+ end
25
+
26
+ def self.object?
27
+ true
28
+ end
29
+
30
+ def self.dependencies
31
+ [::Tcepsni::Vendor::Pathname]
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,35 @@
1
+ module Tcepsni
2
+ module Vendor
3
+ class StringScanner
4
+ attr_reader :pos, :total, :scanned, :rest
5
+
6
+ def initialize(pos:, total:, scanned:, rest:)
7
+ @pos = pos
8
+ @total = total
9
+ @scanned = scanned
10
+ @rest = rest
11
+ end
12
+
13
+ def self.parse(parser)
14
+ parser.skip('StringScanner ') or raise Error, 'no space after string scanner class name'
15
+ pos = parser.parse_integer
16
+ parser.skip('/') or raise Error, 'no string scanner progress delimiter slash'
17
+ total = parser.parse_integer
18
+ parser.skip(' "') or raise Error, 'no space after string scanner progress'
19
+ scanned = parser.parse_string
20
+ parser.skip(' @ "') or raise Error, "no string scanner mark in string: #{parser.scanner.inspect}"
21
+ rest = parser.parse_string
22
+ parser.skip('>') or raise Error, 'no string scanner closer'
23
+ Tcepsni::Vendor::StringScanner.new(pos: pos, total: total, scanned: scanned, rest: rest)
24
+ end
25
+
26
+ def self.dependencies
27
+ []
28
+ end
29
+
30
+ def self.object?
31
+ true
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,3 +1,3 @@
1
1
  module Tcepsni
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
data/lib/tcepsni.rb CHANGED
@@ -1,190 +1,11 @@
1
- require 'strscan'
2
- require 'pathname'
3
- require 'ipaddr'
4
- require 'active_support/ordered_options'
5
- require 'rails/paths'
6
1
  require_relative 'tcepsni/version'
2
+ require_relative 'tcepsni/parser'
7
3
 
8
4
  module Tcepsni
9
5
  class Error < StandardError; end
10
6
 
11
- def self.parse(str)
12
- scanner = ::StringScanner.new(str)
13
- parse_expression(scanner)
14
- end
15
-
16
- class << self
17
- private
18
-
19
- # If it returned nil when failed, it collides with normal nil value.
20
- def parse_expression(scanner)
21
- if scanner.skip(/nil\b/)
22
- nil
23
- elsif scanner.skip(/true\b/)
24
- true
25
- elsif scanner.skip(/false\b/)
26
- false
27
- elsif scanner.skip(':')
28
- parse_identifier(scanner)
29
- elsif scanner.skip('"')
30
- parse_string(scanner)
31
- elsif scanner.skip('[')
32
- parse_array(scanner)
33
- elsif scanner.skip('{')
34
- parse_hash(scanner)
35
- elsif scanner.skip('#<')
36
- parse_object(scanner)
37
- else
38
- if (digits = scanner.scan(/\d+/))
39
- int = Integer(digits)
40
- if scanner.skip('.')
41
- int2 = parse_integer(scanner)
42
- Float("#{int}.#{int2}")
43
- elsif digits.size == 4 && scanner.skip(/-(?<month>[01]\d)-(?<day>\d\d) (?<hour>[012]\d):(?<minute>[0-5]\d):(?<second>[0-5]\d) (?<zone>[+-]\d\d\d\d)/)
44
- Time.new(Integer(int), scanner[:month], scanner[:day],
45
- scanner[:hour], scanner[:minute], scanner[:second],
46
- scanner[:zone])
47
- else
48
- int
49
- end
50
- else
51
- parse_class(scanner)
52
- end
53
- end
54
- end
55
-
56
- def parse_integer(scanner)
57
- int = scanner.scan(/\d+/) or raise Error, 'no digits'
58
- Integer(int)
59
- end
60
-
61
- def parse_identifier(scanner)
62
- id = scanner.scan(/[A-Za-z_][A-Za-z0-9_]*/) or raise Error, 'no identifier'
63
- id.intern
64
- end
65
-
66
- def parse_string(scanner)
67
- result = ''
68
- until scanner.eos?
69
- if scanner.skip('"')
70
- return result
71
- elsif scanner.skip('\\"')
72
- result << '"'
73
- else
74
- result << scanner.getch
75
- end
76
- end
77
- result
78
- end
79
-
80
- def parse_array(scanner)
81
- result = []
82
- until scanner.eos?
83
- result << parse_expression(scanner) rescue break
84
- scanner.skip(', ') or break
85
- end
86
- scanner.skip(']') or raise Error, "no array closer: #{scanner.inspect}"
87
- result
88
- end
89
-
90
- def parse_hash(scanner)
91
- result = {}
92
- until scanner.eos?
93
- key = parse_expression(scanner) rescue break
94
- scanner.skip('=>') or raise Error, 'no hash arrow'
95
- value = parse_expression(scanner)
96
- result[key] = value
97
- scanner.skip(', ') or break
98
- end
99
- scanner.skip('}') or raise Error, 'no hash closer'
100
- result
101
- end
102
-
103
- def parse_class(scanner)
104
- namespaces = [parse_capitalized_identifier(scanner)]
105
- until scanner.eos?
106
- scanner.skip('::') or break
107
- scanner.eos? and raise Error, 'incomplete class'
108
- namespaces << parse_capitalized_identifier(scanner)
109
- end
110
- *namespaces, name = namespaces
111
- Tcepsni::Class.new(name: name, namespaces: namespaces)
112
- end
113
-
114
- def parse_capitalized_identifier(scanner)
115
- id = scanner.scan(/[A-Z][A-Za-z0-9_]*/) or raise Error, "no capitalized identifier: #{scanner.inspect}"
116
- id.intern
117
- end
118
-
119
- def parse_object(scanner)
120
- klass = parse_class(scanner)
121
- if klass.string_scanner?
122
- scanner.skip(' ') or raise Error, 'no space after string scanner class name'
123
- pos = parse_integer(scanner)
124
- scanner.skip('/') or raise Error, 'no string scanner progress delimiter slash'
125
- total = parse_integer(scanner)
126
- scanner.skip(' "') or raise Error, 'no space after string scanner progress'
127
- scanned = parse_string(scanner)
128
- scanner.skip(' @ "') or raise Error, "no string scanner mark in string: #{scanner.inspect}"
129
- rest = parse_string(scanner)
130
- scanner.skip('>') or raise Error, 'no string scanner closer'
131
- Tcepsni::Vendor::StringScanner.new(pos: pos, total: total, scanned: scanned, rest: rest)
132
- elsif klass.pathname?
133
- scanner.skip(':') or raise Error, 'no colon between Pathname class name and path string'
134
- scanner.skip(/(?<path>[^>]+)>/) or raise Error, 'invalid path string and closer'
135
- Pathname(scanner[:path])
136
- elsif klass.encoding?
137
- scanner.skip(':') or raise Error, 'no colon separator in encoding object'
138
- scanner.skip(/(?<name>[^>]+)>/) or raise Error, 'invalid encoding name'
139
- Encoding.find(scanner[:name])
140
- elsif klass.ipaddr?
141
- scanner.skip(/: IPv[46]:(?<addr>[^>]+)>/) or raise Error, 'invalid IP address format error'
142
- IPAddr.new(scanner[:addr])
143
- elsif klass.active_support_ordered_options?
144
- scanner.skip(' {') or raise Error, 'no space between ActiveSupport::OrderedOptions class name and hash opener'
145
- hash = parse_hash(scanner)
146
- scanner.skip('>') or raise Error, "no ActiveSupport ordered options closer: #{scanner.inspect}"
147
- options = ActiveSupport::OrderedOptions.new
148
- hash.each do |key, val|
149
- options[key] = val
150
- end
151
- options
152
- elsif klass.rails_paths_root?
153
- memory_reference = parse_memory_reference(scanner)
154
- if scanner.skip(' ...>')
155
- attributes = {}
156
- else
157
- attributes = parse_attributes(scanner)
158
- end
159
- Tcepsni::Vendor::Rails::Paths::Root.new(memory_reference, attributes)
160
- else
161
- memory_reference = parse_memory_reference(scanner)
162
- attributes = parse_attributes(scanner)
163
- Tcepsni::Object.new(klass: klass, memory_reference: memory_reference, attributes: attributes)
164
- end
165
- end
166
-
167
- def parse_attributes(scanner)
168
- attributes = {}
169
- unless scanner.skip('>')
170
- until scanner.eos?
171
- scanner.skip(' @') or break
172
- key = parse_identifier(scanner)
173
- scanner.skip('=') or raise Error, 'no attribute keyval equal char'
174
- attributes[key.intern] = parse_expression(scanner)
175
- unless scanner.skip(',')
176
- scanner.skip('>') or raise Error, "no object closer: #{scanner.inspect}"
177
- break
178
- end
179
- end
180
- end
181
- attributes
182
- end
183
-
184
- def parse_memory_reference(scanner)
185
- scanner.skip(/:(?<memory_reference>0x[0-9a-f]{16})/) or raise Error, "no memory reference: #{scanner.inspect}"
186
- Integer(scanner[:memory_reference])
187
- end
7
+ def self.parse(str, vendors: [])
8
+ Parser.new(str, vendors: vendors).parse
188
9
  end
189
10
 
190
11
  class Class
@@ -195,29 +16,9 @@ module Tcepsni
195
16
  @namespaces = namespaces
196
17
  end
197
18
 
198
- def string_scanner?
199
- @name == :StringScanner && @namespaces.empty?
200
- end
201
-
202
- def pathname?
203
- @name == :Pathname
204
- end
205
-
206
19
  def encoding?
207
20
  @name == :Encoding && @namespaces.empty?
208
21
  end
209
-
210
- def ipaddr?
211
- @name == :IPAddr && @namespaces.empty?
212
- end
213
-
214
- def active_support_ordered_options?
215
- @name == :OrderedOptions && @namespaces == [:ActiveSupport]
216
- end
217
-
218
- def rails_paths_root?
219
- @name == :Root && @namespaces == [:Rails, :Paths]
220
- end
221
22
  end
222
23
 
223
24
  class Object
@@ -229,30 +30,4 @@ module Tcepsni
229
30
  @memory_reference = memory_reference
230
31
  end
231
32
  end
232
-
233
- module Vendor
234
- class StringScanner
235
- attr_reader :pos, :total, :scanned, :rest
236
-
237
- def initialize(pos:, total:, scanned:, rest:)
238
- @pos = pos
239
- @total = total
240
- @scanned = scanned
241
- @rest = rest
242
- end
243
- end
244
-
245
- module Rails
246
- module Paths
247
- class Root
248
- attr_reader :memory_reference, :attributes
249
-
250
- def initialize(memory_reference, attributes)
251
- @memory_reference = memory_reference
252
- @attributes = attributes
253
- end
254
- end
255
- end
256
- end
257
- end
258
33
  end
data/sig/tcepsni.gen.rbs CHANGED
@@ -4,18 +4,27 @@
4
4
  module Tcepsni
5
5
  VERSION: String
6
6
 
7
- # def self.parse: (String str) -> parsed
8
- def self.parse_expression: (untyped scanner) -> ((Array[(Array[(Class | Float | Integer | Object | String | Time | bool)?] | Hash[Object?, Object?] | Object)?] | Hash[Object?, (Array[Object?] | Hash[Object?, Object?] | Object)?] | Object)?)
9
- def self.parse_integer: (untyped scanner) -> Integer
10
- def self.parse_identifier: (untyped scanner) -> untyped
11
- def self.parse_string: (untyped scanner) -> String
12
- def self.parse_array: (untyped scanner) -> (Array[(Array[(Array[untyped] | Class | Float | Hash[(Class | Float | Integer | Object | String | Time | bool)?, untyped] | Integer | Object | String | Time | bool)?] | Hash[Object?, (Array[untyped] | Hash[Object?, untyped] | Object)?] | Object)?])
13
- def self.parse_hash: (untyped scanner) -> (Hash[Object?, (Array[(Array[untyped] | Hash[Object?, untyped] | Object)?] | Hash[Object?, (Array[untyped] | Hash[Object?, untyped] | Object)?] | Object)?])
14
- def self.parse_class: (untyped scanner) -> Class
15
- def self.parse_capitalized_identifier: (untyped scanner) -> untyped
16
- def self.parse_object: (untyped scanner) -> (Encoding | IPAddr | Object | Pathname | Vendor::Rails::Paths::Root | Vendor::StringScanner)
17
- def self.parse_attributes: (untyped scanner) -> (Hash[untyped, (Array[(Array[untyped] | Hash[Object?, untyped] | Object)?] | Hash[Object?, (Array[untyped] | Hash[Object?, untyped] | Object)?] | Object)?])
18
- def self.parse_memory_reference: (untyped scanner) -> Integer
7
+ # def self.parse: (String str) -> untyped
8
+
9
+ class Parser
10
+ extend Forwardable
11
+ @scanner: StringScanner
12
+ @vendors: Array[Array[untyped]]
13
+
14
+ # def initialize: (String source, vendors: Array[untyped]?) -> void
15
+ # def parse_expression: -> untyped
16
+ alias parse parse_expression
17
+ # def parse_integer: -> Integer
18
+ # def parse_identifier: -> Symbol
19
+ # def parse_string: -> String
20
+ # def parse_array: -> Array[untyped]
21
+ # def parse_hash: -> Hash[untyped, untyped]
22
+ # def parse_class: -> Class
23
+ # def parse_capitalized_identifier: -> Symbol
24
+ # def parse_object: -> Object
25
+ # def parse_attributes: -> Hash[Symbol, untyped]
26
+ # def parse_memory_reference: -> Integer
27
+ end
19
28
 
20
29
  class Class
21
30
  # def initialize: (name: Symbol?, namespaces: Array[Symbol]) -> void
@@ -31,29 +40,55 @@ module Tcepsni
31
40
  end
32
41
 
33
42
  class Object
34
- # def initialize: (klass: Class, attributes: Hash[Symbol, parsed], memory_reference: Integer) -> void
43
+ # def initialize: (klass: Class, attributes: Hash[Symbol, untyped], memory_reference: Integer) -> void
35
44
  # attr_reader klass: Class
36
- # attr_reader attributes: Hash[Symbol, (Array[untyped] | Array[untyped] | Class | Hash[untyped, untyped] | Hash[untyped, untyped] | Integer | Object | String | StringScanner | Symbol | bool)?]
45
+ # attr_reader attributes: Hash[Symbol, untyped]
37
46
  # attr_reader memory_reference: Integer
38
47
  end
39
48
 
40
49
  module Vendor
41
50
  class StringScanner
42
- # def initialize: (pos: Integer, total: Integer, scanned: String, rest: String) -> void
43
- # attr_reader pos: Integer
44
- # attr_reader total: Integer
45
- # attr_reader scanned: String
46
- # attr_reader rest: String
51
+ attr_reader pos: untyped
52
+ attr_reader total: untyped
53
+ attr_reader scanned: untyped
54
+ attr_reader rest: untyped
55
+ def initialize: (pos: untyped, total: untyped, scanned: untyped, rest: untyped) -> void
56
+ def self.parse: (untyped parser) -> StringScanner
57
+ def self.dependencies: -> Array[untyped]
58
+ def self.object?: -> true
47
59
  end
48
60
 
49
61
  module Rails
50
62
  module Paths
51
63
  class Root
52
- # def initialize: (Integer memory_reference, Hash[Symbol, parsed?] attributes) -> void
53
- # attr_reader memory_reference: Integer
54
- # attr_reader attributes: Hash[Symbol, (Array[untyped] | Array[untyped] | Class | Hash[untyped, untyped] | Hash[untyped, untyped] | Integer | Object | String | StringScanner | Symbol | bool)?]
64
+ attr_reader memory_reference: untyped
65
+ attr_reader attributes: Hash[untyped, untyped]
66
+ def initialize: (untyped memory_reference, Hash[untyped, untyped] attributes) -> void
67
+ def self.parse: (untyped parser) -> Root
68
+ def self.object?: -> true
69
+ def self.dependencies: -> [singleton(Pathname)]
55
70
  end
56
71
  end
57
72
  end
73
+
74
+ module ActiveSupport
75
+ class OrderedOptions
76
+ def self.parse: (untyped parser) -> untyped
77
+ def self.dependencies: -> Array[untyped]
78
+ def self.object?: -> true
79
+ end
80
+ end
81
+
82
+ class IPAddr
83
+ def self.parse: (untyped parser) -> IPAddr
84
+ def self.object?: -> true
85
+ def self.dependencies: -> Array[untyped]
86
+ end
87
+
88
+ class Pathname
89
+ def self.parse: (untyped parser) -> Pathname
90
+ def self.object?: -> true
91
+ def self.dependencies: -> Array[untyped]
92
+ end
58
93
  end
59
94
  end
data/sig/tcepsni.rbs CHANGED
@@ -4,11 +4,23 @@ module Tcepsni
4
4
  class Error < StandardError
5
5
  end
6
6
 
7
- type parsed = nil | Symbol | FalseClass | TrueClass | Integer | String |
8
- Array[parsed] | Hash[parsed, parsed] |
9
- Class | Object | StringScanner
7
+ def self.parse: (String str) -> untyped
10
8
 
11
- def self.parse: (String str) -> parsed
9
+ class Parser
10
+ def initialize: (String source, vendors: Array[untyped]?) -> void
11
+ def parse_expression: -> untyped
12
+ alias parse parse_expression
13
+ def parse_integer: -> Integer
14
+ def parse_identifier: -> Symbol
15
+ def parse_string: -> String
16
+ def parse_array: -> Array[untyped]
17
+ def parse_hash: -> Hash[untyped, untyped]
18
+ def parse_class: -> Class
19
+ def parse_capitalized_identifier: -> Symbol
20
+ def parse_object: -> Object
21
+ def parse_attributes: -> Hash[Symbol, untyped]
22
+ def parse_memory_reference: -> Integer
23
+ end
12
24
 
13
25
  class Class
14
26
  attr_reader name: Symbol
@@ -25,28 +37,31 @@ module Tcepsni
25
37
 
26
38
  class Object
27
39
  attr_reader klass: ::Class
28
- attr_reader attributes: Hash[Symbol, parsed]
40
+ attr_reader attributes: Hash[Symbol, untyped]
29
41
  attr_reader memory_reference: Integer
30
- def initialize: (klass: Class, attributes: Hash[Symbol, parsed], memory_reference: Integer) -> void
42
+ def initialize: (klass: Class, attributes: Hash[Symbol, untyped], memory_reference: Integer) -> void
31
43
  end
32
44
 
33
45
  module Vendor
34
46
  class StringScanner
35
- attr_reader pos: Integer
36
- attr_reader total: Integer
37
- attr_reader scanned: String
38
- attr_reader rest: String
39
- def initialize: (pos: Integer, total: Integer, scanned: String, rest: String) -> void
40
47
  end
41
48
 
42
49
  module Rails
43
50
  module Paths
44
51
  class Root
45
- attr_reader memory_reference: Integer
46
- attr_reader attributes: Hash[Symbol, parsed?]
47
- def initialize: (Integer memory_reference, Hash[Symbol, parsed?] attributes) -> void
48
52
  end
49
53
  end
50
54
  end
55
+
56
+ module ActiveSupport
57
+ class OrderedOptions
58
+ end
59
+ end
60
+
61
+ class IPAddr
62
+ end
63
+
64
+ class Pathname
65
+ end
51
66
  end
52
67
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tcepsni
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - gemmaro
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-20 00:00:00.000000000 Z
11
+ date: 2023-11-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Tcepsni gem is a parser library for inspected strings of Ruby objects.
14
14
  email:
@@ -21,6 +21,12 @@ files:
21
21
  - LICENSE.txt
22
22
  - README.md
23
23
  - lib/tcepsni.rb
24
+ - lib/tcepsni/parser.rb
25
+ - lib/tcepsni/vendor/activesupport/ordered_options.rb
26
+ - lib/tcepsni/vendor/ipaddr.rb
27
+ - lib/tcepsni/vendor/pathname.rb
28
+ - lib/tcepsni/vendor/rails/paths/root.rb
29
+ - lib/tcepsni/vendor/string_scanner.rb
24
30
  - lib/tcepsni/version.rb
25
31
  - sig/tcepsni.gen.rbs
26
32
  - sig/tcepsni.rbs