tcepsni 0.1.1 → 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 +4 -4
- data/CHANGELOG.md +30 -0
- data/lib/tcepsni/parser.rb +161 -0
- data/lib/tcepsni/vendor/activesupport/ordered_options.rb +28 -0
- data/lib/tcepsni/vendor/ipaddr.rb +20 -0
- data/lib/tcepsni/vendor/pathname.rb +21 -0
- data/lib/tcepsni/vendor/rails/paths/root.rb +37 -0
- data/lib/tcepsni/vendor/string_scanner.rb +35 -0
- data/lib/tcepsni/version.rb +1 -1
- data/lib/tcepsni.rb +5 -140
- data/sig/tcepsni.gen.rbs +72 -18
- data/sig/tcepsni.rbs +44 -12
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c7e2dad3ee934784b32e2263cfd23a6a478ec4d648b7e02f1a02267238296e5
|
4
|
+
data.tar.gz: 5db7c50e53eea93481004efd7d2f359db19fe8099356bfd980564f3b861d52d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/tcepsni/version.rb
CHANGED
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
|
-
|
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
|
144
|
-
|
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) ->
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
def
|
15
|
-
def
|
16
|
-
|
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,
|
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,
|
45
|
+
# attr_reader attributes: Hash[Symbol, untyped]
|
30
46
|
# attr_reader memory_reference: Integer
|
31
47
|
end
|
32
48
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
8
|
-
Array[parsed] | Hash[parsed, parsed] |
|
9
|
-
Class | Object | StringScanner
|
7
|
+
def self.parse: (String str) -> untyped
|
10
8
|
|
11
|
-
|
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,
|
40
|
+
attr_reader attributes: Hash[Symbol, untyped]
|
24
41
|
attr_reader memory_reference: Integer
|
25
|
-
def initialize: (klass: Class, attributes: Hash[Symbol,
|
42
|
+
def initialize: (klass: Class, attributes: Hash[Symbol, untyped], memory_reference: Integer) -> void
|
26
43
|
end
|
27
44
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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.
|
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-
|
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
|