destructure 0.0.12 → 0.1.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/lib/destructure/sexp_transformer.rb +81 -46
- metadata +15 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5d0b1548c863bb1ba5146873b0c166fd36e055b
|
4
|
+
data.tar.gz: 52f6b0b15e2ceec3c4d486570f3bef4dda4a0371
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b3517fb92fe51414e8568857aa3e98b85151196e07633af028c110a249be9d1ef7774390e9288b93a2e48f3ad2c3abe2a6816beb3318ea6681a947e8f992b248
|
7
|
+
data.tar.gz: d4f3647f5cd6d0bcb3862292abf31e629e79c7c71f3a3ac3e82f12323e3a6d45103efe3aba01845d5342166c60ef7a670e823d3d94fe6f871153e8b571527852
|
@@ -16,73 +16,109 @@ module Destructure
|
|
16
16
|
_ = DMatch::_
|
17
17
|
klass_sym = DMatch::Var.new(&method(:is_constant?))
|
18
18
|
case
|
19
|
+
|
19
20
|
# '_' (wildcard)
|
20
|
-
|
21
|
+
when e = dmatch([:call, _, :_, _], sp); _
|
22
|
+
|
21
23
|
# object matcher without parameters
|
22
|
-
|
23
|
-
|
24
|
+
when e = dmatch([:const, klass_sym], sp)
|
25
|
+
make_obj(e[klass_sym], {})
|
26
|
+
|
27
|
+
# namespace-qualified object matcher without parameters
|
28
|
+
when e = dmatch([:colon2, splat(:args)], sp)
|
29
|
+
make_obj(read_fq_const(sp), {})
|
30
|
+
|
24
31
|
# '~' (splat)
|
25
|
-
|
32
|
+
when e = dmatch([:call, var(:identifier_sexp), :~, [:arglist]], sp); splat(unwind_receivers_and_clean(e[:identifier_sexp]))
|
33
|
+
|
26
34
|
# '!' (variable value)
|
27
|
-
|
28
|
-
|
35
|
+
when e = dmatch([:not, var(:value_sexp)], sp)
|
36
|
+
@caller_binding.eval(unwind_receivers_and_clean(e[:value_sexp]).to_s)
|
37
|
+
|
29
38
|
# '|' (alternative patterns)
|
30
|
-
|
39
|
+
when e = dmatch([:call, var(:rest), :|, [:arglist, var(:alt)]], sp); DMatch::Or.new(*[e[:rest], e[:alt]].map(&method(:transform)))
|
40
|
+
|
31
41
|
# generic call
|
32
|
-
|
33
|
-
|
42
|
+
when e = dmatch([:call, var(:receiver), var(:msg), var(:arglist)], sp)
|
43
|
+
transform_call(e[:receiver], e[:msg], e[:arglist])
|
44
|
+
|
34
45
|
# instance variable
|
35
|
-
|
46
|
+
when e = dmatch([:ivar, var(:name)], sp); var(e[:name].to_s)
|
47
|
+
|
36
48
|
# let
|
37
49
|
# ... with local or instance vars
|
38
|
-
|
39
|
-
|
50
|
+
when e = dmatch([DMatch::Or.new(:lasgn, :iasgn), var(:lhs), var(:rhs)], sp)
|
51
|
+
let_var(e[:lhs], transform(e[:rhs]))
|
52
|
+
|
40
53
|
# ... with attributes or something more complicated
|
41
|
-
|
42
|
-
|
43
|
-
|
54
|
+
when e = dmatch([:attrasgn, var(:obj), var(:attr), [:arglist, var(:rhs)]], sp)
|
55
|
+
var_name = unwind_receivers_and_clean([:call, e[:obj], e[:attr].to_s.sub(/=$/,'').to_sym, [:arglist]])
|
56
|
+
let_var(var_name, transform(e[:rhs]))
|
57
|
+
|
44
58
|
# literal values
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
59
|
+
when e = dmatch([:lit, var(:value)], sp); e[:value]
|
60
|
+
when e = dmatch([:true], sp); true
|
61
|
+
when e = dmatch([:false], sp); false
|
62
|
+
when e = dmatch([:nil], sp); nil
|
63
|
+
when e = dmatch([:str, var(:s)], sp); e[:s]
|
64
|
+
when e = dmatch([:array, splat(:items)], sp); e[:items].map(&method(:transform))
|
65
|
+
when e = dmatch([:hash, splat(:kvs)], sp); Hash[*e[:kvs].map(&method(:transform))]
|
66
|
+
else; raise "Unexpected sexp: #{sp.inspect}"
|
53
67
|
end
|
54
68
|
end
|
55
69
|
|
56
70
|
private ########################################
|
57
71
|
|
72
|
+
def read_fq_const(sp, parts=[])
|
73
|
+
klass_sym = DMatch::Var.new(&method(:is_constant?))
|
74
|
+
case
|
75
|
+
when e = dmatch([:const, klass_sym], sp)
|
76
|
+
parts = [e[klass_sym]] + parts
|
77
|
+
Object.const_get("#{parts.join('::')}")
|
78
|
+
when e = dmatch([:colon2, var(:prefix), var(:last)], sp)
|
79
|
+
read_fq_const(e[:prefix], [e[:last]] + parts)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
58
83
|
def transform_call(*sexp_call)
|
59
84
|
sexp_receiver, sexp_msg, sexp_args = sexp_call
|
60
85
|
_ = DMatch::_
|
61
86
|
klass_sym_var = DMatch::Var.new(&method(:is_constant?))
|
62
87
|
case
|
63
88
|
# Class[...]
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
89
|
+
when e = dmatch([[:const, klass_sym_var], :[]], [sexp_receiver, sexp_msg])
|
90
|
+
field_map = make_field_map(sexp_args)
|
91
|
+
klass_sym = e[klass_sym_var]
|
92
|
+
klass_sym == :Hash ? field_map : make_obj(klass_sym, field_map)
|
93
|
+
|
94
|
+
# namespace-qualified constant receiver
|
95
|
+
when e = dmatch([:colon2, splat(:args)], sexp_receiver)
|
96
|
+
field_map = make_field_map(sexp_args)
|
97
|
+
klass_sym = read_fq_const(sexp_receiver)
|
98
|
+
make_obj(klass_sym, field_map)
|
99
|
+
|
68
100
|
# local variable
|
69
|
-
|
101
|
+
when e = dmatch([nil, var(:name), [:arglist]], sexp_call)
|
102
|
+
var(e[:name])
|
103
|
+
|
70
104
|
# call chain (@one.two(12).three[3].four)
|
71
|
-
|
105
|
+
else
|
106
|
+
var(unwind_receivers_and_clean([:call, *sexp_call]))
|
72
107
|
end
|
73
108
|
end
|
74
109
|
|
75
110
|
def make_field_map(sexp_args)
|
76
111
|
case
|
77
112
|
# Class[a: 1, b: 2]
|
78
|
-
|
79
|
-
|
80
|
-
|
113
|
+
when e = dmatch([:arglist, [:hash, splat(:kv_sexps)]], sexp_args)
|
114
|
+
kvs = transform_many(e[:kv_sexps])
|
115
|
+
Hash[*kvs]
|
116
|
+
|
81
117
|
# Class[a, b, c]
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
118
|
+
when e = dmatch([:arglist, splat(:field_name_sexps)], sexp_args)
|
119
|
+
field_names = transform_many(e[:field_name_sexps])
|
120
|
+
Hash[field_names.map { |f| [f.name, var(f.name)] }]
|
121
|
+
else; raise 'oops'
|
86
122
|
end
|
87
123
|
end
|
88
124
|
|
@@ -96,16 +132,15 @@ module Destructure
|
|
96
132
|
end
|
97
133
|
|
98
134
|
def unwind_receivers(receiver)
|
99
|
-
to_s
|
100
135
|
case
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
136
|
+
when receiver.nil?; ''
|
137
|
+
when e = dmatch([:lit, var(:value)], receiver); "#{e[:value]}."
|
138
|
+
when e = dmatch([:ivar, var(:name)], receiver); "#{e[:name]}."
|
139
|
+
when e = dmatch([:call, var(:receiver), :[], [:arglist, splat(:args)]], receiver)
|
140
|
+
unwind_receivers(e[:receiver]) + format_hash_call(e[:args])
|
141
|
+
when e = dmatch([:call, var(:receiver), var(:msg), [:arglist, splat(:args)]], receiver)
|
142
|
+
unwind_receivers(e[:receiver]) + format_method_call(e[:msg], e[:args])
|
143
|
+
else; raise 'oops'
|
109
144
|
end
|
110
145
|
end
|
111
146
|
|
@@ -153,4 +188,4 @@ module Destructure
|
|
153
188
|
DMatch::Splat.new(name)
|
154
189
|
end
|
155
190
|
end
|
156
|
-
end
|
191
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: destructure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Winton
|
@@ -10,6 +10,20 @@ bindir: bin
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 2013-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: sourcify
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|