Resolve functions in packages loaded from Java classes
This commit is contained in:
+1
-1
@@ -53,7 +53,7 @@ class LazyJavaClassDescriptor(
|
|||||||
private val _typeConstructor = c.storageManager.createLazyValue { LazyJavaClassTypeConstructor() }
|
private val _typeConstructor = c.storageManager.createLazyValue { LazyJavaClassTypeConstructor() }
|
||||||
override fun getTypeConstructor(): TypeConstructor = _typeConstructor()
|
override fun getTypeConstructor(): TypeConstructor = _typeConstructor()
|
||||||
|
|
||||||
private val _scopeForMemberLookup = LazyJavaClassMemberScope(innerC, this, jClass, false)
|
private val _scopeForMemberLookup = LazyJavaClassMemberScope(innerC, this, jClass)
|
||||||
override fun getScopeForMemberLookup() = _scopeForMemberLookup
|
override fun getScopeForMemberLookup() = _scopeForMemberLookup
|
||||||
|
|
||||||
private val _thisAsReceiverParameter = c.storageManager.createLazyValue { DescriptorFactory.createLazyReceiverParameterDescriptor(this) }
|
private val _thisAsReceiverParameter = c.storageManager.createLazyValue { DescriptorFactory.createLazyReceiverParameterDescriptor(this) }
|
||||||
|
|||||||
+2
-93
@@ -54,101 +54,10 @@ import org.jetbrains.jet.lang.types.JetType
|
|||||||
public class LazyJavaClassMemberScope(
|
public class LazyJavaClassMemberScope(
|
||||||
c: LazyJavaResolverContextWithTypes,
|
c: LazyJavaResolverContextWithTypes,
|
||||||
containingDeclaration: LazyJavaClassDescriptor,
|
containingDeclaration: LazyJavaClassDescriptor,
|
||||||
private val jClass: JavaClass,
|
private val jClass: JavaClass
|
||||||
classAsPackage: Boolean
|
|
||||||
) : LazyJavaMemberScope(c, containingDeclaration) {
|
) : LazyJavaMemberScope(c, containingDeclaration) {
|
||||||
|
|
||||||
private val methodIndex = c.storageManager.createLazyValue {
|
override fun computeMemberIndex(): MemberIndex = ClassMemberIndex(jClass, mustBeStatic = false)
|
||||||
jClass.getMethods().iterator().filter { m -> m.isStatic() == classAsPackage && !m.isConstructor() }.groupBy { m -> m.getName() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private val _functions = c.storageManager.createMemoizedFunction {
|
|
||||||
(name: Name): Collection<FunctionDescriptor>
|
|
||||||
->
|
|
||||||
val methods = methodIndex()[name] ?: listOf()
|
|
||||||
val functions = methods.map {
|
|
||||||
method ->
|
|
||||||
val function = JavaMethodDescriptor(
|
|
||||||
containingDeclaration,
|
|
||||||
c.resolveAnnotations(method.getAnnotations()),
|
|
||||||
name
|
|
||||||
)
|
|
||||||
val innerC = c.child(function, method.getTypeParameters().toSet())
|
|
||||||
val valueParameters = resolveValueParameters(innerC, function, method.getValueParameters())
|
|
||||||
val returnTypeAttrs = LazyJavaTypeAttributes(c, method, TypeUsage.MEMBER_SIGNATURE_COVARIANT) {
|
|
||||||
if (method.hasReadOnlyAnnotation() && !method.hasMutableAnnotation())
|
|
||||||
TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT
|
|
||||||
else
|
|
||||||
TypeUsage.MEMBER_SIGNATURE_COVARIANT
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function.initialize(
|
|
||||||
null,
|
|
||||||
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration),
|
|
||||||
method.getTypeParameters().map { p -> innerC.typeParameterResolver.resolveTypeParameter(p) },
|
|
||||||
valueParameters,
|
|
||||||
c.typeResolver.transformJavaType(method.getReturnType()!!, returnTypeAttrs),
|
|
||||||
Modality.convertFromFlags(method.isAbstract(), !method.isFinal()),
|
|
||||||
method.getVisibility(),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
function
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure that lazy things are computed before we release the lock
|
|
||||||
for (f in functions) {
|
|
||||||
for (p in f.getValueParameters()) {
|
|
||||||
p.hasDefaultValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
functions
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getFunctions(name: Name) = _functions(name)
|
|
||||||
override fun getAllFunctionNames(): Collection<Name> = methodIndex().keySet()
|
|
||||||
|
|
||||||
private fun resolveValueParameters(
|
|
||||||
innerC: LazyJavaResolverContextWithTypes,
|
|
||||||
function: FunctionDescriptor,
|
|
||||||
jValueParameters: List<JavaValueParameter>
|
|
||||||
): List<ValueParameterDescriptor> {
|
|
||||||
return jValueParameters.withIndices().map {
|
|
||||||
pair ->
|
|
||||||
val (index, javaParameter) = pair
|
|
||||||
|
|
||||||
val typeUsage = LazyJavaTypeAttributes(c, javaParameter, TypeUsage.MEMBER_SIGNATURE_COVARIANT) {
|
|
||||||
javaParameter.hasMutableAnnotation().iif(TypeUsage.MEMBER_SIGNATURE_COVARIANT, TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT)
|
|
||||||
}
|
|
||||||
|
|
||||||
val (outType, varargElementType) =
|
|
||||||
if (javaParameter.isVararg()) {
|
|
||||||
val paramType = javaParameter.getType()
|
|
||||||
assert (paramType is JavaArrayType, "Vararg parameter should be an array: $paramType")
|
|
||||||
val arrayType = c.typeResolver.transformArrayType(paramType as JavaArrayType, typeUsage, true)
|
|
||||||
val outType = TypeUtils.makeNotNullable(arrayType)
|
|
||||||
Pair(outType, KotlinBuiltIns.getInstance().getArrayElementType(outType))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val jetType = c.typeResolver.transformJavaType(javaParameter.getType(), typeUsage)
|
|
||||||
if (jetType.isNullable() && javaParameter.hasNotNullAnnotation())
|
|
||||||
Pair(TypeUtils.makeNotNullable(jetType), null)
|
|
||||||
else Pair(jetType, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
ValueParameterDescriptorImpl(
|
|
||||||
function,
|
|
||||||
index,
|
|
||||||
innerC.resolveAnnotations(javaParameter.getAnnotations()),
|
|
||||||
// TODO: parameter names may be drawn from attached sources, which is slow; it's better to make them lazy
|
|
||||||
javaParameter.getName() ?: Name.identifier("p$index"),
|
|
||||||
outType,
|
|
||||||
false,
|
|
||||||
varargElementType
|
|
||||||
)
|
|
||||||
}.toList()
|
|
||||||
}
|
|
||||||
|
|
||||||
internal val _constructors = c.storageManager.createLazyValue {
|
internal val _constructors = c.storageManager.createLazyValue {
|
||||||
jClass.getConstructors().map {
|
jClass.getConstructors().map {
|
||||||
|
|||||||
+94
-1
@@ -24,6 +24,7 @@ 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.hasMutableAnnotation
|
||||||
import org.jetbrains.kotlin.util.iif
|
import org.jetbrains.kotlin.util.iif
|
||||||
import org.jetbrains.jet.lang.resolve.java.lazy.hasReadOnlyAnnotation
|
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.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
|
||||||
@@ -36,6 +37,99 @@ public abstract class LazyJavaMemberScope(
|
|||||||
|
|
||||||
override fun getContainingDeclaration() = _containingDeclaration
|
override fun getContainingDeclaration() = _containingDeclaration
|
||||||
|
|
||||||
|
private val memberIndex = c.storageManager.createLazyValue {
|
||||||
|
computeMemberIndex()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun computeMemberIndex(): MemberIndex
|
||||||
|
|
||||||
|
private val _functions = c.storageManager.createMemoizedFunction {
|
||||||
|
(name: Name): Collection<FunctionDescriptor>
|
||||||
|
->
|
||||||
|
val methods = memberIndex().findMethodsByName(name)
|
||||||
|
val functions = methods.map {
|
||||||
|
method ->
|
||||||
|
val function = JavaMethodDescriptor(
|
||||||
|
_containingDeclaration,
|
||||||
|
c.resolveAnnotations(method.getAnnotations()),
|
||||||
|
name
|
||||||
|
)
|
||||||
|
val innerC = c.child(function, method.getTypeParameters().toSet())
|
||||||
|
val valueParameters = resolveValueParameters(innerC, function, method.getValueParameters())
|
||||||
|
val returnTypeAttrs = LazyJavaTypeAttributes(c, method, TypeUsage.MEMBER_SIGNATURE_COVARIANT) {
|
||||||
|
if (method.hasReadOnlyAnnotation() && !method.hasMutableAnnotation())
|
||||||
|
TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT
|
||||||
|
else
|
||||||
|
TypeUsage.MEMBER_SIGNATURE_COVARIANT
|
||||||
|
}
|
||||||
|
|
||||||
|
function.initialize(
|
||||||
|
null,
|
||||||
|
DescriptorUtils.getExpectedThisObjectIfNeeded(_containingDeclaration),
|
||||||
|
method.getTypeParameters().map { p -> innerC.typeParameterResolver.resolveTypeParameter(p) },
|
||||||
|
valueParameters,
|
||||||
|
c.typeResolver.transformJavaType(method.getReturnType()!!, returnTypeAttrs),
|
||||||
|
Modality.convertFromFlags(method.isAbstract(), !method.isFinal()),
|
||||||
|
method.getVisibility(),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
function
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure that lazy things are computed before we release the lock
|
||||||
|
for (f in functions) {
|
||||||
|
for (p in f.getValueParameters()) {
|
||||||
|
p.hasDefaultValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
functions
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun resolveValueParameters(
|
||||||
|
c: LazyJavaResolverContextWithTypes,
|
||||||
|
function: FunctionDescriptor,
|
||||||
|
jValueParameters: List<JavaValueParameter>
|
||||||
|
): List<ValueParameterDescriptor> {
|
||||||
|
return jValueParameters.withIndices().map {
|
||||||
|
pair ->
|
||||||
|
val (index, javaParameter) = pair
|
||||||
|
|
||||||
|
val typeUsage = LazyJavaTypeAttributes(c, javaParameter, TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT) {
|
||||||
|
javaParameter.hasMutableAnnotation().iif(TypeUsage.MEMBER_SIGNATURE_COVARIANT, TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT)
|
||||||
|
}
|
||||||
|
|
||||||
|
val (outType, varargElementType) =
|
||||||
|
if (javaParameter.isVararg()) {
|
||||||
|
val paramType = javaParameter.getType()
|
||||||
|
assert (paramType is JavaArrayType, "Vararg parameter should be an array: $paramType")
|
||||||
|
val arrayType = c.typeResolver.transformArrayType(paramType as JavaArrayType, typeUsage, true)
|
||||||
|
val outType = TypeUtils.makeNotNullable(arrayType)
|
||||||
|
Pair(outType, KotlinBuiltIns.getInstance().getArrayElementType(outType))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val jetType = c.typeResolver.transformJavaType(javaParameter.getType(), typeUsage)
|
||||||
|
if (jetType.isNullable() && javaParameter.hasNotNullAnnotation())
|
||||||
|
Pair(TypeUtils.makeNotNullable(jetType), null)
|
||||||
|
else Pair(jetType, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueParameterDescriptorImpl(
|
||||||
|
function,
|
||||||
|
index,
|
||||||
|
c.resolveAnnotations(javaParameter.getAnnotations()),
|
||||||
|
// TODO: parameter names may be drawn from attached sources, which is slow; it's better to make them lazy
|
||||||
|
javaParameter.getName() ?: Name.identifier("p$index"),
|
||||||
|
outType,
|
||||||
|
false,
|
||||||
|
varargElementType
|
||||||
|
)
|
||||||
|
}.toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFunctions(name: Name) = _functions(name)
|
||||||
|
protected open fun getAllFunctionNames(): Collection<Name> = memberIndex().getAllMetodNames()
|
||||||
|
|
||||||
// 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>()
|
||||||
@@ -75,7 +169,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 getAllPropertyNames(): Collection<Name>
|
||||||
protected abstract fun getAllFunctionNames(): 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
-7
@@ -48,6 +48,8 @@ public class LazyPackageFragmentScopeForJavaPackage(
|
|||||||
packageFragment: LazyJavaPackageFragment
|
packageFragment: LazyJavaPackageFragment
|
||||||
) : LazyJavaPackageFragmentScope(c, packageFragment) {
|
) : LazyJavaPackageFragmentScope(c, packageFragment) {
|
||||||
|
|
||||||
|
override fun computeMemberIndex(): MemberIndex = EMPTY_MEMBER_INDEX
|
||||||
|
|
||||||
override fun getAllClassNames(): Collection<Name> {
|
override fun getAllClassNames(): Collection<Name> {
|
||||||
val javaPackage = c.finder.findPackage(fqName)
|
val javaPackage = c.finder.findPackage(fqName)
|
||||||
assert(javaPackage != null) { "Package not found: $fqName" }
|
assert(javaPackage != null) { "Package not found: $fqName" }
|
||||||
@@ -63,9 +65,6 @@ public class LazyPackageFragmentScopeForJavaPackage(
|
|||||||
|
|
||||||
override fun getProperties(name: Name): Collection<VariableDescriptor> = Collections.emptyList()
|
override fun getProperties(name: Name): Collection<VariableDescriptor> = Collections.emptyList()
|
||||||
override fun getAllPropertyNames() = Collections.emptyList<Name>()
|
override fun getAllPropertyNames() = Collections.emptyList<Name>()
|
||||||
|
|
||||||
override fun getFunctions(name: Name): Collection<FunctionDescriptor> = Collections.emptyList()
|
|
||||||
override fun getAllFunctionNames() = Collections.emptyList<Name>()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LazyPackageFragmentScopeForJavaClass(
|
public class LazyPackageFragmentScopeForJavaClass(
|
||||||
@@ -74,6 +73,8 @@ public class LazyPackageFragmentScopeForJavaClass(
|
|||||||
packageFragment: LazyJavaPackageFragment
|
packageFragment: LazyJavaPackageFragment
|
||||||
) : LazyJavaPackageFragmentScope(c, packageFragment) {
|
) : LazyJavaPackageFragmentScope(c, packageFragment) {
|
||||||
|
|
||||||
|
override fun computeMemberIndex(): MemberIndex = ClassMemberIndex(jClass, mustBeStatic = true)
|
||||||
|
|
||||||
override fun getAllClassNames(): Collection<Name> = listOf() // nested classes are loaded as members of their outer classes, not packages
|
override fun getAllClassNames(): Collection<Name> = listOf() // nested classes are loaded as members of their outer classes, not packages
|
||||||
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) }
|
||||||
@@ -82,8 +83,4 @@ public class LazyPackageFragmentScopeForJavaClass(
|
|||||||
// TODO
|
// TODO
|
||||||
override fun getProperties(name: Name): Collection<VariableDescriptor> = Collections.emptyList()
|
override fun getProperties(name: Name): Collection<VariableDescriptor> = Collections.emptyList()
|
||||||
override fun getAllPropertyNames() = Collections.emptyList<Name>()
|
override fun getAllPropertyNames() = Collections.emptyList<Name>()
|
||||||
|
|
||||||
// TODO
|
|
||||||
override fun getFunctions(name: Name): Collection<FunctionDescriptor> = Collections.emptyList()
|
|
||||||
override fun getAllFunctionNames() = Collections.emptyList<Name>()
|
|
||||||
}
|
}
|
||||||
|
|||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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.lazy.descriptors
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.Name
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass
|
||||||
|
|
||||||
|
trait MemberIndex {
|
||||||
|
fun findMethodsByName(name: Name): Collection<JavaMethod>
|
||||||
|
fun getAllMetodNames(): Collection<Name>
|
||||||
|
}
|
||||||
|
|
||||||
|
object EMPTY_MEMBER_INDEX : MemberIndex {
|
||||||
|
override fun findMethodsByName(name: Name) = listOf<JavaMethod>()
|
||||||
|
override fun getAllMetodNames() = listOf<Name>()
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassMemberIndex(jClass: JavaClass, mustBeStatic: Boolean) : MemberIndex {
|
||||||
|
private val methods = jClass.getMethods().iterator().filter { m -> m.isStatic() == mustBeStatic && !m.isConstructor() }.groupBy { m -> m.getName() }
|
||||||
|
|
||||||
|
override fun findMethodsByName(name: Name): Collection<JavaMethod> {
|
||||||
|
return methods[name] ?: listOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getAllMetodNames(): Collection<Name> = methods.keySet()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user