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() }
|
||||
override fun getTypeConstructor(): TypeConstructor = _typeConstructor()
|
||||
|
||||
private val _scopeForMemberLookup = LazyJavaClassMemberScope(innerC, this, jClass, false)
|
||||
private val _scopeForMemberLookup = LazyJavaClassMemberScope(innerC, this, jClass)
|
||||
override fun getScopeForMemberLookup() = _scopeForMemberLookup
|
||||
|
||||
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(
|
||||
c: LazyJavaResolverContextWithTypes,
|
||||
containingDeclaration: LazyJavaClassDescriptor,
|
||||
private val jClass: JavaClass,
|
||||
classAsPackage: Boolean
|
||||
private val jClass: JavaClass
|
||||
) : LazyJavaMemberScope(c, containingDeclaration) {
|
||||
|
||||
private val methodIndex = c.storageManager.createLazyValue {
|
||||
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()
|
||||
}
|
||||
override fun computeMemberIndex(): MemberIndex = ClassMemberIndex(jClass, mustBeStatic = false)
|
||||
|
||||
internal val _constructors = c.storageManager.createLazyValue {
|
||||
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.kotlin.util.iif
|
||||
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.annotations.TestOnly
|
||||
import org.jetbrains.jet.utils.Printer
|
||||
@@ -36,6 +37,99 @@ public abstract class LazyJavaMemberScope(
|
||||
|
||||
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
|
||||
override fun getObjectDescriptor(name: Name): ClassDescriptor? = null
|
||||
override fun getObjectDescriptors() = emptyList<ClassDescriptor>()
|
||||
@@ -75,7 +169,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 getAllFunctionNames(): Collection<Name>
|
||||
protected abstract fun addExtraDescriptors(result: MutableCollection<in DeclarationDescriptor>)
|
||||
|
||||
override fun toString() = "Lazy scope for ${getContainingDeclaration()}"
|
||||
|
||||
+4
-7
@@ -48,6 +48,8 @@ public class LazyPackageFragmentScopeForJavaPackage(
|
||||
packageFragment: LazyJavaPackageFragment
|
||||
) : LazyJavaPackageFragmentScope(c, packageFragment) {
|
||||
|
||||
override fun computeMemberIndex(): MemberIndex = EMPTY_MEMBER_INDEX
|
||||
|
||||
override fun getAllClassNames(): Collection<Name> {
|
||||
val javaPackage = c.finder.findPackage(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 getAllPropertyNames() = Collections.emptyList<Name>()
|
||||
|
||||
override fun getFunctions(name: Name): Collection<FunctionDescriptor> = Collections.emptyList()
|
||||
override fun getAllFunctionNames() = Collections.emptyList<Name>()
|
||||
}
|
||||
|
||||
public class LazyPackageFragmentScopeForJavaClass(
|
||||
@@ -74,6 +73,8 @@ public class LazyPackageFragmentScopeForJavaClass(
|
||||
packageFragment: LazyJavaPackageFragment
|
||||
) : 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 getAllPackageNames(): Collection<Name> = jClass.getInnerClasses().iterator()
|
||||
.filter { c -> c.isStatic() && JavaNamespaceResolver.hasStaticMembers(c) }
|
||||
@@ -82,8 +83,4 @@ public class LazyPackageFragmentScopeForJavaClass(
|
||||
// TODO
|
||||
override fun getProperties(name: Name): Collection<VariableDescriptor> = Collections.emptyList()
|
||||
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