CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-kotlin--kotlin-scripting-common

Core interfaces and data structures for Kotlin script compilation, evaluation, and IDE integration

Pending
Overview
Eval results
Files

type-system.mddocs/

Type System Integration

Type representation and handling for Kotlin types within the scripting system. Provides utilities for working with Kotlin type information in a scripting context, including type creation, nullability handling, and type conversions.

Capabilities

KotlinType Class

Primary class for representing Kotlin types with support for nullability and class-based type creation.

/**
 * Represents a Kotlin type within the scripting system
 */
class KotlinType private constructor(
    /** String representation of the type name */
    val typeName: String,
    /** Source KClass if created from a class (marked as @Transient) */
    @Transient val fromClass: KClass<*>?,
    /** Whether this type is nullable */
    val isNullable: Boolean
) : Serializable {
    /**
     * Constructs KotlinType from fully-qualified type name
     * @param qualifiedTypeName Dot-separated type name (e.g. "org.acme.Outer.Inner")  
     * @param isNullable Whether the type should be nullable
     */
    @JvmOverloads
    constructor(qualifiedTypeName: String, isNullable: Boolean = false) :
        this(qualifiedTypeName.removeSuffix("?"), null, isNullable = isNullable || qualifiedTypeName.endsWith('?'))
    
    /**
     * Constructs KotlinType from reflected KClass
     * @param kclass The Kotlin class to create type from
     * @param isNullable Whether the type should be nullable
     */
    @JvmOverloads
    constructor(kclass: KClass<*>, isNullable: Boolean = false) :
        this(kclass.qualifiedName ?: error("Cannot use class $kclass as a KotlinType"), kclass, isNullable)
    
    /**
     * Constructs KotlinType from reflected KType
     * @param type The Kotlin type to convert
     */
    constructor(type: KType) : this(type.classifier as KClass<*>, type.isMarkedNullable)
    
    /**
     * Create a new KotlinType with different nullability
     * @param isNullable Whether the new type should be nullable
     * @return New KotlinType with specified nullability
     */
    fun withNullability(isNullable: Boolean): KotlinType
    
    override fun toString(): String
    override fun equals(other: Any?): Boolean
    override fun hashCode(): Int
}

Type Creation Utilities

Convenient functions and extensions for creating KotlinType instances.

/**
 * Create KotlinType from reified type parameter
 */
inline fun <reified T> kotlinType(isNullable: Boolean = false): KotlinType {
    return KotlinType.from(T::class, isNullable)
}

/**
 * Extension function to convert KClass to KotlinType
 */
fun KClass<*>.toKotlinType(isNullable: Boolean = false): KotlinType {
    return KotlinType.from(this, isNullable)
}

/**
 * Extension function to convert KType to KotlinType
 */
fun KType.toKotlinType(): KotlinType {
    return KotlinType.from(this)
}

Usage Examples:

import kotlin.script.experimental.api.*
import kotlin.reflect.full.*

// Create types from classes
val stringType = KotlinType(String::class)
val nullableStringType = KotlinType(String::class, isNullable = true)
val intType = KotlinType(Int::class)
val listType = KotlinType(List::class)

// Create types from type names
val stringTypeFromName = KotlinType("kotlin.String")
val nullableIntFromName = KotlinType("kotlin.Int", isNullable = true)

// Create types from KType
val functionType = KotlinType(typeOf<(String) -> Int>())
val suspendFunctionType = KotlinType(typeOf<suspend (String) -> Int>())

// Work with nullability
val originalType = KotlinType(String::class, isNullable = false)
val nullableVersion = originalType.withNullability(true)
val nonNullableVersion = nullableVersion.withNullability(false)

println("Original: $originalType")           // String
println("Nullable: $nullableVersion")        // String?
println("Non-nullable: $nonNullableVersion") // String

// Check properties
println("Is nullable: ${nullableVersion.isNullable}")     // true
println("Type name: ${originalType.typeName}")           // kotlin.String
println("From class: ${originalType.fromClass}")         // class kotlin.String

Type Usage in Script Configuration

// Using KotlinType in script compilation configuration
val compilationConfig = ScriptCompilationConfiguration {
    // Set base class for scripts
    baseClass(KotlinType(Any::class))
    
    // Add implicit receivers
    implicitReceivers(
        KotlinType(File::class),
        KotlinType(Properties::class)
    )
    
    // Provide properties with specific types
    providedProperties(mapOf(
        "logger" to KotlinType(Logger::class),
        "config" to KotlinType(Configuration::class),
        "args" to KotlinType(Array<String>::class),
        "optionalValue" to KotlinType(String::class, isNullable = true)
    ))
    
    // Add dependencies with type information
    dependencies.append(JvmDependency("org.slf4j:slf4j-api:1.7.36"))
}

// Using KotlinType in script evaluation configuration
val evaluationConfig = ScriptEvaluationConfiguration {
    // Provide implicit receivers as actual objects
    implicitReceivers(
        File(System.getProperty("user.dir")),
        System.getProperties()
    )
    
    // Context variables with type safety
    contextVariables(mapOf(
        "database" to getDatabaseConnection(),  // Type inferred
        "timeout" to Duration.ofSeconds(30)     // Type inferred
    ))
}

Advanced Type Operations

// Complex type creation and manipulation
class TypeManager {
    private val typeCache = mutableMapOf<String, KotlinType>()
    
    fun getOrCreateType(className: String, isNullable: Boolean = false): KotlinType? {
        val cacheKey = "$className:$isNullable"
        return typeCache.getOrPut(cacheKey) {
            try {
                val kClass = Class.forName(className).kotlin
                KotlinType.from(kClass, isNullable)
            } catch (e: ClassNotFoundException) {
                return null
            }
        }
    }
    
    fun createGenericType(baseClassName: String, typeArguments: List<KotlinType>): KotlinType? {
        // This would require more complex type construction
        // For demonstration purposes, simplified
        return getOrCreateType(baseClassName)
    }
}

// Using type manager
val typeManager = TypeManager()
val stringType = typeManager.getOrCreateType("kotlin.String")
val nullableIntType = typeManager.getOrCreateType("kotlin.Int", isNullable = true)

Type Validation and Conversion

// Type validation utilities
object TypeValidator {
    fun isAssignableFrom(target: KotlinType, source: KotlinType): Boolean {
        // Simplified validation logic
        if (target.typeName == source.typeName) {
            return !target.isNullable || source.isNullable
        }
        
        // Check if source can be assigned to target
        val targetClass = target.fromClass
        val sourceClass = source.fromClass
        
        return if (targetClass != null && sourceClass != null) {
            targetClass.isInstance(sourceClass) || sourceClass.isSubclassOf(targetClass)
        } else {
            false
        }
    }
    
    fun canBeNull(type: KotlinType): Boolean = type.isNullable
    
    fun makeNullable(type: KotlinType): KotlinType = type.withNullability(true)
    fun makeNonNull(type: KotlinType): KotlinType = type.withNullability(false)
}

// Type conversion utilities
object TypeConverter {
    fun convertValue(value: Any?, targetType: KotlinType): Any? {
        if (value == null) {
            return if (targetType.isNullable) null 
                   else throw IllegalArgumentException("Cannot assign null to non-nullable type")
        }
        
        // Simplified conversion logic
        return when (targetType.typeName) {
            "kotlin.String" -> value.toString()
            "kotlin.Int" -> when (value) {
                is Number -> value.toInt()
                is String -> value.toIntOrNull()
                else -> null
            }
            "kotlin.Boolean" -> when (value) {
                is Boolean -> value
                is String -> value.toBooleanStrictOrNull()
                else -> null
            }
            else -> value
        }
    }
}

Collection Type Handling

// Working with collection types
fun createCollectionTypes(): Map<String, KotlinType> {
    return mapOf(
        "stringList" to kotlinType<List<String>>(),
        "nullableStringList" to kotlinType<List<String?>>(),
        "stringToIntMap" to kotlinType<Map<String, Int>>(),
        "mutableIntSet" to kotlinType<MutableSet<Int>>(),
        "arrayOfStrings" to kotlinType<Array<String>>(),
        "intArray" to kotlinType<IntArray>()
    )
}

// Function type handling
fun createFunctionTypes(): Map<String, KotlinType> {
    return mapOf(
        "stringTransform" to typeOf<(String) -> String>().toKotlinType(),
        "suspendStringTransform" to typeOf<suspend (String) -> String>().toKotlinType(),
        "predicate" to typeOf<(String) -> Boolean>().toKotlinType(),
        "callback" to typeOf<(Result<String>) -> Unit>().toKotlinType(),
        "supplier" to typeOf<() -> String>().toKotlinType()
    )
}

// Using collection and function types in configuration
val advancedConfig = ScriptCompilationConfiguration {
    providedProperties(mapOf(
        "items" to kotlinType<List<String>>(),
        "processor" to typeOf<(String) -> String>().toKotlinType(),
        "validator" to typeOf<(String) -> Boolean>().toKotlinType(),
        "results" to kotlinType<MutableMap<String, Any?>>(),
        "callback" to typeOf<suspend (Result<Any>) -> Unit>().toKotlinType()
    ))
}

Integration with Reflection

// Type reflection utilities
object TypeReflectionUtils {
    fun getTypeInfo(type: KotlinType): TypeInfo {
        val kClass = type.fromClass
        return TypeInfo(
            typeName = type.typeName,
            isNullable = type.isNullable,
            isInterface = kClass?.isData == true,
            isData = kClass?.isData == true,
            isSealed = kClass?.isSealed == true,
            constructors = kClass?.constructors?.size ?: 0,
            properties = kClass?.memberProperties?.size ?: 0,
            functions = kClass?.memberFunctions?.size ?: 0
        )
    }
    
    fun validateTypeUsage(type: KotlinType, value: Any?): ValidationResult {
        if (value == null) {
            return if (type.isNullable) {
                ValidationResult.Success
            } else {
                ValidationResult.Error("Null value for non-nullable type ${type.typeName}")
            }
        }
        
        val valueClass = value::class
        val targetClass = type.fromClass
        
        return if (targetClass != null && targetClass.isInstance(value)) {
            ValidationResult.Success
        } else {
            ValidationResult.Error("Value of type ${valueClass.simpleName} cannot be assigned to ${type.typeName}")
        }
    }
}

data class TypeInfo(
    val typeName: String,
    val isNullable: Boolean,
    val isInterface: Boolean,
    val isData: Boolean,
    val isSealed: Boolean,
    val constructors: Int,
    val properties: Int,
    val functions: Int
)

sealed class ValidationResult {
    object Success : ValidationResult()
    data class Error(val message: String) : ValidationResult()
}

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-kotlin--kotlin-scripting-common

docs

error-handling.md

host-integration.md

index.md

repl-system.md

script-annotations.md

script-compilation.md

script-evaluation.md

source-code.md

type-system.md

tile.json