override fun visitFunctionDefinition()

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
  }