Utilities moved closer to their usages and rewritten to Kotlin

This commit is contained in:
Andrey Breslav
2014-02-05 09:37:35 +01:00
committed by Alexander Udalov
parent e119ca27ca
commit 76c722b81c
9 changed files with 97 additions and 126 deletions
@@ -9,7 +9,6 @@ import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import org.jetbrains.jet.lang.types.TypeConstructor
import org.jetbrains.jet.lang.resolve.java.resolver.JavaClassResolver
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
import java.util.Collections
import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContextWithTypes
@@ -18,7 +17,6 @@ import org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage
import org.jetbrains.jet.lang.resolve.java.lazy.resolveAnnotations
import org.jetbrains.jet.lang.resolve.java.lazy.types.toAttributes
import org.jetbrains.jet.lang.resolve.scopes.InnerClassesScopeWrapper
import org.jetbrains.jet.lang.resolve.java.resolver.JavaSupertypeResolver
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.utils.*
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils
@@ -32,6 +30,11 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl
import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler
import org.jetbrains.jet.lang.resolve.scopes.WritableScope
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.descriptors.ClassKind
import org.jetbrains.jet.lang.resolve.DescriptorFactory
import java.util.ArrayList
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
class LazyJavaClassDescriptor(
private val outerC: LazyJavaResolverContextWithTypes,
@@ -46,10 +49,19 @@ class LazyJavaClassDescriptor(
c.javaResolverCache.recordClass(jClass, this)
}
private val _kind = JavaClassResolver.determineClassKind(jClass)
private val _modality = JavaClassResolver.determineClassModality(jClass)
private val _kind = when {
jClass.isAnnotationType() -> ClassKind.ANNOTATION_CLASS
jClass.isInterface() -> ClassKind.TRAIT
jClass.isEnum() -> ClassKind.ENUM_CLASS
else -> ClassKind.CLASS
}
private val _modality = if (jClass.isAnnotationType())
Modality.FINAL
else Modality.convertFromFlags(jClass.isAbstract() || jClass.isInterface(), !jClass.isFinal())
private val _visibility = jClass.getVisibility()
private val _isInner = JavaClassResolver.isInnerClass(jClass)
private val _isInner = jClass.getOuterClass() != null && !jClass.isStatic()
override fun getKind() = _kind
override fun getModality() = _modality
@@ -82,12 +94,22 @@ class LazyJavaClassDescriptor(
classObject.setScopeForMemberLookup(writableScope)
JavaClassResolver.createEnumSyntheticMethods(classObject, this.getDefaultType())
createEnumSyntheticMethods(classObject, this.getDefaultType())
classObject
}
else null
}
private fun createEnumSyntheticMethods(classObject: JavaEnumClassObjectDescriptor, enumType: JetType) {
val valuesReturnType = KotlinBuiltIns.getInstance().getArrayType(enumType)
val valuesMethod = DescriptorFactory.createEnumClassObjectValuesMethod(classObject, valuesReturnType)
classObject.getBuilder().addFunctionDescriptor(valuesMethod)
val valueOfMethod = DescriptorFactory.createEnumClassObjectValueOfMethod(classObject, enumType)
classObject.getBuilder().addFunctionDescriptor(valueOfMethod)
}
override fun getClassObjectDescriptor(): ClassDescriptor? = _classObjectDescriptor()
override fun getClassObjectType(): JetType? = getClassObjectDescriptor()?.let { d -> d.getDefaultType() }
@@ -115,10 +137,33 @@ class LazyJavaClassDescriptor(
return _scopeForMemberLookup.resolveMethodToFunctionDescriptor(samInterfaceMethod, false)
}
else {
return JavaClassResolver.findFunctionWithMostSpecificReturnType(TypeUtils.getAllSupertypes(getDefaultType()))
return findFunctionWithMostSpecificReturnType(TypeUtils.getAllSupertypes(getDefaultType()))
}
}
private fun findFunctionWithMostSpecificReturnType(supertypes: Set<JetType>): SimpleFunctionDescriptor {
val candidates = ArrayList<SimpleFunctionDescriptor>(supertypes.size())
for (supertype in supertypes) {
val abstractMembers = SingleAbstractMethodUtils.getAbstractMembers(supertype)
if (!abstractMembers.isEmpty()) {
candidates.add((abstractMembers[0] as SimpleFunctionDescriptor))
}
}
if (candidates.isEmpty()) {
throw IllegalStateException("Couldn't find abstract method in supertypes " + supertypes)
}
var currentMostSpecificType = candidates[0]
for (candidate in candidates) {
val candidateReturnType = candidate.getReturnType()
val currentMostSpecificReturnType = currentMostSpecificType.getReturnType()
assert(candidateReturnType != null && currentMostSpecificReturnType != null, "$candidate, $currentMostSpecificReturnType")
if (JetTypeChecker.INSTANCE.isSubtypeOf(candidateReturnType!!, currentMostSpecificReturnType!!)) {
currentMostSpecificType = candidate
}
}
return currentMostSpecificType
}
override fun toString() = "lazy java class $fqName"
private inner class LazyJavaClassTypeConstructor : TypeConstructor {
@@ -26,7 +26,6 @@ import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType
import org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage
import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl
import java.util.Collections
import org.jetbrains.jet.lang.resolve.java.resolver.JavaConstructorResolver
import org.jetbrains.jet.utils.*
import java.util.ArrayList
import org.jetbrains.jet.lang.resolve.java.lazy.types.toAttributes
@@ -34,6 +33,8 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils
import org.jetbrains.jet.lang.descriptors.impl.EnumEntrySyntheticClassDescriptor
import org.jetbrains.jet.lang.types.TypeUtils
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils
import org.jetbrains.jet.lang.resolve.java.JavaVisibilities
public class LazyJavaClassMemberScope(
c: LazyJavaResolverContextWithTypes,
@@ -53,7 +54,7 @@ public class LazyJavaClassMemberScope(
jClass.getConstructors().flatMap {
jCtor ->
val constructor = resolveConstructor(jCtor, getContainingDeclaration(), jClass.isStatic())
val samAdapter = JavaConstructorResolver.resolveSamAdapter(constructor)
val samAdapter = resolveSamAdapter(constructor)
if (samAdapter != null) {
(samAdapter as ConstructorDescriptorImpl).setReturnType(containingDeclaration.getDefaultType())
listOf(constructor, samAdapter)
@@ -65,6 +66,12 @@ public class LazyJavaClassMemberScope(
}
}
private fun resolveSamAdapter(original: ConstructorDescriptor): ConstructorDescriptor? {
return if (SingleAbstractMethodUtils.isSamAdapterNecessary(original))
SingleAbstractMethodUtils.createSamAdapterConstructor(original) as ConstructorDescriptor
else null
}
private fun resolveConstructor(constructor: JavaMethod, classDescriptor: ClassDescriptor, isStaticClass: Boolean): ConstructorDescriptor {
val constructorDescriptor = ConstructorDescriptorImpl(classDescriptor, Annotations.EMPTY, isPrimary = false)
@@ -102,12 +109,20 @@ public class LazyJavaClassMemberScope(
val valueParameters = if (isAnnotation) createAnnotationConstructorParameters(constructorDescriptor)
else Collections.emptyList<ValueParameterDescriptor>()
constructorDescriptor.initialize(typeParameters, valueParameters, JavaConstructorResolver.getConstructorVisibility(classDescriptor), jClass.isStatic())
constructorDescriptor.initialize(typeParameters, valueParameters, getConstructorVisibility(classDescriptor), jClass.isStatic())
constructorDescriptor.setReturnType(classDescriptor.getDefaultType())
c.javaResolverCache.recordConstructor(jClass, constructorDescriptor);
return constructorDescriptor
}
private fun getConstructorVisibility(classDescriptor: ClassDescriptor): Visibility {
val visibility = classDescriptor.getVisibility()
if (visibility == JavaVisibilities.PROTECTED_STATIC_VISIBILITY) {
return JavaVisibilities.PROTECTED_AND_PACKAGE
}
return visibility
}
private fun createAnnotationConstructorParameters(constructor: ConstructorDescriptorImpl): List<ValueParameterDescriptor> {
val methods = jClass.getMethods()
val result = ArrayList<ValueParameterDescriptor>(methods.size())
@@ -22,16 +22,13 @@ import org.jetbrains.jet.lang.resolve.java.lazy.types.LazyJavaTypeAttributes
import org.jetbrains.jet.lang.resolve.java.lazy.hasMutableAnnotation
import org.jetbrains.jet.lang.resolve.java.lazy.hasReadOnlyAnnotation
import org.jetbrains.jet.lang.resolve.java.structure.JavaValueParameter
import org.jetbrains.jet.lang.resolve.java.resolver.JavaFunctionResolver
import java.util.ArrayList
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
import java.util.LinkedHashSet
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.resolve.java.resolver.JavaPropertyResolver
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPropertyDescriptor
import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorImpl
import java.util.Collections
import org.jetbrains.jet.utils.emptyOrSingletonList
import org.jetbrains.annotations.TestOnly
import org.jetbrains.jet.lang.resolve.java.resolver.ExternalSignatureResolver
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils
@@ -70,7 +67,7 @@ public abstract class LazyJavaMemberScope(
.flatMap {
m ->
val function = resolveMethodToFunctionDescriptor(m, true)
val samAdapter = JavaFunctionResolver.resolveSamAdapter(function)
val samAdapter = resolveSamAdapter(function)
if (samAdapter != null)
listOf(function, samAdapter).iterator()
else
@@ -85,7 +82,7 @@ public abstract class LazyJavaMemberScope(
}
if (_containingDeclaration is ClassDescriptor) {
val functionsFromSupertypes = JavaFunctionResolver.getFunctionsFromSupertypes(name, _containingDeclaration);
val functionsFromSupertypes = getFunctionsFromSupertypes(name, _containingDeclaration);
functions.addAll(DescriptorResolverUtils.resolveOverrides(name, functionsFromSupertypes, functions, _containingDeclaration, c.errorReporter));
}
@@ -204,6 +201,18 @@ public abstract class LazyJavaMemberScope(
}.toList()
}
private fun resolveSamAdapter(original: SimpleFunctionDescriptor): SimpleFunctionDescriptor? {
return if (SingleAbstractMethodUtils.isSamAdapterNecessary(original))
SingleAbstractMethodUtils.createSamAdapterFunction(original) as SimpleFunctionDescriptor
else null
}
private fun getFunctionsFromSupertypes(name: Name, descriptor: ClassDescriptor): Set<SimpleFunctionDescriptor> {
return descriptor.getTypeConstructor().getSupertypes().flatMap {
it.getMemberScope().getFunctions(name).map { f -> f as SimpleFunctionDescriptor }
}.toSet()
}
override fun getFunctions(name: Name) = _functions(name)
protected open fun getAllFunctionNames(): Collection<Name> = memberIndex().getAllMethodNames()
@@ -219,7 +228,7 @@ public abstract class LazyJavaMemberScope(
}
if (_containingDeclaration is ClassDescriptor) {
val propertiesFromSupertypes = JavaPropertyResolver.getPropertiesFromSupertypes(name, _containingDeclaration);
val propertiesFromSupertypes = getPropertiesFromSupertypes(name, _containingDeclaration);
properties.addAll(DescriptorResolverUtils.resolveOverrides(name, propertiesFromSupertypes, properties, _containingDeclaration,
c.errorReporter));
@@ -260,12 +269,18 @@ public abstract class LazyJavaMemberScope(
private fun getPropertyType(field: JavaField): JetType {
// Fields do not have their own generic parameters
val propertyType = c.typeResolver.transformJavaType(field.getType(), LazyJavaTypeAttributes(c, field, TypeUsage.MEMBER_SIGNATURE_INVARIANT))
if (JavaPropertyResolver.isStaticFinalField(field)) {
if (field.isFinal() && field.isStatic()) {
return TypeUtils.makeNotNullable(propertyType)
}
return propertyType
}
private fun getPropertiesFromSupertypes(name: Name, descriptor: ClassDescriptor): Set<PropertyDescriptor> {
return descriptor.getTypeConstructor().getSupertypes().flatMap {
it.getMemberScope().getProperties(name).map { p -> p as PropertyDescriptor }
}.toSet()
}
override fun getProperties(name: Name): Collection<VariableDescriptor> = _properties(name)
protected open fun getAllPropertyNames(): Collection<Name> = memberIndex().getAllFieldNames()
@@ -271,21 +271,6 @@ public final class JavaClassResolver {
return classDescriptor;
}
@NotNull
public static ClassKind determineClassKind(@NotNull JavaClass klass) {
if (klass.isInterface()) {
return klass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT;
}
return klass.isEnum() ? ClassKind.ENUM_CLASS : ClassKind.CLASS;
}
@NotNull
public static Modality determineClassModality(@NotNull JavaClass klass) {
return klass.isAnnotationType()
? Modality.FINAL
: Modality.convertFromFlags(klass.isAbstract() || klass.isInterface(), !klass.isFinal());
}
@NotNull
public static FqNameUnsafe getFqNameForClassObject(@NotNull JavaClass javaClass) {
FqName fqName = javaClass.getFqName();
@@ -312,30 +297,6 @@ public final class JavaClassResolver {
}
}
@NotNull
public static SimpleFunctionDescriptor findFunctionWithMostSpecificReturnType(@NotNull Set<JetType> supertypes) {
List<SimpleFunctionDescriptor> candidates = new ArrayList<SimpleFunctionDescriptor>(supertypes.size());
for (JetType supertype : supertypes) {
List<CallableMemberDescriptor> abstractMembers = SingleAbstractMethodUtils.getAbstractMembers(supertype);
if (!abstractMembers.isEmpty()) {
candidates.add((SimpleFunctionDescriptor) abstractMembers.get(0));
}
}
if (candidates.isEmpty()) {
throw new IllegalStateException("Couldn't find abstract method in supertypes " + supertypes);
}
SimpleFunctionDescriptor currentMostSpecificType = candidates.get(0);
for (SimpleFunctionDescriptor candidate : candidates) {
JetType candidateReturnType = candidate.getReturnType();
JetType currentMostSpecificReturnType = currentMostSpecificType.getReturnType();
assert candidateReturnType != null && currentMostSpecificReturnType != null : candidate + ", " + currentMostSpecificReturnType;
if (JetTypeChecker.INSTANCE.isSubtypeOf(candidateReturnType, currentMostSpecificReturnType)) {
currentMostSpecificType = candidate;
}
}
return currentMostSpecificType;
}
private void cache(@NotNull FqNameUnsafe fqName, @Nullable ClassDescriptor classDescriptor) {
if (classDescriptor == null) {
cacheNegativeValue(fqName);
@@ -392,19 +353,6 @@ public final class JavaClassResolver {
return FqNameUnsafe.fromSegments(correctedSegments);
}
public static boolean isInnerClass(@NotNull JavaClass javaClass) {
return javaClass.getOuterClass() != null && !javaClass.isStatic();
}
public static void createEnumSyntheticMethods(@NotNull JavaEnumClassObjectDescriptor classObject, @NotNull JetType enumType) {
JetType valuesReturnType = KotlinBuiltIns.getInstance().getArrayType(enumType);
SimpleFunctionDescriptor valuesMethod = DescriptorFactory.createEnumClassObjectValuesMethod(classObject, valuesReturnType);
classObject.getBuilder().addFunctionDescriptor(valuesMethod);
SimpleFunctionDescriptor valueOfMethod = DescriptorFactory.createEnumClassObjectValueOfMethod(classObject, enumType);
classObject.getBuilder().addFunctionDescriptor(valueOfMethod);
}
@NotNull
private JavaEnumClassObjectDescriptor createEnumClassObject(@NotNull ClassDescriptor enumClass, @NotNull JavaClass javaClass) {
JavaEnumClassObjectDescriptor classObject = new JavaEnumClassObjectDescriptor(enumClass);
@@ -171,15 +171,6 @@ public final class JavaConstructorResolver {
return result;
}
@NotNull
public static Visibility getConstructorVisibility(@NotNull ClassDescriptor classDescriptor) {
Visibility visibility = classDescriptor.getVisibility();
if (visibility == JavaVisibilities.PROTECTED_STATIC_VISIBILITY) {
return JavaVisibilities.PROTECTED_AND_PACKAGE;
}
return visibility;
}
@NotNull
private ConstructorDescriptor resolveConstructor(
@NotNull JavaMethod constructor,
@@ -218,9 +209,4 @@ public final class JavaConstructorResolver {
cache.recordConstructor(constructor, constructorDescriptor);
return constructorDescriptor;
}
@Nullable
public static ConstructorDescriptor resolveSamAdapter(@NotNull ConstructorDescriptor original) {
return isSamAdapterNecessary(original) ? (ConstructorDescriptor) createSamAdapterConstructor(original) : null;
}
}
@@ -224,22 +224,6 @@ public final class JavaFunctionResolver {
return functions;
}
@Nullable
public static SamConstructorDescriptor resolveSamConstructor(@NotNull JavaPackageFragmentDescriptor owner, @NotNull NamedMembers namedMembers) {
if (namedMembers.getSamInterface() != null) {
ClassDescriptor klass = owner.getJavaDescriptorResolver().resolveClass(owner.getFqName().child(namedMembers.getName()));
if (klass instanceof JavaClassDescriptor) {
return createSamConstructorFunction(owner, (JavaClassDescriptor) klass);
}
}
return null;
}
@Nullable
public static SimpleFunctionDescriptor resolveSamAdapter(@NotNull SimpleFunctionDescriptor original) {
return isSamAdapterNecessary(original) ? (SimpleFunctionDescriptor) createSamAdapterFunction(original) : null;
}
@NotNull
private JetType makeReturnType(
@NotNull JavaType returnType,
@@ -259,15 +243,4 @@ public final class JavaFunctionResolver {
return transformedType;
}
}
@NotNull
public static Set<SimpleFunctionDescriptor> getFunctionsFromSupertypes(@NotNull Name name, @NotNull ClassDescriptor descriptor) {
Set<SimpleFunctionDescriptor> result = new LinkedHashSet<SimpleFunctionDescriptor>();
for (JetType supertype : descriptor.getTypeConstructor().getSupertypes()) {
for (FunctionDescriptor function : supertype.getMemberScope().getFunctions(name)) {
result.add((SimpleFunctionDescriptor) function);
}
}
return result;
}
}
@@ -143,20 +143,4 @@ public final class JavaPropertyResolver {
return propertyType;
}
@NotNull
public static Set<PropertyDescriptor> getPropertiesFromSupertypes(@NotNull Name name, @NotNull ClassDescriptor descriptor) {
Set<PropertyDescriptor> result = new HashSet<PropertyDescriptor>();
for (JetType supertype : descriptor.getTypeConstructor().getSupertypes()) {
for (VariableDescriptor property : supertype.getMemberScope().getProperties(name)) {
result.add((PropertyDescriptor) property);
}
}
return result;
}
public static boolean isStaticFinalField(@NotNull JavaField field) {
return field.isFinal() && field.isStatic();
}
}