Skip to content

Commit 0cd4964

Browse files
committed
fix: couldn't chain multiple methods
1 parent b5bf2ac commit 0cd4964

File tree

4 files changed

+51
-30
lines changed

4 files changed

+51
-30
lines changed

autoload/vimlparser.vim

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4028,44 +4028,26 @@ function! s:ExprParser.parse_expr8() abort
40284028
endif
40294029
unlet node
40304030
elseif token.type ==# s:TOKEN_ARROW
4031+
let funcname_or_lambda = self.parse_expr9()
4032+
let token = self.tokenizer.get()
4033+
if token.type !=# s:TOKEN_POPEN
4034+
throw s:Err('E107: Missing parentheses: lambda', token.pos)
4035+
endif
4036+
let right = s:Node(s:NODE_CALL)
4037+
let right.pos = token.pos
4038+
let right.left = funcname_or_lambda
4039+
let right.rlist = self.parse_rlist()
40314040
let node = s:Node(s:NODE_METHOD)
40324041
let node.pos = token.pos
40334042
let node.left = left
4034-
let node.right = self.parse_expr8()
4035-
let node.lambda_rlist = s:NIL
4036-
if node.right.type !=# s:NODE_CALL
4037-
throw s:Err('Rhs of method operator must be an function call', node.right.pos)
4038-
endif
4043+
let node.right = right
40394044
let left = node
40404045
unlet node
40414046
elseif token.type ==# s:TOKEN_POPEN
40424047
let node = s:Node(s:NODE_CALL)
40434048
let node.pos = token.pos
40444049
let node.left = left
4045-
let node.rlist = []
4046-
if self.tokenizer.peek().type ==# s:TOKEN_PCLOSE
4047-
call self.tokenizer.get()
4048-
else
4049-
while s:TRUE
4050-
call add(node.rlist, self.parse_expr1())
4051-
let token = self.tokenizer.get()
4052-
if token.type ==# s:TOKEN_COMMA
4053-
" XXX: Vim allows foo(a, b, ). Lint should warn it.
4054-
if self.tokenizer.peek().type ==# s:TOKEN_PCLOSE
4055-
call self.tokenizer.get()
4056-
break
4057-
endif
4058-
elseif token.type ==# s:TOKEN_PCLOSE
4059-
break
4060-
else
4061-
throw s:Err(printf('unexpected token: %s', token.value), token.pos)
4062-
endif
4063-
endwhile
4064-
endif
4065-
if len(node.rlist) > s:MAX_FUNC_ARGS
4066-
" TODO: funcname E740: Too many arguments for function: %s
4067-
throw s:Err('E740: Too many arguments for function', node.pos)
4068-
endif
4050+
let node.rlist = self.parse_rlist()
40694051
let left = node
40704052
unlet node
40714053
elseif !s:iswhite(c) && token.type ==# s:TOKEN_DOT " TODO check scriptversion?
@@ -4084,6 +4066,35 @@ function! s:ExprParser.parse_expr8() abort
40844066
return left
40854067
endfunction
40864068

4069+
function! s:ExprParser.parse_rlist() abort
4070+
let rlist = []
4071+
let token = self.tokenizer.peek()
4072+
if self.tokenizer.peek().type ==# s:TOKEN_PCLOSE
4073+
call self.tokenizer.get()
4074+
else
4075+
while s:TRUE
4076+
call add(rlist, self.parse_expr1())
4077+
let token = self.tokenizer.get()
4078+
if token.type ==# s:TOKEN_COMMA
4079+
" XXX: Vim allows foo(a, b, ). Lint should warn it.
4080+
if self.tokenizer.peek().type ==# s:TOKEN_PCLOSE
4081+
call self.tokenizer.get()
4082+
break
4083+
endif
4084+
elseif token.type ==# s:TOKEN_PCLOSE
4085+
break
4086+
else
4087+
throw s:Err(printf('unexpected token: %s', token.value), token.pos)
4088+
endif
4089+
endwhile
4090+
endif
4091+
if len(rlist) > s:MAX_FUNC_ARGS
4092+
" TODO: funcname E740: Too many arguments for function: %s
4093+
throw s:Err('E740: Too many arguments for function', token.pos)
4094+
endif
4095+
return rlist
4096+
endfunction
4097+
40874098
" expr9: number
40884099
" "string"
40894100
" 'string'

test/test_err_toomanyarg.ok

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
vimlparser: E740: Too many arguments for function: line 1 col 9
1+
vimlparser: E740: Too many arguments for function: line 1 col 83

test/test_method.ok

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,8 @@
44
(echo (method 'john' ((lambda (s) (concat 'hello ' s)))))
55
(echo (method 'john' ((lambda (s b) (concat (concat (concat (concat 'hello ' s) ' ... and goodbye ') b) '!')) 'bob')))
66
(echo (method 'john' ((lambda (...) (concat 'hello ' (method a:000 (join ', ')))) 'bob')))
7+
(eval (method funcs (map (lambda () (v:val)))))
8+
(let = session (method (method (s:get_sessions) (filter (lambda () (==# (dot v:val name) session_name)))) (get 0 (dict))))
9+
(let = session (method (method (s:get_sessions) (filter (lambda () (==# (dot v:val name) session_name)))) (get 0 (dict))))
10+
(echo (method expr8 (s:flatmap)))
11+
(echo (method (method expr8 (s:flatmap)) (filter (lambda (i) (% i 2)))))

test/test_method.vim

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,8 @@ echo [1,2,3]->map({i,n -> n * 2})
44
echo 'john'->{s -> 'hello ' .. s }()
55
echo 'john'->{s,b -> 'hello ' .. s .. ' ... and goodbye ' .. b .. '!' }('bob')
66
echo 'john'->{... -> 'hello ' .. a:000->join(', ') }('bob')
7+
eval funcs->map({-> v:val() })
8+
let session = s:get_sessions()->filter({-> v:val.name ==# session_name })->get(0, {})
9+
let session = (s:get_sessions()->filter({-> v:val.name ==# session_name }))->get(0, {})
10+
echo expr8->s:flatmap()
11+
echo expr8->s:flatmap()->filter({i -> i % 2})

0 commit comments

Comments
 (0)