diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt index d5e7dbe9be8..7ad9f825d1e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt @@ -27,12 +27,12 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERR import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider import org.jetbrains.kotlin.fileClasses.isInsideJvmMultifileClassFile +import org.jetbrains.kotlin.idea.MainFunctionDetector import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -import org.jetbrains.kotlin.psi.JetDeclaration +import org.jetbrains.kotlin.psi.JetNamedFunction import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.jvm.diagnostics.* import org.jetbrains.kotlin.utils.addIfNotNull import java.util.* @@ -54,6 +54,8 @@ class BuilderFactoryForDuplicateSignatureDiagnostics( // Avoid errors when some classes are not loaded for some reason private val typeMapper = JetTypeMapper(bindingContext, ClassBuilderMode.LIGHT_CLASSES, fileClassesProvider, incrementalCache, moduleName) + private val mainFunctionDetector = MainFunctionDetector(bindingContext) + override fun handleClashingSignatures(data: ConflictingJvmDeclarationsData) { val noOwnImplementations = data.signatureOrigins.all { it.originKind in EXTERNAL_SOURCES_KINDS } @@ -66,11 +68,7 @@ class BuilderFactoryForDuplicateSignatureDiagnostics( var element = origin.element // TODO Remove this code after dropping package facades - val descriptor = origin.descriptor - if (descriptor != null && element is JetDeclaration && DescriptorUtils.isTopLevelMainFunction(descriptor) && - !element.isInsideJvmMultifileClassFile()) { - return - } + if (element is JetNamedFunction && mainFunctionDetector.isMain(element) && !element.isInsideJvmMultifileClassFile()) return if (element == null || origin.originKind in EXTERNAL_SOURCES_KINDS) { element = data.classOrigin.element diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorToSourceUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorToSourceUtils.kt index 83497ae982e..8ca94a63422 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorToSourceUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorToSourceUtils.kt @@ -17,15 +17,14 @@ package org.jetbrains.kotlin.resolve import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource -import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.kotlin.idea.MainFunctionDetector import org.jetbrains.kotlin.psi.JetAnnotationEntry import org.jetbrains.kotlin.psi.JetFile +import org.jetbrains.kotlin.psi.JetNamedFunction import org.jetbrains.kotlin.resolve.source.getPsi import java.util.ArrayList @@ -81,6 +80,16 @@ public object DescriptorToSourceUtils { return declaration.getContainingFile() as? JetFile } + @JvmStatic + public fun isTopLevelMainFunction(declarationDescriptor: DeclarationDescriptor, mainFunctionDetector: MainFunctionDetector): Boolean { + if (declarationDescriptor !is FunctionDescriptor || + !DescriptorUtils.isTopLevelDeclaration(declarationDescriptor) || + declarationDescriptor.name.asString() != "main") return false + + val element = descriptorToDeclaration(declarationDescriptor) + return element is JetNamedFunction && mainFunctionDetector.isMain(element) + } + private fun findTopLevelParent(declarationDescriptor: DeclarationDescriptor): DeclarationDescriptor? { var descriptor: DeclarationDescriptor? = declarationDescriptor if (declarationDescriptor is PropertyAccessorDescriptor) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.java index 7f91bc1c5cf..7cf79102c32 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.java @@ -22,6 +22,7 @@ import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.diagnostics.Errors; +import org.jetbrains.kotlin.idea.MainFunctionDetector; import org.jetbrains.kotlin.name.FqNameUnsafe; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.JetClassOrObject; @@ -37,9 +38,11 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName; public class OverloadResolver { @NotNull private final BindingTrace trace; + @NotNull private final MainFunctionDetector mainFunctionDetector; public OverloadResolver(@NotNull BindingTrace trace) { this.trace = trace; + mainFunctionDetector = new MainFunctionDetector(trace.getBindingContext()); } public void process(@NotNull BodiesResolveContext c) { @@ -195,7 +198,7 @@ public class OverloadResolver { @NotNull Set> redeclarations) { for (Pair redeclaration : redeclarations) { CallableMemberDescriptor memberDescriptor = redeclaration.getSecond(); - if (DescriptorUtils.isTopLevelMainFunction(memberDescriptor)) break; + if (DescriptorToSourceUtils.isTopLevelMainFunction(memberDescriptor, mainFunctionDetector)) return; JetDeclaration jetDeclaration = redeclaration.getFirst(); if (memberDescriptor instanceof PropertyDescriptor) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java index 7eb2ca79f85..44bf4db53cb 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java @@ -630,21 +630,6 @@ public class DescriptorUtils { return SourceFile.NO_SOURCE_FILE; } - public static boolean isTopLevelMainFunction(@NotNull DeclarationDescriptor descriptor) { - if (!(descriptor instanceof FunctionDescriptor) || - !isTopLevelDeclaration(descriptor) || - !"main".equals(descriptor.getName().asString())) return false; - - FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor; - List valueParameterDescriptors = functionDescriptor.getValueParameters(); - if (valueParameterDescriptors.size() != 1) return false; - - JetType type = valueParameterDescriptors.get(0).getType(); - - return KotlinBuiltIns.isArray(type) && type.getArguments().size() == 1 && KotlinBuiltIns.isString(type.getArguments().get(0).getType()); - } - - private static void getSubPackagesFqNames(PackageViewDescriptor packageView, Set result) { FqName fqName = packageView.getFqName(); if (!fqName.isRoot()) {