in vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/parser/visitors/ExecutableVisitor.kt [92:137]
override fun visitFunctionDefinition(ctx: VimscriptParser.FunctionDefinitionContext): Executable {
val functionScope = if (ctx.functionScope() != null) Scope.getByValue(ctx.functionScope().text) else null
val args = ctx.argumentsDeclaration().variableName().map { it.text }
val defaultArgs = ctx.argumentsDeclaration().defaultValue()
.map { Pair<String, Expression>(it.variableName().text, ExpressionVisitor.visit(it.expr())) }
val body = ctx.blockMember().mapNotNull { visitBlockMember(it) }
val replaceExisting = ctx.replace != null
val flags = mutableSetOf<FunctionFlag?>()
val hasOptionalArguments = ctx.argumentsDeclaration().ETC() != null
for (flag in ctx.functionFlag()) {
flags.add(FunctionFlag.getByName(flag.text))
}
val definition = if (ctx.functionName() != null) {
val functionName = ctx.functionName().text
FunctionDeclaration(
functionScope,
functionName,
args,
defaultArgs,
body,
replaceExisting,
flags.filterNotNull().toSet(),
hasOptionalArguments
)
} else {
var sublistExpression = IndexedExpression(
SimpleExpression(ctx.literalDictionaryKey(1).text),
VariableExpression(functionScope, ctx.literalDictionaryKey(0).text)
)
for (i in 2 until ctx.literalDictionaryKey().size) {
sublistExpression =
IndexedExpression(SimpleExpression(ctx.literalDictionaryKey(i).text), sublistExpression)
}
AnonymousFunctionDeclaration(
sublistExpression,
args,
defaultArgs,
body,
replaceExisting,
flags.filterNotNull().toSet(),
hasOptionalArguments
)
}
definition.rangeInScript = ctx.getTextRange()
return definition
}