diff --git a/compiler/testData/readClass/FunClassParamNotNull.kt b/compiler/testData/readClass/FunClassParamNotNull.kt index 5dd2abe1afb..92e6b8f1fd8 100644 --- a/compiler/testData/readClass/FunClassParamNotNull.kt +++ b/compiler/testData/readClass/FunClassParamNotNull.kt @@ -1,5 +1,6 @@ namespace test import java.util.List +import java.lang.CharSequence -fun ff(p: List) = 1 +fun ff(p: List) = 1 diff --git a/compiler/testData/readClass/FunClassParamNullable.kt b/compiler/testData/readClass/FunClassParamNullable.kt index fafa4387a77..8b40b9ff0bc 100644 --- a/compiler/testData/readClass/FunClassParamNullable.kt +++ b/compiler/testData/readClass/FunClassParamNullable.kt @@ -1,5 +1,6 @@ namespace test import java.util.List +import java.lang.CharSequence -fun ff(p: List) = 1 +fun ff(p: List) = 1 diff --git a/compiler/testData/readClass/FunParamNotNull.kt b/compiler/testData/readClass/FunParamNotNull.kt index 72d84f88278..1673576064f 100644 --- a/compiler/testData/readClass/FunParamNotNull.kt +++ b/compiler/testData/readClass/FunParamNotNull.kt @@ -1,3 +1,3 @@ namespace test -fun fff(a: String) = 1 +fun fff(a: java.lang.CharSequence) = 1 diff --git a/compiler/testData/readClass/FunParamNullable.kt b/compiler/testData/readClass/FunParamNullable.kt index 288582a2f08..af1e70d8115 100644 --- a/compiler/testData/readClass/FunParamNullable.kt +++ b/compiler/testData/readClass/FunParamNullable.kt @@ -1,3 +1,3 @@ namespace test -fun fff(a: String?) = 1 +fun fff(a: java.lang.CharSequence?) = 1 diff --git a/compiler/testData/readClass/ReturnTypeClassParamNotNull.kt b/compiler/testData/readClass/ReturnTypeClassParamNotNull.kt index 90e394a811a..94613473c88 100644 --- a/compiler/testData/readClass/ReturnTypeClassParamNotNull.kt +++ b/compiler/testData/readClass/ReturnTypeClassParamNotNull.kt @@ -2,5 +2,6 @@ namespace test import java.util.List import java.util.ArrayList +import java.lang.CharSequence -fun ffgg(): List = ArrayList() +fun ffgg(): List = ArrayList() diff --git a/compiler/testData/readClass/ReturnTypeClassParamNullable.kt b/compiler/testData/readClass/ReturnTypeClassParamNullable.kt index 447be6bbfaa..4c9bb54a59e 100644 --- a/compiler/testData/readClass/ReturnTypeClassParamNullable.kt +++ b/compiler/testData/readClass/ReturnTypeClassParamNullable.kt @@ -2,5 +2,6 @@ namespace test import java.util.List import java.util.ArrayList +import java.lang.CharSequence -fun ffgg(): List = ArrayList() +fun ffgg(): List = ArrayList() diff --git a/compiler/testData/readClass/ReturnTypeNotNull.kt b/compiler/testData/readClass/ReturnTypeNotNull.kt index 0e025241a22..fd57fb31d3d 100644 --- a/compiler/testData/readClass/ReturnTypeNotNull.kt +++ b/compiler/testData/readClass/ReturnTypeNotNull.kt @@ -1,3 +1,3 @@ namespace test -fun ff(): String = "" +fun ff(): java.lang.CharSequence = throw Exception() diff --git a/compiler/testData/readClass/ReturnTypeNullable.kt b/compiler/testData/readClass/ReturnTypeNullable.kt index 6b3e33f7136..61d5a242d1d 100644 --- a/compiler/testData/readClass/ReturnTypeNullable.kt +++ b/compiler/testData/readClass/ReturnTypeNullable.kt @@ -1,3 +1,3 @@ namespace test -fun ff(): String? = "" +fun ff(): java.lang.CharSequence? = null diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java index 4f72a7af786..03936722192 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java @@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorImpl; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; @@ -36,11 +37,13 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeConstructor; import org.jetbrains.jet.lang.types.TypeProjection; +import org.jetbrains.jet.lang.types.Variance; import org.jetbrains.jet.plugin.JetLanguage; import org.junit.Assert; import java.io.File; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -146,137 +149,182 @@ public class ReadClassDataTest extends UsefulTestCase { } private void compareClassifiers(@NotNull ClassifierDescriptor a, @NotNull ClassifierDescriptor b) { - Assert.assertEquals(a.getName(), b.getName()); - System.out.println("classifier " + a.getName()); - if (a instanceof ClassDescriptor || b instanceof ClassDescriptor) { - compareClasses((ClassDescriptor) a, (ClassDescriptor) b); - } - } + String as = serializeContent((ClassDescriptor) a); + String bs = serializeContent((ClassDescriptor) b); - private void compareClasses(@NotNull ClassDescriptor a, @NotNull ClassDescriptor b) { - System.out.println("... is class"); + Assert.assertEquals(as, bs); + System.out.println(a); } + private String serializeContent(ClassDescriptor klass) { + + StringBuilder sb = new StringBuilder(); + sb.append("class "); + + serialize(klass, sb); + + // TODO: supers + // TODO: constructors + + sb.append(" {\n"); + + if (false) { + // TODO: for some reason I don't understand scope of ClassDescriptor came from source is empty + + List typeArguments = new ArrayList(); + for (TypeParameterDescriptor param : klass.getTypeConstructor().getParameters()) { + typeArguments.add(new TypeProjection(Variance.INVARIANT, param.getDefaultType())); + } + + JetScope memberScope = klass.getMemberScope(typeArguments); + for (DeclarationDescriptor member : memberScope.getAllDescriptors()) { + serialize(member, sb); + sb.append("\n"); + } + + } + + sb.append("}\n"); + return sb.toString(); + } + + private void compareFunctions(@NotNull FunctionDescriptor a, @NotNull FunctionDescriptor b) { - Assert.assertEquals(a.getName(), b.getName()); + String as = serialize(a); + String bs = serialize(b); - Assert.assertEquals(a.getTypeParameters().size(), b.getTypeParameters().size()); - for (int i = 0; i < a.getTypeParameters().size(); ++i) { - compareAnything(TypeParameterDescriptor.class, a.getTypeParameters().get(i), b.getTypeParameters().get(i)); - } - - Assert.assertEquals(a.getValueParameters().size(), b.getValueParameters().size()); - for (int i = 0; i < a.getValueParameters().size(); ++i) { - compareAnything(ValueParameterDescriptor.class, a.getValueParameters().get(i), b.getValueParameters().get(i)); - } - compareTypes(a.getReturnType(), b.getReturnType()); - System.out.println("fun " + a.getName() + "(...): " + a.getReturnType()); + Assert.assertEquals(as, bs); + System.out.println(as); } - private void compareAnything(Object a, Object b) { - if (a instanceof JetType || b instanceof JetType) { - compareTypes((JetType) a, (JetType) b); - } else if (a instanceof TypeConstructor && b instanceof TypeConstructor) { - compareTypeConstructors((TypeConstructor) a, (TypeConstructor) b); - } else if (a instanceof List || b instanceof List) { - compareLists((List) a, (List) b); - } else if (a instanceof TypeProjection || b instanceof TypeProjection) { - compareTypeProjections((TypeProjection) a, (TypeProjection) b); - } else if (a instanceof TypeParameterDescriptor || b instanceof TypeParameterDescriptor) { - compareTypeParameterDescriptors((TypeParameterDescriptor) a, (TypeParameterDescriptor) b); - } else { - Assert.assertEquals(a, b); - } - } - - private void compareTypeParameterDescriptors(TypeParameterDescriptor a, TypeParameterDescriptor b) { - compareAnything(TypeParameterDescriptor.class, a, b); - } - - private void compareTypeProjections(TypeProjection a, TypeProjection b) { - compareAnything(TypeProjection.class, a, b); - } - - private void compareLists(List a, List b) { - Assert.assertEquals(a.size(), b.size()); - for (int i = 0; i < a.size(); ++i) { - compareAnything(a.get(i), b.get(i)); - } - } - private void compareTypeConstructors(TypeConstructor a, TypeConstructor b) { - //compareAnything(TypeConstructor.class, a, b); - Assert.assertEquals(a.toString(), b.toString()); - } - - private void compareTypes(JetType a, JetType b) { - compareAnything(JetType.class, a, b); - } - - private void compareAnything(Class clazz, T a, T b) { - System.out.println("Comparing " + clazz); - Assert.assertNotNull(a); - Assert.assertNotNull(b); - - for (Method method : clazz.getMethods()) { - if (!isGetter(method)) { - continue; - } - - if (JetScope.class.isAssignableFrom(method.getReturnType())) { - continue; - } - - if (method.getName().equals("getContainingDeclaration")) { - continue; - } - - if (method.getName().equals("isReified")) { - // TODO - continue; - } - - if (clazz.equals(ValueParameterDescriptor.class)) { - if (method.getName().equals("isRef") || method.getName().equals("getOriginal")) { - continue; - } - } - - if (method.getDeclaringClass().equals(DeclarationDescriptorImpl.class) - || method.getDeclaringClass().equals(DeclarationDescriptor.class)) - { - if (method.getName().equals("getOriginal")) { - continue; - } - } - - System.out.println(method.getName()); - Object ap = invoke(method, a); - Object bp = invoke(method, b); - compareAnything(ap, bp); - } - } - - private static boolean isGetter(Method method) { - if (method.getParameterTypes().length > 0) { - return false; - } - if (method.getName().matches("is.+")) { - return method.getReturnType().equals(boolean.class); - } else if (method.getName().matches("get.+")) { - return true; - } else { - return false; - } - } - private static Object invoke(Method method, Object thiz, Object... args) { try { + method.setAccessible(true); return method.invoke(thiz, args); } catch (Exception e) { - throw new RuntimeException("failed to invoke " + method + ": " + e); + throw new RuntimeException("failed to invoke " + method + ": " + e, e); } } + + + private void serialize(FunctionDescriptor fun, StringBuilder sb) { + sb.append("fun "); + if (!fun.getTypeParameters().isEmpty()) { + sb.append("<"); + serializeCommaSeparated(fun.getTypeParameters(), sb); + sb.append(">"); + } + sb.append(fun.getName()); + sb.append("("); + serializeCommaSeparated(fun.getValueParameters(), sb); + sb.append("): "); + serialize(fun.getReturnType(), sb); + } + + private void serialize(ValueParameterDescriptor valueParameter, StringBuilder sb) { + sb.append(valueParameter.getName()); + sb.append(": "); + if (valueParameter.getVarargElementType() != null) { + sb.append("vararg "); + serialize(valueParameter.getVarargElementType()); + } else { + serialize(valueParameter.getOutType()); + } + if (valueParameter.hasDefaultValue()) { + sb.append(" = ?"); + } + } + + private void serialize(Variance variance, StringBuilder sb) { + sb.append(variance); + } + + private void serialize(JetType type, StringBuilder sb) { + serialize(type.getConstructor().getDeclarationDescriptor(), sb); + if (!type.getArguments().isEmpty()) { + sb.append("<"); + boolean first = true; + for (TypeProjection proj : type.getArguments()) { + serialize(proj.getProjectionKind(), sb); + serialize(proj.getType(), sb); + if (!first) { + sb.append(", "); + } + first = false; + } + sb.append(">"); + } + } + + private String serialize(Object o) { + StringBuilder sb = new StringBuilder(); + serialize(o, sb); + return sb.toString(); + } + + private void serializeCommaSeparated(List list, StringBuilder sb) { + boolean first = true; + for (Object o : list) { + if (!first) { + sb.append(", "); + } + serialize(o, sb); + first = false; + } + } + + private void serialize(Object o, StringBuilder sb) { + // TODO: cache + for (Method method : ReadClassDataTest.class.getDeclaredMethods()) { + if (!method.getName().equals("serialize")) { + continue; + } + if (method.getParameterTypes().length != 2) { + continue; + } + if (!method.getParameterTypes()[1].equals(StringBuilder.class)) { + continue; + } + if (method.getParameterTypes()[0].equals(Object.class)) { + continue; + } + if (method.getParameterTypes()[0].isInstance(o)) { + invoke(method, this, o, sb); + return; + } + } + throw new IllegalStateException("don't know how to serialize " + o + " (of " + o.getClass() + ")"); + } + + private void serialize(ModuleDescriptor module, StringBuilder sb) { + // nop + } + + private void serialize(ClassDescriptor clazz, StringBuilder sb) { + serialize(clazz.getContainingDeclaration(), sb); + sb.append("."); + sb.append(clazz.getName()); + } + + private void serialize(NamespaceDescriptor ns, StringBuilder sb) { + if (ns.getContainingDeclaration() == null) { + // root ns + return; + } + serialize(ns.getContainingDeclaration(), sb); + sb.append("."); + sb.append(ns.getName()); + } + + private void serialize(TypeParameterDescriptor param, StringBuilder sb) { + if (param.getVariance() != Variance.INVARIANT) { + serialize(param.getVariance(), sb); + } + sb.append(param.getName()); + // TODO: serialize bounds + } + public static Test suite() { return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/readClass", true, new JetTestCaseBuilder.NamedTestFactory() {