Extract interface out of TypeVariableResolver

Also make getTypeVariable() nullable: when a type is not found, it's better to
use error type instead of throwing an exception
This commit is contained in:
Alexander Udalov
2013-09-06 20:42:13 +04:00
parent ccff9e38fe
commit b8f9ef9910
8 changed files with 95 additions and 57 deletions
@@ -118,7 +118,7 @@ public final class JavaConstructorResolver {
List<ValueParameterDescriptor> valueParameters;
if (isAnnotation) {
TypeVariableResolver typeVariableResolver = new TypeVariableResolver(typeParameters, containingClass);
TypeVariableResolver typeVariableResolver = new TypeVariableResolverImpl(typeParameters, containingClass);
valueParameters = resolveAnnotationParameters(javaClass, constructorDescriptor, typeVariableResolver);
}
else {
@@ -202,7 +202,7 @@ public final class JavaConstructorResolver {
List<ValueParameterDescriptor> valueParameters = valueParameterResolver.resolveValueParameters(
constructorDescriptor, constructor,
new TypeVariableResolver(typeParameters, classDescriptor)
new TypeVariableResolverImpl(typeParameters, classDescriptor)
);
ExternalSignatureResolver.AlternativeMethodSignature effectiveSignature = externalSignatureResolver
@@ -126,7 +126,7 @@ public final class JavaFunctionResolver {
typeParameterInitializer.initialize();
List<TypeParameterDescriptor> methodTypeParameters = typeParameterInitializer.getDescriptors();
TypeVariableResolver typeVariableResolver = new TypeVariableResolver(methodTypeParameters, functionDescriptorImpl);
TypeVariableResolver typeVariableResolver = new TypeVariableResolverImpl(methodTypeParameters, functionDescriptorImpl);
List<ValueParameterDescriptor> valueParameters =
valueParameterResolver.resolveValueParameters(functionDescriptorImpl, method, typeVariableResolver);
@@ -109,7 +109,7 @@ public final class JavaPropertyResolver {
propertyDescriptor.initialize(null, null);
TypeVariableResolver typeVariableResolver =
new TypeVariableResolver(Collections.<TypeParameterDescriptor>emptyList(), propertyDescriptor);
new TypeVariableResolverImpl(Collections.<TypeParameterDescriptor>emptyList(), propertyDescriptor);
JetType propertyType = getPropertyType(field, typeVariableResolver);
@@ -59,7 +59,7 @@ public final class JavaSupertypeResolver {
@NotNull JavaClass javaClass,
@NotNull List<TypeParameterDescriptor> typeParameters
) {
TypeVariableResolver typeVariableResolver = new TypeVariableResolver(typeParameters, classDescriptor);
TypeVariableResolver typeVariableResolver = new TypeVariableResolverImpl(typeParameters, classDescriptor);
List<JetType> result = transformSupertypeList(javaClass.getSupertypes(), typeVariableResolver);
@@ -80,7 +80,7 @@ public final class JavaTypeParameterResolver {
}
public void initialize() {
TypeVariableResolver typeVariableResolver = new TypeVariableResolver(getDescriptors(), owner);
TypeVariableResolver typeVariableResolver = new TypeVariableResolverImpl(getDescriptors(), owner);
Iterator<TypeParameterDescriptor> descriptorIterator = descriptors.iterator();
Iterator<JavaTypeParameter> typeParameterIterator = javaTypeParameters.iterator();
@@ -84,7 +84,7 @@ public class JavaTypeTransformer {
JavaClassifierType classifierType = (JavaClassifierType) type;
JetType jetType = transformClassifierType(classifierType, howThisTypeIsUsed, typeVariableResolver);
if (jetType == null) {
return ErrorUtils.createErrorType("Unresolved java class: " + classifierType.getPresentableText());
return ErrorUtils.createErrorType("Unresolved java classifier: " + classifierType.getPresentableText());
}
return jetType;
}
@@ -140,14 +140,15 @@ public class JavaTypeTransformer {
return TypeUtils.intersect(JetTypeChecker.INSTANCE, supertypesJet);
}
TypeParameterDescriptor typeParameterDescriptor = typeVariableResolver.getTypeVariable(typeParameter.getName());
TypeParameterDescriptor descriptor = typeVariableResolver.getTypeVariable(typeParameter.getName());
if (descriptor == null) return null;
// In Java: ArrayList<T>
// In Kotlin: ArrayList<T>, not ArrayList<T?>
// nullability will be taken care of in individual member signatures
boolean nullable = !EnumSet.of(TYPE_ARGUMENT, UPPER_BOUND, SUPERTYPE_ARGUMENT).contains(howThisTypeIsUsed);
return TypeUtils.makeNullableIfNeeded(typeParameterDescriptor.getDefaultType(), nullable);
return TypeUtils.makeNullableIfNeeded(descriptor.getDefaultType(), nullable);
}
@Nullable
@@ -17,57 +17,19 @@
package org.jetbrains.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.List;
/* package */ class TypeVariableResolver {
@NotNull
private final List<TypeParameterDescriptor> typeParameters;
@NotNull
private final DeclarationDescriptor owner;
public TypeVariableResolver(@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull DeclarationDescriptor owner) {
this.typeParameters = typeParameters;
this.owner = owner;
assert parametersBelongToOwner() : "Type parameters should belong to owner: " + owner + "; " + typeParameters;
}
private boolean parametersBelongToOwner() {
for (TypeParameterDescriptor typeParameter : typeParameters) {
if (typeParameter.getContainingDeclaration() != owner) {
return false;
}
public interface TypeVariableResolver {
TypeVariableResolver EMPTY = new TypeVariableResolver() {
@Nullable
@Override
public TypeParameterDescriptor getTypeVariable(@NotNull Name name) {
return null;
}
return true;
}
};
@NotNull
public TypeParameterDescriptor getTypeVariable(@NotNull Name name) {
return getTypeVariable(name, typeParameters, owner);
}
@NotNull
private static TypeParameterDescriptor getTypeVariable(
@NotNull Name name,
@NotNull List<TypeParameterDescriptor> typeParameters,
@NotNull DeclarationDescriptor owner
) {
for (TypeParameterDescriptor typeParameter : typeParameters) {
if (typeParameter.getName().equals(name)) {
return typeParameter;
}
}
DeclarationDescriptor container = owner.getContainingDeclaration();
if (container instanceof ClassDescriptor) {
return getTypeVariable(name, ((ClassDescriptor) container).getTypeConstructor().getParameters(), container);
}
throw new IllegalStateException("Type parameter not found by name: " + name);
}
@Nullable
TypeParameterDescriptor getTypeVariable(@NotNull Name name);
}
@@ -0,0 +1,75 @@
/*
* Copyright 2010-2013 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.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.List;
/* package */ class TypeVariableResolverImpl implements TypeVariableResolver {
@NotNull
private final List<TypeParameterDescriptor> typeParameters;
@NotNull
private final DeclarationDescriptor owner;
public TypeVariableResolverImpl(@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull DeclarationDescriptor owner) {
this.typeParameters = typeParameters;
this.owner = owner;
assert parametersBelongToOwner() : "Type parameters should belong to owner: " + owner + "; " + typeParameters;
}
private boolean parametersBelongToOwner() {
for (TypeParameterDescriptor typeParameter : typeParameters) {
if (typeParameter.getContainingDeclaration() != owner) {
return false;
}
}
return true;
}
@Nullable
@Override
public TypeParameterDescriptor getTypeVariable(@NotNull Name name) {
return getTypeVariable(name, typeParameters, owner);
}
@Nullable
private static TypeParameterDescriptor getTypeVariable(
@NotNull Name name,
@NotNull List<TypeParameterDescriptor> typeParameters,
@NotNull DeclarationDescriptor owner
) {
for (TypeParameterDescriptor typeParameter : typeParameters) {
if (typeParameter.getName().equals(name)) {
return typeParameter;
}
}
DeclarationDescriptor container = owner.getContainingDeclaration();
if (container instanceof ClassDescriptor) {
return getTypeVariable(name, ((ClassDescriptor) container).getTypeConstructor().getParameters(), container);
}
return null;
}
}