Drop enum class object hack
Place valueOf() and values() into the static scope of the corresponding enum class #KT-5580 Fixed #KT-2410 Fixed
This commit is contained in:
+1
-9
@@ -39,7 +39,6 @@ import org.jetbrains.jet.lang.descriptors.annotations.Annotations
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
|
||||
import org.jetbrains.jet.lang.types.AbstractClassTypeConstructor
|
||||
import org.jetbrains.jet.lang.descriptors.impl.EnumClassObjectDescriptor
|
||||
|
||||
class LazyJavaClassDescriptor(
|
||||
private val outerC: LazyJavaResolverContextWithTypes,
|
||||
@@ -88,14 +87,7 @@ class LazyJavaClassDescriptor(
|
||||
|
||||
override fun getUnsubstitutedPrimaryConstructor(): ConstructorDescriptor? = null
|
||||
|
||||
private val _classObjectDescriptor = c.storageManager.createNullableLazyValue {
|
||||
if (jClass.isEnum()) {
|
||||
EnumClassObjectDescriptor(c.storageManager, this)
|
||||
}
|
||||
else null
|
||||
}
|
||||
|
||||
override fun getClassObjectDescriptor(): ClassDescriptor? = _classObjectDescriptor()
|
||||
override fun getClassObjectDescriptor(): ClassDescriptor? = null
|
||||
override fun getClassObjectType(): JetType? = getClassObjectDescriptor()?.let { d -> d.getDefaultType() }
|
||||
|
||||
override fun getConstructors() = _scopeForMemberLookup._constructors()
|
||||
|
||||
+2
@@ -87,6 +87,8 @@ public class LazyJavaClassMemberScope(
|
||||
c.errorReporter))
|
||||
}
|
||||
|
||||
override fun computeAdditionalFunctions(name: Name) = listOf<SimpleFunctionDescriptor>()
|
||||
|
||||
private fun getPropertiesFromSupertypes(name: Name, descriptor: ClassDescriptor): Set<PropertyDescriptor> {
|
||||
return descriptor.getTypeConstructor().getSupertypes().flatMap {
|
||||
it.getMemberScope().getProperties(name).map { p -> p as PropertyDescriptor }
|
||||
|
||||
+15
-14
@@ -38,7 +38,6 @@ 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 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.descriptor.JavaPropertyDescriptor
|
||||
@@ -72,23 +71,25 @@ public abstract class LazyJavaMemberScope(
|
||||
|
||||
protected abstract fun getExpectedThisObject(): ReceiverParameterDescriptor?
|
||||
|
||||
protected abstract fun computeAdditionalFunctions(name: Name): Collection<SimpleFunctionDescriptor>
|
||||
|
||||
private val _functions = c.storageManager.createMemoizedFunction {
|
||||
(name: Name): Collection<FunctionDescriptor>
|
||||
->
|
||||
(name: Name): Collection<FunctionDescriptor> ->
|
||||
val methods = memberIndex().findMethodsByName(name)
|
||||
val functions = LinkedHashSet<SimpleFunctionDescriptor>(
|
||||
methods.stream()
|
||||
// values() and valueOf() are added manually, see LazyJavaClassDescriptor::getClassObjectDescriptor()
|
||||
.filter{ m -> !DescriptorResolverUtils.shouldBeInEnumClassObject(m) }
|
||||
.flatMap {
|
||||
m ->
|
||||
val function = resolveMethodToFunctionDescriptor(m, true)
|
||||
val samAdapter = resolveSamAdapter(function)
|
||||
if (samAdapter != null)
|
||||
listOf(function, samAdapter).stream()
|
||||
else
|
||||
listOf(function).stream()
|
||||
}.toList())
|
||||
.flatMap {
|
||||
m ->
|
||||
val function = resolveMethodToFunctionDescriptor(m, true)
|
||||
val samAdapter = resolveSamAdapter(function)
|
||||
if (samAdapter != null)
|
||||
listOf(function, samAdapter).stream()
|
||||
else
|
||||
listOf(function).stream()
|
||||
}
|
||||
.plus(computeAdditionalFunctions(name))
|
||||
.toList()
|
||||
)
|
||||
|
||||
computeNonDeclaredFunctions(functions, name)
|
||||
|
||||
|
||||
+18
@@ -36,6 +36,7 @@ import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaMemberScope.
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.name.SpecialNames
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorFactory.*
|
||||
|
||||
public abstract class LazyJavaStaticScope(
|
||||
c: LazyJavaResolverContext,
|
||||
@@ -131,6 +132,8 @@ public class LazyPackageFragmentScopeForJavaPackage(
|
||||
|
||||
override fun computeMemberIndex(): MemberIndex = computeMemberIndexForSamConstructors(EMPTY_MEMBER_INDEX)
|
||||
|
||||
override fun computeAdditionalFunctions(name: Name) = listOf<SimpleFunctionDescriptor>()
|
||||
|
||||
override fun getAllClassNames(): Collection<Name> {
|
||||
return jPackage.getClasses().stream()
|
||||
.filter { c -> c.getOriginKind() != JavaClass.OriginKind.KOTLIN_LIGHT_CLASS }
|
||||
@@ -165,6 +168,21 @@ public class LazyJavaStaticClassScope(
|
||||
|
||||
override fun computeMemberIndex(): MemberIndex = computeMemberIndexForSamConstructors(ClassMemberIndex(jClass, { m -> m.isStatic() }))
|
||||
|
||||
override fun getAllFunctionNames(): Collection<Name> {
|
||||
if (jClass.isEnum()) {
|
||||
return super.getAllFunctionNames() + listOf(Name.identifier("valueOf"), Name.identifier("values"))
|
||||
}
|
||||
return super.getAllFunctionNames()
|
||||
}
|
||||
|
||||
override fun computeAdditionalFunctions(name: Name): Collection<SimpleFunctionDescriptor> {
|
||||
if (jClass.isEnum()) {
|
||||
if (name.asString() == "valueOf") return listOf(createEnumValueOfMethod(getContainingDeclaration()))
|
||||
if (name.asString() == "values") return listOf(createEnumValuesMethod(getContainingDeclaration()))
|
||||
}
|
||||
return listOf()
|
||||
}
|
||||
|
||||
override fun getAllClassNames(): Collection<Name> = listOf()
|
||||
override fun getClassifier(name: Name): ClassifierDescriptor? = null
|
||||
|
||||
|
||||
-17
@@ -87,23 +87,6 @@ public final class DescriptorResolverUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if {@code method} is a static method of enum class, which is to be put into its class object (and not into the
|
||||
* corresponding package). This applies to values() and valueOf(String) methods
|
||||
*/
|
||||
public static boolean shouldBeInEnumClassObject(@NotNull JavaMethod method) {
|
||||
if (!method.getContainingClass().isEnum()) return false;
|
||||
|
||||
String name = method.getName().asString();
|
||||
if (name.equals("values")) {
|
||||
return method.getValueParameters().isEmpty();
|
||||
}
|
||||
else if (name.equals("valueOf")) {
|
||||
return isMethodWithOneParameterWithFqName(method, "java.lang.String");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isObjectMethodInInterface(@NotNull JavaMember member) {
|
||||
return member.getContainingClass().isInterface() && member instanceof JavaMethod && isObjectMethod((JavaMethod) member);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user