tcepsni 0.1.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f68a9bde443479e50e62f0f201a17c986eaad09e686e48adb24fa6a600ce38cb
4
- data.tar.gz: 2e718d175261eb10ded9c3fbcad4926b6c98e5072d0a81d148aa1f40c6f04571
3
+ metadata.gz: 3c7e2dad3ee934784b32e2263cfd23a6a478ec4d648b7e02f1a02267238296e5
4
+ data.tar.gz: 5db7c50e53eea93481004efd7d2f359db19fe8099356bfd980564f3b861d52d1
5
5
  SHA512:
6
- metadata.gz: 232ff2963d9bca49cea25eb7cc90bc6fc08815808058289e61b6ffae5dc8ee1516b43a2d56b64fde23c707034b7d1d1c068c417fc66a1e21503327f32237d5bb
7
- data.tar.gz: aadf113b5b26b20fc9d648ead1b43bf29f1c48eddd977348f0ef195af98dc0ab5fed4654dfd79a7b4f3009411b47a3d97e4834143c3ee99f6dab0b724300135c
6
+ metadata.gz: fc943477c66e694f76a6711ec01a2f82893c756fe7e30b1f00e8ef82d04c63699899b28252e2d046d148af68195a049bf2ca79b8b90bde359474ac610d9d3804
7
+ data.tar.gz: 8daf45aa53eb860b306357831c0c86a17d0e847fba6cfa8a051fe932a6d355ccfee936aee3ef48949b05a418013b7e140ce37ff57108ae653f768c97359c2f94
data/CHANGELOG.md CHANGED
@@ -2,6 +2,36 @@
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
+
16
+ ## 0.2.0 - 2023-10-20
17
+
18
+ ### Added
19
+
20
+ - `Time` support
21
+ - `Pathname` support
22
+ - `Encoding` support
23
+ - `IPAddr` support
24
+ - `ActiveSupport::OrderedOptions` support
25
+ - `Rails::Paths::Root` support
26
+ - `Float` support
27
+
28
+ ### Fixed
29
+
30
+ - Parsing the empty array
31
+ - Parsing the object with some attributes
32
+ - Parsing the `nil`, `true`, and `false` literals
33
+ - Detecting `StringScanner`-like object
34
+
5
35
  ## 0.1.1 - 2023-10-02
6
36
 
7
37
  ### Changed
@@ -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.1.1'
2
+ VERSION = '0.3.0'
3
3
  end
data/lib/tcepsni.rb CHANGED
@@ -1,135 +1,11 @@
1
- require 'strscan'
2
1
  require_relative 'tcepsni/version'
2
+ require_relative 'tcepsni/parser'
3
3
 
4
4
  module Tcepsni
5
5
  class Error < StandardError; end
6
6
 
7
- def self.parse(str)
8
- scanner = ::StringScanner.new(str)
9
- parse_expression(scanner)
10
- end
11
-
12
- class << self
13
- private
14
-
15
- # If it returned nil when failed, it collides with normal nil value.
16
- def parse_expression(scanner)
17
- if scanner.skip('nil')
18
- nil
19
- elsif scanner.skip('true')
20
- true
21
- elsif scanner.skip('false')
22
- false
23
- elsif scanner.skip(':')
24
- parse_identifier(scanner)
25
- elsif scanner.skip('"')
26
- parse_string(scanner)
27
- elsif scanner.skip('[')
28
- parse_array(scanner)
29
- elsif scanner.skip('{')
30
- parse_hash(scanner)
31
- elsif scanner.skip('#<')
32
- parse_object(scanner)
33
- else
34
- parse_integer(scanner) or parse_class(scanner)
35
- end
36
- end
37
-
38
- # Returns nil if it's not integer.
39
- # This doesn't raise error for convenience.
40
- def parse_integer(scanner)
41
- int = scanner.scan(/\d+/) or return
42
- Integer(int)
43
- end
44
-
45
- def parse_identifier(scanner)
46
- id = scanner.scan(/[A-Za-z_][A-Za-z0-9_]*/) or raise Error, 'no identifier'
47
- id.intern
48
- end
49
-
50
- def parse_string(scanner)
51
- result = ''
52
- until scanner.eos?
53
- if scanner.skip('"')
54
- return result
55
- elsif scanner.skip('\\"')
56
- result << '"'
57
- else
58
- result << scanner.getch
59
- end
60
- end
61
- result
62
- end
63
-
64
- def parse_array(scanner)
65
- result = [parse_expression(scanner)]
66
- until scanner.eos?
67
- scanner.skip(', ') or break
68
- scanner.eos? and raise Error, 'incomplete array'
69
- result << parse_expression(scanner)
70
- end
71
- scanner.skip(']') or raise Error, 'no array closer'
72
- result
73
- end
74
-
75
- def parse_hash(scanner)
76
- result = {}
77
- until scanner.eos?
78
- key = parse_expression(scanner) rescue break
79
- scanner.skip('=>') or raise Error, 'no hash arrow'
80
- value = parse_expression(scanner)
81
- result[key] = value
82
- scanner.skip(', ') or break
83
- end
84
- scanner.skip('}') or raise Error, 'no hash closer'
85
- result
86
- end
87
-
88
- def parse_class(scanner)
89
- namespaces = [parse_capitalized_identifier(scanner)]
90
- until scanner.eos?
91
- scanner.skip('::') or break
92
- scanner.eos? and raise Error, 'incomplete class'
93
- namespaces << parse_capitalized_identifier(scanner)
94
- end
95
- *namespaces, name = namespaces
96
- Tcepsni::Class.new(name: name, namespaces: namespaces)
97
- end
98
-
99
- def parse_capitalized_identifier(scanner)
100
- id = scanner.scan(/[A-Z][A-Za-z0-9_]*/) or raise Error, 'no capitalized identifier'
101
- id.intern
102
- end
103
-
104
- def parse_object(scanner)
105
- klass = parse_class(scanner)
106
- if klass.string_scanner?
107
- scanner.skip(' ') or raise Error, 'no space after string scanner class name'
108
- pos = parse_integer(scanner) or raise Error, 'no string scanner pos'
109
- scanner.skip('/') or raise Error, 'no string scanner progress delimiter slash'
110
- total = parse_integer(scanner) or raise Error, 'no string scanner total size'
111
- scanner.skip(' "') or raise Error, 'no space after string scanner progress'
112
- scanned = parse_string(scanner)
113
- scanner.skip(' @ "') or raise Error, "no string scanner mark in string: #{scanner.inspect}"
114
- rest = parse_string(scanner)
115
- scanner.skip('>') or raise Error, 'no string scanner closer'
116
- Tcepsni::StringScanner.new(pos: pos, total: total, scanned: scanned, rest: rest)
117
- else
118
- scanner.skip(/:(?<memory_reference>0x[0-9a-f]{16})/) or raise Error, "no memory reference: #{scanner.inspect}"
119
- memory_reference = Integer(scanner[:memory_reference])
120
- attributes = {}
121
- unless scanner.skip('>')
122
- until scanner.eos?
123
- scanner.skip(' @') or break
124
- key = parse_identifier(scanner)
125
- scanner.skip('=') or raise Error, 'no attribute keyval equal char'
126
- attributes[key.intern] = parse_expression(scanner)
127
- scanner.skip(',') or break
128
- end
129
- end
130
- Tcepsni::Object.new(klass: klass, memory_reference: memory_reference, attributes: attributes)
131
- end
132
- end
7
+ def self.parse(str, vendors: [])
8
+ Parser.new(str, vendors: vendors).parse
133
9
  end
134
10
 
135
11
  class Class
@@ -140,8 +16,8 @@ module Tcepsni
140
16
  @namespaces = namespaces
141
17
  end
142
18
 
143
- def string_scanner?
144
- [name, *namespaces].include?(:StringScanner)
19
+ def encoding?
20
+ @name == :Encoding && @namespaces.empty?
145
21
  end
146
22
  end
147
23
 
@@ -154,15 +30,4 @@ module Tcepsni
154
30
  @memory_reference = memory_reference
155
31
  end
156
32
  end
157
-
158
- class StringScanner
159
- attr_reader :pos, :total, :scanned, :rest
160
-
161
- def initialize(pos:, total:, scanned:, rest:)
162
- @pos = pos
163
- @total = total
164
- @scanned = scanned
165
- @rest = rest
166
- end
167
- end
168
33
  end
data/sig/tcepsni.gen.rbs CHANGED
@@ -4,37 +4,91 @@
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 | Integer | Object | String | StringScanner | bool)?] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, (Class | Integer | Object | String | StringScanner | bool)?] | Integer | Object | String | StringScanner | bool)?] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, (Array[(Class | Integer | Object | String | StringScanner | bool)?] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, (Class | Integer | Object | String | StringScanner | bool)?] | Integer | Object | String | StringScanner | bool)?] | Integer | Object | String | StringScanner | bool)?)
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 | Hash[(Class | Integer | Object | String | StringScanner | bool)?, untyped] | Integer | Object | String | StringScanner | bool)?] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, (Array[untyped] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, untyped] | Integer | Object | String | StringScanner | bool)?] | Integer | Object | String | StringScanner | bool)?])
13
- def self.parse_hash: (untyped scanner) -> (Hash[(Class | Integer | Object | String | StringScanner | bool)?, (Array[(Array[untyped] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, untyped] | Integer | Object | String | StringScanner | bool)?] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, (Array[untyped] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, untyped] | Integer | Object | String | StringScanner | bool)?] | Integer | Object | String | StringScanner | bool)?])
14
- def self.parse_class: (untyped scanner) -> Class
15
- def self.parse_capitalized_identifier: (untyped scanner) -> untyped
16
- def self.parse_object: (untyped scanner) -> (Object | StringScanner)
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
17
28
 
18
29
  class Class
19
30
  # def initialize: (name: Symbol?, namespaces: Array[Symbol]) -> void
20
31
  # def ==: (Class other) -> bool
21
32
  # def string_scanner?: -> bool
33
+ # def pathname?: -> bool
34
+ # def encoding?: -> bool
35
+ # def ipaddr?: -> bool
36
+ # def active_support_ordered_options?: -> bool
37
+ # def rails_paths_root?: -> bool
22
38
  # attr_reader name: Symbol?
23
39
  # attr_reader namespaces: Array[Symbol]
24
40
  end
25
41
 
26
42
  class Object
27
- # 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
28
44
  # attr_reader klass: Class
29
- # 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]
30
46
  # attr_reader memory_reference: Integer
31
47
  end
32
48
 
33
- class StringScanner
34
- # def initialize: (pos: Integer, total: Integer, scanned: String, rest: String) -> void
35
- # attr_reader pos: Integer
36
- # attr_reader total: Integer
37
- # attr_reader scanned: String
38
- # attr_reader rest: String
49
+ module Vendor
50
+ class StringScanner
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
59
+ end
60
+
61
+ module Rails
62
+ module Paths
63
+ class Root
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)]
70
+ end
71
+ end
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
39
93
  end
40
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
@@ -16,20 +28,40 @@ module Tcepsni
16
28
  def initialize: (name: Symbol?, namespaces: Array[Symbol]) -> void
17
29
  def ==: (Class other) -> bool
18
30
  def string_scanner?: -> bool
31
+ def pathname?: -> bool
32
+ def encoding?: -> bool
33
+ def ipaddr?: -> bool
34
+ def active_support_ordered_options?: -> bool
35
+ def rails_paths_root?: -> bool
19
36
  end
20
37
 
21
38
  class Object
22
39
  attr_reader klass: ::Class
23
- attr_reader attributes: Hash[Symbol, parsed]
40
+ attr_reader attributes: Hash[Symbol, untyped]
24
41
  attr_reader memory_reference: Integer
25
- 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
26
43
  end
27
44
 
28
- class StringScanner
29
- attr_reader pos: Integer
30
- attr_reader total: Integer
31
- attr_reader scanned: String
32
- attr_reader rest: String
33
- def initialize: (pos: Integer, total: Integer, scanned: String, rest: String) -> void
45
+ module Vendor
46
+ class StringScanner
47
+ end
48
+
49
+ module Rails
50
+ module Paths
51
+ class Root
52
+ end
53
+ end
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
34
66
  end
35
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.1.1
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-01 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