Generate copy() in data class even if constructor is empty or not present

This commit is contained in:
Nikolay Krasko
2014-09-08 14:45:47 +04:00
parent fa393cf4f5
commit caee19cdc7
6 changed files with 32 additions and 9 deletions
@@ -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);
} }
@@ -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");