@@ -17,7 +17,11 @@ func isDigit(c byte) bool {
17
17
}
18
18
19
19
func isAlpha (c byte ) bool {
20
- return (c >= 'a' && c <= 'z' ) || (c >= 'A' && c <= 'Z' ) || (c == ' ' )
20
+ return (c >= 'a' && c <= 'z' ) || (c >= 'A' && c <= 'Z' )
21
+ }
22
+
23
+ func isSpace (c byte ) bool {
24
+ return c == ' '
21
25
}
22
26
23
27
func isIdentifierSymbol (c byte ) bool {
@@ -35,7 +39,7 @@ func parseToken(unescapedSelector string, isIdent bool) (string, string, error)
35
39
}
36
40
for position < len (unescapedSelector ) {
37
41
char := unescapedSelector [position ]
38
- if ! (isAlpha (char ) || isDigit (char ) || (isIdent && isIdentifierSymbol (char ))) {
42
+ if ! (isAlpha (char ) || isDigit (char ) || (isIdent && isIdentifierSymbol (char )) || ( ! isIdent && isSpace ( char )) ) {
39
43
break
40
44
}
41
45
position ++
@@ -48,6 +52,32 @@ func parseIdentifier(unescapedSelector string) (string, string, error) {
48
52
}
49
53
50
54
func parseElementaryType (unescapedSelector string ) (parsedType string , rest string , err error ) {
55
+ parsedType , rest , err = parseToken (unescapedSelector , false )
56
+ if err != nil {
57
+ return "" , "" , fmt .Errorf ("failed to parse elementary type: %v" , err )
58
+ }
59
+ parts := strings .Split (parsedType , " " )
60
+ if len (parts ) > 1 {
61
+ parsedType = parsedType [len (parts [0 ])+ 1 :]
62
+ }
63
+ // handle arrays
64
+ for len (rest ) > 0 && rest [0 ] == '[' {
65
+ parsedType = parsedType + string (rest [0 ])
66
+ rest = rest [1 :]
67
+ for len (rest ) > 0 && isDigit (rest [0 ]) {
68
+ parsedType = parsedType + string (rest [0 ])
69
+ rest = rest [1 :]
70
+ }
71
+ if len (rest ) == 0 || rest [0 ] != ']' {
72
+ return "" , "" , fmt .Errorf ("failed to parse array: expected ']', got %c" , unescapedSelector [0 ])
73
+ }
74
+ parsedType = parsedType + string (rest [0 ])
75
+ rest = rest [1 :]
76
+ }
77
+ return parsedType , rest , nil
78
+ }
79
+
80
+ func parseElementaryTypeWithName (unescapedSelector string ) (parsedType string , rest string , err error ) {
51
81
parsedType , rest , err = parseToken (unescapedSelector , false )
52
82
if err != nil {
53
83
return "" , "" , fmt .Errorf ("failed to parse elementary type: %v" , err )
@@ -95,7 +125,77 @@ func parseCompositeType(unescapedSelector string) (result []interface{}, rest st
95
125
return result , rest [1 :], nil
96
126
}
97
127
128
+ func parseCompositeTypeWithName (unescapedSelector string ) (result []interface {}, rest string , err error ) {
129
+ var name string
130
+ parts := strings .Split (unescapedSelector , " " )
131
+ if len (parts ) < 2 {
132
+ return nil , "" , fmt .Errorf ("expected name in the beginning, got %s" , unescapedSelector )
133
+ } else {
134
+ name = parts [0 ]
135
+ unescapedSelector = unescapedSelector [len (parts [0 ])+ 1 :]
136
+ }
137
+ if len (unescapedSelector ) == 0 || unescapedSelector [0 ] != '(' {
138
+ return nil , "" , fmt .Errorf ("expected '(...', got %s" , unescapedSelector )
139
+ }
140
+ result = []interface {}{name }
141
+ var parsedType interface {}
142
+ var counter int64
143
+ parsedType , rest , err = parseTypeWithName (unescapedSelector [1 :], counter )
144
+ if err != nil {
145
+ return nil , "" , fmt .Errorf ("failed to parse type: %v" , err )
146
+ }
147
+ result = append (result , parsedType )
148
+ for len (rest ) > 0 && rest [0 ] != ')' {
149
+ counter += 1
150
+ parsedType , rest , err = parseTypeWithName (rest [1 :], counter )
151
+ if err != nil {
152
+ return nil , "" , fmt .Errorf ("failed to parse type: %v" , err )
153
+ }
154
+ result = append (result , parsedType )
155
+ }
156
+ if len (rest ) == 0 || rest [0 ] != ')' {
157
+ return nil , "" , fmt .Errorf ("expected ')', got '%s'" , rest )
158
+ }
159
+ if len (rest ) >= 3 && rest [1 ] == '[' && rest [2 ] == ']' {
160
+ return append (result , "[]" ), rest [3 :], nil
161
+ }
162
+ return result , rest [1 :], nil
163
+ }
164
+
165
+ func parseFunctionsArgs (unescapedSelector string ) (result []interface {}, rest string , err error ) {
166
+ if len (unescapedSelector ) == 0 || unescapedSelector [0 ] != '(' {
167
+ return nil , "" , fmt .Errorf ("expected '(...', got %s" , unescapedSelector )
168
+ }
169
+ var parsedType interface {}
170
+ var counter int64
171
+ parsedType , rest , err = parseTypeWithName (unescapedSelector [1 :], counter )
172
+ if err != nil {
173
+ return nil , "" , fmt .Errorf ("failed to parse type: %v" , err )
174
+ }
175
+ result = []interface {}{parsedType }
176
+
177
+ for len (rest ) > 0 && rest [0 ] != ')' {
178
+ counter += 1
179
+ parsedType , rest , err = parseTypeWithName (rest [1 :], counter )
180
+ if err != nil {
181
+ return nil , "" , fmt .Errorf ("failed to parse type: %v" , err )
182
+ }
183
+ result = append (result , parsedType )
184
+ }
185
+ if len (rest ) == 0 || rest [0 ] != ')' {
186
+ return nil , "" , fmt .Errorf ("expected ')', got '%s'" , rest )
187
+ }
188
+ if len (rest ) >= 3 && rest [1 ] == '[' && rest [2 ] == ']' {
189
+ return append (result , "[]" ), rest [3 :], nil
190
+ }
191
+ return result , rest [1 :], nil
192
+ }
193
+
98
194
func parseType (unescapedSelector string ) (interface {}, string , error ) {
195
+ parts := strings .Split (unescapedSelector , " " )
196
+ if len (parts ) > 1 {
197
+ unescapedSelector = unescapedSelector [len (parts [0 ])+ 1 :]
198
+ }
99
199
if len (unescapedSelector ) == 0 {
100
200
return nil , "" , errors .New ("empty type" )
101
201
}
@@ -106,22 +206,48 @@ func parseType(unescapedSelector string) (interface{}, string, error) {
106
206
}
107
207
}
108
208
209
+ func parseTypeWithName (unescapedSelector string , counter int64 ) (interface {}, string , error ) {
210
+ name , rest , _ := parseIdentifier (unescapedSelector )
211
+ if len (rest ) > 0 && rest [0 ] == ' ' {
212
+ unescapedSelector = unescapedSelector [len (name )+ 1 :]
213
+ } else {
214
+ name = fmt .Sprintf ("name%d" , counter )
215
+ }
216
+ if len (unescapedSelector ) == 0 {
217
+ return nil , "" , errors .New ("empty type" )
218
+ }
219
+ if unescapedSelector [0 ] == '(' {
220
+ return parseCompositeTypeWithName (fmt .Sprintf ("%v %v" , name , unescapedSelector ))
221
+ } else {
222
+ return parseElementaryTypeWithName (fmt .Sprintf ("%v %v" , name , unescapedSelector ))
223
+ }
224
+ }
225
+
109
226
func assembleArgs (args []interface {}) (arguments []ArgumentMarshaling , err error ) {
110
227
arguments = make ([]ArgumentMarshaling , 0 )
111
- for i , arg := range args {
112
- // generate dummy name to avoid unmarshal issues
113
- name := fmt .Sprintf ("name%d" , i )
228
+ for _ , arg := range args {
229
+ var name string
114
230
if s , ok := arg .(string ); ok {
231
+ if s == "[]" {
232
+ arguments = append (arguments , ArgumentMarshaling {Name : name , Type : s , InternalType : s })
233
+ continue
234
+ }
115
235
parts := strings .Split (s , " " )
116
- if len (parts ) > 2 {
117
- return nil , fmt .Errorf ("more than 2 spaces in type declaration in selector %s" , s )
118
- } else if len ( parts ) == 2 {
236
+ if len (parts ) < 2 {
237
+ return nil , fmt .Errorf ("no name in arg %s" , s )
238
+ } else {
119
239
name = parts [0 ]
120
- s = parts [ 1 ]
240
+ s = s [ len ( name ) + 1 : ]
121
241
}
122
242
arguments = append (arguments , ArgumentMarshaling {Name : name , Type : s , InternalType : s })
123
243
} else if components , ok := arg .([]interface {}); ok {
124
244
var subArgs []ArgumentMarshaling
245
+ if len (components ) < 2 {
246
+ return nil , fmt .Errorf ("no name in components %s" , components )
247
+ } else {
248
+ name = components [0 ].(string )
249
+ components = components [1 :]
250
+ }
125
251
subArgs , err = assembleArgs (components )
126
252
if err != nil {
127
253
return nil , fmt .Errorf ("failed to assemble components: %v" , err )
@@ -153,7 +279,7 @@ func ParseSelector(unescapedSelector string) (m SelectorMarshaling, err error) {
153
279
if len (rest ) >= 2 && rest [0 ] == '(' && rest [1 ] == ')' {
154
280
rest = rest [2 :]
155
281
} else {
156
- args , rest , err = parseCompositeType (rest )
282
+ args , rest , err = parseFunctionsArgs (rest )
157
283
if err != nil {
158
284
return SelectorMarshaling {}, fmt .Errorf ("failed to parse selector '%s': %v" , unescapedSelector , err )
159
285
}
0 commit comments