Why can I not access `::class.companionObject`? - kotlin

I am trying to access the companion object of an unknown class with a known interface, given an instance of the class.
Code below:
class AccessTest() {
companion object {
val prop = 5
}
fun getComp() {
print(this)
print(this::class)
print(this::class.companionObject) // Unresolved reference.
print(this::class.companionObjectInstance) // Unresolved reference.
}
}
inline fun <reified T> getCompanion() {
print(T::class.companionObject) // Unresolved reference.
print(T::class.companionObjectInstance) // Unresolved reference.
}
fun main() {
AccessTest().getComp()
getCompanion<AccessTest>()
}
Output:
$ kotlinc -d main.jar main.kt && kotlin -classpath main.jar MainKt
main.kt:8:27: error: unresolved reference: companionObject
print(this::class.companionObject) // Unresolved reference.
^
main.kt:9:27: error: unresolved reference: companionObjectInstance
print(this::class.companionObjectInstance) // Unresolved reference.
^
main.kt:14:20: error: unresolved reference: companionObject
print(T::class.companionObject) // Unresolved reference.
^
main.kt:15:20: error: unresolved reference: companionObjectInstance
print(T::class.companionObjectInstance) // Unresolved reference.
^
I do not think this is a duplicate of either of the below questions, as I am specifically asking what has changed or what I am misunderstanding such that the solution in the two below questions is not working for me:
how to access companion object from object instance in kotlin?
Kotlin invoke companion function with reflection

After a short discussion in comments, it turned out it was just a missing import.
companionObject is not a member of KClass, but extension on it, so it is possible we have access to KClass object, but we don't see its companionObject property. Also, as it's the part of kotlin-reflect library, it is not located in kotlin.reflect package, but in kotlin.reflect.full, so importing kotlin.reflect.* isn't enough to get it.

Related

#JvmOverloads error on kotlin interface companion object function

Cannot use #JvmOverloads on kotlin interface companion object function, even an #JvmStatic on it:
interface Foo {
companion object {
#JvmStatic
#JvmOverloads
fun bar(a: Int = 1, b: Int = 2){}
}
}
No error tipps shows on IDEA when coding, but error shows in compile:
Method bar in class Foo has illegal modifiers: 0x19
java.lang.ClassFormatError: Method bar in class Foo has illegal modifiers: 0x19
Problem is solved, this is a bug and fixed in 1.4.20
It's a bug in compiler. Will be fixed in 1.4.20.
According to https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html:
Default methods are available only for targets JVM 1.8 and above.

How to map a List to a Set while applying a method(Java to Kotlin code conversion)?

I have this code snippet in Java (this is an MCVE; actual code is more complex but has exact same issue):
enum StatusEnum { A, B, C; }
[...]
final static Set<String> names = Arrays.asList(StatusEnum.values())
.stream().map(StatusEnum::name).collect(Collectors.toSet());
IntelliJ gave me the following automated conversion to Kotlin:
internal val names = Arrays.asList(*StatusEnum.values())
.stream().map<String>(Function<StatusEnum, String> { it.name })
.collect<Set<String>, Any>(Collectors.toSet())
This unfortunately has compile errors:
Interface Function does not have constructors
Type inference failed. Expected type mismatch: inferred type is Collector!>! but Collector!>! was expected
Unresolved reference: it
This is my very first attempt at converting some code to Kotlin. I have reviewed the Functions and Lambdas section of the documentation. Still not clear what's going on here or how to fix it.
Use Kotlin methods instead of Java streams:
val names = StatusEnum.values()
.map { it.name }
.toSet()

How to handle nullable generics with Java interop

I have a Java class that is out of my control, defined as:
public #interface ValueSource {
String[] strings() default {}
}
I am trying to use this class from a Kotlin file I control, like so:
class Thing {
#ValueSource(string = ["non-null", null])
fun performAction(value: String?) {
// Do stuff
}
}
I get a compiler error
Kotlin: Type inference failed. Expected type mismatch: inferred type is Array<String?> but Array<String> was expected.
I understand why the inferred type is Array<String?>, but why is the expected type not the same? Why is Kotlin interpreting the Java generic as String! rather than String?? And finally, is there a way to suppress the error?
Kotlin 1.2.61
This isn't a Kotlin issue - this code isn't valid either, because Java simply doesn't allow null values in annotation parameters:
public class Thing {
#ValueSource(strings = {"non-null", null}) // Error: Attribute value must be constant
void performAction(String value) {
// Do stuff
}
}
See this article and this question for more discussion on this.

Unable to reference companion object methods

I have the following code:
fun process(call: () -> Int) {
}
fun aa() = 5
class A {
companion object Factory {
fun bb() = 6
}
}
fun test() {
process(::aa) // OK
process(::A.bb) // Overload resolution ambiguity
}
When I try to call process(::A.bb) I get the following error:
Error:Overload resolution ambiguity:
public constructor A() defined in ru.netimen.hitch_hikingstats.A
public companion object Factory defined in ru.netimen.hitch_hikingstats.A
Is there any way to reference companion object methods?
In Kotlin 1.4+ you can use process(A::bb).
In 1.1.2+ you can use process(A.Factory::bb) or process((A)::bb).
Not so long after this question was asked Kotlin 1.1 was released with support for bound callable references:
https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md#11-m01-eap-1
https://blog.jetbrains.com/kotlin/2016/07/first-glimpse-of-kotlin-1-1-coroutines-type-aliases-and-more/
http://kotlinlang.org/docs/reference/whatsnew11.html#bound-callable-references
http://kotlinlang.org/docs/reference/reflection.html#bound-function-and-property-references-since-11
Kotlin 1.1.2 came with a fix for KT-15951, meaning that since then you can call process(A.Factory::bb).
There is also KT-13934 targeted for Kotlin 1.4, to support process(A::bb).
Syntactically it would be A.Factory:bb but it will not work. At first, bb is a A.Factory.() -> Int while () -> Int is required.
Secondly, callable references to object members are not supported at the moment as the Kotlin compiler says. Here's a parent task for all callable members tasks: https://youtrack.jetbrains.com/issue/KT-1183.

Kotlin Annotation: Type mismatch: inferred type is java.lang.Class<foo> but java.lang.Class<out jet.Annotation> was expected

Given the following Kotlin Annotation:
public Retention(RetentionPolicy.RUNTIME) annotation class foo(val text : String)
and the following code to check if a class is annotated by above annotation:
if (javaClass<Bar>().isAnnotationPresent(javaClass<foo>())) {
// do something here.
}
If the annotation class (foo) and the code which is using it were located in the same module (maven artifact), the code can compile and run without any issue.
But, if I separate them into different modules, the following compile error happens:
Kotlin: Type mismatch: inferred type is java.lang.Class but
java.lang.Class was expected
Any idea what could be the issue?
Problem seems to be marked as fixed. https://youtrack.jetbrains.com/issue/KT-3197 This was a bug.