DATACMNS-1391 - Use prefered constructors to discover Kotlin's copy method.

We now use the primary constructor of Kotlin classes to discover the copy method. We use the primary constructor args to compare signatures and only use the copy method that takes all parameters in the constructor args order. This allows to find the appropriate copy method in case the class declares multiple copy methods.

We now also cache the copy method (KCallable) to reduce lookups in BeanWrapper.

Original pull request: #312.
This commit is contained in:
Mark Paluch
2018-09-12 15:46:33 +02:00
committed by Oliver Gierke
parent a31ac40c03
commit 7eacab6a34
7 changed files with 441 additions and 209 deletions

View File

@@ -21,8 +21,10 @@ import lombok.Data;
import lombok.Value;
import lombok.experimental.Wither;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.function.Function;
import org.junit.Test;
@@ -98,18 +100,42 @@ public class PersistentPropertyAccessorTests {
assertThat(accessor.getProperty(property)).isEqualTo("value");
}
@Test // DATACMNS-1322
@Test // DATACMNS-1322, DATACMNS-1391
public void shouldSetExtendedKotlinDataClassProperty() {
ExtendedDataClassKt bean = new ExtendedDataClassKt("foo", "bar");
ExtendedDataClassKt bean = new ExtendedDataClassKt(0, "bar");
PersistentPropertyAccessor accessor = propertyAccessorFunction.apply(bean);
SamplePersistentProperty property = getProperty(bean, "id");
accessor.setProperty(property, "value");
accessor.setProperty(property, 1L);
assertThat(accessor.getBean()).hasFieldOrPropertyWithValue("id", "value");
assertThat(accessor.getBean()).hasFieldOrPropertyWithValue("id", 1L);
assertThat(accessor.getBean()).isNotSameAs(bean);
assertThat(accessor.getProperty(property)).isEqualTo("value");
assertThat(accessor.getProperty(property)).isEqualTo(1L);
}
@Test // DATACMNS-1391
public void shouldUseKotlinGeneratedCopyMethod() {
UnusedCustomCopy bean = new UnusedCustomCopy(new Timestamp(100));
PersistentPropertyAccessor accessor = propertyAccessorFunction.apply(bean);
SamplePersistentProperty property = getProperty(bean, "date");
accessor.setProperty(property, new Timestamp(200));
assertThat(accessor.getBean()).hasFieldOrPropertyWithValue("date", new Timestamp(200));
assertThat(accessor.getBean()).isNotSameAs(bean);
assertThat(accessor.getProperty(property)).isEqualTo(new Timestamp(200));
}
@Test // DATACMNS-1391
public void kotlinCopyMethodShouldNotSetUnsettableProperty() {
SingleSettableProperty bean = new SingleSettableProperty(UUID.randomUUID());
PersistentPropertyAccessor accessor = propertyAccessorFunction.apply(bean);
SamplePersistentProperty property = getProperty(bean, "version");
assertThatThrownBy(() -> accessor.setProperty(property, 1)).isInstanceOf(UnsupportedOperationException.class);
}
@Test // DATACMNS-1322