All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlinx.jupyter.libraries.LibraryResolutionInfoParser.kt Maven / Gradle / Ivy

Go to download

Implementation of REPL compiler and preprocessor for Jupyter dialect of Kotlin (IDE-compatible)

There is a newer version: 0.12.0-250
Show newest version
package org.jetbrains.kotlinx.jupyter.libraries

import org.jetbrains.kotlinx.jupyter.api.libraries.LibraryResolutionInfo
import org.jetbrains.kotlinx.jupyter.api.libraries.Variable
import org.jetbrains.kotlinx.jupyter.exceptions.ReplLibraryLoadingException
import kotlin.script.experimental.api.ResultWithDiagnostics
import kotlin.script.experimental.api.asSuccess

abstract class LibraryResolutionInfoParser(val name: String, private val parameters: List) {
    fun getInfo(args: List): LibraryResolutionInfo {
        val map = when (val mapResult = substituteArguments(parameters, args)) {
            is ResultWithDiagnostics.Success -> mapResult.value
            is ResultWithDiagnostics.Failure -> throw ReplLibraryLoadingException(name, mapResult.reports.firstOrNull()?.message)
        }

        return getInfo(map)
    }

    abstract fun getInfo(args: Map): LibraryResolutionInfo

    companion object {
        fun make(name: String, parameters: List, getInfo: (Map) -> LibraryResolutionInfo): LibraryResolutionInfoParser {
            return object : LibraryResolutionInfoParser(name, parameters) {
                override fun getInfo(args: Map): LibraryResolutionInfo = getInfo(args)
            }
        }

        private fun substituteArguments(parameters: List, arguments: List): ResultWithDiagnostics> {
            val result = mutableMapOf()
            val possibleParamsNames = parameters.map { it.name }.toHashSet()

            var argIndex = 0

            for (arg in arguments) {
                val param = parameters.getOrNull(argIndex)
                    ?: return diagFailure("Too many arguments for library resolution info: ${arguments.size} got, ${parameters.size} allowed")
                if (arg.name.isNotEmpty()) break

                result[param.name] = arg.value
                argIndex++
            }

            for (i in argIndex until arguments.size) {
                val arg = arguments[i]
                if (arg.name.isEmpty()) return diagFailure("Positional arguments in library resolution info shouldn't appear after keyword ones")
                if (arg.name !in possibleParamsNames) return diagFailure("There is no such argument: ${arg.name}")

                result[arg.name] = arg.value
            }

            parameters.forEach {
                if (!result.containsKey(it.name)) {
                    if (it is Parameter.Optional) result[it.name] = it.default
                    else return diagFailure("Parameter ${it.name} is required, but was not specified")
                }
            }

            return result.asSuccess()
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy