diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/error/MissingDependencyErrorClass.kt b/core/descriptors/src/org/jetbrains/jet/lang/types/error/MissingDependencyErrorClass.kt index 2cb638cb4a6..22de67fb0ba 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/error/MissingDependencyErrorClass.kt +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/error/MissingDependencyErrorClass.kt @@ -17,50 +17,8 @@ package org.jetbrains.jet.lang.types.error import org.jetbrains.jet.lang.resolve.name.FqName -import org.jetbrains.jet.lang.types.TypeConstructorImpl -import org.jetbrains.jet.lang.descriptors.annotations.Annotations -import java.util.ArrayList -import org.jetbrains.jet.lang.types.TypeConstructor -import org.jetbrains.jet.lang.descriptors.ClassDescriptor -import org.jetbrains.jet.lang.types.TypeSubstitutor -import org.jetbrains.jet.lang.resolve.scopes.JetScope -import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorImpl -import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl -import java.util.Collections -import org.jetbrains.jet.lang.descriptors.Visibilities -import org.jetbrains.jet.lang.descriptors.Modality -import org.jetbrains.jet.lang.types.JetType -import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor -import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor -import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor -import org.jetbrains.jet.lang.types.ErrorUtils.* -import org.jetbrains.jet.lang.resolve.name.Name -import org.jetbrains.jet.lang.types.TypeProjection // marker for DescriptorRenderer to treat specially in decompiler mode public trait MissingDependencyErrorClass { val fullFqName: FqName -} - -public class MissingDependencyErrorClassDescriptor(override val fullFqName: FqName) -: MissingDependencyErrorClass, ClassDescriptorImpl(getErrorModule(), fullFqName.shortName(), Modality.OPEN, Collections.emptyList()) { - - override fun substitute(substitutor: TypeSubstitutor): ClassDescriptor { - return this - } - - override fun toString(): String { - return getName().asString() - } - - override fun getMemberScope(typeArguments: List): JetScope { - return createErrorScope("Error scope for class " + getName() + " with arguments: " + typeArguments) - } - - { - val emptyConstructor = ConstructorDescriptorImpl.create(this, Annotations.EMPTY, true) - emptyConstructor.initialize(Collections.emptyList(), Collections.emptyList(), Visibilities.INTERNAL, false) - emptyConstructor.setReturnType(createErrorType("")) - initialize(JetScope.EMPTY, Collections.singleton(emptyConstructor), emptyConstructor) - } -} +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt b/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt index 18d9537ccad..462b4478fad 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt +++ b/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt @@ -25,7 +25,6 @@ import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass import org.jetbrains.jet.lang.resolve.name.FqName import org.jetbrains.jet.lang.resolve.name.Name -import org.jetbrains.jet.lang.types.ErrorUtils import org.jetbrains.jet.storage.LockBasedStorageManager import java.util.Collections import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils @@ -35,7 +34,6 @@ import org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedPackageMemberScope import org.jetbrains.jet.lang.resolve.kotlin.AnnotationDescriptorLoader import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter -import org.jetbrains.jet.lang.types.error.MissingDependencyErrorClassDescriptor import org.jetbrains.jet.lang.resolve.java.PackageClassUtils import com.intellij.openapi.diagnostic.Logger import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder @@ -44,6 +42,9 @@ import org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage import org.jetbrains.jet.lang.resolve.kotlin.ConstantDescriptorLoader import org.jetbrains.jet.lang.resolve.java.structure.JavaClass import org.jetbrains.jet.descriptors.serialization.context.DeserializationGlobalContext +import org.jetbrains.jet.lang.PlatformToKotlinClassMap +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns +import org.jetbrains.jet.lang.types.ErrorUtils public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForDecompiler { val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile) @@ -148,7 +149,15 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di } } - val moduleDescriptor = ErrorUtils.getErrorModule() + private val moduleDescriptor = + ModuleDescriptorImpl(Name.special(""), listOf(), PlatformToKotlinClassMap.EMPTY); + + { + moduleDescriptor.addFragmentProvider(DependencyKind.BUILT_INS, + KotlinBuiltIns.getInstance().getBuiltInsModule().getPackageFragmentProvider()) + moduleDescriptor.addFragmentProvider(DependencyKind.SOURCES, packageFragmentProvider) + moduleDescriptor.addFragmentProvider(DependencyKind.BINARIES, PackageFragmentProviderForMissingDependencies(moduleDescriptor)) + } val deserializationContext = DeserializationGlobalContext(storageManager, moduleDescriptor, descriptorFinder, annotationLoader, constantLoader, packageFragmentProvider) @@ -157,19 +166,13 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di } private fun resolveClassByClassId(classId: ClassId): ClassDescriptor? { - val fullFqName = classId.asSingleFqName() - if (fullFqName.isSafe()) { - val fromBuiltIns = DescriptorResolverUtils.getKotlinBuiltinClassDescriptor(fullFqName.toSafe()) - if (fromBuiltIns != null) { - return fromBuiltIns - } - } val binaryClass = localClassFinder.findKotlinClass(classId) if (binaryClass != null) { return deserializeBinaryClass(binaryClass) } + val fullFqName = classId.asSingleFqName() assert(fullFqName.isSafe(), "Safe fq name expected here, got $fullFqName instead") - return MissingDependencyErrorClassDescriptor(fullFqName.toSafe()) + return MissingDependencyErrorClassDescriptor(ErrorUtils.getErrorModule(), fullFqName.toSafe()) } private fun deserializeBinaryClass(kotlinClass: KotlinJvmBinaryClass): ClassDescriptor { diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/missingDependencies.kt b/idea/src/org/jetbrains/jet/plugin/libraries/missingDependencies.kt new file mode 100644 index 00000000000..935c30fc5bd --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/libraries/missingDependencies.kt @@ -0,0 +1,105 @@ +/* + * Copyright 2010-2014 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.plugin.libraries + +import org.jetbrains.jet.lang.resolve.name.FqName +import org.jetbrains.jet.lang.descriptors.ModuleDescriptor +import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptorImpl +import org.jetbrains.jet.lang.resolve.scopes.JetScope +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor +import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl +import org.jetbrains.jet.utils.Printer +import org.jetbrains.jet.lang.resolve.name.Name +import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor +import org.jetbrains.jet.lang.descriptors.PackageFragmentProvider +import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor +import org.jetbrains.jet.lang.types.error.MissingDependencyErrorClass +import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorImpl +import org.jetbrains.jet.lang.types.ErrorUtils.getErrorModule +import org.jetbrains.jet.lang.descriptors.Modality +import java.util.Collections +import org.jetbrains.jet.lang.types.JetType +import org.jetbrains.jet.lang.types.TypeSubstitutor +import org.jetbrains.jet.lang.descriptors.ClassDescriptor +import org.jetbrains.jet.lang.types.TypeProjection +import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl +import org.jetbrains.jet.lang.descriptors.annotations.Annotations +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor +import org.jetbrains.jet.lang.descriptors.Visibilities +import org.jetbrains.jet.lang.types.ErrorUtils.createErrorType +import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor + +private class PackageFragmentWithMissingDependencies(override val fqName: FqName, moduleDescriptor: ModuleDescriptor) : + PackageFragmentDescriptorImpl(moduleDescriptor, fqName) { + override fun getMemberScope(): JetScope { + return ScopeWithMissingDependencies(fqName, this) + } +} + +private class ScopeWithMissingDependencies(val fqName: FqName, val containing: DeclarationDescriptor) : JetScopeImpl() { + override fun getContainingDeclaration(): DeclarationDescriptor { + return containing + } + + override fun printScopeStructure(p: Printer) { + p.println("Special scope for decompiler, containing class with any name") + } + + override fun getClassifier(name: Name): ClassifierDescriptor? { + return MissingDependencyErrorClassDescriptor(getContainingDeclaration(), fqName.child(name)) + } +} + +private class PackageFragmentProviderForMissingDependencies(val moduleDescriptor: ModuleDescriptor) : PackageFragmentProvider { + override fun getPackageFragments(fqName: FqName): List { + return listOf(PackageFragmentWithMissingDependencies(fqName, moduleDescriptor)) + } + override fun getSubPackagesOf(fqName: FqName): Collection { + throw UnsupportedOperationException("This method is not supposed to be called.") + } +} + +private class MissingDependencyErrorClassDescriptor(containing: DeclarationDescriptor, override val fullFqName: FqName) +: MissingDependencyErrorClass, ClassDescriptorImpl(containing, fullFqName.shortName(), Modality.OPEN, Collections.emptyList()) { + + private val scope = ScopeWithMissingDependencies(fullFqName, this) + + override fun substitute(substitutor: TypeSubstitutor): ClassDescriptor { + return this + } + + override fun getClassObjectDescriptor(): ClassDescriptor? { + //NOTE: only used in types and rendered fq name should be the same as of containing class + return MissingDependencyErrorClassDescriptor(this, fullFqName) + } + + override fun getScopeForMemberLookup(): JetScope { + return scope + } + + override fun getMemberScope(typeArguments: List): JetScope { + return scope + } + + { + val emptyConstructor = ConstructorDescriptorImpl.create(this, Annotations.EMPTY, true) + emptyConstructor.initialize(Collections.emptyList(), Collections.emptyList(), Visibilities.INTERNAL, false) + emptyConstructor.setReturnType(createErrorType("")) + initialize(JetScope.EMPTY, Collections.singleton(emptyConstructor), emptyConstructor) + } +} diff --git a/idea/testData/libraries/decompiledText/DependencyOnNestedClasses.expected.kt b/idea/testData/libraries/decompiledText/DependencyOnNestedClasses.expected.kt new file mode 100644 index 00000000000..7f3bafe8ca9 --- /dev/null +++ b/idea/testData/libraries/decompiledText/DependencyOnNestedClasses.expected.kt @@ -0,0 +1,8 @@ +// IntelliJ API Decompiler stub source generated from a class file +// Implementation of methods is not available + +package test + +public final class DependencyOnNestedClasses() : dependency.D.Nested { + internal final fun f(nc: dependency.D.NestedInClassObject, i: dependency.D.Inner, ii: dependency.D.Inner.Inner, nn: dependency.D.Nested.Nested): dependency.D.Nested { /* compiled code */ } +} \ No newline at end of file diff --git a/idea/testData/libraries/decompiledText/DependencyOnNestedClasses/Dependency.kt b/idea/testData/libraries/decompiledText/DependencyOnNestedClasses/Dependency.kt new file mode 100644 index 00000000000..2502e0c6823 --- /dev/null +++ b/idea/testData/libraries/decompiledText/DependencyOnNestedClasses/Dependency.kt @@ -0,0 +1,14 @@ +package dependency + +class D { + inner class Inner { + inner class Inner + } + open class Nested { + class Nested + } + + class object { + class NestedInClassObject + } +} diff --git a/idea/testData/libraries/decompiledText/DependencyOnNestedClasses/DependencyOnNestedClasses.kt b/idea/testData/libraries/decompiledText/DependencyOnNestedClasses/DependencyOnNestedClasses.kt new file mode 100644 index 00000000000..c55e10b1cce --- /dev/null +++ b/idea/testData/libraries/decompiledText/DependencyOnNestedClasses/DependencyOnNestedClasses.kt @@ -0,0 +1,9 @@ +package test + +import dependency.* + +public class DependencyOnNestedClasses : D.Nested() { + fun f(nc: D.NestedInClassObject, i: D.Inner, ii: D.Inner.Inner, nn: D.Nested.Nested): D.Nested { + return D.Nested() + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextTestGenerated.java index 4ecc67473b2..9efb8db678d 100644 --- a/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextTestGenerated.java @@ -47,6 +47,11 @@ public class DecompiledTextTestGenerated extends AbstractDecompiledTextTest { doTest("idea/testData/libraries/decompiledText/ClassWithClassObject/"); } + @TestMetadata("DependencyOnNestedClasses") + public void testDependencyOnNestedClasses() throws Exception { + doTest("idea/testData/libraries/decompiledText/DependencyOnNestedClasses/"); + } + @TestMetadata("Enum") public void testEnum() throws Exception { doTest("idea/testData/libraries/decompiledText/Enum/");