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

TypeName.get(...) produces invalid wildcard type names for generic classes #857

Open
richarddd opened this issue Nov 19, 2021 · 3 comments

Comments

@richarddd
Copy link

richarddd commented Nov 19, 2021

Hi,

I have a bunch of annotate generic Kotlin classes with Maps as parameters.

The class looks like this:

class ExampleClass : ExampleGenericClass<Map<String, String>, Map<String, Int>>

The TypeMirror looks something like this:

com.example.ExampleClass<java.util.Map<java.lang.String,? extends java.lang.String>,java.util.Map<java.lang.String,? extends java.lang.Integer>>

The problem here is that the wildcards types can not be compiled as-is since they are bounded by boxed primitives and strings. This compiler produces the following error:

 incompatible types: Map<String,CAP#1> cannot be converted to Map<String,String>
    return HANDLER.handleRequest(input,context);
                                 ^
  where CAP#1 is a fresh type-variable:
    CAP#1 extends String from capture of ? extends String

The workaround I've implemented is to recursively iterate through the Parameterized type and replace the invalid wildcard types:

private fun TypeName.ensureProperWildcards(): TypeName = when (this) {
    is ParameterizedTypeName -> {
        ParameterizedTypeName.get(this.rawType, *this.typeArguments.map {
            it.ensureProperWildcards()
        }.toTypedArray())
    }
    is WildcardTypeName -> {
        val firstUpperBound = this.upperBounds.firstOrNull()
        val firstLowerBound = this.lowerBounds.firstOrNull()
        if (firstUpperBound != null && (firstUpperBound == TypeName.get(String::class.java) || firstUpperBound.isBoxedPrimitive) && firstLowerBound == null) {
            firstUpperBound
        } else {
            this
        }
    }
    else -> {
        this
    }
}

Could this be avoided when Javapoet parses the TypeMirror and removes the wildcard for boxed primitives and strings?

@Yobyn
Copy link

Yobyn commented Jan 12, 2024

Hi, happy to look into this issue.

@liujianpc
Copy link

liujianpc commented Jan 12, 2024 via email

@Yobyn
Copy link

Yobyn commented Jan 14, 2024

@richarddd not a 100% sure what version you are using, but did some research and it seem that JavaPoet from version 1.10.0 doesn’t support code compilation.

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

3 participants