Generate copy() in data class even if constructor is empty or not present
This commit is contained in:
@@ -227,10 +227,14 @@ public class DeclarationResolver {
|
|||||||
JetClassOrObject klass = entry.getKey();
|
JetClassOrObject klass = entry.getKey();
|
||||||
MutableClassDescriptor classDescriptor = (MutableClassDescriptor) entry.getValue();
|
MutableClassDescriptor classDescriptor = (MutableClassDescriptor) entry.getValue();
|
||||||
|
|
||||||
if (klass instanceof JetClass && klass.hasPrimaryConstructor() && KotlinBuiltIns.getInstance().isData(classDescriptor)) {
|
if (klass instanceof JetClass && KotlinBuiltIns.getInstance().isData(classDescriptor)) {
|
||||||
ConstructorDescriptor constructor = getConstructorOfDataClass(classDescriptor);
|
List<ValueParameterDescriptor> parameters =
|
||||||
createComponentFunctions(classDescriptor, constructor);
|
klass.hasPrimaryConstructor() ?
|
||||||
createCopyFunction(classDescriptor, constructor);
|
getConstructorOfDataClass(classDescriptor).getValueParameters() :
|
||||||
|
Collections.<ValueParameterDescriptor>emptyList();
|
||||||
|
|
||||||
|
createComponentFunctions(classDescriptor, parameters);
|
||||||
|
createCopyFunction(classDescriptor, parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,9 +246,9 @@ public class DeclarationResolver {
|
|||||||
return constructors.iterator().next();
|
return constructors.iterator().next();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createComponentFunctions(@NotNull MutableClassDescriptor classDescriptor, @NotNull ConstructorDescriptor constructorDescriptor) {
|
private void createComponentFunctions(@NotNull MutableClassDescriptor classDescriptor, List<ValueParameterDescriptor> parameters) {
|
||||||
int parameterIndex = 0;
|
int parameterIndex = 0;
|
||||||
for (ValueParameterDescriptor parameter : constructorDescriptor.getValueParameters()) {
|
for (ValueParameterDescriptor parameter : parameters) {
|
||||||
if (!parameter.getType().isError()) {
|
if (!parameter.getType().isError()) {
|
||||||
PropertyDescriptor property = trace.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter);
|
PropertyDescriptor property = trace.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter);
|
||||||
if (property != null) {
|
if (property != null) {
|
||||||
@@ -259,9 +263,9 @@ public class DeclarationResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createCopyFunction(@NotNull MutableClassDescriptor classDescriptor, @NotNull ConstructorDescriptor constructorDescriptor) {
|
private void createCopyFunction(@NotNull MutableClassDescriptor classDescriptor, List<ValueParameterDescriptor> parameters) {
|
||||||
SimpleFunctionDescriptor functionDescriptor = DescriptorResolver.createCopyFunctionDescriptor(
|
SimpleFunctionDescriptor functionDescriptor = DescriptorResolver.createCopyFunctionDescriptor(
|
||||||
constructorDescriptor.getValueParameters(), classDescriptor, trace);
|
parameters, classDescriptor, trace);
|
||||||
|
|
||||||
classDescriptor.getBuilder().addFunctionDescriptor(functionDescriptor);
|
classDescriptor.getBuilder().addFunctionDescriptor(functionDescriptor);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -175,7 +175,7 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!constructor.getValueParameters().isEmpty() && name.equals(DescriptorResolver.COPY_METHOD_NAME)) {
|
if (name.equals(DescriptorResolver.COPY_METHOD_NAME)) {
|
||||||
SimpleFunctionDescriptor copyFunctionDescriptor = DescriptorResolver.createCopyFunctionDescriptor(
|
SimpleFunctionDescriptor copyFunctionDescriptor = DescriptorResolver.createCopyFunctionDescriptor(
|
||||||
constructor.getValueParameters(),
|
constructor.getValueParameters(),
|
||||||
thisDescriptor, trace);
|
thisDescriptor, trace);
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
data class A
|
||||||
|
|
||||||
|
fun foo(a: A) {
|
||||||
|
a.<!UNRESOLVED_REFERENCE!>component1<!>()
|
||||||
|
a.<!UNRESOLVED_REFERENCE!>component2<!>()
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
data class DataClass
|
data class DataClass
|
||||||
|
data class OtherDataClass()
|
||||||
@@ -2,4 +2,10 @@ package test
|
|||||||
|
|
||||||
kotlin.data() internal final class DataClass {
|
kotlin.data() internal final class DataClass {
|
||||||
/*primary*/ public constructor DataClass()
|
/*primary*/ public constructor DataClass()
|
||||||
|
internal final /*synthesized*/ fun copy(): test.DataClass
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin.data() internal final class OtherDataClass {
|
||||||
|
/*primary*/ public constructor OtherDataClass()
|
||||||
|
internal final /*synthesized*/ fun copy(): test.OtherDataClass
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2127,6 +2127,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("noConstructor.kt")
|
||||||
|
public void testNoConstructor() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dataClasses/noConstructor.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("notADataClass.kt")
|
@TestMetadata("notADataClass.kt")
|
||||||
public void testNotADataClass() throws Exception {
|
public void testNotADataClass() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dataClasses/notADataClass.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dataClasses/notADataClass.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user