Add basic support for class references
Also use class name for `Any.toString` and `Throwable.toString`.
This commit is contained in:
committed by
GitHub
parent
a6ca64871f
commit
786374ef86
+2
-2
@@ -44,8 +44,8 @@ internal class KonanLower(val context: Context) {
|
|||||||
irModule.files.forEach(TestProcessor(context)::lower)
|
irModule.files.forEach(TestProcessor(context)::lower)
|
||||||
}
|
}
|
||||||
|
|
||||||
phaser.phase(KonanPhase.LOWER_SPECIAL_CALLS) {
|
phaser.phase(KonanPhase.LOWER_BEFORE_INLINE) {
|
||||||
irModule.files.forEach(SpecialCallsLowering(context)::lower)
|
irModule.files.forEach(PreInlineLowering(context)::lower)
|
||||||
}
|
}
|
||||||
|
|
||||||
phaser.phase(KonanPhase.LOWER_INLINE_CONSTRUCTORS) {
|
phaser.phase(KonanPhase.LOWER_INLINE_CONSTRUCTORS) {
|
||||||
|
|||||||
+3
-3
@@ -29,9 +29,9 @@ enum class KonanPhase(val description: String,
|
|||||||
/* */ BACKEND("All backend"),
|
/* */ BACKEND("All backend"),
|
||||||
/* ... */ LOWER("IR Lowering"),
|
/* ... */ LOWER("IR Lowering"),
|
||||||
/* ... ... */ TEST_PROCESSOR("Unit test processor"),
|
/* ... ... */ TEST_PROCESSOR("Unit test processor"),
|
||||||
/* ... ... */ LOWER_SPECIAL_CALLS("Special calls processing before inlining"),
|
/* ... ... */ LOWER_BEFORE_INLINE("Special operations processing before inlining"),
|
||||||
/* ... ... */ LOWER_INLINE_CONSTRUCTORS("Inline constructors transformation", LOWER_SPECIAL_CALLS),
|
/* ... ... */ LOWER_INLINE_CONSTRUCTORS("Inline constructors transformation", LOWER_BEFORE_INLINE),
|
||||||
/* ... ... */ LOWER_INLINE("Functions inlining", LOWER_INLINE_CONSTRUCTORS, LOWER_SPECIAL_CALLS),
|
/* ... ... */ LOWER_INLINE("Functions inlining", LOWER_INLINE_CONSTRUCTORS, LOWER_BEFORE_INLINE),
|
||||||
/* ... ... ... */ DESERIALIZER("Deserialize inline bodies"),
|
/* ... ... ... */ DESERIALIZER("Deserialize inline bodies"),
|
||||||
/* ... ... */ LOWER_INTEROP_PART1("Interop lowering, part 1", LOWER_INLINE),
|
/* ... ... */ LOWER_INTEROP_PART1("Interop lowering, part 1", LOWER_INLINE),
|
||||||
/* ... ... */ LOWER_FOR_LOOPS("For loops lowering"),
|
/* ... ... */ LOWER_FOR_LOOPS("For loops lowering"),
|
||||||
|
|||||||
+22
@@ -28,10 +28,15 @@ import org.jetbrains.kotlin.builtins.isFunctionType
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
|
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
|
import org.jetbrains.kotlin.ir.util.constructors
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
@@ -89,6 +94,12 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable): Sym
|
|||||||
it to symbolTable.referenceClass(context.getInternalClass("${it.classFqName.shortName()}Box"))
|
it to symbolTable.referenceClass(context.getInternalClass("${it.classFqName.shortName()}Box"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val valueClassToBox = ValueType.values().associate {
|
||||||
|
val valueClassId = ClassId.topLevel(it.classFqName.toSafe())
|
||||||
|
val valueClassDescriptor = context.builtIns.builtInsModule.findClassAcrossModuleDependencies(valueClassId)!!
|
||||||
|
valueClassDescriptor to boxClasses[it]!!
|
||||||
|
}
|
||||||
|
|
||||||
val unboxFunctions = ValueType.values().mapNotNull {
|
val unboxFunctions = ValueType.values().mapNotNull {
|
||||||
val unboxFunctionName = "unbox${it.classFqName.shortName()}"
|
val unboxFunctionName = "unbox${it.classFqName.shortName()}"
|
||||||
context.getInternalFunctions(unboxFunctionName).atMostOne()?.let { descriptor ->
|
context.getInternalFunctions(unboxFunctionName).atMostOne()?.let { descriptor ->
|
||||||
@@ -170,6 +181,17 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable): Sym
|
|||||||
val kLocalDelegatedPropertyImpl = symbolTable.referenceClass(context.reflectionTypes.kLocalDelegatedPropertyImpl)
|
val kLocalDelegatedPropertyImpl = symbolTable.referenceClass(context.reflectionTypes.kLocalDelegatedPropertyImpl)
|
||||||
val kLocalDelegatedMutablePropertyImpl = symbolTable.referenceClass(context.reflectionTypes.kLocalDelegatedMutablePropertyImpl)
|
val kLocalDelegatedMutablePropertyImpl = symbolTable.referenceClass(context.reflectionTypes.kLocalDelegatedMutablePropertyImpl)
|
||||||
|
|
||||||
|
val getClassTypeInfo = internalFunction("getClassTypeInfo")
|
||||||
|
val getObjectTypeInfo = internalFunction("getObjectTypeInfo")
|
||||||
|
val kClassImpl = internalClass("KClassImpl")
|
||||||
|
val kClassImplConstructor by lazy { kClassImpl.constructors.single() }
|
||||||
|
|
||||||
|
private fun internalFunction(name: String): IrSimpleFunctionSymbol =
|
||||||
|
symbolTable.referenceSimpleFunction(context.getInternalFunctions(name).single())
|
||||||
|
|
||||||
|
private fun internalClass(name: String): IrClassSymbol =
|
||||||
|
symbolTable.referenceClass(context.getInternalClass(name))
|
||||||
|
|
||||||
private fun getKonanTestClass(className: String) = symbolTable.referenceClass(
|
private fun getKonanTestClass(className: String) = symbolTable.referenceClass(
|
||||||
builtInsPackage("konan", "test").getContributedClassifier(
|
builtInsPackage("konan", "test").getContributedClassifier(
|
||||||
Name.identifier(className), NoLookupLocation.FROM_BACKEND
|
Name.identifier(className), NoLookupLocation.FROM_BACKEND
|
||||||
|
|||||||
+17
-2
@@ -1386,8 +1386,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
private fun evaluateStringConst(value: IrConst<String>) =
|
private fun evaluateStringConst(value: IrConst<String>) =
|
||||||
context.llvm.staticData.kotlinStringLiteral(
|
context.llvm.staticData.kotlinStringLiteral(value.value).llvm
|
||||||
context.builtIns.stringType, value).llvm
|
|
||||||
|
|
||||||
private fun evaluateConst(value: IrConst<*>): LLVMValueRef {
|
private fun evaluateConst(value: IrConst<*>): LLVMValueRef {
|
||||||
context.log{"evaluateConst : ${ir2string(value)}"}
|
context.log{"evaluateConst : ${ir2string(value)}"}
|
||||||
@@ -2007,6 +2006,22 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
interop.readBits -> genReadBits(args)
|
interop.readBits -> genReadBits(args)
|
||||||
interop.writeBits -> genWriteBits(args)
|
interop.writeBits -> genWriteBits(args)
|
||||||
|
|
||||||
|
context.ir.symbols.getClassTypeInfo.descriptor -> {
|
||||||
|
val typeArgument = callee.getTypeArgumentOrDefault(descriptor.typeParameters.single())
|
||||||
|
val typeArgumentClass = TypeUtils.getClassDescriptor(typeArgument)
|
||||||
|
if (typeArgumentClass == null) {
|
||||||
|
// E.g. for `T::class` in a body of an inline function itself.
|
||||||
|
functionGenerationContext.unreachable()
|
||||||
|
kNullInt8Ptr
|
||||||
|
} else {
|
||||||
|
val classDescriptor = context.ir.symbols.valueClassToBox[typeArgumentClass]?.descriptor
|
||||||
|
?: typeArgumentClass
|
||||||
|
|
||||||
|
val typeInfo = codegen.typeInfoValue(classDescriptor)
|
||||||
|
LLVMConstBitCast(typeInfo, kInt8Ptr)!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else -> TODO(callee.descriptor.original.toString())
|
else -> TODO(callee.descriptor.original.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-3
@@ -23,9 +23,11 @@ import org.jetbrains.kotlin.backend.konan.isExternalObjCClassMethod
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||||
|
|
||||||
|
|
||||||
internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||||
@@ -45,7 +47,9 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
|||||||
val methods: ConstValue,
|
val methods: ConstValue,
|
||||||
val methodsCount: Int,
|
val methodsCount: Int,
|
||||||
val fields: ConstValue,
|
val fields: ConstValue,
|
||||||
val fieldsCount: Int) :
|
val fieldsCount: Int,
|
||||||
|
val packageName: String?,
|
||||||
|
val relativeName: String?) :
|
||||||
Struct(
|
Struct(
|
||||||
runtime.typeInfoType,
|
runtime.typeInfoType,
|
||||||
|
|
||||||
@@ -64,9 +68,18 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
|||||||
Int32(methodsCount),
|
Int32(methodsCount),
|
||||||
|
|
||||||
fields,
|
fields,
|
||||||
Int32(fieldsCount)
|
Int32(fieldsCount),
|
||||||
|
|
||||||
|
kotlinStringLiteral(packageName),
|
||||||
|
kotlinStringLiteral(relativeName)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private fun kotlinStringLiteral(string: String?): ConstPointer = if (string == null) {
|
||||||
|
NullPointer(runtime.objHeaderType)
|
||||||
|
} else {
|
||||||
|
staticData.kotlinStringLiteral(string)
|
||||||
|
}
|
||||||
|
|
||||||
private fun exportTypeInfoIfRequired(classDesc: ClassDescriptor, typeInfoGlobal: LLVMValueRef?) {
|
private fun exportTypeInfoIfRequired(classDesc: ClassDescriptor, typeInfoGlobal: LLVMValueRef?) {
|
||||||
val annot = classDesc.annotations.findAnnotation(FqName("konan.ExportTypeInfo"))
|
val annot = classDesc.annotations.findAnnotation(FqName("konan.ExportTypeInfo"))
|
||||||
if (annot != null) {
|
if (annot != null) {
|
||||||
@@ -159,12 +172,17 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
|||||||
val methodsPtr = staticData.placeGlobalConstArray("kmethods:$className",
|
val methodsPtr = staticData.placeGlobalConstArray("kmethods:$className",
|
||||||
runtime.methodTableRecordType, methods)
|
runtime.methodTableRecordType, methods)
|
||||||
|
|
||||||
|
val reflectionInfo = getReflectionInfo(classDesc)
|
||||||
|
|
||||||
val typeInfo = TypeInfo(name, size,
|
val typeInfo = TypeInfo(name, size,
|
||||||
superType,
|
superType,
|
||||||
objOffsetsPtr, objOffsets.size,
|
objOffsetsPtr, objOffsets.size,
|
||||||
interfacesPtr, interfaces.size,
|
interfacesPtr, interfaces.size,
|
||||||
methodsPtr, methods.size,
|
methodsPtr, methods.size,
|
||||||
fieldsPtr, if (classDesc.isInterface) -1 else fields.size)
|
fieldsPtr, if (classDesc.isInterface) -1 else fields.size,
|
||||||
|
reflectionInfo.packageName,
|
||||||
|
reflectionInfo.relativeName
|
||||||
|
)
|
||||||
|
|
||||||
val typeInfoGlobal = llvmDeclarations.typeInfoGlobal
|
val typeInfoGlobal = llvmDeclarations.typeInfoGlobal
|
||||||
|
|
||||||
@@ -201,4 +219,26 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
|||||||
}
|
}
|
||||||
return context.specialDeclarationsFactory.getBridgeDescriptor(OverriddenFunctionDescriptor(bridgeOwner, overriddenDescriptor))
|
return context.specialDeclarationsFactory.getBridgeDescriptor(OverriddenFunctionDescriptor(bridgeOwner, overriddenDescriptor))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class ReflectionInfo(val packageName: String?, val relativeName: String?)
|
||||||
|
|
||||||
|
private fun getReflectionInfo(descriptor: ClassDescriptor): ReflectionInfo {
|
||||||
|
// Use data from value class in type info for box class:
|
||||||
|
val descriptorForReflection = context.ir.symbols.valueClassToBox.entries
|
||||||
|
.firstOrNull { it.value.descriptor == descriptor }
|
||||||
|
?.key ?: descriptor
|
||||||
|
|
||||||
|
return if (DescriptorUtils.isAnonymousObject(descriptorForReflection)) {
|
||||||
|
ReflectionInfo(packageName = null, relativeName = null)
|
||||||
|
} else if (DescriptorUtils.isLocal(descriptorForReflection)) {
|
||||||
|
ReflectionInfo(packageName = null, relativeName = descriptorForReflection.name.asString())
|
||||||
|
} else {
|
||||||
|
ReflectionInfo(
|
||||||
|
packageName = descriptorForReflection.findPackage().fqName.asString(),
|
||||||
|
relativeName = descriptorForReflection.parentsWithSelf
|
||||||
|
.takeWhile { it is ClassDescriptor }.toList().reversed()
|
||||||
|
.joinToString(".") { it.name.asString() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -157,8 +157,8 @@ internal class StaticData(override val context: Context): ContextUtils {
|
|||||||
fun cStringLiteral(value: String) =
|
fun cStringLiteral(value: String) =
|
||||||
cStringLiterals.getOrPut(value) { placeCStringLiteral(value) }
|
cStringLiterals.getOrPut(value) { placeCStringLiteral(value) }
|
||||||
|
|
||||||
fun kotlinStringLiteral(type: KotlinType, value: IrConst<String>) =
|
fun kotlinStringLiteral(value: String) =
|
||||||
stringLiterals.getOrPut(value.value) { createKotlinStringLiteral(type, value) }
|
stringLiterals.getOrPut(value) { createKotlinStringLiteral(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+3
-2
@@ -42,8 +42,9 @@ private fun StaticData.arrayHeader(typeInfo: ConstPointer, length: Int): Struct
|
|||||||
return Struct(runtime.arrayHeaderType, typeInfo, Int32(containerOffsetNegative), Int32(length))
|
return Struct(runtime.arrayHeaderType, typeInfo, Int32(containerOffsetNegative), Int32(length))
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun StaticData.createKotlinStringLiteral(type: KotlinType, irConst: IrConst<String>): ConstPointer {
|
internal fun StaticData.createKotlinStringLiteral(value: String): ConstPointer {
|
||||||
val value = irConst.value
|
val type = context.builtIns.stringType
|
||||||
|
|
||||||
val name = "kstr:" + value.globalHashBase64
|
val name = "kstr:" + value.globalHashBase64
|
||||||
val elements = value.toCharArray().map(::Char16)
|
val elements = value.toCharArray().map(::Char16)
|
||||||
|
|
||||||
|
|||||||
+36
-11
@@ -1,33 +1,58 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.lower
|
package org.jetbrains.kotlin.backend.konan.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.IrBuildingTransformer
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.at
|
||||||
import org.jetbrains.kotlin.backend.konan.*
|
import org.jetbrains.kotlin.backend.konan.*
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
||||||
|
import org.jetbrains.kotlin.ir.builders.irCall
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrSpreadElement
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrVararg
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This pass runs before inlining and performs the following additional transformations over some calls:
|
* This pass runs before inlining and performs the following additional transformations over some operations:
|
||||||
* - Assertion call removal.
|
* - Assertion call removal.
|
||||||
* - Convert immutableBinaryBlobOf() arguments to special IrConst.
|
* - Convert immutableBinaryBlobOf() arguments to special IrConst.
|
||||||
|
* - Convert `obj::class` and `Class::class` to calls.
|
||||||
*/
|
*/
|
||||||
internal class SpecialCallsLowering(val context: Context) : FileLoweringPass {
|
internal class PreInlineLowering(val context: Context) : FileLoweringPass {
|
||||||
|
|
||||||
private val asserts = context.ir.symbols.asserts
|
private val symbols get() = context.ir.symbols
|
||||||
|
|
||||||
|
private val asserts = symbols.asserts
|
||||||
private val enableAssertions = context.config.configuration.getBoolean(KonanConfigKeys.ENABLE_ASSERTIONS)
|
private val enableAssertions = context.config.configuration.getBoolean(KonanConfigKeys.ENABLE_ASSERTIONS)
|
||||||
|
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
|
irFile.transformChildrenVoid(object : IrBuildingTransformer(context) {
|
||||||
|
|
||||||
|
override fun visitClassReference(expression: IrClassReference): IrExpression {
|
||||||
|
expression.transformChildrenVoid()
|
||||||
|
builder.at(expression)
|
||||||
|
|
||||||
|
val typeArgument = expression.descriptor.defaultType
|
||||||
|
|
||||||
|
return builder.irCall(symbols.kClassImplConstructor, listOf(typeArgument)).apply {
|
||||||
|
putValueArgument(0, builder.irCall(symbols.getClassTypeInfo, listOf(typeArgument)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitGetClass(expression: IrGetClass): IrExpression {
|
||||||
|
expression.transformChildrenVoid()
|
||||||
|
builder.at(expression)
|
||||||
|
|
||||||
|
val typeArgument = expression.type.arguments.single().type
|
||||||
|
return builder.irCall(symbols.kClassImplConstructor, listOf(typeArgument)).apply {
|
||||||
|
val typeInfo = builder.irCall(symbols.getObjectTypeInfo).apply {
|
||||||
|
putValueArgument(0, expression.argument)
|
||||||
|
}
|
||||||
|
|
||||||
|
putValueArgument(0, typeInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
@@ -928,6 +928,15 @@ task lateinit_inBaseClass(type: RunKonanTest) {
|
|||||||
source = "codegen/lateinit/inBaseClass.kt"
|
source = "codegen/lateinit/inBaseClass.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task kclass0(type: RunKonanTest) {
|
||||||
|
source = "codegen/kclass/kclass0.kt"
|
||||||
|
}
|
||||||
|
|
||||||
|
task kclass1(type: RunKonanTest) {
|
||||||
|
goldValue = "OK :D\n"
|
||||||
|
source = "codegen/kclass/kclass1.kt"
|
||||||
|
}
|
||||||
|
|
||||||
task coroutines_simple(type: RunKonanTest) {
|
task coroutines_simple(type: RunKonanTest) {
|
||||||
disabled = (project.testTarget == 'wasm32') // llvm: 'WebAssembly hasn't implemented computed gotos'
|
disabled = (project.testTarget == 'wasm32') // llvm: 'WebAssembly hasn't implemented computed gotos'
|
||||||
goldValue = "42\n"
|
goldValue = "42\n"
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
checkClass(Any::class, "kotlin.Any", "Any", Any(), null)
|
||||||
|
checkClass(Int::class, "kotlin.Int", "Int", 42, "17")
|
||||||
|
checkClass(String::class, "kotlin.String", "String", "17", 42)
|
||||||
|
checkClass(RootClass::class, "RootClass", "RootClass", RootClass(), Any())
|
||||||
|
checkClass(RootClass.Nested::class, "RootClass.Nested", "Nested", RootClass.Nested(), Any())
|
||||||
|
|
||||||
|
class Local {
|
||||||
|
val captured = args
|
||||||
|
|
||||||
|
inner class Inner
|
||||||
|
}
|
||||||
|
checkClass(Local::class, null, "Local", Local(), Any())
|
||||||
|
checkClass(Local.Inner::class, null, "Inner", Local().Inner(), Any())
|
||||||
|
|
||||||
|
val obj = object : Any() {
|
||||||
|
val captured = args
|
||||||
|
|
||||||
|
inner class Inner
|
||||||
|
val innerKClass = Inner::class
|
||||||
|
}
|
||||||
|
checkClass(obj::class, null, null, obj, Any())
|
||||||
|
checkClass(obj.innerKClass, null, "Inner", obj.Inner(), Any())
|
||||||
|
|
||||||
|
// Interfaces:
|
||||||
|
checkClass(Comparable::class, "kotlin.Comparable", "Comparable", 42, Any())
|
||||||
|
checkClass(Interface::class, "Interface", "Interface", object : Interface {}, Any())
|
||||||
|
|
||||||
|
checkInstanceClass(Any(), Any::class)
|
||||||
|
checkInstanceClass(42, Int::class)
|
||||||
|
assert(42::class == Int::class)
|
||||||
|
|
||||||
|
checkReifiedClass<Int>(Int::class)
|
||||||
|
checkReifiedClass<Int?>(Int::class)
|
||||||
|
checkReifiedClass2<Int>(Int::class)
|
||||||
|
checkReifiedClass2<Int?>(Int::class)
|
||||||
|
checkReifiedClass<Any>(Any::class)
|
||||||
|
checkReifiedClass2<Any>(Any::class)
|
||||||
|
checkReifiedClass2<Any?>(Any::class)
|
||||||
|
checkReifiedClass<Local>(Local::class)
|
||||||
|
checkReifiedClass2<Local>(Local::class)
|
||||||
|
checkReifiedClass<RootClass>(RootClass::class)
|
||||||
|
checkReifiedClass2<RootClass>(RootClass::class)
|
||||||
|
}
|
||||||
|
|
||||||
|
class RootClass {
|
||||||
|
class Nested
|
||||||
|
}
|
||||||
|
interface Interface
|
||||||
|
|
||||||
|
fun checkClass(
|
||||||
|
clazz: KClass<*>,
|
||||||
|
expectedQualifiedName: String?, expectedSimpleName: String?,
|
||||||
|
expectedInstance: Any, expectedNotInstance: Any?
|
||||||
|
) {
|
||||||
|
assert(clazz.qualifiedName == expectedQualifiedName)
|
||||||
|
assert(clazz.simpleName == expectedSimpleName)
|
||||||
|
|
||||||
|
assert(clazz.isInstance(expectedInstance))
|
||||||
|
if (expectedNotInstance != null) assert(!clazz.isInstance(expectedNotInstance))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkInstanceClass(instance: Any, clazz: KClass<*>) {
|
||||||
|
assert(instance::class == clazz)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T> checkReifiedClass(expectedClass: KClass<*>) {
|
||||||
|
assert(T::class == expectedClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T> checkReifiedClass2(expectedClass: KClass<*>) {
|
||||||
|
checkReifiedClass<T>(expectedClass)
|
||||||
|
checkReifiedClass<T?>(expectedClass)
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
// FILE: main.kt
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
com.github.salomonbrys.kmffkn.App(testQualified = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: app.kt
|
||||||
|
|
||||||
|
// Taken from:
|
||||||
|
// https://github.com/SalomonBrys/kmffkn/blob/master/shared/main/kotlin/com/github/salomonbrys/kmffkn/app.kt
|
||||||
|
|
||||||
|
package com.github.salomonbrys.kmffkn
|
||||||
|
|
||||||
|
@DslMarker
|
||||||
|
annotation class MyDsl
|
||||||
|
|
||||||
|
@MyDsl
|
||||||
|
class DslMain {
|
||||||
|
fun <T: Any> kClass(block: KClassDsl.() -> T): T = KClassDsl().block()
|
||||||
|
}
|
||||||
|
|
||||||
|
@MyDsl
|
||||||
|
class KClassDsl {
|
||||||
|
inline fun <reified T: Any> of() = T::class
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T: Any> dsl(block: DslMain.() -> T): T = DslMain().block()
|
||||||
|
|
||||||
|
class Test
|
||||||
|
|
||||||
|
class App(testQualified: Boolean) {
|
||||||
|
|
||||||
|
@Volatile // This could be noop in Kotlin Native, or the equivalent of volatile in C.
|
||||||
|
var type = dsl {
|
||||||
|
kClass {
|
||||||
|
//kClass { } // This should error if uncommented because of `@DslMarker`.
|
||||||
|
of<Test>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
assert(type.simpleName == "Test")
|
||||||
|
if (testQualified)
|
||||||
|
assert(type.qualifiedName == "com.github.salomonbrys.kmffkn.Test") // This is not really necessary, but always better :).
|
||||||
|
|
||||||
|
assert(String::class == String::class)
|
||||||
|
assert(String::class != Int::class)
|
||||||
|
|
||||||
|
assert(Test()::class == Test()::class)
|
||||||
|
assert(Test()::class == Test::class)
|
||||||
|
|
||||||
|
println("OK :D")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -70,4 +70,8 @@ void Kotlin_system_exitProcess(KInt status) {
|
|||||||
konan::exit(status);
|
konan::exit(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const void* Kotlin_Any_getTypeInfo(KConstRef obj) {
|
||||||
|
return obj->type_info();
|
||||||
|
}
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|||||||
@@ -68,18 +68,6 @@ template <typename T> OBJ_GETTER(Kotlin_toStringRadix, T value, KInt radix) {
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
OBJ_GETTER(Kotlin_Any_toString, KConstRef thiz) {
|
|
||||||
char cstring[80];
|
|
||||||
if (IsArray(thiz)) {
|
|
||||||
konan::snprintf(cstring, sizeof(cstring), "%d@%p: array of %d",
|
|
||||||
Kotlin_Any_hashCode(thiz), thiz->type_info_, thiz->array()->count_);
|
|
||||||
} else {
|
|
||||||
konan::snprintf(cstring, sizeof(cstring), "%d@%p: object",
|
|
||||||
Kotlin_Any_hashCode(thiz), thiz->type_info_);
|
|
||||||
}
|
|
||||||
RETURN_RESULT_OF(CreateStringFromCString, cstring);
|
|
||||||
}
|
|
||||||
|
|
||||||
OBJ_GETTER(Kotlin_Byte_toString, KByte value) {
|
OBJ_GETTER(Kotlin_Byte_toString, KByte value) {
|
||||||
char cstring[8];
|
char cstring[8];
|
||||||
konan::snprintf(cstring, sizeof(cstring), "%d", value);
|
konan::snprintf(cstring, sizeof(cstring), "%d", value);
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Names.h"
|
#include "Names.h"
|
||||||
|
|
||||||
|
struct ObjHeader;
|
||||||
|
|
||||||
// An element of sorted by hash in-place array representing methods.
|
// An element of sorted by hash in-place array representing methods.
|
||||||
// For systems where introspection is not needed - only open methods are in
|
// For systems where introspection is not needed - only open methods are in
|
||||||
// this table.
|
// this table.
|
||||||
@@ -56,6 +58,15 @@ struct TypeInfo {
|
|||||||
// Is negative to mark an interface.
|
// Is negative to mark an interface.
|
||||||
int32_t fieldsCount_;
|
int32_t fieldsCount_;
|
||||||
|
|
||||||
|
// String for the fully qualified dot-separated name of the package containing class,
|
||||||
|
// or `null` if the class is local or anonymous.
|
||||||
|
ObjHeader* packageName_;
|
||||||
|
|
||||||
|
// String for the qualified class name relative to the containing package
|
||||||
|
// (e.g. TopLevel.Nested1.Nested2), or simple class name if it is local,
|
||||||
|
// or `null` if the class is anonymous.
|
||||||
|
ObjHeader* relativeName_;
|
||||||
|
|
||||||
// vtable starts just after declared contents of the TypeInfo:
|
// vtable starts just after declared contents of the TypeInfo:
|
||||||
// void* const vtable_[];
|
// void* const vtable_[];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -50,4 +50,16 @@ void CheckInstance(const ObjHeader* obj, const TypeInfo* type_info) {
|
|||||||
ThrowClassCastException();
|
ThrowClassCastException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KBoolean Kotlin_TypeInfo_isInstance(KConstRef obj, KNativePtr typeInfo) {
|
||||||
|
return IsInstance(obj, reinterpret_cast<const TypeInfo*>(typeInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
OBJ_GETTER(Kotlin_TypeInfo_getPackageName, KNativePtr typeInfo) {
|
||||||
|
RETURN_OBJ(reinterpret_cast<const TypeInfo*>(typeInfo)->packageName_);
|
||||||
|
}
|
||||||
|
|
||||||
|
OBJ_GETTER(Kotlin_TypeInfo_getRelativeName, KNativePtr typeInfo) {
|
||||||
|
RETURN_OBJ(reinterpret_cast<const TypeInfo*>(typeInfo)->relativeName_);
|
||||||
|
}
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package konan.internal
|
||||||
|
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
@ExportForCompiler
|
||||||
|
internal class KClassImpl<T : Any>(private val typeInfo: NativePtr) : KClass<T> {
|
||||||
|
override val simpleName: String?
|
||||||
|
get() {
|
||||||
|
val relativeName = getRelativeName(typeInfo)
|
||||||
|
?: return null
|
||||||
|
|
||||||
|
return relativeName.substringAfterLast(".")
|
||||||
|
}
|
||||||
|
|
||||||
|
override val qualifiedName: String?
|
||||||
|
get() {
|
||||||
|
val packageName = getPackageName(typeInfo)
|
||||||
|
?: return null
|
||||||
|
|
||||||
|
val relativeName = getRelativeName(typeInfo)!!
|
||||||
|
return if (packageName.isEmpty()) {
|
||||||
|
relativeName
|
||||||
|
} else {
|
||||||
|
"$packageName.$relativeName"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isInstance(value: Any?): Boolean = value != null && isInstance(value, this.typeInfo)
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean =
|
||||||
|
other is KClassImpl<*> && this.typeInfo == other.typeInfo
|
||||||
|
|
||||||
|
override fun hashCode(): Int = typeInfo.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExportForCompiler
|
||||||
|
@SymbolName("Kotlin_Any_getTypeInfo")
|
||||||
|
internal external fun getObjectTypeInfo(obj: Any): NativePtr
|
||||||
|
|
||||||
|
@ExportForCompiler
|
||||||
|
@Intrinsic
|
||||||
|
internal external inline fun <reified T : Any> getClassTypeInfo(): NativePtr
|
||||||
|
|
||||||
|
@SymbolName("Kotlin_TypeInfo_getPackageName")
|
||||||
|
private external fun getPackageName(typeInfo: NativePtr): String?
|
||||||
|
|
||||||
|
@SymbolName("Kotlin_TypeInfo_getRelativeName")
|
||||||
|
private external fun getRelativeName(typeInfo: NativePtr): String?
|
||||||
|
|
||||||
|
@SymbolName("Kotlin_TypeInfo_isInstance")
|
||||||
|
private external fun isInstance(obj: Any, typeInfo: NativePtr): Boolean
|
||||||
@@ -48,8 +48,13 @@ public open class Any {
|
|||||||
/**
|
/**
|
||||||
* Returns a string representation of the object.
|
* Returns a string representation of the object.
|
||||||
*/
|
*/
|
||||||
@SymbolName("Kotlin_Any_toString")
|
public open fun toString(): String {
|
||||||
external public open fun toString(): String
|
val kClass = this::class
|
||||||
|
val className = kClass.qualifiedName ?: kClass.simpleName ?: "<object>"
|
||||||
|
val unsignedHashCode = this.hashCode().toLong() and 0xffffffffL
|
||||||
|
val hashCodeStr = unsignedHashCode.toString(16)
|
||||||
|
return "$className@$hashCodeStr"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun Any?.hashCode() = if (this != null) this.hashCode() else 0
|
public fun Any?.hashCode() = if (this != null) this.hashCode() else 0
|
||||||
@@ -50,7 +50,8 @@ public open class Throwable(open val message: String?, open val cause: Throwable
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
val s = "Throwable" // TODO: should be class name
|
val kClass = this::class
|
||||||
|
val s = kClass.qualifiedName ?: kClass.simpleName ?: "Throwable"
|
||||||
return if (message != null) s + ": " + message.toString() else s
|
return if (message != null) s + ": " + message.toString() else s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.reflect
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a class and provides introspection capabilities.
|
||||||
|
* Instances of this class are obtainable by the `::class` syntax.
|
||||||
|
* See the [Kotlin language documentation](http://kotlinlang.org/docs/reference/reflection.html#class-references)
|
||||||
|
* for more information.
|
||||||
|
*
|
||||||
|
* @param T the type of the class.
|
||||||
|
*/
|
||||||
|
public interface KClass<T : Any> : KDeclarationContainer, KAnnotatedElement, KClassifier {
|
||||||
|
/**
|
||||||
|
* The simple name of the class as it was declared in the source code,
|
||||||
|
* or `null` if the class has no name (if, for example, it is an anonymous object literal).
|
||||||
|
*/
|
||||||
|
public val simpleName: String?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fully qualified dot-separated name of the class,
|
||||||
|
* or `null` if the class is local or it is an anonymous object literal.
|
||||||
|
*/
|
||||||
|
public val qualifiedName: String?
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * All functions and properties accessible in this class, including those declared in this class
|
||||||
|
// * and all of its superclasses. Does not include constructors.
|
||||||
|
// */
|
||||||
|
// override val members: Collection<KCallable<*>>
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * All constructors declared in this class.
|
||||||
|
// */
|
||||||
|
// public val constructors: Collection<KFunction<T>>
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * All classes declared inside this class. This includes both inner and static nested classes.
|
||||||
|
// */
|
||||||
|
// public val nestedClasses: Collection<KClass<*>>
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * The instance of the object declaration, or `null` if this class is not an object declaration.
|
||||||
|
// */
|
||||||
|
// public val objectInstance: T?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns `true` if [value] is an instance of this class on a given platform.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.1")
|
||||||
|
public fun isInstance(value: Any?): Boolean
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * The list of type parameters of this class. This list does *not* include type parameters of outer classes.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val typeParameters: List<KTypeParameter>
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * The list of immediate supertypes of this class, in the order they are listed in the source code.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val supertypes: List<KType>
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Visibility of this class, or `null` if its visibility cannot be represented in Kotlin.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val visibility: KVisibility?
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * `true` if this class is `final`.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val isFinal: Boolean
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * `true` if this class is `open`.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val isOpen: Boolean
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * `true` if this class is `abstract`.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val isAbstract: Boolean
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * `true` if this class is `sealed`.
|
||||||
|
// * See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/classes.html#sealed-classes)
|
||||||
|
// * for more information.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val isSealed: Boolean
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * `true` if this class is a data class.
|
||||||
|
// * See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/data-classes.html)
|
||||||
|
// * for more information.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val isData: Boolean
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * `true` if this class is an inner class.
|
||||||
|
// * See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/nested-classes.html#inner-classes)
|
||||||
|
// * for more information.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val isInner: Boolean
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * `true` if this class is a companion object.
|
||||||
|
// * See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/object-declarations.html#companion-objects)
|
||||||
|
// * for more information.
|
||||||
|
// */
|
||||||
|
// @SinceKotlin("1.1")
|
||||||
|
// public val isCompanion: Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns `true` if this [KClass] instance represents the same Kotlin class as the class represented by [other].
|
||||||
|
* On JVM this means that all of the following conditions are satisfied:
|
||||||
|
*
|
||||||
|
* 1. [other] has the same (fully qualified) Kotlin class name as this instance.
|
||||||
|
* 2. [other]'s backing [Class] object is loaded with the same class loader as the [Class] object of this instance.
|
||||||
|
* 3. If the classes represent [Array], then [Class] objects of their element types are equal.
|
||||||
|
*
|
||||||
|
* For example, on JVM, [KClass] instances for a primitive type (`int`) and the corresponding wrapper type (`java.lang.Integer`)
|
||||||
|
* are considered equal, because they have the same fully qualified name "kotlin.Int".
|
||||||
|
*/
|
||||||
|
override fun equals(other: Any?): Boolean
|
||||||
|
|
||||||
|
override fun hashCode(): Int
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.reflect
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A classifier is either a class or a type parameter.
|
||||||
|
*
|
||||||
|
* @see [KClass]
|
||||||
|
* @see [KTypeParameter]
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.1")
|
||||||
|
public interface KClassifier
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.reflect
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an entity which may contain declarations of any other entities,
|
||||||
|
* such as a class or a package.
|
||||||
|
*/
|
||||||
|
public interface KDeclarationContainer {
|
||||||
|
// /**
|
||||||
|
// * All functions and properties accessible in this container.
|
||||||
|
// */
|
||||||
|
// public val members: Collection<KCallable<*>>
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user