Type input error: not enough information for parameter infer. Please indicate this explicitly.

I am trying to write a Vaadin app in Kotlin. To bind data, Vaadin 8 now provides the ability to bind data of type safe. In Kotlin, I would expect such work:

class LoginModel { var username: String = "" var password: String = "" } class LoginView : FormLayout() { val name = TextField("name") val password = TextField("password") val loginButton = Button("login") init { val binder = Binder<LoginModel>() binder.forField(name).bind( { it.username }, { bean, value -> bean.username = value }) //... } } 

I get the following error message here:

 Error:(23, 31) Kotlin: Type inference failed: Not enough information to infer parameter BEAN in fun <BEAN : Any!, TARGET : Any!, BEAN : Any!> Binder.BindingBuilder<BEAN#1 (type parameter of bind), TARGET>.bind(p0: ((BEAN#1!) -> TARGET!)!, p1: ((BEAN#1!, TARGET!) -> Unit)!): Binder.Binding<BEAN#1!, TARGET!>! Please specify it explicitly. 

I tried to explicitly specify type parameters:

 binder.forField(name).bind<LoginView, String, LoginView>( { it.username }, { bean, value -> bean.username = value }) 

but this leads to an error message (and other sytax errors, so I did not follow this approach)

 Error:(23, 35) Kotlin: No type arguments expected for fun bind(p0: ValueProvider<LoginModel!, String!>!, p1: Setter<LoginModel!, String!>!): Binder.Binding<LoginModel!, String!>! defined in com.vaadin.data.Binder.BindingBuilder 

My second approach was to pass property attributes of Kotlin directly, but the error message was the same as the first:

 binder.forField(name).bind(LoginModel::username.getter, LoginModel::username.setter) 

The last request tried to use the extension method and make everything as explicit as possible:

 fun <BEAN, TARGET> Binder.BindingBuilder<BEAN, TARGET>.bind(property: KMutableProperty1<BEAN, TARGET>) { fun set(bean: BEAN): TARGET = property.get(bean) fun get(bean: BEAN, value: TARGET): Unit = property.set(bean, value) this.bind(::set, ::get) } 

But this leads to the same error message as the first

+5
source share
3 answers

I tried your example and it compiles fine with my Intellij 2017.1.4 and Kotlin 1.1.2-5. Did you probably find a bug in the old version of the Kotlin plugin?

The bind method does not accept any general parameters, so it cannot be generated. The forField method takes one general parameter, so maybe you can try

  binder.forField<String>(name).bind( { it.username }, { bean, value -> bean.username = value }) 

But first, make sure you have the latest version of the Kotlin plugin and / or maybe try it with Intellij Community Edition.

However, I urge you to use bind(String) , as other binding methods will not work with JSR303 checks. You can also define the following extension method:

 fun <BEAN, FIELDVALUE> Binder.BindingBuilder<BEAN, FIELDVALUE>.bind(prop: KMutableProperty1<BEAN, FIELDVALUE?>): Binder.Binding<BEAN, FIELDVALUE> = bind(prop.name) 

And name it as follows from your code binder.forField(name).bind(LoginModel::username) . See here for more details: https://github.com/mvysny/karibu-dsl/blob/master/example-v8/src/main/kotlin/com/github/vok/karibudsl/example/form/FormView.kt

+3
source

You must use API level 26+. This version has changed the signature of View.findViewById () - see here https://developer.android.com/preview/api-overview.html#fvbi-signature

The result of findViewById is ambiguous, you need to specify the type:

For instance:

 val myTextView = findViewById(R.id.list) as TextView 

becomes

 val myTextView = findViewById<TextView>(R.id.myTextView) 
+1
source

Since your model is quite simple, you can complete the binding by connecting to a property with the given name using the Binder#bind(String propertyName) method

 val binder = Binder<LoginModel>() binder.forField(name).bind("username"); 
0
source

Source: https://habr.com/ru/post/1268882/


All Articles