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-290
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