Support loading Java fields as properties
This commit is contained in:
-5
@@ -144,11 +144,6 @@ public class LazyJavaClassMemberScope(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
override fun getProperties(name: Name): Collection<VariableDescriptor> = listOf()
|
|
||||||
override fun getAllPropertyNames(): Collection<Name> = listOf()
|
|
||||||
|
|
||||||
private val nestedClassIndex = c.storageManager.createLazyValue {
|
private val nestedClassIndex = c.storageManager.createLazyValue {
|
||||||
jClass.getInnerClasses().valuesToMap { c -> c.getName() }
|
jClass.getInnerClasses().valuesToMap { c -> c.getName() }
|
||||||
}
|
}
|
||||||
|
|||||||
+66
-1
@@ -29,6 +29,13 @@ import org.jetbrains.jet.lang.resolve.java.resolver.JavaFunctionResolver
|
|||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
|
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
|
||||||
import java.util.LinkedHashSet
|
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.jet.lang.resolve.java.lazy.LazyJavaResolverContext
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.jet.utils.Printer
|
import org.jetbrains.jet.utils.Printer
|
||||||
@@ -140,6 +147,63 @@ public abstract class LazyJavaMemberScope(
|
|||||||
override fun getFunctions(name: Name) = _functions(name)
|
override fun getFunctions(name: Name) = _functions(name)
|
||||||
protected open fun getAllFunctionNames(): Collection<Name> = memberIndex().getAllMetodNames()
|
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
|
// No object can be defined in Java
|
||||||
override fun getObjectDescriptor(name: Name): ClassDescriptor? = null
|
override fun getObjectDescriptor(name: Name): ClassDescriptor? = null
|
||||||
override fun getObjectDescriptors() = emptyList<ClassDescriptor>()
|
override fun getObjectDescriptors() = emptyList<ClassDescriptor>()
|
||||||
@@ -147,6 +211,8 @@ public abstract class LazyJavaMemberScope(
|
|||||||
override fun getLocalVariable(name: Name): VariableDescriptor? = null
|
override fun getLocalVariable(name: Name): VariableDescriptor? = null
|
||||||
override fun getDeclarationsByLabel(labelName: LabelName) = emptyList<DeclarationDescriptor>()
|
override fun getDeclarationsByLabel(labelName: LabelName) = emptyList<DeclarationDescriptor>()
|
||||||
|
|
||||||
|
override fun getClassifiers(name: Name) = emptyOrSingletonList(getClassifier(name))
|
||||||
|
|
||||||
override fun getOwnDeclaredDescriptors() = getAllDescriptors()
|
override fun getOwnDeclaredDescriptors() = getAllDescriptors()
|
||||||
override fun getAllDescriptors() = allDescriptors()
|
override fun getAllDescriptors() = allDescriptors()
|
||||||
|
|
||||||
@@ -178,7 +244,6 @@ public abstract class LazyJavaMemberScope(
|
|||||||
|
|
||||||
protected abstract fun getAllPackageNames(): Collection<Name>
|
protected abstract fun getAllPackageNames(): Collection<Name>
|
||||||
protected abstract fun getAllClassNames(): Collection<Name>
|
protected abstract fun getAllClassNames(): Collection<Name>
|
||||||
protected abstract fun getAllPropertyNames(): Collection<Name>
|
|
||||||
protected abstract fun addExtraDescriptors(result: MutableCollection<in DeclarationDescriptor>)
|
protected abstract fun addExtraDescriptors(result: MutableCollection<in DeclarationDescriptor>)
|
||||||
|
|
||||||
override fun toString() = "Lazy scope for ${getContainingDeclaration()}"
|
override fun toString() = "Lazy scope for ${getContainingDeclaration()}"
|
||||||
|
|||||||
-4
@@ -79,8 +79,4 @@ public class LazyPackageFragmentScopeForJavaClass(
|
|||||||
override fun getAllPackageNames(): Collection<Name> = jClass.getInnerClasses().iterator()
|
override fun getAllPackageNames(): Collection<Name> = jClass.getInnerClasses().iterator()
|
||||||
.filter { c -> c.isStatic() && JavaNamespaceResolver.hasStaticMembers(c) }
|
.filter { c -> c.isStatic() && JavaNamespaceResolver.hasStaticMembers(c) }
|
||||||
.map { c -> c.getName() }.toList()
|
.map { c -> c.getName() }.toList()
|
||||||
|
|
||||||
// TODO
|
|
||||||
override fun getProperties(name: Name): Collection<VariableDescriptor> = Collections.emptyList()
|
|
||||||
override fun getAllPropertyNames() = Collections.emptyList<Name>()
|
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-4
@@ -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.structure.JavaClass
|
||||||
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
|
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
|
||||||
import org.jetbrains.jet.lang.descriptors.Visibilities
|
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 {
|
trait MemberIndex {
|
||||||
fun findMethodsByName(name: Name): Collection<JavaMethod>
|
fun findMethodsByName(name: Name): Collection<JavaMethod>
|
||||||
fun getAllMetodNames(): Collection<Name>
|
fun getAllMetodNames(): Collection<Name>
|
||||||
|
|
||||||
|
fun findFieldByName(name: Name): JavaField?
|
||||||
|
fun getAllFieldNames(): Collection<Name>
|
||||||
}
|
}
|
||||||
|
|
||||||
object EMPTY_MEMBER_INDEX : MemberIndex {
|
object EMPTY_MEMBER_INDEX : MemberIndex {
|
||||||
override fun findMethodsByName(name: Name) = listOf<JavaMethod>()
|
override fun findMethodsByName(name: Name) = listOf<JavaMethod>()
|
||||||
override fun getAllMetodNames() = listOf<Name>()
|
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 {
|
class ClassMemberIndex(val jClass: JavaClass, mustBeStatic: Boolean) : MemberIndex {
|
||||||
private val methodFilter = {
|
private val memberFilter = {
|
||||||
(m: JavaMethod) ->
|
(m: JavaMember) ->
|
||||||
m.isStatic() == mustBeStatic &&
|
m.isStatic() == mustBeStatic &&
|
||||||
!m.isConstructor() &&
|
|
||||||
!DescriptorResolverUtils.isObjectMethodInInterface(m) &&
|
|
||||||
m.getVisibility() != Visibilities.PRIVATE
|
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 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> {
|
override fun findMethodsByName(name: Name): Collection<JavaMethod> {
|
||||||
return methods[name] ?: listOf()
|
return methods[name] ?: listOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAllMetodNames(): Collection<Name> = jClass.getAllMethods().iterator().filter(methodFilter).map { m -> m.getName() }.toList()
|
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()
|
||||||
}
|
}
|
||||||
+2
-2
@@ -145,7 +145,7 @@ public final class JavaPropertyResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@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>();
|
Set<PropertyDescriptor> result = new HashSet<PropertyDescriptor>();
|
||||||
for (JetType supertype : descriptor.getTypeConstructor().getSupertypes()) {
|
for (JetType supertype : descriptor.getTypeConstructor().getSupertypes()) {
|
||||||
for (VariableDescriptor property : supertype.getMemberScope().getProperties(name)) {
|
for (VariableDescriptor property : supertype.getMemberScope().getProperties(name)) {
|
||||||
@@ -156,7 +156,7 @@ public final class JavaPropertyResolver {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isStaticFinalField(@NotNull JavaField field) {
|
public static boolean isStaticFinalField(@NotNull JavaField field) {
|
||||||
return field.isFinal() && field.isStatic();
|
return field.isFinal() && field.isStatic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user