diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaSubModule.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaSubModule.kt new file mode 100644 index 00000000000..44277b48a03 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/LazyJavaSubModule.kt @@ -0,0 +1,15 @@ +package org.jetbrains.jet.lang.resolve.java.lazy + +import org.jetbrains.jet.lang.descriptors.ModuleDescriptor +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor +import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaPackageFragment +import org.jetbrains.jet.storage.MemoizedFunctionToNullable +import org.jetbrains.jet.lang.resolve.name.FqName + +public open class LazyJavaSubModule( + c: LazyJavaResolverContext, + module: ModuleDescriptor +) { + public val packageFragments: MemoizedFunctionToNullable + = c.storageManager.createMemoizedFunctionWithNullableValues {fqName -> LazyJavaPackageFragment(c, module, fqName)} +} \ No newline at end of file diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/context.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/context.kt new file mode 100644 index 00000000000..7f31af54505 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/context.kt @@ -0,0 +1,51 @@ +/* + * 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 + +import org.jetbrains.jet.storage.StorageManager +import org.jetbrains.jet.lang.resolve.java.lazy.types.LazyJavaTypeResolver +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor +import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter +import org.jetbrains.jet.lang.resolve.java.JavaClassFinder + +open class LazyJavaResolverContext( + val storageManager: StorageManager, + val finder: JavaClassFinder, + val javaClassResolver: LazyJavaClassResolver +) + +fun LazyJavaResolverContext.withTypes( + typeParameterResolver: TypeParameterResolver = TypeParameterResolver.EMPTY +) = LazyJavaResolverContextWithTypes( + storageManager, + finder, + javaClassResolver, + LazyJavaTypeResolver(this, typeParameterResolver), + typeParameterResolver) + +class LazyJavaResolverContextWithTypes( + storageManager: StorageManager, + finder: JavaClassFinder, + javaClassResolver: LazyJavaClassResolver, + val typeResolver: LazyJavaTypeResolver, + val typeParameterResolver: TypeParameterResolver +) : LazyJavaResolverContext(storageManager, finder, javaClassResolver) + +fun LazyJavaResolverContextWithTypes.child( + containingDeclaration: DeclarationDescriptor, + typeParameters: Set +): LazyJavaResolverContextWithTypes = this.withTypes(LazyJavaTypeParameterResolver(this, containingDeclaration, typeParameters)) \ No newline at end of file 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 new file mode 100644 index 00000000000..a17e664cce9 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt @@ -0,0 +1,100 @@ +package org.jetbrains.jet.lang.resolve.java.lazy.descriptors + +import org.jetbrains.jet.lang.resolve.name.FqName +import org.jetbrains.jet.lang.resolve.java.structure.JavaClass +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor +import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorBase +import org.jetbrains.jet.lang.resolve.scopes.JetScope +import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor +import org.jetbrains.jet.lang.types.JetType +import org.jetbrains.jet.lang.descriptors.ClassDescriptor +import org.jetbrains.jet.lang.types.TypeConstructor +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.jet.lang.resolve.java.resolver.JavaClassResolver +import org.jetbrains.jet.utils.emptyOrSingletonList +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor +import java.util.Collections +import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContextWithTypes +import org.jetbrains.jet.lang.resolve.DescriptorFactory +import org.jetbrains.jet.lang.resolve.java.lazy.child +import org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage + +class LazyJavaClassDescriptor( + private val c: LazyJavaResolverContextWithTypes, + containingDeclaration: DeclarationDescriptor, + fqName: FqName, + private val jClass: JavaClass +) : ClassDescriptorBase(containingDeclaration, fqName.shortName()), LazyJavaDescriptor { + + private val innerC: LazyJavaResolverContextWithTypes = c.child(this, jClass.getTypeParameters().toSet()) + + private val _kind = JavaClassResolver.determineClassKind(jClass) + private val _modality = JavaClassResolver.determineClassModality(jClass) + private val _visibility = jClass.getVisibility() + private val _isInner = JavaClassResolver.isInnerClass(jClass) + + override fun getKind() = _kind + override fun getModality() = _modality + override fun getVisibility() = _visibility + override fun isInner() = _isInner + + 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 _thisAsReceiverParameter = c.storageManager.createLazyValue { DescriptorFactory.createLazyReceiverParameterDescriptor(this) } + override fun getThisAsReceiverParameter() = _thisAsReceiverParameter() + + // TODO + override fun getUnsubstitutedInnerClassesScope(): JetScope = JetScope.EMPTY + + override fun getUnsubstitutedPrimaryConstructor(): ConstructorDescriptor? = null + + // TODO + override fun getConstructors() = emptyOrSingletonList(getUnsubstitutedPrimaryConstructor()) + + override fun getClassObjectType(): JetType? = null + + override fun getClassObjectDescriptor(): ClassDescriptor? = null + + // TODO + override fun getAnnotations(): List = Collections.emptyList() + + private inner class LazyJavaClassTypeConstructor : TypeConstructor { + + private val _parameters = c.storageManager.createLazyValue { + this@LazyJavaClassDescriptor.jClass.getTypeParameters().map { + p -> + innerC.typeParameterResolver.resolveTypeParameter(p) + ?: throw AssertionError("Parameter $p surely belongs to class $jClass, so it must be resolved") + } + } + + override fun getParameters(): List = _parameters() + + private val _supertypes = c.storageManager.createLazyValue { + jClass.getSupertypes().map { + supertype -> + innerC.typeResolver.transformJavaType(supertype, TypeUsage.SUPERTYPE) + } + } + + override fun getSupertypes(): Collection = _supertypes() + + override fun getAnnotations() = Collections.emptyList() + + override fun isFinal() = !getModality().isOverridable() + + override fun isDenotable() = true + + override fun getDeclarationDescriptor() = this@LazyJavaClassDescriptor + + override fun toString(): String? = getName().asString() + } +} \ No newline at end of file diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaDescriptor.kt new file mode 100644 index 00000000000..bd3e2da66f2 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaDescriptor.kt @@ -0,0 +1,5 @@ +package org.jetbrains.jet.lang.resolve.java.lazy.descriptors + +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor + +public trait LazyJavaDescriptor : DeclarationDescriptor \ 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 new file mode 100644 index 00000000000..29ec1929289 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt @@ -0,0 +1,70 @@ +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.lazy.LazyJavaResolverContext +import org.jetbrains.annotations.TestOnly +import org.jetbrains.jet.utils.Printer + +public abstract class LazyJavaMemberScope( + private val c: LazyJavaResolverContext, + private val _containingDeclaration: DeclarationDescriptor +) : JetScope { + private val allDescriptors: NotNullLazyValue> = c.storageManager.createLazyValue{computeAllDescriptors()} + + override fun getContainingDeclaration() = _containingDeclaration + + // No object can be defined in Java + override fun getObjectDescriptor(name: Name): ClassDescriptor? = null + override fun getObjectDescriptors() = emptyList() + + // namespaces should be resolved elsewhere + override fun getNamespace(name: Name): NamespaceDescriptor? = null + + override fun getLocalVariable(name: Name): VariableDescriptor? = null + override fun getDeclarationsByLabel(labelName: LabelName) = emptyList() + + override fun getOwnDeclaredDescriptors() = getAllDescriptors() + override fun getAllDescriptors() = allDescriptors() + + private fun computeAllDescriptors(): MutableCollection { + val result = arrayListOf() + + for (name in getAllClassNames()) { + val descriptor = getClassifier(name) + assert(descriptor != null) {"Descriptor not found for name " + name + " in " + getContainingDeclaration()} + result.add(descriptor!!) + } + + for (name in getAllFunctionNames()) { + result.addAll(getFunctions(name)) + } + + for (name in getAllPropertyNames()) { + result.addAll(getProperties(name)) + } + + addExtraDescriptors(result) + + return result + } + protected abstract fun getAllClassNames(): Collection + protected abstract fun getAllPropertyNames(): Collection + protected abstract fun getAllFunctionNames(): Collection + protected abstract fun addExtraDescriptors(result: MutableCollection) + + TestOnly + override fun printScopeStructure(p: Printer) { + p.println(javaClass.getSimpleName(), " {") + p.pushIndent() + + p.println("containigDeclaration: ${getContainingDeclaration()}") + + p.popIndent() + p.println("}") + } +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragment.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragment.kt new file mode 100644 index 00000000000..19a94d596ef --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragment.kt @@ -0,0 +1,25 @@ +package org.jetbrains.jet.lang.resolve.java.lazy.descriptors + +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor +import org.jetbrains.jet.lang.descriptors.impl.AbstractNamespaceDescriptorImpl +import org.jetbrains.jet.lang.descriptors.impl.NamespaceDescriptorParent +import org.jetbrains.jet.lang.resolve.name.FqName +import org.jetbrains.jet.utils.emptyList +import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContext +import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe + +public class LazyJavaPackageFragment( + c: LazyJavaResolverContext, + containingDeclaration: NamespaceDescriptorParent, + private val _fqName: FqName +) : AbstractNamespaceDescriptorImpl( + containingDeclaration, + emptyList(), + if (_fqName.isRoot()) FqNameUnsafe.ROOT_NAME else _fqName.shortName() + ), NamespaceDescriptor, LazyJavaDescriptor { + + private val _memberScope = LazyJavaPackageFragmentScope(c, this) + + override fun getMemberScope() = _memberScope + override fun getFqName() = _fqName +} 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 new file mode 100644 index 00000000000..f7b956ffa7c --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragmentScope.kt @@ -0,0 +1,50 @@ +package org.jetbrains.jet.lang.resolve.java.lazy.descriptors + +import org.jetbrains.jet.lang.descriptors.* +import org.jetbrains.jet.lang.resolve.DescriptorUtils +import org.jetbrains.jet.lang.resolve.name.Name +import java.util.Collections +import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContext +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, + containingDeclaration: NamespaceDescriptor +) : LazyJavaMemberScope(c.withTypes(), containingDeclaration) { + + private val fqName = DescriptorUtils.getFQName(containingDeclaration).toSafe() + private val classes = c.storageManager.createMemoizedFunctionWithNullableValues { + name -> + val fqName = fqName.child(name) + val javaClass = c.finder.findClass(fqName) + if (javaClass == null) + null + else + LazyJavaClassDescriptor(c.withTypes(TypeParameterResolver.EMPTY), containingDeclaration, fqName, javaClass) + } + + override fun getAllClassNames(): Collection { + val javaPackage = c.finder.findPackage(fqName) + assert(javaPackage != null) { "Package not found: $fqName" } + return javaPackage!!.getClasses().map { c -> c.getName() } + } + + override fun getAllPropertyNames() = Collections.emptyList() + override fun getAllFunctionNames() = Collections.emptyList() + + override fun addExtraDescriptors(result: MutableCollection) { + // no extra descriptors + } + + override fun getClassifier(name: Name): ClassifierDescriptor? = classes(name) + + // TODO + override fun getProperties(name: Name): Collection = Collections.emptyList() + + // TODO + override fun getFunctions(name: Name): Collection = Collections.emptyList() + + override fun getImplicitReceiversHierarchy(): List = listOf() + +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaTypeParameterDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaTypeParameterDescriptor.kt new file mode 100644 index 00000000000..77bf71e34f9 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaTypeParameterDescriptor.kt @@ -0,0 +1,54 @@ +/* + * 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.impl.AbstractLazyTypeParameterDescriptor +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor +import org.jetbrains.jet.lang.types.Variance +import org.jetbrains.jet.lang.types.JetType +import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns +import org.jetbrains.jet.lang.resolve.java.lazy.types.LazyJavaTypeResolver +import org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage +import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContextWithTypes + +class LazyJavaTypeParameterDescriptor( + private val c: LazyJavaResolverContextWithTypes, + public val javaTypeParameter: JavaTypeParameter, + containingDeclaration: DeclarationDescriptor +) : AbstractLazyTypeParameterDescriptor( + c.storageManager, + containingDeclaration, + name = javaTypeParameter.getName(), + variance = Variance.INVARIANT, + isReified = false, + index = javaTypeParameter.getIndex() +) { + + override fun resolveUpperBounds(): Set { + val bounds = javaTypeParameter.getUpperBounds() + if (bounds.isEmpty()) { + return setOf(KotlinBuiltIns.getInstance().getDefaultBound()) + } + else { + return bounds.map { + javaType -> c.typeResolver.transformJavaType(javaType, TypeUsage.UPPER_BOUND) + }.toSet() + } + } + +} \ No newline at end of file diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/resolvers.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/resolvers.kt new file mode 100644 index 00000000000..9d2046db01b --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/resolvers.kt @@ -0,0 +1,74 @@ +/* + * 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 + +import org.jetbrains.jet.lang.resolve.java.structure.JavaClass +import org.jetbrains.jet.lang.descriptors.ClassDescriptor +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor +import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter +import org.jetbrains.jet.utils.toMap +import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaTypeParameterDescriptor +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor +import org.jetbrains.jet.lang.resolve.java.lazy.types.LazyJavaTypeResolver + +trait LazyJavaClassResolver { + fun resolveClass(javaClass: JavaClass): ClassDescriptor? +} + +trait TypeParameterResolver { + class object { + object EMPTY : TypeParameterResolver { + override fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? = null + } + } + + fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? +} + +class TypeParameterResolverImpl( + _typeParameters: Collection, + private val parent: TypeParameterResolver = TypeParameterResolver.EMPTY +) : TypeParameterResolver { + + private val parameters = _typeParameters.toMap { p -> p.javaTypeParameter } + + override fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? { + return parameters[javaTypeParameter] ?: parent.resolveTypeParameter(javaTypeParameter) + } +} + +class LazyJavaTypeParameterResolver( + val c: LazyJavaResolverContextWithTypes, + private val containingDeclaration: DeclarationDescriptor, + private val typeParameters: Set +) : TypeParameterResolver { + + private val resolve: (JavaTypeParameter) -> TypeParameterDescriptor? = c.storageManager.createMemoizedFunctionWithNullableValues { + javaTypeParameter -> + if (javaTypeParameter in typeParameters) + LazyJavaTypeParameterDescriptor( + c.withTypes(this), + javaTypeParameter, + containingDeclaration + ) + else null + } + + override fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? { + return resolve(javaTypeParameter) ?: c.typeParameterResolver.resolveTypeParameter(javaTypeParameter) + } +} \ No newline at end of file diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/types/LazyJavaTypeResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/types/LazyJavaTypeResolver.kt new file mode 100644 index 00000000000..f956934ec1d --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/types/LazyJavaTypeResolver.kt @@ -0,0 +1,160 @@ +/* + * 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.types + +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.jet.lang.resolve.java.structure.JavaType +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor +import org.jetbrains.jet.lang.descriptors.ClassDescriptor +import org.jetbrains.jet.lang.resolve.java.structure.JavaWildcardType +import org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage.* +import org.jetbrains.jet.lang.resolve.java.resolver.* +import org.jetbrains.jet.lang.types.Variance.* +import org.jetbrains.jet.lang.types.* +import org.jetbrains.kotlin.util.iif +import org.jetbrains.jet.utils.* +import org.jetbrains.jet.storage.* +import org.jetbrains.kotlin.util.eq +import org.jetbrains.jet.lang.resolve.java.structure.JavaPrimitiveType +import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType +import org.jetbrains.jet.lang.resolve.java.structure.JavaClassifierType +import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns +import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter +import org.jetbrains.jet.lang.resolve.java.structure.JavaClass +import org.jetbrains.kotlin.util.sure +import org.jetbrains.jet.lang.resolve.java.lazy.TypeParameterResolver +import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaTypeParameterDescriptor +import org.jetbrains.jet.lang.resolve.java.lazy.TypeParameterResolverImpl +import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContext +import org.jetbrains.jet.lang.resolve.scopes.JetScope + +class LazyJavaTypeResolver( + private val c: LazyJavaResolverContext, + private val typeParameterResolver: TypeParameterResolver +) { + private val NOT_NULL_POSITIONS = setOf(TYPE_ARGUMENT, UPPER_BOUND, SUPERTYPE_ARGUMENT, SUPERTYPE) + + public fun transformJavaType(javaType: JavaType, howThisTypeIsUsed: TypeUsage): JetType { + return when (javaType) { + is JavaPrimitiveType -> { + val canonicalText = javaType.getCanonicalText() + val jetType = JavaToKotlinClassMap.getInstance().mapPrimitiveKotlinClass(canonicalText) + assert(jetType != null, "Primitive type is not found: " + canonicalText) + return jetType!! + } + is JavaClassifierType -> LazyJavaClassifierType(javaType, howThisTypeIsUsed).applyNullablility(howThisTypeIsUsed) + is JavaArrayType -> transformArrayType(javaType, howThisTypeIsUsed).applyNullablility(howThisTypeIsUsed) + else -> throw UnsupportedOperationException("Unsupported type: " + javaType) + } + } + + public fun transformArrayType(arrayType: JavaArrayType, howThisTypeIsUsed: TypeUsage, isVararg: Boolean = false): JetType { + val javaComponentType = arrayType.getComponentType() + if (javaComponentType is JavaPrimitiveType) { + val jetType = JavaToKotlinClassMap.getInstance().mapPrimitiveKotlinClass("[" + javaComponentType.getCanonicalText()) + if (jetType != null) return jetType + } + + val projectionKind = if (howThisTypeIsUsed == MEMBER_SIGNATURE_CONTRAVARIANT && !isVararg) OUT_VARIANCE else INVARIANT + + val howArgumentTypeIsUsed = isVararg.iif(MEMBER_SIGNATURE_CONTRAVARIANT, TYPE_ARGUMENT) + val componentType = transformJavaType(javaComponentType, howArgumentTypeIsUsed) + return TypeUtils.makeNullable(KotlinBuiltIns.getInstance().getArrayType(projectionKind, componentType)) + } + + private fun JetType.applyNullablility(howThisTypeIsUsed: TypeUsage): JetType { + return TypeUtils.makeNullableAsSpecified(this, howThisTypeIsUsed !in NOT_NULL_POSITIONS) + } + + private fun transformToTypeProjection( + javaType: JavaType, + howThisTypeIsUsed: TypeUsage, + typeConstructorBeingApplied: () -> TypeConstructor, + typeParameterIndex: Int + ): TypeProjection { + return when (javaType) { + is JavaWildcardType -> { + val bound = javaType.getBound() + if (bound == null) + LazyStarProjection(c, typeConstructorBeingApplied, typeParameterIndex) + else { + TypeProjectionImpl(javaType.isExtends().iif(OUT_VARIANCE, IN_VARIANCE), transformJavaType(bound, UPPER_BOUND)) + } + } + else -> TypeProjectionImpl(INVARIANT, transformJavaType(javaType, howThisTypeIsUsed)) + } + } + + private class LazyStarProjection( + c: LazyJavaResolverContext, + typeConstructor: () -> TypeConstructor, + typeParameterIndex: Int + ) : TypeProjectionBase() { + private val typeParameter by c.storageManager.createLazyValue {typeConstructor().getParameters()[typeParameterIndex]} + + override fun getProjectionKind() = typeParameter.getVariance().eq(OUT_VARIANCE).iif(INVARIANT, OUT_VARIANCE) + override fun getType() = typeParameter.getUpperBoundsAsType() + } + + private inner class LazyJavaClassifierType( + private val javaType: JavaClassifierType, + private val howThisTypeIsUsed: TypeUsage + ) : LazyType(c.storageManager) { + + + override fun computeTypeConstructor(): TypeConstructor { + val classifier = javaType.getClassifier() + if (classifier == null) { + return ErrorUtils.createErrorTypeConstructor("Unresolved java classifier: " + javaType.getPresentableText()) + } + return when (classifier) { + is JavaClass -> { + val fqName = classifier.getFqName() + .sure("Class type should have a FQ name: " + classifier) + val classData = JavaToKotlinClassMap.getInstance().mapKotlinClass(fqName, howThisTypeIsUsed) + ?: c.javaClassResolver.resolveClass(classifier) + + classData?.getTypeConstructor() + ?: ErrorUtils.createErrorTypeConstructor("Unresolved java classifier: " + javaType.getPresentableText()) + } + is JavaTypeParameter -> { + typeParameterResolver.resolveTypeParameter(classifier)?.getTypeConstructor() + ?: ErrorUtils.createErrorTypeConstructor("Unresolved Java type parameter: " + javaType.getPresentableText()) + } + else -> throw IllegalStateException("Unknown classifier kind: $classifier") + } + } + + override fun computeArguments(): List { + var howTheProjectionIsUsed = howThisTypeIsUsed.eq(SUPERTYPE).iif(SUPERTYPE_ARGUMENT, TYPE_ARGUMENT) + return javaType.getTypeArguments().withIndices().map { + p -> + val (i, t) = p + transformToTypeProjection(t, howTheProjectionIsUsed, {getConstructor()}, i) + }.toList() + } + + override fun computeMemberScope(): JetScope { + val descriptor = getConstructor().getDeclarationDescriptor()!! + + if (descriptor is TypeParameterDescriptor) return descriptor.getDefaultType().getMemberScope() + + return (descriptor as ClassDescriptor).getMemberScope(getArguments()) + } + } +} \ No newline at end of file diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/types/LazyType.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/types/LazyType.kt new file mode 100644 index 00000000000..56cb30c5dc5 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/types/LazyType.kt @@ -0,0 +1,48 @@ +/* + * 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.types + +import org.jetbrains.jet.storage.StorageManager +import org.jetbrains.jet.lang.types.TypeConstructor +import org.jetbrains.jet.lang.types.TypeProjection +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.jet.lang.resolve.scopes.JetScope +import org.jetbrains.jet.lang.types.AbstractJetType + +abstract class LazyType(storageManager: StorageManager) : AbstractJetType() { + + private val _typeConstructor = storageManager.createLazyValue {computeTypeConstructor()} + override fun getConstructor(): TypeConstructor = _typeConstructor() + + protected abstract fun computeTypeConstructor(): TypeConstructor + + private val _arguments = storageManager.createLazyValue {computeArguments()} + override fun getArguments(): List = _arguments() + + protected abstract fun computeArguments(): List + + private val _memberScope = storageManager.createLazyValue {computeMemberScope()} + override fun getMemberScope() = _memberScope() + + protected abstract fun computeMemberScope(): JetScope + + override fun isNullable() = false + + override fun isError() = false + + override fun getAnnotations(): List = listOf() +}