read upper bound from jet signature, merge dup code

This commit is contained in:
Stepan Koltsov
2011-12-19 21:36:46 +04:00
parent f0dfa436ad
commit bf751bfa98
7 changed files with 132 additions and 80 deletions
@@ -550,6 +550,9 @@ public class JetTypeMapper {
signatureVisitor.writeClassBound(); signatureVisitor.writeClassBound();
for (JetType jetType : typeParameterDescriptor.getUpperBounds()) { for (JetType jetType : typeParameterDescriptor.getUpperBounds()) {
if (jetType.equals(JetStandardClasses.getNullableAnyType())) {
continue;
}
if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) { if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) {
if (!CodegenUtil.isInterface(jetType)) { if (!CodegenUtil.isInterface(jetType)) {
mapType(jetType, signatureVisitor); mapType(jetType, signatureVisitor);
@@ -65,10 +65,24 @@ public class JavaDescriptorResolver {
private static class TypeParameterDescriptorInitialization { private static class TypeParameterDescriptorInitialization {
private final TypeParameterDescriptorOrigin origin; private final TypeParameterDescriptorOrigin origin;
private final TypeParameterDescriptor descriptor; private final TypeParameterDescriptor descriptor;
@Nullable
private final List<JetType> upperBoundsForKotlin;
@Nullable
private final List<JetType> lowerBoundsForKotlin;
private TypeParameterDescriptorInitialization(TypeParameterDescriptorOrigin origin, TypeParameterDescriptor descriptor) { private TypeParameterDescriptorInitialization(TypeParameterDescriptor descriptor) {
this.origin = origin; this.origin = TypeParameterDescriptorOrigin.JAVA;
this.descriptor = descriptor; this.descriptor = descriptor;
this.upperBoundsForKotlin = null;
this.lowerBoundsForKotlin = null;
}
private TypeParameterDescriptorInitialization(TypeParameterDescriptor descriptor,
List<JetType> upperBoundsForKotlin, List<JetType> lowerBoundsForKotlin) {
this.origin = TypeParameterDescriptorOrigin.KOTLIN;
this.descriptor = descriptor;
this.upperBoundsForKotlin = upperBoundsForKotlin;
this.lowerBoundsForKotlin = lowerBoundsForKotlin;
} }
} }
@@ -229,13 +243,71 @@ public class JavaDescriptorResolver {
} }
@NotNull @NotNull
private PsiTypeParameter getPsiTypeParameterByName(PsiTypeParameterListOwner clazz, String ownerName, String name) { private PsiTypeParameter getPsiTypeParameterByName(PsiTypeParameterListOwner clazz, String name) {
for (PsiTypeParameter typeParameter : clazz.getTypeParameters()) { for (PsiTypeParameter typeParameter : clazz.getTypeParameters()) {
if (typeParameter.getName().equals(name)) { if (typeParameter.getName().equals(name)) {
return typeParameter; 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<JetType> upperBounds = new ArrayList<JetType>();
List<JetType> lowerBounds = new ArrayList<JetType>();
@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.<AnnotationDescriptor>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() { new JetSignatureReader(jetSignature).accept(new JetSignatureExceptionsAdapter() {
@Override @Override
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) { public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
return new JetSignatureExceptionsAdapter() { return new JetSignatureTypeParameterVisitor(classDescriptor, clazz, name, variance) {
int index = 0;
@Override @Override
public JetSignatureVisitor visitClassBound() { protected void done(TypeParameterDescriptor typeParameterDescriptor) {
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) { r.add(typeParameterDescriptor);
@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(
classDescriptor,
Collections.<AnnotationDescriptor>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.getName(),
psiTypeParameter.getIndex() psiTypeParameter.getIndex()
); );
typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(TypeParameterDescriptorOrigin.JAVA, typeParameterDescriptor)); typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(typeParameterDescriptor));
return typeParameterDescriptor; return typeParameterDescriptor;
} }
private void initializeTypeParameter(PsiTypeParameter typeParameter, TypeParameterDescriptorInitialization typeParameterDescriptorInitialization) { private void initializeTypeParameter(PsiTypeParameter typeParameter, TypeParameterDescriptorInitialization typeParameterDescriptorInitialization) {
TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptorInitialization.descriptor; TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptorInitialization.descriptor;
if (typeParameterDescriptorInitialization.origin == TypeParameterDescriptorOrigin.KOTLIN) { 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 { } else {
PsiClassType[] referencedTypes = typeParameter.getExtendsList().getReferencedTypes(); PsiClassType[] referencedTypes = typeParameter.getExtendsList().getReferencedTypes();
if (referencedTypes.length == 0){ if (referencedTypes.length == 0){
@@ -667,44 +716,14 @@ public class JavaDescriptorResolver {
new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(new JetSignatureExceptionsAdapter() { new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(new JetSignatureExceptionsAdapter() {
@Override @Override
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) { public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
return new JetSignatureExceptionsAdapter() { return new JetSignatureTypeParameterVisitor(functionDescriptor, method, name, variance) {
int index = 0;
@Override @Override
public JetSignatureVisitor visitClassBound() { protected void done(TypeParameterDescriptor typeParameterDescriptor) {
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) { r.add(typeParameterDescriptor);
@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.<AnnotationDescriptor>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);
} }
}; };
} }
}); });
return r; return r;
@@ -0,0 +1,3 @@
namespace test
class Clock<A : java.lang.Number>
@@ -0,0 +1,3 @@
namespace test
class Clock<A> where A : java.lang.Number, A : java.lang.CharSequence
@@ -0,0 +1,3 @@
namespace test
class Clock<A : java.lang.CharSequence>
@@ -0,0 +1,3 @@
namespace test
class Clock<A> where A : java.lang.CharSequence, A : java.lang.Number
@@ -32,6 +32,7 @@ import org.junit.Assert;
import java.io.File; import java.io.File;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -259,16 +260,20 @@ public class ReadClassDataTest extends UsefulTestCase {
} }
private void serializeCommaSeparated(List<?> list, StringBuilder sb) { private void serializeCommaSeparated(List<?> list, StringBuilder sb) {
serializeSeparated(list, sb, ", ");
}
private void serializeSeparated(List<?> list, StringBuilder sb, String sep) {
boolean first = true; boolean first = true;
for (Object o : list) { for (Object o : list) {
if (!first) { if (!first) {
sb.append(", "); sb.append(sep);
} }
serialize(o, sb); serialize(o, sb);
first = false; first = false;
} }
} }
private Method getMethodToSerialize(Object o) { private Method getMethodToSerialize(Object o) {
// TODO: cache // TODO: cache
for (Method method : ReadClassDataTest.class.getDeclaredMethods()) { for (Method method : ReadClassDataTest.class.getDeclaredMethods()) {
@@ -296,6 +301,10 @@ public class ReadClassDataTest extends UsefulTestCase {
Method method = getMethodToSerialize(o); Method method = getMethodToSerialize(o);
invoke(method, this, o, sb); invoke(method, this, o, sb);
} }
private void serialize(String s, StringBuilder sb) {
sb.append(s);
}
private void serialize(ModuleDescriptor module, StringBuilder sb) { private void serialize(ModuleDescriptor module, StringBuilder sb) {
// nop // nop
@@ -316,11 +325,20 @@ public class ReadClassDataTest extends UsefulTestCase {
sb.append("."); sb.append(".");
sb.append(ns.getName()); sb.append(ns.getName());
} }
private void serialize(TypeParameterDescriptor param, StringBuilder sb) { private void serialize(TypeParameterDescriptor param, StringBuilder sb) {
serialize(param.getVariance(), sb); serialize(param.getVariance(), sb);
sb.append(param.getName()); sb.append(param.getName());
// TODO: serialize bounds if (!param.getUpperBounds().isEmpty()) {
sb.append(" : ");
List<String> list = new ArrayList<String>();
for (JetType upper : param.getUpperBounds()) {
list.add(serialize(upper));
}
Collections.sort(list);
serializeSeparated(list, sb, " & "); // TODO: use where
}
// TODO: lower bounds
} }