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 30994268934..be62a8d089f 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 @@ -43,12 +43,8 @@ class LazyJavaClassDescriptor( private val _typeConstructor = c.storageManager.createLazyValue { LazyJavaClassTypeConstructor() } override fun getTypeConstructor() = _typeConstructor() - private val _scopeForMemberLookup = c.storageManager.createLazyValue { - // TODO - throw UnsupportedOperationException() - } - - override fun getScopeForMemberLookup() = _scopeForMemberLookup() + private val _scopeForMemberLookup = LazyJavaClassMemberScope(c, this, jClass, false) + override fun getScopeForMemberLookup() = _scopeForMemberLookup private val _thisAsReceiverParameter = c.storageManager.createLazyValue { DescriptorFactory.createLazyReceiverParameterDescriptor(this) } override fun getThisAsReceiverParameter() = _thisAsReceiverParameter() 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 new file mode 100644 index 00000000000..108c276724a --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt @@ -0,0 +1,161 @@ +/* + * 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.descriptors.* +import org.jetbrains.jet.storage.NotNullLazyValue +import org.jetbrains.jet.lang.resolve.name.LabelName +import org.jetbrains.jet.lang.resolve.name.Name +import org.jetbrains.jet.lang.resolve.scopes.JetScope +import org.jetbrains.jet.utils.emptyList +import org.jetbrains.jet.lang.resolve.java.structure.JavaClass +import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod +import org.jetbrains.jet.lang.resolve.java.structure.JavaField +import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContextWithTypes +import org.jetbrains.jet.lang.resolve.java.descriptor.JavaMethodDescriptor +import org.jetbrains.jet.lang.resolve.DescriptorUtils +import org.jetbrains.jet.lang.resolve.java.lazy.child +import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl +import org.jetbrains.jet.lang.resolve.java.lazy.resolveAnnotations +import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType +import org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage +import org.jetbrains.jet.lang.types.TypeUtils +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns +import org.jetbrains.jet.lang.resolve.java.lazy.hasNotNullAnnotation +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.utils.valuesToMap +import org.jetbrains.jet.lang.resolve.java.structure.JavaValueParameter + +public class LazyJavaClassMemberScope( + c: LazyJavaResolverContextWithTypes, + containingDeclaration: DeclarationDescriptor, + private val jClass: JavaClass, + classAsPackage: Boolean +) : 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() + } + + + // TODO + override fun getProperties(name: Name): Collection = listOf() + override fun getAllPropertyNames(): Collection = listOf() + + // TODO + override fun getClassifier(name: Name): ClassifierDescriptor? = null + override fun getAllClassNames(): Collection = listOf() + + override fun addExtraDescriptors(result: MutableCollection) { + // TODO + } + + // TODO + override fun getImplicitReceiversHierarchy(): List = listOf() + +} \ No newline at end of file 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 29ec1929289..8df3518bfc1 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 @@ -6,12 +6,30 @@ import org.jetbrains.jet.lang.resolve.name.LabelName import org.jetbrains.jet.lang.resolve.name.Name import org.jetbrains.jet.lang.resolve.scopes.JetScope import org.jetbrains.jet.utils.emptyList +import org.jetbrains.jet.lang.resolve.java.structure.JavaClass +import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod +import org.jetbrains.jet.lang.resolve.java.structure.JavaField +import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContextWithTypes +import org.jetbrains.jet.lang.resolve.java.descriptor.JavaMethodDescriptor +import org.jetbrains.jet.lang.resolve.DescriptorUtils +import org.jetbrains.jet.lang.resolve.java.lazy.child +import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl +import org.jetbrains.jet.lang.resolve.java.lazy.resolveAnnotations +import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType +import org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage +import org.jetbrains.jet.lang.types.TypeUtils +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns +import org.jetbrains.jet.lang.resolve.java.lazy.hasNotNullAnnotation +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.lazy.LazyJavaResolverContext import org.jetbrains.annotations.TestOnly import org.jetbrains.jet.utils.Printer public abstract class LazyJavaMemberScope( - private val c: LazyJavaResolverContext, + protected val c: LazyJavaResolverContextWithTypes, private val _containingDeclaration: DeclarationDescriptor ) : JetScope { private val allDescriptors: NotNullLazyValue> = c.storageManager.createLazyValue{computeAllDescriptors()} @@ -52,6 +70,7 @@ public abstract class LazyJavaMemberScope( return result } + protected abstract fun getAllClassNames(): Collection protected abstract fun getAllPropertyNames(): Collection protected abstract fun getAllFunctionNames(): Collection 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 f7b956ffa7c..c7cf32749ca 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 @@ -9,7 +9,7 @@ import org.jetbrains.jet.lang.resolve.java.lazy.withTypes import org.jetbrains.jet.lang.resolve.java.lazy.TypeParameterResolver public class LazyJavaPackageFragmentScope( - private val c: LazyJavaResolverContext, + c: LazyJavaResolverContext, containingDeclaration: NamespaceDescriptor ) : LazyJavaMemberScope(c.withTypes(), containingDeclaration) { diff --git a/core/util.runtime/src/org/jetbrains/jet/utils/collections.kt b/core/util.runtime/src/org/jetbrains/jet/utils/collections.kt index 8ae8156de3b..301f562946a 100644 --- a/core/util.runtime/src/org/jetbrains/jet/utils/collections.kt +++ b/core/util.runtime/src/org/jetbrains/jet/utils/collections.kt @@ -19,6 +19,18 @@ package org.jetbrains.jet.utils import java.util.LinkedHashMap public fun Iterable.valuesToMap(key: (V) -> K): Map { + return iterator().valuesToMap(key) +} + +public fun Iterable.keysToMap(value: (K) -> V): Map { + return iterator().keysToMap(value) +} + +public fun Iterable.keysToMapExceptNulls(value: (K) -> V?): Map { + return iterator().keysToMapExceptNulls(value) +} + +public fun Iterator.valuesToMap(key: (V) -> K): Map { val map = LinkedHashMap() for (v in this) { map[key(v)] = v @@ -26,7 +38,7 @@ public fun Iterable.valuesToMap(key: (V) -> K): Map { return map } -public fun Iterable.keysToMap(value: (K) -> V): Map { +public fun Iterator.keysToMap(value: (K) -> V): Map { val map = LinkedHashMap() for (k in this) { map[k] = value(k) @@ -34,7 +46,7 @@ public fun Iterable.keysToMap(value: (K) -> V): Map { return map } -public fun Iterable.keysToMapExceptNulls(value: (K) -> V?): Map { +public fun Iterator.keysToMapExceptNulls(value: (K) -> V?): Map { val map = LinkedHashMap() for (k in this) { val v = value(k)