Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClassName.bestGuess() fails for classes starting with a lowercase character #978

Closed
vRallev opened this issue Sep 2, 2020 · 4 comments
Closed

Comments

@vRallev
Copy link

vRallev commented Sep 2, 2020

package abc

class MyClass @Inject constructor(a: asg) {
  class asg @Inject constructor()
}

Calling ClassName.bestGuess("abc.MyClass.asg") fails:

e: java.lang.IllegalArgumentException: couldn't make a guess for abc.MyClass.asg
        at com.squareup.kotlinpoet.ClassName$Companion.bestGuess(TypeName.kt:465)

One could argue that classes should start with an uppercase letter, but Kotlin allows it and it's the input of another program that internally uses Kotlin Poet.

@JakeWharton
Copy link
Member

Java also allows this and JavaPoet will fail in the same way. If you're inside a Kotlin compiler plugin you shouldn't need to use bestGuess and can instead get the package and list of simple names to create the ClassName "normally".

@vRallev
Copy link
Author

vRallev commented Sep 2, 2020

What exactly do you mean with "normally"? Do you mean the constructor? The compiler often works with full qualified names and then it's very convenient to rely on bestGuess() rather than breaking down the string manually. I see how Kotlin Poet has less context and might not be able to make the decision. So the exception is by design?

@JakeWharton
Copy link
Member

Yes, because MyClass could also be a package segment that just happened to be capitalized as well. So we have no idea if it's a nested class named MyClass.asg in the abc package or a class named adg in the abc.MyClass package. The only way we can guess is if you follow the standard naming rules of package segments starting with lowercase and type names starting with uppercase. It could even be a class named adc in the default package with MyClass and asg nested types. There's just no context, like you said.

The compiler API should give you a way to break apart a qualified reference into component parts. Otherwise I don't see how it would know how to emit bytecode where these cases are all defined differently since / splits packages whereas $ splits nested types.

@vRallev
Copy link
Author

vRallev commented Sep 2, 2020

Sounds reasonable. Thanks for clarifying.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants