diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt index 83706926a20..6289282d5db 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt @@ -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) } diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt index c24367f0b43..410023109b2 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt @@ -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 - -> - 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 = methodIndex().keySet() - - private fun resolveValueParameters( - innerC: LazyJavaResolverContextWithTypes, - function: FunctionDescriptor, - jValueParameters: List - ): List { - 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 { diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt index 3cb2043dcfd..98a53971b4e 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt @@ -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 + -> + 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 + ): List { + 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 = memberIndex().getAllMetodNames() + // No object can be defined in Java override fun getObjectDescriptor(name: Name): ClassDescriptor? = null override fun getObjectDescriptors() = emptyList() @@ -75,7 +169,6 @@ public abstract class LazyJavaMemberScope( protected abstract fun getAllPackageNames(): Collection protected abstract fun getAllClassNames(): Collection protected abstract fun getAllPropertyNames(): Collection - protected abstract fun getAllFunctionNames(): Collection protected abstract fun addExtraDescriptors(result: MutableCollection) override fun toString() = "Lazy scope for ${getContainingDeclaration()}" diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragmentScope.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragmentScope.kt index bf4b7e3a8c2..c4a88cb63fa 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragmentScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragmentScope.kt @@ -48,6 +48,8 @@ public class LazyPackageFragmentScopeForJavaPackage( packageFragment: LazyJavaPackageFragment ) : LazyJavaPackageFragmentScope(c, packageFragment) { + override fun computeMemberIndex(): MemberIndex = EMPTY_MEMBER_INDEX + override fun getAllClassNames(): Collection { 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 = Collections.emptyList() override fun getAllPropertyNames() = Collections.emptyList() - - override fun getFunctions(name: Name): Collection = Collections.emptyList() - override fun getAllFunctionNames() = Collections.emptyList() } 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 = listOf() // nested classes are loaded as members of their outer classes, not packages override fun getAllPackageNames(): Collection = jClass.getInnerClasses().iterator() .filter { c -> c.isStatic() && JavaNamespaceResolver.hasStaticMembers(c) } @@ -82,8 +83,4 @@ public class LazyPackageFragmentScopeForJavaClass( // TODO override fun getProperties(name: Name): Collection = Collections.emptyList() override fun getAllPropertyNames() = Collections.emptyList() - - // TODO - override fun getFunctions(name: Name): Collection = Collections.emptyList() - override fun getAllFunctionNames() = Collections.emptyList() } diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/MemberIndex.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/MemberIndex.kt new file mode 100644 index 00000000000..1d0ec762d12 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/MemberIndex.kt @@ -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 + fun getAllMetodNames(): Collection +} + +object EMPTY_MEMBER_INDEX : MemberIndex { + override fun findMethodsByName(name: Name) = listOf() + override fun getAllMetodNames() = listOf() +} + +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 { + return methods[name] ?: listOf() + } + + override fun getAllMetodNames(): Collection = methods.keySet() +} \ No newline at end of file