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 67757131b00..1f0cbc8fd93 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 @@ -23,6 +23,13 @@ import org.jetbrains.jet.lang.resolve.java.lazy.types.toAttributes import org.jetbrains.jet.lang.resolve.scopes.InnerClassesScopeWrapper import org.jetbrains.jet.lang.resolve.java.resolver.JavaSupertypeResolver import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor +import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl +import org.jetbrains.jet.lang.resolve.java.resolver.JavaConstructorResolver +import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl +import java.util.ArrayList +import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType +import org.jetbrains.jet.utils.* class LazyJavaClassDescriptor( private val c: LazyJavaResolverContextWithTypes, @@ -44,9 +51,9 @@ class LazyJavaClassDescriptor( override fun isInner() = _isInner private val _typeConstructor = c.storageManager.createLazyValue { LazyJavaClassTypeConstructor() } - override fun getTypeConstructor() = _typeConstructor() + override fun getTypeConstructor(): TypeConstructor = _typeConstructor() - private val _scopeForMemberLookup = LazyJavaClassMemberScope(c, this, jClass, false) + private val _scopeForMemberLookup = LazyJavaClassMemberScope(innerC, this, jClass, false) override fun getScopeForMemberLookup() = _scopeForMemberLookup private val _thisAsReceiverParameter = c.storageManager.createLazyValue { DescriptorFactory.createLazyReceiverParameterDescriptor(this) } @@ -57,8 +64,7 @@ class LazyJavaClassDescriptor( override fun getUnsubstitutedPrimaryConstructor(): ConstructorDescriptor? = null - // TODO - override fun getConstructors() = emptyOrSingletonList(getUnsubstitutedPrimaryConstructor()) + override fun getConstructors() = _scopeForMemberLookup._constructors() override fun getClassObjectType(): JetType? = null 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 80cf616e1a7..b4885f6f72e 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 @@ -42,6 +42,14 @@ 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 +import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl +import java.util.Collections +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.jet.lang.resolve.java.resolver.JavaConstructorResolver +import org.jetbrains.jet.utils.* +import java.util.ArrayList +import org.jetbrains.jet.lang.resolve.java.lazy.types.toAttributes +import org.jetbrains.jet.lang.types.JetType public class LazyJavaClassMemberScope( c: LazyJavaResolverContextWithTypes, @@ -142,6 +150,91 @@ public class LazyJavaClassMemberScope( }.toList() } + internal val _constructors = c.storageManager.createLazyValue { + jClass.getConstructors().map { + jCtor -> resolveConstructor(jCtor, getContainingDeclaration(), jClass.isStatic()) + } ifEmpty { + emptyOrSingletonList(createDefaultConstructor()) + } + } + + private fun resolveConstructor(constructor: JavaMethod, classDescriptor: ClassDescriptor, isStaticClass: Boolean): ConstructorDescriptor { + val constructorDescriptor = ConstructorDescriptorImpl(classDescriptor, Collections.emptyList(), isPrimary = false) + + val valueParameters = resolveValueParameters(c, constructorDescriptor, constructor.getValueParameters()) + val effectiveSignature = c.externalSignatureResolver.resolveAlternativeMethodSignature( + constructor, false, null, null, valueParameters, Collections.emptyList()) + + constructorDescriptor.initialize( + classDescriptor.getTypeConstructor().getParameters(), + effectiveSignature.getValueParameters(), + constructor.getVisibility(), + isStaticClass + ) + + constructorDescriptor.setReturnType(classDescriptor.getDefaultType()) + + val signatureErrors = effectiveSignature.getErrors() + if (!signatureErrors.isEmpty()) { + c.externalSignatureResolver.reportSignatureErrors(constructorDescriptor, signatureErrors) + } + + c.javaResolverCache.recordConstructor(constructor, constructorDescriptor) + + return constructorDescriptor + } + + private fun createDefaultConstructor(): ConstructorDescriptor? { + val isAnnotation: Boolean = jClass.isAnnotationType() + if (jClass.isInterface() && !isAnnotation) + return null + + val classDescriptor = getContainingDeclaration() + val constructorDescriptor = ConstructorDescriptorImpl(classDescriptor, Collections.emptyList(), isPrimary = true) + val typeParameters = classDescriptor.getTypeConstructor().getParameters() + val valueParameters = if (isAnnotation) createAnnotationConstructorParameters(constructorDescriptor) + else Collections.emptyList() + + constructorDescriptor.initialize(typeParameters, valueParameters, JavaConstructorResolver.getConstructorVisibility(classDescriptor), jClass.isStatic()) + constructorDescriptor.setReturnType(classDescriptor.getDefaultType()) + c.javaResolverCache.recordConstructor(jClass, constructorDescriptor); + return constructorDescriptor + } + + private fun createAnnotationConstructorParameters(constructor: ConstructorDescriptorImpl): List { + val methods = jClass.getMethods() + val result = ArrayList(methods.size()) + + for ((index, method) in methods.withIndices()) { + assert(method.getValueParameters().isEmpty(), "Annotation method can't have parameters: " + method) + + val jReturnType = method.getReturnType() ?: throw AssertionError("Annotation method has no return type: " + method) + + val varargElementType = + if (index == methods.size() - 1 && jReturnType is JavaArrayType) { + c.typeResolver.transformJavaType( + jReturnType.getComponentType(), + TypeUsage.MEMBER_SIGNATURE_INVARIANT.toAttributes() + ) + } + else null + + val returnType = c.typeResolver.transformJavaType(jReturnType, TypeUsage.MEMBER_SIGNATURE_INVARIANT.toAttributes()) + + result.add(ValueParameterDescriptorImpl( + constructor, + index, + Collections.emptyList(), + method.getName(), + returnType, + method.hasAnnotationParameterDefaultValue(), + varargElementType + )) + } + + return result + } + // TODO override fun getProperties(name: Name): Collection = listOf() diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java index 376055c6020..a9d4a455f41 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java @@ -172,7 +172,7 @@ public final class JavaConstructorResolver { } @NotNull - private static Visibility getConstructorVisibility(@NotNull ClassDescriptor classDescriptor) { + public static Visibility getConstructorVisibility(@NotNull ClassDescriptor classDescriptor) { Visibility visibility = classDescriptor.getVisibility(); if (visibility == JavaVisibilities.PROTECTED_STATIC_VISIBILITY) { return JavaVisibilities.PROTECTED_AND_PACKAGE;