diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index e9e43f81662..b8b5b163136 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -370,7 +370,6 @@ public class KotlinCoreEnvironment private constructor( with (projectEnvironment.getProject()) { registerService(javaClass(), JetScriptDefinitionProvider()) registerService(javaClass(), KotlinJavaPsiFacade(this)) - registerService(javaClass(), KotlinLightClassForFacade.PackageFacadeStubCache(this)) registerService(javaClass(), KotlinLightClassForFacade.FacadeStubCache(this)) } } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/fileClasses/NoResolveFileClassesProvider.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/fileClasses/NoResolveFileClassesProvider.kt index 6dccfa502ed..04fd00e197e 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/fileClasses/NoResolveFileClassesProvider.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/fileClasses/NoResolveFileClassesProvider.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.fileClasses -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtFile diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinJavaFileStubProvider.java b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinJavaFileStubProvider.java index aff5936366b..57d2c6925e5 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinJavaFileStubProvider.java +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinJavaFileStubProvider.java @@ -70,88 +70,6 @@ import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToD public class KotlinJavaFileStubProvider implements CachedValueProvider { - @NotNull - public static KotlinJavaFileStubProvider createForPackageClass( - @NotNull final Project project, - @NotNull final FqName packageFqName, - @NotNull final GlobalSearchScope searchScope - ) { - return new KotlinJavaFileStubProvider( - project, - false, - new StubGenerationStrategy() { - @NotNull - @Override - public LightClassConstructionContext getContext(@NotNull Collection files) { - return LightClassGenerationSupport.getInstance(project).getContextForPackage(files); - } - - @NotNull - @Override - public Collection getFiles() { - // Don't memoize this, it can be called again after an out-of-code-block modification occurs, - // and the set of files changes - return LightClassGenerationSupport.getInstance(project).findFilesForPackage(packageFqName, searchScope); - } - - @NotNull - @Override - public KotlinFacadeLightClassData createLightClassData( - PsiJavaFileStub javaFileStub, - BindingContext bindingContext, - Diagnostics extraDiagnostics - ) { - return new KotlinFacadeLightClassData(javaFileStub, extraDiagnostics); - } - - @NotNull - @Override - public FqName getPackageFqName() { - return packageFqName; - } - - @Override - public GenerationState.GenerateClassFilter getGenerateClassFilter() { - return new GenerationState.GenerateClassFilter() { - - @Override - public boolean shouldGeneratePackagePart(KtFile jetFile) { - return true; - } - - @Override - public boolean shouldAnnotateClass(KtClassOrObject classOrObject) { - return shouldGenerateClass(classOrObject); - } - - @Override - public boolean shouldGenerateClass(KtClassOrObject classOrObject) { - // Top-level classes and such should not be generated for performance reasons. - // Local classes in top-level functions must still be generated - return KtPsiUtil.isLocal(classOrObject); - } - - @Override - public boolean shouldGenerateScript(KtScript script) { - // Scripts yield top-level classes, and should not be generated - return false; - } - }; - } - - @Override - public void generate(@NotNull GenerationState state, @NotNull Collection files) { - KotlinCodegenFacade.doGenerateFiles(files, state, CompilationErrorHandler.THROW_EXCEPTION); - } - - @Override - public String toString() { - return StubGenerationStrategy.class.getName() + " for package class"; - } - } - ); - } - @NotNull public static CachedValueProvider createForFacadeClass( @NotNull final Project project, @@ -219,7 +137,7 @@ public class KotlinJavaFileStubProvider files) { if (!files.isEmpty()) { KtFile representativeFile = files.iterator().next(); - JvmFileClassInfo fileClassInfo = NoResolveFileClassesProvider.INSTANCE$.getFileClassInfo(representativeFile); + JvmFileClassInfo fileClassInfo = NoResolveFileClassesProvider.INSTANCE.getFileClassInfo(representativeFile); if (!fileClassInfo.getWithJvmMultifileClass()) { PackageCodegen codegen = state.getFactory().forPackage(representativeFile.getPackageFqName(), files); codegen.generate(CompilationErrorHandler.THROW_EXCEPTION); diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightClassForFacade.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightClassForFacade.kt index 3ed464a4a8c..9b4590f825a 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightClassForFacade.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightClassForFacade.kt @@ -46,33 +46,6 @@ public class KotlinLightClassForFacade private constructor( private data class StubCacheKey(val fqName: FqName, val searchScope: GlobalSearchScope) - public class PackageFacadeStubCache(private val project: Project) { - private inner class PackageFacadeCacheData { - val cache = object : SLRUCache>(20, 30) { - override fun createValue(key: StubCacheKey): CachedValue { - val stubProvider = KotlinJavaFileStubProvider.createForPackageClass(project, key.fqName, key.searchScope) - return CachedValuesManager.getManager(project).createCachedValue(stubProvider, /*trackValue = */false) - } - } - } - - private val cachedValue: CachedValue = CachedValuesManager.getManager(project).createCachedValue( - { CachedValueProvider.Result.create(PackageFacadeCacheData(), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT) }, - /*trackValue = */ false) - - public fun get(qualifiedName: FqName, searchScope: GlobalSearchScope): CachedValue { - synchronized (cachedValue) { - return cachedValue.getValue().cache.get(StubCacheKey(qualifiedName, searchScope)) - } - } - - companion object { - public fun getInstance(project: Project): PackageFacadeStubCache { - return ServiceManager.getService(project, javaClass()) - } - } - } - public class FacadeStubCache(private val project: Project) { private inner class FacadeCacheData { val cache = object : SLRUCache>(20, 30) { diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/StubClassBuilder.java b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/StubClassBuilder.java index f8db645c18a..fd5bfeefc7e 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/StubClassBuilder.java +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/StubClassBuilder.java @@ -25,6 +25,9 @@ import com.intellij.util.containers.Stack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.codegen.AbstractClassBuilder; +import org.jetbrains.kotlin.load.kotlin.PackageClassUtils; +import org.jetbrains.kotlin.name.FqName; +import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin; import org.jetbrains.org.objectweb.asm.ClassVisitor; import org.jetbrains.org.objectweb.asm.FieldVisitor; @@ -47,6 +50,7 @@ public class StubClassBuilder extends AbstractClassBuilder { private final StubElement parent; private StubBuildingVisitor v; private final Stack parentStack; + private boolean isPackageClass = false; public StubClassBuilder(@NotNull Stack parentStack) { this.parentStack = parentStack; @@ -75,7 +79,18 @@ public class StubClassBuilder extends AbstractClassBuilder { super.defineClass(origin, version, access, name, signature, superName, interfaces); - parentStack.push(v.getResult()); + if (origin instanceof KtFile) { + FqName packageName = ((KtFile) origin).getPackageFqName(); + String packageClassName = PackageClassUtils.getPackageClassName(packageName); + + if (name.equals(packageClassName) || name.endsWith("/" + packageClassName)) { + isPackageClass = true; + } + } + + if (!isPackageClass) { + parentStack.push(v.getResult()); + } ((StubBase) v.getResult()).putUserData(ClsWrapperStubPsiFactory.ORIGIN_ELEMENT, origin); } @@ -134,8 +149,10 @@ public class StubClassBuilder extends AbstractClassBuilder { @Override public void done() { - StubElement pop = parentStack.pop(); - assert pop == v.getResult(); + if (!isPackageClass) { + StubElement pop = parentStack.pop(); + assert pop == v.getResult() : "parentStack: got " + pop + ", expected " + v.getResult(); + } super.done(); } } diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/duplicateJvmSignatureUtil.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/duplicateJvmSignatureUtil.kt index 54d350358a0..ed678584ca8 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/duplicateJvmSignatureUtil.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/duplicateJvmSignatureUtil.kt @@ -26,14 +26,16 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.* import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.diagnostics.DiagnosticFactory.* import org.jetbrains.kotlin.diagnostics.DiagnosticFactory +import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm public fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostics, moduleScope: GlobalSearchScope): Diagnostics? { - fun getDiagnosticsForPackage(file: KtFile): Diagnostics? { - val project = file.getProject() - val cache = KotlinLightClassForFacade.PackageFacadeStubCache.getInstance(project) - return cache[file.getPackageFqName(), moduleScope].getValue()?.extraDiagnostics + fun getDiagnosticsForFileFacade(file: KtFile): Diagnostics? { + val project = file.project + val cache = KotlinLightClassForFacade.FacadeStubCache.getInstance(project) + val facadeFqName = NoResolveFileClassesProvider.getFileClassInfo(file).facadeClassFqName + return cache[facadeFqName, moduleScope].getValue()?.extraDiagnostics } fun getDiagnosticsForClass(ktClassOrObject: KtClassOrObject): Diagnostics { @@ -58,7 +60,7 @@ public fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Dia when (parent) { is KtFile -> { - return getDiagnosticsForPackage(parent) + return getDiagnosticsForFileFacade(parent) } is KtClassBody -> { val parentsParent = parent.getParent() diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/PackageClassUtils.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/PackageClassUtils.java index 43ec5bc1a50..9e880aa6931 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/PackageClassUtils.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/PackageClassUtils.java @@ -31,7 +31,7 @@ public final class PackageClassUtils { // ex. -> _DefaultPackage, a -> APackage, a.b -> BPackage @NotNull - private static String getPackageClassName(@NotNull FqName packageFQN) { + public static String getPackageClassName(@NotNull FqName packageFQN) { if (packageFQN.isRoot()) { return DEFAULT_PACKAGE_CLASS_NAME; } diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 4aac93d7b3e..44a517aa6a0 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -246,9 +246,6 @@ - - diff --git a/idea/testData/checker/duplicateJvmSignature/functionAndProperty/topLevelMultifileRuntime.kt b/idea/testData/checker/duplicateJvmSignature/functionAndProperty/topLevelMultifileRuntime.kt new file mode 100644 index 00000000000..346ad72b70a --- /dev/null +++ b/idea/testData/checker/duplicateJvmSignature/functionAndProperty/topLevelMultifileRuntime.kt @@ -0,0 +1,13 @@ +@file:JvmName("TopLevelMultifile") +@file:JvmMultifileClass +package test + +import kotlin.jvm.JvmName +import kotlin.jvm.JvmMultifileClass + +val x = 1 +fun getX() = 1 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/checkers/JetPsiCheckerTestGenerated.java b/idea/tests/org/jetbrains/kotlin/checkers/JetPsiCheckerTestGenerated.java index c054eca6833..88cef5ac94a 100644 --- a/idea/tests/org/jetbrains/kotlin/checkers/JetPsiCheckerTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/checkers/JetPsiCheckerTestGenerated.java @@ -630,6 +630,12 @@ public class JetPsiCheckerTestGenerated extends AbstractJetPsiCheckerTest { doTest(fileName); } + @TestMetadata("topLevelMultifileRuntime.kt") + public void testTopLevelMultifileRuntime() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/checker/duplicateJvmSignature/functionAndProperty/topLevelMultifileRuntime.kt"); + doTest(fileName); + } + @TestMetadata("trait.kt") public void testTrait() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/checker/duplicateJvmSignature/functionAndProperty/trait.kt");