Generate copy function for data classes

#KT-2779 Fixed
This commit is contained in:
Natalia.Ukhorskaya
2012-10-31 15:34:46 +04:00
parent 6009038342
commit 3b58eb4b60
20 changed files with 388 additions and 33 deletions
@@ -0,0 +1,42 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.codegen;
import org.jetbrains.asm4.Type;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.JetParameter;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
public interface DefaultParameterValueLoader {
void putValueOnStack(ValueParameterDescriptor descriptor, ExpressionCodegen codegen);
DefaultParameterValueLoader DEFAULT = new DefaultParameterValueLoader() {
@Override
public void putValueOnStack(
ValueParameterDescriptor descriptor,
ExpressionCodegen codegen
) {
JetParameter jetParameter = (JetParameter) descriptorToDeclaration(codegen.getBindingContext(), descriptor);
assert jetParameter != null;
Type propertyType = codegen.typeMapper.mapType(descriptor.getType());
codegen.gen(jetParameter.getDefaultValue(), propertyType);
}
};
}
@@ -33,12 +33,12 @@ import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter;
import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter;
import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.GenerationStateAware;
import org.jetbrains.jet.codegen.state.JetTypeMapper;
import org.jetbrains.jet.codegen.state.JetTypeMapperMode;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
import org.jetbrains.jet.lang.psi.JetNamedFunction;
import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
@@ -107,7 +107,7 @@ public class FunctionCodegen extends GenerationStateAware {
}
}
generateDefaultIfNeeded(context, state, v, jvmSignature.getAsmMethod(), functionDescriptor, kind);
generateDefaultIfNeeded(context, state, v, jvmSignature.getAsmMethod(), functionDescriptor, kind, DefaultParameterValueLoader.DEFAULT);
}
private void generateMethodHeaderAndBody(
@@ -142,10 +142,7 @@ public class FunctionCodegen extends GenerationStateAware {
return;
}
LocalVariablesInfo localVariablesInfo = new LocalVariablesInfo();
for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) {
localVariablesInfo.names.add(parameter.getName().getName());
}
LocalVariablesInfo localVariablesInfo = generateLocalVariablesInfo(functionDescriptor);
MethodBounds methodBounds = generateMethodBody(mv, fun, functionDescriptor, context, asmMethod, localVariablesInfo);
@@ -161,7 +158,7 @@ public class FunctionCodegen extends GenerationStateAware {
thisType = null;
}
generateLocalVariableTable(mv, functionDescriptor, thisType, localVariablesInfo, methodBounds);
generateLocalVariableTable(typeMapper, mv, functionDescriptor, thisType, localVariablesInfo, methodBounds);
endVisit(mv, null, fun);
}
@@ -218,24 +215,33 @@ public class FunctionCodegen extends GenerationStateAware {
return new MethodBounds(methodBegin, methodEnd);
}
private static class MethodBounds {
public static class MethodBounds {
@NotNull private final Label begin;
@NotNull private final Label end;
private MethodBounds(@NotNull Label begin, @NotNull Label end) {
public MethodBounds(@NotNull Label begin, @NotNull Label end) {
this.begin = begin;
this.end = end;
}
}
private static class LocalVariablesInfo {
@NotNull private final Collection<String> names = new HashSet<String>();
public static class LocalVariablesInfo {
@NotNull public final Collection<String> names = new HashSet<String>();
@NotNull private final Map<Name, Label> labelsForSharedVars = new HashMap<Name, Label>();
@NotNull public final Map<Name, Label> labelsForSharedVars = new HashMap<Name, Label>();
}
private void generateLocalVariableTable(
public static LocalVariablesInfo generateLocalVariablesInfo(FunctionDescriptor functionDescriptor) {
LocalVariablesInfo localVariablesInfo = new LocalVariablesInfo();
for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) {
localVariablesInfo.names.add(parameter.getName().getName());
}
return localVariablesInfo;
}
public static void generateLocalVariableTable(
@NotNull JetTypeMapper typeMapper,
@NotNull MethodVisitor mv,
@NotNull FunctionDescriptor functionDescriptor,
@Nullable Type thisType,
@@ -525,7 +531,8 @@ public class FunctionCodegen extends GenerationStateAware {
ClassBuilder v,
Method jvmSignature,
@NotNull FunctionDescriptor functionDescriptor,
OwnerKind kind
OwnerKind kind,
DefaultParameterValueLoader loadStrategy
) {
DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();
@@ -575,7 +582,7 @@ public class FunctionCodegen extends GenerationStateAware {
else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
generateDefaultImpl(owner, state, jvmSignature, functionDescriptor, kind, receiverParameter, hasReceiver, isStatic,
ownerInternalName,
isConstructor, mv, iv);
isConstructor, mv, iv, loadStrategy);
}
}
@@ -591,7 +598,8 @@ public class FunctionCodegen extends GenerationStateAware {
JvmClassName ownerInternalName,
boolean constructor,
MethodVisitor mv,
InstructionAdapter iv
InstructionAdapter iv,
DefaultParameterValueLoader loadStrategy
) {
mv.visitCode();
@@ -656,9 +664,7 @@ public class FunctionCodegen extends GenerationStateAware {
Label loadArg = new Label();
iv.ifeq(loadArg);
JetParameter jetParameter = (JetParameter) descriptorToDeclaration(state.getBindingContext(), parameterDescriptor);
assert jetParameter != null;
codegen.gen(jetParameter.getDefaultValue(), t);
loadStrategy.putValueOnStack(parameterDescriptor, codegen);
int ind = frameMap.getIndex(parameterDescriptor);
iv.store(ind, t);
@@ -32,6 +32,7 @@ import org.jetbrains.jet.codegen.binding.CodegenBinding;
import org.jetbrains.jet.codegen.binding.MutableClosure;
import org.jetbrains.jet.codegen.context.CodegenContext;
import org.jetbrains.jet.codegen.context.ConstructorContext;
import org.jetbrains.jet.codegen.context.MethodContext;
import org.jetbrains.jet.codegen.signature.*;
import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter;
import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter;
@@ -41,6 +42,7 @@ import org.jetbrains.jet.codegen.state.JetTypeMapperMode;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.OverridingUtil;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
@@ -414,6 +416,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (!KotlinBuiltIns.getInstance().isData(descriptor)) return;
generateComponentFunctionsForDataClasses();
generateCopyFunctionForDataClasses();
List<PropertyDescriptor> properties = getDataProperties();
if (!properties.isEmpty()) {
@@ -423,6 +426,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
private void generateCopyFunctionForDataClasses() {
FunctionDescriptor copyFunction = bindingContext.get(BindingContext.DATA_CLASS_COPY_FUNCTION, descriptor);
if (copyFunction != null) {
generateCopyFunction(copyFunction);
}
}
private void generateDataClassToStringIfNeeded(List<PropertyDescriptor> properties) {
ClassDescriptor stringClass = KotlinBuiltIns.getInstance().getString();
if (getDeclaredFunctionByRawSignature(descriptor, Name.identifier("toString"), stringClass) == null) {
@@ -640,6 +650,76 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
FunctionCodegen.endVisit(mv, function.getName().getName(), myClass);
}
private void generateCopyFunction(@NotNull final FunctionDescriptor function) {
JetType returnType = function.getReturnType();
assert returnType != null : "Return type of copy function should not be null: " + function;
JvmMethodSignature methodSignature = typeMapper.mapSignature(function.getName(), function);
final String methodDesc = methodSignature.getAsmMethod().getDescriptor();
MethodVisitor mv = v.newMethod(myClass, FunctionCodegen.getMethodAsmFlags(function, OwnerKind.IMPLEMENTATION),
function.getName().getName(), methodDesc,
null, null);
FunctionCodegen.genJetAnnotations(state, function, null, null, mv);
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
ConstructorDescriptor constructor = DescriptorUtils.getConstructorOfDataClass(descriptor);
Label methodBegin = new Label();
mv.visitLabel(methodBegin);
final Type thisDescriptorType = typeMapper.mapType(descriptor.getDefaultType());
iv.anew(thisDescriptorType);
iv.dup();
String thisInternalName = thisDescriptorType.getInternalName();
assert function.getValueParameters().size() == constructor.getValueParameters().size() :
"Number of parameters of copy function and constructor are different. Copy: " + function.getValueParameters().size() + ", constructor: " + constructor.getValueParameters().size();
int parameterIndex = 0;
for (ValueParameterDescriptor parameterDescriptor : function.getValueParameters()) {
iv.load(parameterIndex + 1, typeMapper.mapType(parameterDescriptor.getType()));
parameterIndex++;
}
String constructorJvmDescriptor = typeMapper.mapToCallableMethod(constructor).getSignature().getAsmMethod().getDescriptor();
iv.invokespecial(thisInternalName, "<init>", constructorJvmDescriptor);
iv.areturn(thisDescriptorType);
Label methodEnd = new Label();
mv.visitLabel(methodEnd);
FunctionCodegen.MethodBounds methodBounds = new FunctionCodegen.MethodBounds(methodBegin, methodEnd);
FunctionCodegen.generateLocalVariableTable(typeMapper, mv, function, thisDescriptorType, FunctionCodegen.generateLocalVariablesInfo(function), methodBounds);
FunctionCodegen.endVisit(mv, function.getName().getName(), myClass);
final MethodContext functionContext = context.intoFunction(function);
FunctionCodegen.generateDefaultIfNeeded(functionContext, state, v, methodSignature.getAsmMethod(), function, OwnerKind.IMPLEMENTATION,
new DefaultParameterValueLoader() {
@Override
public void putValueOnStack(
ValueParameterDescriptor descriptor,
ExpressionCodegen codegen
) {
assert (KotlinBuiltIns.getInstance().isData((ClassDescriptor) function.getContainingDeclaration()))
: "Trying to create function with default arguments for function that isn't presented in code for class without data annotation";
PropertyDescriptor propertyDescriptor = codegen.getBindingContext().get(
BindingContext.VALUE_PARAMETER_AS_PROPERTY, descriptor);
assert propertyDescriptor != null : "Trying to generate default value for parameter of copy function that doesn't correspond to any property";
codegen.v.load(0, thisDescriptorType);
Type propertyType = codegen.typeMapper.mapType(propertyDescriptor.getType());
codegen.intermediateValueForProperty(propertyDescriptor, false, null).put(propertyType, codegen.v);
}
});
}
private void generateEnumMethods() {
if (myEnumConstants.size() > 0) {
{
@@ -971,7 +1051,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
assert constructorDescriptor != null;
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor,
OwnerKind.IMPLEMENTATION);
OwnerKind.IMPLEMENTATION, DefaultParameterValueLoader.DEFAULT);
}
private void genSuperCallToDelegatorToSuperClass(InstructionAdapter iv) {
@@ -238,6 +238,8 @@ public interface BindingContext {
WritableSlice<ValueParameterDescriptor, FunctionDescriptor> DATA_CLASS_COMPONENT_FUNCTION =
Slices.<ValueParameterDescriptor, FunctionDescriptor>sliceBuilder().build();
WritableSlice<ClassDescriptor, FunctionDescriptor> DATA_CLASS_COPY_FUNCTION =
Slices.<ClassDescriptor, FunctionDescriptor>sliceBuilder().build();
WritableSlice<FqName, ClassDescriptor> FQNAME_TO_CLASS_DESCRIPTOR = new BasicWritableSlice<FqName, ClassDescriptor>(DO_NOTHING, true);
WritableSlice<FqName, NamespaceDescriptor> FQNAME_TO_NAMESPACE_DESCRIPTOR =
@@ -91,7 +91,7 @@ public class DeclarationResolver {
resolveConstructorHeaders();
resolveAnnotationStubsOnClassesAndConstructors();
resolveFunctionAndPropertyHeaders();
createComponentFunctionsForDataClasses();
createFunctionsForDataClasses();
importsResolver.processMembersImports(rootScope);
checkRedeclarationsInNamespaces();
checkRedeclarationsInInnerClassNames();
@@ -219,24 +219,22 @@ public class DeclarationResolver {
}
}
private void createComponentFunctionsForDataClasses() {
private void createFunctionsForDataClasses() {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
JetClass jetClass = entry.getKey();
MutableClassDescriptor classDescriptor = entry.getValue();
if (jetClass.hasPrimaryConstructor() && KotlinBuiltIns.getInstance().isData(classDescriptor)) {
createComponentFunctions(classDescriptor);
ConstructorDescriptor constructor = DescriptorUtils.getConstructorOfDataClass(classDescriptor);
createComponentFunctions(classDescriptor, constructor);
createCopyFunction(classDescriptor, constructor);
}
}
}
private void createComponentFunctions(MutableClassDescriptor classDescriptor) {
Set<ConstructorDescriptor> constructors = classDescriptor.getConstructors();
assert constructors.size() == 1 : "Data class hasn't a single constructor: " + constructors.size();
ConstructorDescriptor constructor = constructors.iterator().next();
private void createComponentFunctions(@NotNull MutableClassDescriptor classDescriptor, @NotNull ConstructorDescriptor constructorDescriptor) {
int parameterIndex = 0;
for (ValueParameterDescriptor parameter : constructor.getValueParameters()) {
for (ValueParameterDescriptor parameter : constructorDescriptor.getValueParameters()) {
if (!ErrorUtils.isErrorType(parameter.getType())) {
PropertyDescriptor property = trace.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter);
if (property != null) {
@@ -251,6 +249,13 @@ public class DeclarationResolver {
}
}
private void createCopyFunction(@NotNull MutableClassDescriptor classDescriptor, @NotNull ConstructorDescriptor constructorDescriptor) {
SimpleFunctionDescriptor functionDescriptor = DescriptorResolver.createCopyFunctionDescriptor(
constructorDescriptor.getValueParameters(), classDescriptor, trace);
classDescriptor.getBuilder().addFunctionDescriptor(functionDescriptor);
}
private void processPrimaryConstructor(MutableClassDescriptor classDescriptor, JetClass klass) {
if (classDescriptor.getKind() == ClassKind.TRAIT) {
JetParameterList primaryConstructorParameterList = klass.getPrimaryConstructorParameterList();
@@ -356,8 +361,8 @@ public class DeclarationResolver {
descriptorMap.put(desc.getName(), desc);
}
}
reportRedeclarations(descriptorMap);
reportRedeclarations(descriptorMap);
}
}
@@ -392,5 +397,5 @@ public class DeclarationResolver {
}
}
}
@@ -57,6 +57,7 @@ import static org.jetbrains.jet.lexer.JetTokens.OVERRIDE_KEYWORD;
public class DescriptorResolver {
public static final Name VALUE_OF_METHOD_NAME = Name.identifier("valueOf");
public static final Name VALUES_METHOD_NAME = Name.identifier("values");
public static final Name COPY_METHOD_NAME = Name.identifier("copy");
public static final String COMPONENT_FUNCTION_NAME_PREFIX = "component";
@NotNull
@@ -349,6 +350,53 @@ public class DescriptorResolver {
return functionDescriptor;
}
@NotNull
public static SimpleFunctionDescriptor createCopyFunctionDescriptor(
@NotNull Collection<ValueParameterDescriptor> constructorParameters,
@NotNull ClassDescriptor classDescriptor,
@NotNull BindingTrace trace
) {
JetType returnType = classDescriptor.getDefaultType();
SimpleFunctionDescriptorImpl functionDescriptor = new SimpleFunctionDescriptorImpl(
classDescriptor,
Collections.<AnnotationDescriptor>emptyList(),
COPY_METHOD_NAME,
CallableMemberDescriptor.Kind.SYNTHESIZED
);
List<ValueParameterDescriptor> parameterDescriptors = Lists.newArrayList();
for (ValueParameterDescriptor parameter : constructorParameters) {
PropertyDescriptor propertyDescriptor = trace.getBindingContext().get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter);
// If parameter hasn't corresponding property, so it mustn't have default value as a parameter in copy function for data class
boolean declaresDefaultValue = propertyDescriptor != null;
ValueParameterDescriptorImpl parameterDescriptor =
new ValueParameterDescriptorImpl(functionDescriptor, parameter.getIndex(), parameter.getAnnotations(),
parameter.getName(), parameter.isVar(), parameter.getType(),
declaresDefaultValue,
parameter.getVarargElementType());
parameterDescriptors.add(parameterDescriptor);
if (declaresDefaultValue) {
trace.record(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameterDescriptor, propertyDescriptor);
}
}
functionDescriptor.initialize(
null,
classDescriptor.getImplicitReceiver(),
Collections.<TypeParameterDescriptor>emptyList(),
parameterDescriptors,
returnType,
Modality.FINAL,
classDescriptor.getVisibility(),
true
);
trace.record(BindingContext.DATA_CLASS_COPY_FUNCTION, classDescriptor, functionDescriptor);
return functionDescriptor;
}
public static Visibility getDefaultVisibility(JetModifierListOwner modifierListOwner, DeclarationDescriptor containingDescriptor) {
Visibility defaultVisibility;
if (containingDescriptor instanceof ClassDescriptor) {
@@ -365,4 +365,10 @@ public class DescriptorUtils {
+ (classifier == null ? "null" : classifier.getClass());
return (ClassDescriptor) classifier;
}
public static ConstructorDescriptor getConstructorOfDataClass(ClassDescriptor classDescriptor) {
Collection<ConstructorDescriptor> constructors = classDescriptor.getConstructors();
assert constructors.size() == 1 : "Data class must have only one constructor: " + constructors;
return constructors.iterator().next();
}
}
@@ -174,6 +174,12 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
break;
}
}
if (!constructor.getValueParameters().isEmpty() && name.equals(DescriptorResolver.COPY_METHOD_NAME)) {
SimpleFunctionDescriptor copyFunctionDescriptor = DescriptorResolver.createCopyFunctionDescriptor(
constructor.getValueParameters(),
thisDescriptor, resolveSession.getTrace());
result.add(copyFunctionDescriptor);
}
}
private void generateEnumClassObjectMethods(@NotNull Collection<? super FunctionDescriptor> result, @NotNull Name name) {
@@ -307,6 +313,7 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
if (functions.isEmpty()) break;
n++;
}
getFunctions(Name.identifier("copy"));
}
@Override
@@ -0,0 +1,29 @@
data class A(val a: Int = 1, val b: String = "$a") {}
fun box() : String {
var result = ""
val a = A()
val b = a.copy()
if (b.a == 1 && b.b == "1") {
result += "1"
}
val c = a.copy(a = 2)
if (c.a == 2 && c.b == "1") {
result += "2"
}
val d = a.copy(b = "2")
if (d.a == 1 && d.b == "2") {
result += "3"
}
val e = a.copy(a = 2, b = "2")
if (e.a == 2 && e.b == "2") {
result += "4"
}
if (result == "1234") {
return "OK"
}
return "fail"
}
@@ -0,0 +1,17 @@
data class A(a: Int, b: String) {}
fun box() : String {
for (method in javaClass<A>().getDeclaredMethods()) {
if (method.getName() == "copy"){
val parameterTypes = method.getParameterTypes()
if (parameterTypes != null && parameterTypes.size == 2) {
val copy = A(1, "a").copy(a = 2, b = "b")
return "OK"
}
else {
return "Method copy has " + (if (parameterTypes == null) "0" else parameterTypes.size) + " parameters, expected 2"
}
}
}
return "fail"
}
@@ -0,0 +1,29 @@
data class A(val a: Int, val b: String) {}
fun box() : String {
var result = ""
val a = A(1, "a")
val b = a.copy()
if (b.a == 1 && b.b == "a") {
result += "1"
}
val c = a.copy(a = 2)
if (c.a == 2 && c.b == "a") {
result += "2"
}
val d = a.copy(b = "b")
if (d.a == 1 && d.b == "b") {
result += "3"
}
val e = a.copy(a = 2, b = "b")
if (e.a == 2 && e.b == "b") {
result += "4"
}
if (result == "1234") {
return "OK"
}
return "fail"
}
@@ -0,0 +1,29 @@
data class A(var a: Int, var b: String) {}
fun box() : String {
var result = ""
val a = A(1, "a")
val b = a.copy()
if (b.a == 1 && b.b == "a") {
result += "1"
}
val c = a.copy(a = 2)
if (c.a == 2 && c.b == "a") {
result += "2"
}
val d = a.copy(b = "b")
if (d.a == 1 && d.b == "b") {
result += "3"
}
val e = a.copy(a = 2, b = "b")
if (e.a == 2 && e.b == "b") {
result += "4"
}
if (result == "1234") {
return "OK"
}
return "fail"
}
@@ -0,0 +1,14 @@
data class A(val a: Foo<String>) {}
class Foo<T>(val a: T) { }
fun box() : String {
val f1 = Foo("a")
val f2 = Foo("b")
val a = A(f1)
val b = a.copy(f2)
if (b.a.a == "b") {
return "OK"
}
return "fail"
}
@@ -4,6 +4,7 @@ jet.data() internal final class test.DataClass : jet.Any {
public final /*constructor*/ fun <init>(/*0*/ x: jet.String, /*1*/ y: jet.Int, /*2*/ z: jet.Double): test.DataClass
internal final /*synthesized*/ fun component1(): jet.String
internal final /*synthesized*/ fun component2(): jet.Double
internal final /*synthesized*/ fun copy(/*0*/ x: jet.String = ?, /*1*/ y: jet.Int, /*2*/ z: jet.Double = ?): test.DataClass
internal final var x: jet.String
internal final val z: jet.Double
}
@@ -3,5 +3,6 @@ namespace test
jet.data() internal final class test.DataClass : jet.Any {
public final /*constructor*/ fun <init>(/*0*/ x: jet.String): test.DataClass
internal final /*synthesized*/ fun component1(): jet.String
internal final /*synthesized*/ fun copy(/*0*/ x: jet.String = ?): test.DataClass
internal final val x: jet.String
}
@@ -3,5 +3,6 @@ namespace test
jet.data() internal open class test.DataClass : jet.Any {
public final /*constructor*/ fun <init>(/*0*/ x: jet.String): test.DataClass
internal final /*synthesized*/ fun component1(): jet.String
internal final /*synthesized*/ fun copy(/*0*/ x: jet.String = ?): test.DataClass
internal final val x: jet.String
}
@@ -3,5 +3,6 @@ namespace test
jet.data() internal open class test.DataClass : jet.Any {
public final /*constructor*/ fun <init>(/*0*/ x: jet.String): test.DataClass
internal final /*synthesized*/ fun component1(): jet.String
internal final /*synthesized*/ fun copy(/*0*/ x: jet.String = ?): test.DataClass
internal open val x: jet.String
}
@@ -4,6 +4,7 @@ jet.data() internal final class test.DataClass : jet.Any {
public final /*constructor*/ fun <init>(/*0*/ x: jet.String, /*1*/ y: jet.Int): test.DataClass
internal final /*synthesized*/ fun component1(): jet.String
internal final /*synthesized*/ fun component2(): jet.Int
internal final /*synthesized*/ fun copy(/*0*/ x: jet.String = ?, /*1*/ y: jet.Int = ?): test.DataClass
internal final val x: jet.String
internal final val y: jet.Int
}
@@ -4,6 +4,7 @@ jet.data() internal final class test.DataClass : jet.Any {
public final /*constructor*/ fun <init>(/*0*/ x: jet.String, /*1*/ y: jet.Int): test.DataClass
internal final /*synthesized*/ fun component1(): jet.String
internal final /*synthesized*/ fun component2(): jet.Int
internal final /*synthesized*/ fun copy(/*0*/ x: jet.String = ?, /*1*/ y: jet.Int = ?): test.DataClass
internal final var x: jet.String
internal final var y: jet.Int
}
@@ -25,7 +25,7 @@ import java.io.File;
/** This class is generated by {@link org.jetbrains.jet.codegen.AbstractDataClassCodegenTest}. DO NOT MODIFY MANUALLY */
@TestMetadata("compiler/testData/codegen/dataClasses")
@InnerTestClasses({DataClassCodegenTestGenerated.Equals.class, DataClassCodegenTestGenerated.Hashcode.class, DataClassCodegenTestGenerated.Tostring.class})
@InnerTestClasses({DataClassCodegenTestGenerated.Copy.class, DataClassCodegenTestGenerated.Equals.class, DataClassCodegenTestGenerated.Hashcode.class, DataClassCodegenTestGenerated.Tostring.class})
public class DataClassCodegenTestGenerated extends AbstractDataClassCodegenTest {
public void testAllFilesPresentInDataClasses() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.codegen.AbstractDataClassCodegenTest", new File("compiler/testData/codegen/dataClasses"), "kt", true);
@@ -81,6 +81,40 @@ public class DataClassCodegenTestGenerated extends AbstractDataClassCodegenTest
blackBoxFileByFullPath("compiler/testData/codegen/dataClasses/unitComponent.kt");
}
@TestMetadata("compiler/testData/codegen/dataClasses/copy")
public static class Copy extends AbstractDataClassCodegenTest {
public void testAllFilesPresentInCopy() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.codegen.AbstractDataClassCodegenTest",
new File("compiler/testData/codegen/dataClasses/copy"), "kt", true);
}
@TestMetadata("constructorWithDefaultParam.kt")
public void testConstructorWithDefaultParam() throws Exception {
blackBoxFileByFullPath("compiler/testData/codegen/dataClasses/copy/constructorWithDefaultParam.kt");
}
@TestMetadata("paramWithoutProperty.kt")
public void testParamWithoutProperty() throws Exception {
blackBoxFileByFullPath("compiler/testData/codegen/dataClasses/copy/paramWithoutProperty.kt");
}
@TestMetadata("valInConstructorParams.kt")
public void testValInConstructorParams() throws Exception {
blackBoxFileByFullPath("compiler/testData/codegen/dataClasses/copy/valInConstructorParams.kt");
}
@TestMetadata("varInConstructorParams.kt")
public void testVarInConstructorParams() throws Exception {
blackBoxFileByFullPath("compiler/testData/codegen/dataClasses/copy/varInConstructorParams.kt");
}
@TestMetadata("withGenericParameter.kt")
public void testWithGenericParameter() throws Exception {
blackBoxFileByFullPath("compiler/testData/codegen/dataClasses/copy/withGenericParameter.kt");
}
}
@TestMetadata("compiler/testData/codegen/dataClasses/equals")
public static class Equals extends AbstractDataClassCodegenTest {
public void testAllFilesPresentInEquals() throws Exception {
@@ -243,6 +277,7 @@ public class DataClassCodegenTestGenerated extends AbstractDataClassCodegenTest
public static Test suite() {
TestSuite suite = new TestSuite("DataClassCodegenTestGenerated");
suite.addTestSuite(DataClassCodegenTestGenerated.class);
suite.addTestSuite(Copy.class);
suite.addTestSuite(Equals.class);
suite.addTestSuite(Hashcode.class);
suite.addTestSuite(Tostring.class);