diff --git a/compiler/frontend/src/org/jetbrains/kotlin/idea/MainFunctionDetector.java b/compiler/frontend/src/org/jetbrains/kotlin/idea/MainFunctionDetector.java index 335f563f1bc..13c7200d5ac 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/idea/MainFunctionDetector.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/idea/MainFunctionDetector.java @@ -80,13 +80,19 @@ public class MainFunctionDetector { return false; } - FunctionDescriptor functionDescriptor = getFunctionDescriptor.fun(function); + return isMain(getFunctionDescriptor.fun(function)); + } + + public static boolean isMain(@NotNull DeclarationDescriptor descriptor) { + if (!(descriptor instanceof FunctionDescriptor)) return false; + + FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor; if (!getJVMFunctionName(functionDescriptor).equals("main")) { return false; } List parameters = functionDescriptor.getValueParameters(); - if (parameters.size() != 1) return false; + if (parameters.size() != 1 || !functionDescriptor.getTypeParameters().isEmpty()) return false; ValueParameterDescriptor parameter = parameters.get(0); KotlinType parameterType = parameter.getType(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorToSourceUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorToSourceUtils.kt index e95fbbdae68..eca85e16ae6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorToSourceUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorToSourceUtils.kt @@ -17,16 +17,17 @@ package org.jetbrains.kotlin.resolve import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor 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.KtAnnotationEntry import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.resolve.source.getPsi -import java.util.ArrayList +import java.util.* public object DescriptorToSourceUtils { private fun collectEffectiveReferencedDescriptors(result: MutableList, descriptor: DeclarationDescriptor) { @@ -80,16 +81,6 @@ public object DescriptorToSourceUtils { return declaration.getContainingFile() as? KtFile } - @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 KtNamedFunction && 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 08cf687121c..b86e7fd17de 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.java @@ -36,7 +36,6 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName; public class OverloadResolver { @NotNull private final BindingTrace trace; @NotNull private final OverloadFilter overloadFilter; - @NotNull private final MainFunctionDetector mainFunctionDetector; public OverloadResolver( @NotNull BindingTrace trace, @@ -44,8 +43,6 @@ public class OverloadResolver { ) { this.trace = trace; this.overloadFilter = overloadFilter; - - mainFunctionDetector = new MainFunctionDetector(trace.getBindingContext()); } public void process(@NotNull BodiesResolveContext c) { @@ -160,7 +157,7 @@ public class OverloadResolver { } @NotNull - private Set> findRedeclarations(@NotNull Collection members) { + private static Set> findRedeclarations(@NotNull Collection members) { Set> redeclarations = Sets.newLinkedHashSet(); for (CallableMemberDescriptor member : members) { for (CallableMemberDescriptor member2 : members) { @@ -195,13 +192,15 @@ public class OverloadResolver { member.getContainingDeclaration().getContainingDeclaration().equals(member2.getContainingDeclaration().getContainingDeclaration()); } - private boolean isTopLevelMainInDifferentFiles(@NotNull CallableMemberDescriptor member, @NotNull CallableMemberDescriptor member2) { - if (!DescriptorToSourceUtils.isTopLevelMainFunction(member, mainFunctionDetector) || - !DescriptorToSourceUtils.isTopLevelMainFunction(member2, mainFunctionDetector)) { + private static boolean isTopLevelMainInDifferentFiles(@NotNull CallableMemberDescriptor member, @NotNull CallableMemberDescriptor member2) { + if (!MainFunctionDetector.isMain(member) || + !MainFunctionDetector.isMain(member2)) { return false; } - return DescriptorToSourceUtils.getContainingFile(member) != DescriptorToSourceUtils.getContainingFile(member2); + KtFile file = DescriptorToSourceUtils.getContainingFile(member); + KtFile file2 = DescriptorToSourceUtils.getContainingFile(member2); + return file == null || file2 == null || file != file2; } private void reportRedeclarations(@NotNull String functionContainer, diff --git a/jps-plugin/test/org/jetbrains/kotlin/jps/build/ExperimentalIncrementalJpsTestGenerated.java b/jps-plugin/test/org/jetbrains/kotlin/jps/build/ExperimentalIncrementalJpsTestGenerated.java index 32bd506fd4d..828ea743a87 100644 --- a/jps-plugin/test/org/jetbrains/kotlin/jps/build/ExperimentalIncrementalJpsTestGenerated.java +++ b/jps-plugin/test/org/jetbrains/kotlin/jps/build/ExperimentalIncrementalJpsTestGenerated.java @@ -395,6 +395,12 @@ public class ExperimentalIncrementalJpsTestGenerated extends AbstractExperimenta doTest(fileName); } + @TestMetadata("mainRedeclaration") + public void testMainRedeclaration() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/"); + doTest(fileName); + } + @TestMetadata("moveClass") public void testMoveClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/moveClass/"); diff --git a/jps-plugin/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java b/jps-plugin/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java index 63fd8b14dab..c9c192a8b94 100644 --- a/jps-plugin/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java +++ b/jps-plugin/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java @@ -395,6 +395,12 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest { doTest(fileName); } + @TestMetadata("mainRedeclaration") + public void testMainRedeclaration() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/"); + doTest(fileName); + } + @TestMetadata("moveClass") public void testMoveClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/moveClass/"); diff --git a/jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/a.kt b/jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/a.kt new file mode 100644 index 00000000000..8eb2fb2be08 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/a.kt @@ -0,0 +1,3 @@ +package foo + +fun main(args: Array) = println("a") \ No newline at end of file diff --git a/jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/a.kt.new b/jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/a.kt.new new file mode 100644 index 00000000000..4feab3ef68d --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/a.kt.new @@ -0,0 +1,3 @@ +package foo + +fun main(args: Array) = println("A") \ No newline at end of file diff --git a/jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/b.kt b/jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/b.kt new file mode 100644 index 00000000000..7d4e748601c --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/b.kt @@ -0,0 +1,3 @@ +package foo + +fun main(args: Array) = println("b") \ No newline at end of file diff --git a/jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/build.log b/jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/build.log new file mode 100644 index 00000000000..9ecb2e772f7 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/build.log @@ -0,0 +1,7 @@ +Cleaning output files: +out/production/module/META-INF/module.kotlin_module +out/production/module/foo/AKt.class +End of files +Compiling files: +src/a.kt +End of files \ No newline at end of file