@@ -27,6 +27,9 @@ let s:regexs = {
27
27
\ ' class' : ' ^class\s\|^\s*class\s' ,
28
28
\ ' async' : ' ^async\s*def\s\|^\s*async\sdef\s' ,
29
29
\ ' typed_args' : ' \([0-9A-Za-z_.]\+:[0-9A-Za-z_.]\+\|[0-9A-Za-z_.]\+\)\(,\|$\)' ,
30
+ \ ' typed_bracket' : ' \(\w\+\s*:\s*\w\+\[.*\],\|\w\+\s*:\s*\w\+\[.*\]\)' ,
31
+ \ ' typed_primitive' : ' \(\w\+:\s*\w\+,\|\w\+:\s*\w\+\)' ,
32
+ \ ' none_typed' : ' \w\+,' ,
30
33
\ }
31
34
32
35
function ! s: readtmpl (type )
@@ -58,93 +61,95 @@ function! s:compare(lhs, rhs)
58
61
endfunction
59
62
60
63
function ! s: parse_args (args_str)
61
- let primitive_pos = 0
62
- let nested = 0
63
- let start_pos = 0
64
- let end_pos = 0
64
+ " FIXME Very very work around.
65
+ " If Python2 is dead, consider to use Python interface
66
+ let args_str = copy (a: args_str )
65
67
let args = []
66
- let primitives = []
68
+ let pos = len (args_str)
67
69
68
- " Extract none typed arguments or primitive arguments first.
70
+ " If last argument is none-typed or bracket typed(e.g. List[int]),
71
+ " Add to args first.
69
72
while 1
70
- let primitives = matchstrpos (a: args_str , s: regexs [' typed_args' ], primitive_pos)
71
- if primitives[1 ] == -1
73
+ let comma_idx = strridx (args_str, ' ,' , pos)
74
+ if comma_idx == -1
75
+ " No multipul args left.
72
76
break
73
- endif
74
-
75
- if match (primitives[0 ], ' [0-9A-Za-z_.]\+:[0-9A-Za-z_.]\+' ) == -1
76
- let separator_pos = strridx (a: args_str , ' :' , primitives[1 ])
77
- if a: args_str [primitives[1 ] - 1 : primitives[1 ] - 1 ] == ' ['
78
- " If `[` exist right before argument, current argument is inner of
79
- " braket. So this argument is not standalone argument.
80
- let primitive_pos = primitives[2 ]
81
- continue
82
- endif
83
- let braket_start_pos = stridx (a: args_str , ' [' , separator_pos)
84
- let next_separator_pos = stridx (a: args_str , ' :' , primitives[2 ])
85
- let braket_end_pos = strridx (a: args_str , ' ]' , next_separator_pos)
86
- if next_separator_pos == -1
87
- if braket_start_pos == -1 && braket_end_pos == -1
88
- \ && a: args_str [primitives[1 ] : ] == primitives[0 ]
89
- " Current argument is last argument.
90
- else
91
- " Arguments are still remains.
92
- let primitive_pos = primitives[2 ]
93
- continue
77
+ end
78
+ let idx = stridx (args_str, ' :' , comma_idx)
79
+ if idx == -1
80
+ let last_arg = args_str[comma_idx + 1 :]
81
+ if last_arg = ~ ' ]'
82
+ let sep_pos = strridx (args_str, ' :' , pos)
83
+ let comma_idx = strridx (args_str, ' ,' , sep_pos)
84
+ if comma_idx == -1
85
+ " One argument left
86
+ break
94
87
endif
95
- endif
88
+ " Last argument is typed and have `[]`.
89
+ let last_arg = args_str[comma_idx + 1 :]
90
+ let last_arg = substitute (last_arg, ' ,\s*$' , ' ' , ' ' )
96
91
97
- if braket_start_pos < primitives[1 ] && primitives[1 ] < braket_end_pos
98
- " Current argument is inner of braket,
99
- " such as `List[str, str, str]`'s second `str`.
100
- let primitive_pos = primitives[2 ]
101
- continue
92
+ call add (args , {' val' : last_arg, ' start' : comma_idx})
93
+ let args_str = args_str[ : comma_idx]
94
+
95
+ break
96
+ else
97
+ " Last argument is not none-typed.
98
+ let last_arg = substitute (last_arg, ' ,\s*$' , ' ' , ' ' )
99
+ call add (args , {' val' : last_arg, ' start' : comma_idx})
100
+ let arg_length = len (last_arg)
101
+ let args_str = args_str[ : comma_idx]
102
102
endif
103
+ let pos = comma_idx - 1
104
+ else
105
+ break
103
106
endif
104
-
105
- " `[: -1] trims `,`.
106
- let arg = primitives[0 ][: -1 ]
107
- let arg = substitute (arg, ' ,$' , ' ' , ' ' )
108
-
109
- call add (args , {' val' : arg, ' start' : primitives[1 ]})
110
- " Move current position.
111
- let primitive_pos = primitives[2 ]
112
107
endwhile
113
108
114
- " Parse nested typed args.
115
109
while 1
116
- let start_idx = match (a: args_str , ' \[' , start_pos)
117
- let end_idx = match (a: args_str , ' \]' , end_pos)
110
+ " " Parse like `arg: List[str]`
111
+ let bracket_match = match (args_str, s: regexs [' typed_bracket' ])
112
+ if bracket_match != -1
113
+ let ret = matchstrpos (args_str, s: regexs [' typed_bracket' ])
114
+ let arg_length = len (ret [0 ])
115
+ let pos = printf (' @%s%s,' , ret [1 ], repeat (' ' , arg_length - len (arg_length) - 1 ))
116
+
117
+ let args_str = substitute (args_str, s: regexs [' typed_bracket' ], pos, ' ' )
118
+ let arg = substitute (ret [0 ], ' ,$' , ' ' , ' ' )
119
+ call add (args , {' val' : arg, ' start' : ret [1 ]})
120
+ endif
118
121
119
- if start_idx == -1 && end_idx == -1
120
- break
122
+ " Parse like `arg1: str`
123
+ let primitive_match = match (args_str, s: regexs [' typed_primitive' ])
124
+ if primitive_match != -1
125
+ let ret = matchstrpos (args_str, s: regexs [' typed_primitive' ])
126
+ let arg_length = len (ret [0 ])
127
+ let pos = printf (' @%s%s,' , ret [1 ], repeat (' ' , arg_length - len (arg_length) - 2 ))
128
+ let args_str = substitute (args_str, s: regexs [' typed_primitive' ], pos, ' ' )
129
+ let arg = substitute (ret [0 ], ' ,$' , ' ' , ' ' )
130
+ call add (args , {' val' : arg, ' start' : ret [1 ]})
121
131
endif
122
132
123
- if end_pos > start_idx
124
- " For nested. e.g. `arg: List[List[List[int, int], List[List[int, int]]]`.
125
- let idx = strridx (a: args_str , ' ,' , nested)
126
- if idx == -1
127
- let idx = strridx (a: args_str , ' (' , nested)
128
- endif
129
- let arg = a: args_str [idx + 1 : end_idx]
130
- " Override previous arg by complete one.
131
- let args [-1 ] = {' val' : arg, ' start' : idx + 1 }
132
- else
133
- let idx = strridx (a: args_str , ' ,' , start_idx)
134
- if idx == -1
135
- let idx = strridx (a: args_str , ' (' , start_idx)
133
+ " Parse like `arg`
134
+ let none_typed_match = match (args_str, s: regexs [' none_typed' ])
135
+ if none_typed_match != -1
136
+ if match (args_str, ' [A-Za-z]' ) == -1
137
+ break
136
138
endif
137
139
138
- let arg = a: args_str [idx + 1 : end_idx]
139
- call add (args , {' val' : arg, ' start' : idx + 1 })
140
- let nested = start_idx
140
+ let ret = matchstrpos (args_str, s: regexs [' none_typed' ])
141
+ let arg_length = len (ret [0 ])
142
+ let pos = printf (' @%s%s,' , ret [1 ], repeat (' ' , arg_length - len (arg_length) - 1 ))
143
+ let args_str = substitute (args_str, s: regexs [' none_typed' ], pos, ' ' )
144
+ let arg = substitute (ret [0 ], ' ,$' , ' ' , ' ' )
145
+ call add (args , {' val' : arg, ' start' : ret [1 ]})
141
146
endif
142
147
143
- let start_pos = start_idx + 1
144
- let end_pos = end_idx + 1
148
+ if bracket_match == -1 && primitive_match == -1 && none_typed_match == -1
149
+ break
150
+ endif
145
151
endwhile
146
152
147
- " Sort by argument start position.
148
153
call sort (args , ' s:compare' )
149
154
return map (args , {i , v - > substitute (v [' val' ], ' ,' , ' , ' , ' g' )})
150
155
endfunction
0 commit comments