Support loading Java fields as properties

This commit is contained in:
Andrey Breslav
2013-10-23 20:50:15 +04:00
parent 03cb977b2a
commit 03a9c776b2
5 changed files with 90 additions and 16 deletions
@@ -144,11 +144,6 @@ public class LazyJavaClassMemberScope(
return result
}
// TODO
override fun getProperties(name: Name): Collection<VariableDescriptor> = listOf()
override fun getAllPropertyNames(): Collection<Name> = listOf()
private val nestedClassIndex = c.storageManager.createLazyValue {
jClass.getInnerClasses().valuesToMap { c -> c.getName() }
}
@@ -29,6 +29,13 @@ 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.lazy.types.toAttributes
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.jet.lang.resolve.java.lazy.LazyJavaResolverContext
import org.jetbrains.annotations.TestOnly
import org.jetbrains.jet.utils.Printer
@@ -140,6 +147,63 @@ public abstract class LazyJavaMemberScope(
override fun getFunctions(name: Name) = _functions(name)
protected open fun getAllFunctionNames(): Collection<Name> = memberIndex().getAllMetodNames()
val _properties = c.storageManager.createMemoizedFunction {
(name: Name) ->
val properties = ArrayList<PropertyDescriptor>()
val field = memberIndex().findFieldByName(name)
if (field != null) {
properties.add(resolveProperty(field))
}
if (_containingDeclaration is ClassDescriptor) {
val propertiesFromSupertypes = JavaPropertyResolver.getPropertiesFromSupertypes(name, _containingDeclaration);
properties.addAll(DescriptorResolverUtils.resolveOverrides(name, propertiesFromSupertypes, properties, _containingDeclaration,
c.errorReporter));
}
properties
}
private fun resolveProperty(field: JavaField): PropertyDescriptor {
val isVar = !field.isFinal()
val propertyDescriptor = JavaPropertyDescriptor(
getContainingDeclaration(),
c.resolveAnnotations(field.getAnnotations()),
field.getVisibility(),
isVar,
field.getName()
)
propertyDescriptor.initialize(null, null)
val propertyType = getPropertyType(field)
val effectiveSignature = c.externalSignatureResolver.resolveAlternativeFieldSignature(field, propertyType, isVar)
val signatureErrors = effectiveSignature.getErrors()
if (!signatureErrors.isEmpty()) {
c.externalSignatureResolver.reportSignatureErrors(propertyDescriptor, signatureErrors)
}
propertyDescriptor.setType(effectiveSignature.getReturnType(), Collections.emptyList(), DescriptorUtils.getExpectedThisObjectIfNeeded(getContainingDeclaration()), null : JetType?)
c.javaResolverCache.recordField(field, propertyDescriptor);
return propertyDescriptor
}
private fun getPropertyType(field: JavaField): JetType {
// Fields do not have their own generic parameters
val propertyType = c.typeResolver.transformJavaType(field.getType(), TypeUsage.MEMBER_SIGNATURE_INVARIANT.toAttributes())
if (JavaPropertyResolver.isStaticFinalField(field)) {
return TypeUtils.makeNotNullable(propertyType)
}
return propertyType
}
override fun getProperties(name: Name): Collection<VariableDescriptor> = _properties(name)
protected open fun getAllPropertyNames(): Collection<Name> = memberIndex().getAllFieldNames()
// No object can be defined in Java
override fun getObjectDescriptor(name: Name): ClassDescriptor? = null
override fun getObjectDescriptors() = emptyList<ClassDescriptor>()
@@ -147,6 +211,8 @@ public abstract class LazyJavaMemberScope(
override fun getLocalVariable(name: Name): VariableDescriptor? = null
override fun getDeclarationsByLabel(labelName: LabelName) = emptyList<DeclarationDescriptor>()
override fun getClassifiers(name: Name) = emptyOrSingletonList(getClassifier(name))
override fun getOwnDeclaredDescriptors() = getAllDescriptors()
override fun getAllDescriptors() = allDescriptors()
@@ -178,7 +244,6 @@ public abstract class LazyJavaMemberScope(
protected abstract fun getAllPackageNames(): Collection<Name>
protected abstract fun getAllClassNames(): Collection<Name>
protected abstract fun getAllPropertyNames(): Collection<Name>
protected abstract fun addExtraDescriptors(result: MutableCollection<in DeclarationDescriptor>)
override fun toString() = "Lazy scope for ${getContainingDeclaration()}"
@@ -79,8 +79,4 @@ public class LazyPackageFragmentScopeForJavaClass(
override fun getAllPackageNames(): Collection<Name> = jClass.getInnerClasses().iterator()
.filter { c -> c.isStatic() && JavaNamespaceResolver.hasStaticMembers(c) }
.map { c -> c.getName() }.toList()
// TODO
override fun getProperties(name: Name): Collection<VariableDescriptor> = Collections.emptyList()
override fun getAllPropertyNames() = Collections.emptyList<Name>()
}
@@ -21,31 +21,49 @@ import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
import org.jetbrains.jet.lang.descriptors.Visibilities
import org.jetbrains.jet.lang.resolve.java.structure.JavaField
import org.jetbrains.jet.lang.resolve.java.structure.JavaMember
import org.jetbrains.jet.utils.valuesToMap
trait MemberIndex {
fun findMethodsByName(name: Name): Collection<JavaMethod>
fun getAllMetodNames(): Collection<Name>
fun findFieldByName(name: Name): JavaField?
fun getAllFieldNames(): Collection<Name>
}
object EMPTY_MEMBER_INDEX : MemberIndex {
override fun findMethodsByName(name: Name) = listOf<JavaMethod>()
override fun getAllMetodNames() = listOf<Name>()
override fun findFieldByName(name: Name): JavaField? = null
override fun getAllFieldNames() = listOf<Name>()
}
class ClassMemberIndex(val jClass: JavaClass, mustBeStatic: Boolean) : MemberIndex {
private val methodFilter = {
(m: JavaMethod) ->
private val memberFilter = {
(m: JavaMember) ->
m.isStatic() == mustBeStatic &&
!m.isConstructor() &&
!DescriptorResolverUtils.isObjectMethodInInterface(m) &&
m.getVisibility() != Visibilities.PRIVATE
}
private val methodFilter = {
(m: JavaMethod) ->
memberFilter(m) &&
!m.isConstructor() &&
!DescriptorResolverUtils.isObjectMethodInInterface(m)
}
private val methods = jClass.getMethods().iterator().filter(methodFilter).groupBy { m -> m.getName() }
private val fields = jClass.getFields().iterator().filter(memberFilter).valuesToMap { m -> m.getName() }
override fun findMethodsByName(name: Name): Collection<JavaMethod> {
return methods[name] ?: listOf()
}
override fun getAllMetodNames(): Collection<Name> = jClass.getAllMethods().iterator().filter(methodFilter).map { m -> m.getName() }.toList()
override fun findFieldByName(name: Name): JavaField? = fields[name]
override fun getAllFieldNames() = jClass.getAllFields().iterator().filter(memberFilter).map { m -> m.getName() }.toList()
}
@@ -145,7 +145,7 @@ public final class JavaPropertyResolver {
}
@NotNull
private static Set<PropertyDescriptor> getPropertiesFromSupertypes(@NotNull Name name, @NotNull ClassDescriptor descriptor) {
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)) {
@@ -156,7 +156,7 @@ public final class JavaPropertyResolver {
return result;
}
private static boolean isStaticFinalField(@NotNull JavaField field) {
public static boolean isStaticFinalField(@NotNull JavaField field) {
return field.isFinal() && field.isStatic();
}
}