1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-04-09 17:15:50 +02:00

Function as method call

This commit is contained in:
lippfi 2021-10-01 03:21:34 +03:00
parent 806184aa5d
commit 97502a5bd5
4 changed files with 92 additions and 6 deletions
src
com/maddyhome/idea/vim/vimscript/parser/visitors
main/antlr
test/org/jetbrains/plugins/ideavim/ex/implementation/expressions
vimscript-info

View File

@ -10,6 +10,8 @@ import com.maddyhome.idea.vim.vimscript.model.expressions.EnvVariableExpression
import com.maddyhome.idea.vim.vimscript.model.expressions.Expression
import com.maddyhome.idea.vim.vimscript.model.expressions.FalsyExpression
import com.maddyhome.idea.vim.vimscript.model.expressions.FunctionCallExpression
import com.maddyhome.idea.vim.vimscript.model.expressions.LambdaExpression
import com.maddyhome.idea.vim.vimscript.model.expressions.LambdaFunctionCallExpression
import com.maddyhome.idea.vim.vimscript.model.expressions.ListExpression
import com.maddyhome.idea.vim.vimscript.model.expressions.OneElementSublistExpression
import com.maddyhome.idea.vim.vimscript.model.expressions.OptionExpression
@ -187,6 +189,19 @@ object ExpressionVisitor : VimscriptBaseVisitor<Expression>() {
return TernaryExpression(condition, then, otherwise)
}
override fun visitFunctionAsMethodCall1(ctx: VimscriptParser.FunctionAsMethodCall1Context): FunctionCallExpression {
val functionCall = visitFunctionCall(ctx.functionCall())
functionCall.arguments.add(0, visit(ctx.expr()))
return functionCall
}
override fun visitFunctionAsMethodCall2(ctx: VimscriptParser.FunctionAsMethodCall2Context): LambdaFunctionCallExpression {
val lambda = visitLambda(ctx.lambda())
val arguments = mutableListOf(visit(ctx.expr()))
arguments.addAll(ctx.functionArguments().expr().mapNotNull { visit(it) })
return LambdaFunctionCallExpression(lambda, arguments)
}
override fun visitFunctionCallExpression(ctx: FunctionCallExpressionContext): Expression {
return visitFunctionCall(ctx.functionCall())
}

View File

@ -398,9 +398,6 @@ commandName:
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
expr: WS* EXCLAMATION WS* expr #UnaryExpression
| expr WS* ARROW functionName L_PAREN WS* functionArguments WS* R_PAREN #FunctionAsMethodCall1
| expr WS* ARROW lambda L_PAREN WS* functionArguments WS* R_PAREN #FunctionAsMethodCall2
| lambda #LambdaExpression
| expr L_BRACKET expr R_BRACKET #OneElementSublistExpression
| expr L_BRACKET WS* from = expr? WS* COLON WS* to = expr? WS* R_BRACKET #SublistExpression
| expr WS* binaryOperator1 WS* expr #BinExpression1
@ -409,11 +406,15 @@ expr: WS* EXCLAMATION WS* expr
| expr WS* binaryOperator4 WS* expr #BinExpression4
| expr WS* binaryOperator5 WS* expr #BinExpression5
| WS* unaryOperator = (PLUS | MINUS) WS* expr #UnaryExpression
| expr WS* ARROW WS* functionCall #FunctionAsMethodCall1
| expr WS* ARROW WS* lambda L_PAREN WS* functionArguments WS* R_PAREN #FunctionAsMethodCall2
| functionCall #FunctionCallExpression
| lambda L_PAREN WS* functionArguments WS* R_PAREN #LambdaFunctionCallExpression
| lambda #LambdaExpression
| unsignedInt #IntExpression
| unsignedFloat #FloatExpression
| string #StringExpression
| blob #BlobExpression
| functionCall #FunctionCallExpression
| variable #VariableExpression
| option #OptionExpression
| envVariable #EnvVariableExpression
@ -443,7 +444,7 @@ binaryOperator4: AMPERSAND AMPERSAND;
binaryOperator5: LOGICAL_OR;
register: AT (DIGIT | alphabeticChar | MINUS | COLON | DOT | MOD | NUM | ASSIGN | STAR | PLUS | TILDE | UNDERSCORE | DIV | AT);
lambda: L_CURLY WS* functionArguments WS* ARROW WS* expr WS* R_CURLY;
lambda: L_CURLY WS* argumentsDeclaration WS* ARROW WS* expr WS* R_CURLY;
variable: (variableScope COLON)? variableName;
variableName: anyCaseNameWithDigitsAndUnderscores | unsignedInt;

View File

@ -0,0 +1,70 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2021 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.jetbrains.plugins.ideavim.ex.implementation.expressions
import org.jetbrains.plugins.ideavim.VimTestCase
class FunctionCallTest : VimTestCase() {
fun `test function as method call`() {
configureByText("\n")
typeText(commandToKeys("echo -4->abs()"))
assertExOutput("4\n")
}
fun `test chained function as method call`() {
configureByText("\n")
typeText(
commandToKeys(
"""
function! Power2(number) |
return a:number * a:number |
endfunction |
echo -3->abs()->Power2()->Power2()
""".trimIndent()
)
)
assertExOutput("81\n")
typeText(commandToKeys("delfunction! Power2"))
}
fun `test function as method call with args`() {
configureByText("\n")
typeText(
commandToKeys(
"""
function! Subtraction(minuend, subtrahend) |
return a:minuend - a:subtrahend |
endfunction |
echo 52->Subtraction(10)
""".trimIndent()
)
)
assertExOutput("42\n")
typeText(commandToKeys("delfunction! Subtraction"))
}
fun `test function as method call with lambda`() {
configureByText("\n")
typeText(commandToKeys("echo 52->{x,y -> x-y}(10)"))
assertExOutput("42\n")
}
}

View File

@ -24,7 +24,7 @@
- [x] optional arguments `...`
- [x] funcref type
- [x] lambdas
- [ ] function as method
- [x] function as method
- [ ] `function` function
- [ ] `funcref` function
- [ ] dictionary functions