提交 617b3b5d 编写于 作者: S Stepan Koltsov

ReadClassDataTest: type variable resolver

上级 0d5283d0
......@@ -619,6 +619,11 @@ public class JetTypeMapper {
signatureVisitor.writeInterfaceBoundEnd();
}
}
if (jetType.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
signatureVisitor.writeInterfaceBound();
mapType(jetType, signatureVisitor);
signatureVisitor.writeInterfaceBoundEnd();
}
}
signatureVisitor.writeFormalTypeParameterEnd();
......
......@@ -166,8 +166,17 @@ public class JavaDescriptorResolver {
);
classDescriptor.setName(name);
class OuterClassTypeVariableResolver implements TypeVariableResolver {
@NotNull
@Override
public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
throw new IllegalStateException("not implemented"); // TODO
}
}
List<JetType> supertypes = new ArrayList<JetType>();
List<TypeParameterDescriptor> typeParameters = resolveClassTypeParameters(psiClass, classDescriptor);
List<TypeParameterDescriptor> typeParameters = resolveClassTypeParameters(psiClass, classDescriptor, new OuterClassTypeVariableResolver());
classDescriptor.setTypeConstructor(new TypeConstructorImpl(
classDescriptor,
Collections.<AnnotationDescriptor>emptyList(), // TODO
......@@ -225,7 +234,10 @@ public class JavaDescriptorResolver {
classDescriptor,
Collections.<AnnotationDescriptor>emptyList(), // TODO
false);
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters());
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor,
constructor.getParameterList().getParameters(),
new TypeParameterListTypeVariableResolver(typeParameters) // TODO: outer too
);
if (valueParameterDescriptors.receiverType != null) {
throw new IllegalStateException();
}
......@@ -242,14 +254,14 @@ public class JavaDescriptorResolver {
return classDescriptor;
}
private List<TypeParameterDescriptor> resolveClassTypeParameters(PsiClass psiClass, JavaClassDescriptor classDescriptor) {
private List<TypeParameterDescriptor> resolveClassTypeParameters(PsiClass psiClass, JavaClassDescriptor classDescriptor, TypeVariableResolver typeVariableResolver) {
for (PsiAnnotation annotation : psiClass.getModifierList().getAnnotations()) {
if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_CLASS.getFqName())) {
PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_CLASS_SIGNATURE);
if (attributeValue != null) {
String typeParametersString = (String) attributeValue.getValue();
if (typeParametersString != null) {
return resolveClassTypeParametersFromJetSignature(typeParametersString, psiClass, classDescriptor);
return resolveClassTypeParametersFromJetSignature(typeParametersString, psiClass, classDescriptor, typeVariableResolver);
}
}
}
......@@ -290,14 +302,20 @@ public class JavaDescriptorResolver {
private final PsiTypeParameterListOwner psiOwner;
private final String name;
private final TypeInfoVariance variance;
private final TypeVariableResolver typeVariableResolver;
protected JetSignatureTypeParameterVisitor(DeclarationDescriptor containingDeclaration, PsiTypeParameterListOwner psiOwner,
String name, TypeInfoVariance variance)
String name, TypeInfoVariance variance, TypeVariableResolver typeVariableResolver)
{
if (name.isEmpty()) {
throw new IllegalStateException();
}
this.containingDeclaration = containingDeclaration;
this.psiOwner = psiOwner;
this.name = name;
this.variance = variance;
this.typeVariableResolver = typeVariableResolver;
}
int index = 0;
......@@ -307,7 +325,7 @@ public class JavaDescriptorResolver {
@Override
public JetSignatureVisitor visitClassBound() {
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) {
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) {
@Override
protected void done(@NotNull JetType jetType) {
if (isJavaLangObject(jetType)) {
......@@ -320,7 +338,7 @@ public class JavaDescriptorResolver {
@Override
public JetSignatureVisitor visitInterfaceBound() {
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) {
return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) {
@Override
protected void done(@NotNull JetType jetType) {
upperBounds.add(jetType);
......@@ -348,12 +366,28 @@ public class JavaDescriptorResolver {
/**
* @see #resolveMethodTypeParametersFromJetSignature(String, FunctionDescriptor)
*/
private List<TypeParameterDescriptor> resolveClassTypeParametersFromJetSignature(String jetSignature, final PsiClass clazz, final JavaClassDescriptor classDescriptor) {
private List<TypeParameterDescriptor> resolveClassTypeParametersFromJetSignature(String jetSignature, final PsiClass clazz,
final JavaClassDescriptor classDescriptor, final TypeVariableResolver outerClassTypeVariableResolver) {
final List<TypeParameterDescriptor> r = new ArrayList<TypeParameterDescriptor>();
class MyTypeVariableResolver implements TypeVariableResolver {
@NotNull
@Override
public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
for (TypeParameterDescriptor typeParameter : r) {
if (typeParameter.getName().equals(name)) {
return typeParameter;
}
}
return outerClassTypeVariableResolver.getTypeVariable(name);
}
}
new JetSignatureReader(jetSignature).accept(new JetSignatureExceptionsAdapter() {
@Override
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
return new JetSignatureTypeParameterVisitor(classDescriptor, clazz, name, variance) {
return new JetSignatureTypeParameterVisitor(classDescriptor, clazz, name, variance, new MyTypeVariableResolver()) {
@Override
protected void done(TypeParameterDescriptor typeParameterDescriptor) {
r.add(typeParameterDescriptor);
......@@ -548,12 +582,13 @@ public class JavaDescriptorResolver {
}
}
public ValueParameterDescriptors resolveParameterDescriptors(DeclarationDescriptor containingDeclaration, PsiParameter[] parameters) {
public ValueParameterDescriptors resolveParameterDescriptors(DeclarationDescriptor containingDeclaration,
PsiParameter[] parameters, TypeVariableResolver typeVariableResolver) {
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
JetType receiverType = null;
for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) {
PsiParameter parameter = parameters[i];
JvmMethodParameterMeaning meaning = resolveParameterDescriptor(containingDeclaration, i, parameter);
JvmMethodParameterMeaning meaning = resolveParameterDescriptor(containingDeclaration, i, parameter, typeVariableResolver);
if (meaning.kind == JvmMethodParameterKind.TYPE_INFO) {
// TODO
} else if (meaning.kind == JvmMethodParameterKind.REGULAR) {
......@@ -601,7 +636,8 @@ public class JavaDescriptorResolver {
}
@NotNull
private JvmMethodParameterMeaning resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i, PsiParameter parameter) {
private JvmMethodParameterMeaning resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i,
PsiParameter parameter, TypeVariableResolver typeVariableResolver) {
PsiType psiType = parameter.getType();
JetType varargElementType;
......@@ -663,7 +699,7 @@ public class JavaDescriptorResolver {
JetType outType;
if (typeFromAnnotation != null && typeFromAnnotation.length() > 0) {
outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation);
outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation, typeVariableResolver);
} else {
outType = semanticServices.getTypeTransformer().transformToType(psiType);
}
......@@ -750,6 +786,26 @@ public class JavaDescriptorResolver {
return typeSubstitutor;
}
private static class TypeParameterListTypeVariableResolver implements TypeVariableResolver {
private final List<TypeParameterDescriptor> typeParameters;
private TypeParameterListTypeVariableResolver(List<TypeParameterDescriptor> typeParameters) {
this.typeParameters = typeParameters;
}
@NotNull
@Override
public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
for (TypeParameterDescriptor typeParameter : typeParameters) {
if (typeParameter.getName().equals(name)) {
return typeParameter;
}
}
throw new IllegalStateException("unresolver variable: " + name); // TODO: report properly
}
}
@Nullable
public FunctionDescriptor resolveMethodToFunctionDescriptor(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethod method) {
PsiType returnType = method.getReturnType();
......@@ -763,7 +819,17 @@ public class JavaDescriptorResolver {
}
return functionDescriptor;
}
DeclarationDescriptor classDescriptor = method.hasModifierProperty(PsiModifier.STATIC) ? resolveNamespace(method.getContainingClass()) : resolveClass(method.getContainingClass());
DeclarationDescriptor classDescriptor;
final List<TypeParameterDescriptor> classTypeParameters;
if (method.hasModifierProperty(PsiModifier.STATIC)) {
classDescriptor = resolveNamespace(method.getContainingClass());
classTypeParameters = Collections.emptyList();
}
else {
ClassDescriptor classClassDescriptor = resolveClass(method.getContainingClass());
classDescriptor = classClassDescriptor;
classTypeParameters = classClassDescriptor.getTypeConstructor().getParameters();
}
if (classDescriptor == null) {
return null;
}
......@@ -774,14 +840,39 @@ public class JavaDescriptorResolver {
method.getName()
);
methodDescriptorCache.put(method, functionDescriptorImpl);
List<TypeParameterDescriptor> typeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl);
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(functionDescriptorImpl, parameters);
// TODO: add outer classes
TypeParameterListTypeVariableResolver typeVariableResolverForParameters = new TypeParameterListTypeVariableResolver(classTypeParameters);
final List<TypeParameterDescriptor> methodTypeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl, typeVariableResolverForParameters);
class MethodTypeVariableResolver implements TypeVariableResolver {
@NotNull
@Override
public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
for (TypeParameterDescriptor typeParameter : methodTypeParameters) {
if (typeParameter.getName().equals(name)) {
return typeParameter;
}
}
for (TypeParameterDescriptor typeParameter : classTypeParameters) {
if (typeParameter.getName().equals(name)) {
return typeParameter;
}
}
throw new IllegalStateException("unresolver variable: " + name); // TODO: report properly
}
}
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(functionDescriptorImpl, parameters, new MethodTypeVariableResolver());
functionDescriptorImpl.initialize(
valueParameterDescriptors.receiverType,
DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor),
typeParameters,
methodTypeParameters,
valueParameterDescriptors.descriptors,
makeReturnType(returnType, method),
makeReturnType(returnType, method, new MethodTypeVariableResolver()),
Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL)),
resolveVisibilityFromPsiModifiers(method)
);
......@@ -793,14 +884,14 @@ public class JavaDescriptorResolver {
return substitutedFunctionDescriptor;
}
private List<TypeParameterDescriptor> resolveMethodTypeParameters(PsiMethod method, FunctionDescriptorImpl functionDescriptorImpl) {
private List<TypeParameterDescriptor> resolveMethodTypeParameters(PsiMethod method, FunctionDescriptorImpl functionDescriptorImpl, TypeVariableResolver classTypeVariableResolver) {
for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) {
if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_METHOD.getFqName())) {
PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD);
if (attributeValue != null) {
String typeParametersString = (String) attributeValue.getValue();
if (typeParametersString != null) {
List<TypeParameterDescriptor> r = resolveMethodTypeParametersFromJetSignature(typeParametersString, method, functionDescriptorImpl);
List<TypeParameterDescriptor> r = resolveMethodTypeParametersFromJetSignature(typeParametersString, method, functionDescriptorImpl, classTypeVariableResolver);
initializeTypeParameters(method);
return r;
}
......@@ -816,13 +907,30 @@ public class JavaDescriptorResolver {
/**
* @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, JavaClassDescriptor)
*/
private List<TypeParameterDescriptor> resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method, final FunctionDescriptor functionDescriptor) {
private List<TypeParameterDescriptor> resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method,
final FunctionDescriptor functionDescriptor, final TypeVariableResolver classTypeVariableResolver)
{
final List<TypeParameterDescriptor> r = new ArrayList<TypeParameterDescriptor>();
class MyTypeVariableResolver implements TypeVariableResolver {
@NotNull
@Override
public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
for (TypeParameterDescriptor typeParameter : r) {
if (typeParameter.getName().equals(name)) {
return typeParameter;
}
}
return classTypeVariableResolver.getTypeVariable(name);
}
}
new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(new JetSignatureExceptionsAdapter() {
@Override
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
return new JetSignatureTypeParameterVisitor(functionDescriptor, method, name, variance) {
return new JetSignatureTypeParameterVisitor(functionDescriptor, method, name, variance, new MyTypeVariableResolver()) {
@Override
protected void done(TypeParameterDescriptor typeParameterDescriptor) {
r.add(typeParameterDescriptor);
......@@ -834,7 +942,7 @@ public class JavaDescriptorResolver {
return r;
}
private JetType makeReturnType(PsiType returnType, PsiMethod method) {
private JetType makeReturnType(PsiType returnType, PsiMethod method, TypeVariableResolver typeVariableResolver) {
boolean changeNullable = false;
boolean nullable = true;
......@@ -859,7 +967,7 @@ public class JavaDescriptorResolver {
}
JetType transformedType;
if (returnTypeFromAnnotation != null && returnTypeFromAnnotation.length() > 0) {
transformedType = semanticServices.getTypeTransformer().transformToType(returnTypeFromAnnotation);
transformedType = semanticServices.getTypeTransformer().transformToType(returnTypeFromAnnotation, typeVariableResolver);
} else {
transformedType = semanticServices.getTypeTransformer().transformToType(returnType);
}
......
......@@ -59,9 +59,9 @@ public class JavaTypeTransformer {
}
@NotNull
public JetType transformToType(@NotNull String kotlinSignature) {
public JetType transformToType(@NotNull String kotlinSignature, TypeVariableResolver typeVariableResolver) {
final JetType[] r = new JetType[1];
JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(resolver, standardLibrary) {
JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(resolver, standardLibrary, typeVariableResolver) {
@Override
protected void done(@NotNull JetType jetType) {
r[0] = jetType;
......
......@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetStandardClasses;
......@@ -25,10 +26,12 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
private final JavaDescriptorResolver javaDescriptorResolver;
private final JetStandardLibrary jetStandardLibrary;
private final TypeVariableResolver typeVariableResolver;
public JetTypeJetSignatureReader(JavaDescriptorResolver javaDescriptorResolver, JetStandardLibrary jetStandardLibrary) {
public JetTypeJetSignatureReader(JavaDescriptorResolver javaDescriptorResolver, JetStandardLibrary jetStandardLibrary, TypeVariableResolver typeVariableResolver) {
this.javaDescriptorResolver = javaDescriptorResolver;
this.jetStandardLibrary = jetStandardLibrary;
this.typeVariableResolver = typeVariableResolver;
}
......@@ -111,7 +114,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
@Override
public JetSignatureVisitor visitTypeArgument(final char wildcard) {
return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary) {
return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary, typeVariableResolver) {
@Override
protected void done(@NotNull JetType jetType) {
......@@ -122,7 +125,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
@Override
public JetSignatureVisitor visitArrayType(final boolean nullable) {
return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary) {
return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary, typeVariableResolver) {
@Override
protected void done(@NotNull JetType jetType) {
JetType arrayType = TypeUtils.makeNullableAsSpecified(jetStandardLibrary.getArrayType(jetType), nullable);
......@@ -133,8 +136,8 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
@Override
public void visitTypeVariable(String name, boolean nullable) {
// TODO: need a way to get type TypeParameterDescriptor by name
throw new IllegalStateException();
JetType r = TypeUtils.makeNullableAsSpecified(typeVariableResolver.getTypeVariable(name).getDefaultType(), nullable);
done(r);
}
@Override
......
package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
/**
* @author Stepan Koltsov
*/
public interface TypeVariableResolver {
@NotNull
TypeParameterDescriptor getTypeVariable(@NotNull String name);
}
package test
class ClassParamReferencesParam<A, B : A>
package test
class ClassParamReferencesParam<A, in B : A>
package test
class ClassTwoParams<P, Q>
package test
class ClassTwoParams<out P, Q>
package test
class ClassParamUsedInFun<in T> {
fun f(t: T) = 1
}
package test
class ClassParamUsedInFun<T> {
fun f(t: T) = 1
}
package test
fun <P> funParamParam(a: Int, b: P) = 1
package test
fun <in P, Q : P> funParamReferencesParam() = 1
package test
fun <P> funParamVarargParam(a: Int, vararg b: P) = 1
......@@ -403,7 +403,7 @@ public class ReadClassDataTest extends UsefulTestCase {
List<String> list = new ArrayList<String>();
for (JetType upper : param.getUpperBounds()) {
StringBuilder sb = new StringBuilder();
new Serializer(sb).serialize(upper);
new ValueParameterSerializer(sb).serialize(upper);
list.add(sb.toString());
}
Collections.sort(list);
......
......@@ -63,7 +63,11 @@ public class JetSignatureReader {
if (end < 0) {
throw new IllegalStateException();
}
JetSignatureVisitor parameterVisitor = v.visitFormalTypeParameter(signature.substring(pos, end), variance);
String typeParameterName = signature.substring(pos, end);
if (typeParameterName.isEmpty()) {
throw new IllegalStateException("incorrect signature: " + signature);
}
JetSignatureVisitor parameterVisitor = v.visitFormalTypeParameter(typeParameterName, variance);
pos = end + 1;
c = signature.charAt(pos);
......@@ -71,12 +75,14 @@ public class JetSignatureReader {
pos = parseType(signature, pos, parameterVisitor.visitClassBound());
}
while ((c = signature.charAt(pos++)) == ':') {
while ((c = signature.charAt(pos)) == ':') {
++pos;
pos = parseType(signature, pos, parameterVisitor.visitInterfaceBound());
}
parameterVisitor.visitFormalTypeParameterEnd();
} while (c != '>');
++pos;
} else {
pos = 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册