Can I disambiguate between something that's availa...
# compiler
m
Can I disambiguate between something that's available on the Companion vs the class itself?
Copy code
class Foo {
  object bar {}

  companion object {
    val bar = "companion bar"
  }
}

// I can read the companion bar
println(Foo.bar) // companion bar
// How do I access the object bar?
println(Foo.??)
s
Nice question, I would love to know if there's a good answer to this.
Copy code
println(Foo.bar) // prints "companion"
println(Foo.bar.toString()) // prints "Foo$bar@3fa77460"
How weird is that? So my first suggestion is
Foo.bar.let { it }
. The IDE warns me I'm being stupid, but it works. Though I don't think I'd want to rely on it continuing to work in future versions...
m
Foo.bar.let { it }
mind blown
Nice find! I wonder how future proof it is too!
s
Reminds me a little of KT-47412
👀 1
m
Yup, really similar. The fact that it was fixed seems to indicate that this is a supported use case
w
Copy code
Foo::class.nestedClasses.single { !it.isCompanion }.objectInstance as Foo.bar
🧌
blob joy 3
blob think smart 1
😮 1
I’m curious what’s the use case here — generally classes should start with an uppercase, so I’d expect
Foo#Bar
and
Foo#Companion#bar
. Clearly since you’re asking you have a reason to distinguish those, I’m just curious
m
Generated code coming from GraphQL
And we can't really uppercase everything because
bar
and
Bar
can be two different enum values...
w
Ah, the classes name are user input basically 👌 And I assume you have to be consistent with GraphQL spec which allows that? I’d consider something like
_bar
for the lowercase variant if there’s a collision. #notHelpful
m
Yep, we might end up doing that. We're doing it for
name
and
ordinal
already which are not allowed in kotlin enums. Was just curious if there was a better fix
w
If you open an issue for this problem please link here, I’m very curious if there’s a kosher way to get both `bar`s here. The
let { }
seems like an implementation detail?
toString()
too, like function calls prioritise types, but raw
Foo.bar
prioritises properties mind blown
1
👍 1
d
Please report it in kotl.in/issue
👍 1
h
What about importing the class as a more stable workaround?
m
@hfhbd how would you import it? I can do
Copy code
import Foo.bar as companionBar
But that still resolves to the companion. In the imports or in the code the problem is the same
h
I mean this 🤔:
Copy code
import Foo.bar

class Foo {
    object bar {}

    companion object {
        val bar = "companion bar"
    }
}

fun main() {
    println(Foo.bar) // companion bar
    println(bar) // Foo$bar@58644d46
}
👍 1
m
Ah, interesting! I'm almost sure I tried this and
import Foo.bar
was resolving to
companion bar
...
MMmm seems to work now, not sure what I did but yea, that would work too!