diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 6cc20a1ed98..70dd53b2527 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -550,6 +550,9 @@ public class JetTypeMapper { signatureVisitor.writeClassBound(); for (JetType jetType : typeParameterDescriptor.getUpperBounds()) { + if (jetType.equals(JetStandardClasses.getNullableAnyType())) { + continue; + } if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) { if (!CodegenUtil.isInterface(jetType)) { mapType(jetType, signatureVisitor); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index b2bc1cf5568..13edfab638f 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -65,10 +65,24 @@ public class JavaDescriptorResolver { private static class TypeParameterDescriptorInitialization { private final TypeParameterDescriptorOrigin origin; private final TypeParameterDescriptor descriptor; + @Nullable + private final List upperBoundsForKotlin; + @Nullable + private final List lowerBoundsForKotlin; - private TypeParameterDescriptorInitialization(TypeParameterDescriptorOrigin origin, TypeParameterDescriptor descriptor) { - this.origin = origin; + private TypeParameterDescriptorInitialization(TypeParameterDescriptor descriptor) { + this.origin = TypeParameterDescriptorOrigin.JAVA; this.descriptor = descriptor; + this.upperBoundsForKotlin = null; + this.lowerBoundsForKotlin = null; + } + + private TypeParameterDescriptorInitialization(TypeParameterDescriptor descriptor, + List upperBoundsForKotlin, List lowerBoundsForKotlin) { + this.origin = TypeParameterDescriptorOrigin.KOTLIN; + this.descriptor = descriptor; + this.upperBoundsForKotlin = upperBoundsForKotlin; + this.lowerBoundsForKotlin = lowerBoundsForKotlin; } } @@ -229,13 +243,71 @@ public class JavaDescriptorResolver { } @NotNull - private PsiTypeParameter getPsiTypeParameterByName(PsiTypeParameterListOwner clazz, String ownerName, String name) { + private PsiTypeParameter getPsiTypeParameterByName(PsiTypeParameterListOwner clazz, String name) { for (PsiTypeParameter typeParameter : clazz.getTypeParameters()) { if (typeParameter.getName().equals(name)) { return typeParameter; } } - throw new IllegalStateException("PsiTypeParameter '" + name + "' is not found in '" + ownerName + "'"); + throw new IllegalStateException("PsiTypeParameter '" + name + "' is not found"); + } + + private abstract class JetSignatureTypeParameterVisitor extends JetSignatureExceptionsAdapter { + + private final DeclarationDescriptor containingDeclaration; + private final PsiTypeParameterListOwner psiOwner; + private final String name; + private final TypeInfoVariance variance; + + protected JetSignatureTypeParameterVisitor(DeclarationDescriptor containingDeclaration, PsiTypeParameterListOwner psiOwner, + String name, TypeInfoVariance variance) + { + this.containingDeclaration = containingDeclaration; + this.psiOwner = psiOwner; + this.name = name; + this.variance = variance; + } + + int index = 0; + + List upperBounds = new ArrayList(); + List lowerBounds = new ArrayList(); + + @Override + public JetSignatureVisitor visitClassBound() { + return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) { + @Override + protected void done(@NotNull JetType jetType) { + upperBounds.add(jetType); + } + }; + } + + @Override + public JetSignatureVisitor visitInterfaceBound() { + return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) { + @Override + protected void done(@NotNull JetType jetType) { + upperBounds.add(jetType); + } + }; + } + + @Override + public void visitFormalTypeParameterEnd() { + TypeParameterDescriptor typeParameter = TypeParameterDescriptor.createForFurtherModification( + containingDeclaration, + Collections.emptyList(), // TODO: wrong + true, // TODO: wrong + JetSignatureUtils.translateVariance(variance), + name, + ++index); + PsiTypeParameter psiTypeParameter = getPsiTypeParameterByName(psiOwner, name); + typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(typeParameter, upperBounds, lowerBounds)); + done(typeParameter); + } + + protected abstract void done(TypeParameterDescriptor typeParameterDescriptor); } /** @@ -246,43 +318,11 @@ public class JavaDescriptorResolver { new JetSignatureReader(jetSignature).accept(new JetSignatureExceptionsAdapter() { @Override public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) { - return new JetSignatureExceptionsAdapter() { - int index = 0; - + return new JetSignatureTypeParameterVisitor(classDescriptor, clazz, name, variance) { @Override - public JetSignatureVisitor visitClassBound() { - return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) { - @Override - protected void done(@NotNull JetType jetType) { - // TODO - } - }; + protected void done(TypeParameterDescriptor typeParameterDescriptor) { + r.add(typeParameterDescriptor); } - - @Override - public JetSignatureVisitor visitInterfaceBound() { - return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) { - @Override - protected void done(@NotNull JetType jetType) { - // TODO - } - }; - } - - @Override - public void visitFormalTypeParameterEnd() { - TypeParameterDescriptor typeParameter = TypeParameterDescriptor.createForFurtherModification( - classDescriptor, - Collections.emptyList(), // TODO: wrong - true, // TODO: wrong - JetSignatureUtils.translateVariance(variance), - name, - ++index); - PsiTypeParameter psiTypeParameter = getPsiTypeParameterByName(clazz, clazz.getQualifiedName(), name); - typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(TypeParameterDescriptorOrigin.KOTLIN, typeParameter)); - r.add(typeParameter); - } - }; } @@ -332,14 +372,23 @@ public class JavaDescriptorResolver { psiTypeParameter.getName(), psiTypeParameter.getIndex() ); - typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(TypeParameterDescriptorOrigin.JAVA, typeParameterDescriptor)); + typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(typeParameterDescriptor)); return typeParameterDescriptor; } private void initializeTypeParameter(PsiTypeParameter typeParameter, TypeParameterDescriptorInitialization typeParameterDescriptorInitialization) { TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptorInitialization.descriptor; if (typeParameterDescriptorInitialization.origin == TypeParameterDescriptorOrigin.KOTLIN) { - // TODO + List upperBounds = typeParameterDescriptorInitialization.upperBoundsForKotlin; + if (upperBounds.size() == 0){ + typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType()); + } else { + for (JetType upperBound : typeParameterDescriptorInitialization.upperBoundsForKotlin) { + typeParameterDescriptor.addUpperBound(upperBound); + } + } + + // TODO: lower bounds } else { PsiClassType[] referencedTypes = typeParameter.getExtendsList().getReferencedTypes(); if (referencedTypes.length == 0){ @@ -667,44 +716,14 @@ public class JavaDescriptorResolver { new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(new JetSignatureExceptionsAdapter() { @Override public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) { - - return new JetSignatureExceptionsAdapter() { - int index = 0; - + + return new JetSignatureTypeParameterVisitor(functionDescriptor, method, name, variance) { @Override - public JetSignatureVisitor visitClassBound() { - return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) { - @Override - protected void done(@NotNull JetType jetType) { - // TODO - } - }; - } - - @Override - public JetSignatureVisitor visitInterfaceBound() { - return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) { - @Override - protected void done(@NotNull JetType jetType) { - // TODO - } - }; - } - - @Override - public void visitFormalTypeParameterEnd() { - TypeParameterDescriptor typeParameter = TypeParameterDescriptor.createForFurtherModification( - functionDescriptor, - Collections.emptyList(), // TODO: wrong - true, // TODO: wrong - JetSignatureUtils.translateVariance(variance), - name, - ++index); - PsiTypeParameter psiTypeParameter = getPsiTypeParameterByName(method, method.getName(), name); - typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(TypeParameterDescriptorOrigin.KOTLIN, typeParameter)); - r.add(typeParameter); + protected void done(TypeParameterDescriptor typeParameterDescriptor) { + r.add(typeParameterDescriptor); } }; + } }); return r; diff --git a/compiler/testData/readClass/class/ClassParamUpperClassBound.kt b/compiler/testData/readClass/class/ClassParamUpperClassBound.kt new file mode 100644 index 00000000000..4867fac53bc --- /dev/null +++ b/compiler/testData/readClass/class/ClassParamUpperClassBound.kt @@ -0,0 +1,3 @@ +namespace test + +class Clock diff --git a/compiler/testData/readClass/class/ClassParamUpperClassInterfaceBound.kt b/compiler/testData/readClass/class/ClassParamUpperClassInterfaceBound.kt new file mode 100644 index 00000000000..992a24af91b --- /dev/null +++ b/compiler/testData/readClass/class/ClassParamUpperClassInterfaceBound.kt @@ -0,0 +1,3 @@ +namespace test + +class Clock where A : java.lang.Number, A : java.lang.CharSequence diff --git a/compiler/testData/readClass/class/ClassParamUpperInterfaceBound.kt b/compiler/testData/readClass/class/ClassParamUpperInterfaceBound.kt new file mode 100644 index 00000000000..8f05d69017f --- /dev/null +++ b/compiler/testData/readClass/class/ClassParamUpperInterfaceBound.kt @@ -0,0 +1,3 @@ +namespace test + +class Clock diff --git a/compiler/testData/readClass/class/ClassParamUpperInterfaceClassBound.kt b/compiler/testData/readClass/class/ClassParamUpperInterfaceClassBound.kt new file mode 100644 index 00000000000..8e8170d48c5 --- /dev/null +++ b/compiler/testData/readClass/class/ClassParamUpperInterfaceClassBound.kt @@ -0,0 +1,3 @@ +namespace test + +class Clock where A : java.lang.CharSequence, A : java.lang.Number diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java index 31a450c025d..2627cd5c94d 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java @@ -32,6 +32,7 @@ import org.junit.Assert; import java.io.File; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -259,16 +260,20 @@ public class ReadClassDataTest extends UsefulTestCase { } private void serializeCommaSeparated(List list, StringBuilder sb) { + serializeSeparated(list, sb, ", "); + } + + private void serializeSeparated(List list, StringBuilder sb, String sep) { boolean first = true; for (Object o : list) { if (!first) { - sb.append(", "); + sb.append(sep); } serialize(o, sb); first = false; } } - + private Method getMethodToSerialize(Object o) { // TODO: cache for (Method method : ReadClassDataTest.class.getDeclaredMethods()) { @@ -296,6 +301,10 @@ public class ReadClassDataTest extends UsefulTestCase { Method method = getMethodToSerialize(o); invoke(method, this, o, sb); } + + private void serialize(String s, StringBuilder sb) { + sb.append(s); + } private void serialize(ModuleDescriptor module, StringBuilder sb) { // nop @@ -316,11 +325,20 @@ public class ReadClassDataTest extends UsefulTestCase { sb.append("."); sb.append(ns.getName()); } - + private void serialize(TypeParameterDescriptor param, StringBuilder sb) { serialize(param.getVariance(), sb); sb.append(param.getName()); - // TODO: serialize bounds + if (!param.getUpperBounds().isEmpty()) { + sb.append(" : "); + List list = new ArrayList(); + for (JetType upper : param.getUpperBounds()) { + list.add(serialize(upper)); + } + Collections.sort(list); + serializeSeparated(list, sb, " & "); // TODO: use where + } + // TODO: lower bounds }