fix KT-10064 Regression: Error with multiple main functions within a single package
#KT-10064 Fixed
This commit is contained in:
@@ -80,13 +80,19 @@ public class MainFunctionDetector {
|
|||||||
return false;
|
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")) {
|
if (!getJVMFunctionName(functionDescriptor).equals("main")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
|
||||||
if (parameters.size() != 1) return false;
|
if (parameters.size() != 1 || !functionDescriptor.getTypeParameters().isEmpty()) return false;
|
||||||
|
|
||||||
ValueParameterDescriptor parameter = parameters.get(0);
|
ValueParameterDescriptor parameter = parameters.get(0);
|
||||||
KotlinType parameterType = parameter.getType();
|
KotlinType parameterType = parameter.getType();
|
||||||
|
|||||||
@@ -17,16 +17,17 @@
|
|||||||
package org.jetbrains.kotlin.resolve
|
package org.jetbrains.kotlin.resolve
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
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.DECLARATION
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED
|
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.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
|
||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
import java.util.ArrayList
|
import java.util.*
|
||||||
|
|
||||||
public object DescriptorToSourceUtils {
|
public object DescriptorToSourceUtils {
|
||||||
private fun collectEffectiveReferencedDescriptors(result: MutableList<DeclarationDescriptor>, descriptor: DeclarationDescriptor) {
|
private fun collectEffectiveReferencedDescriptors(result: MutableList<DeclarationDescriptor>, descriptor: DeclarationDescriptor) {
|
||||||
@@ -80,16 +81,6 @@ public object DescriptorToSourceUtils {
|
|||||||
return declaration.getContainingFile() as? KtFile
|
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? {
|
private fun findTopLevelParent(declarationDescriptor: DeclarationDescriptor): DeclarationDescriptor? {
|
||||||
var descriptor: DeclarationDescriptor? = declarationDescriptor
|
var descriptor: DeclarationDescriptor? = declarationDescriptor
|
||||||
if (declarationDescriptor is PropertyAccessorDescriptor) {
|
if (declarationDescriptor is PropertyAccessorDescriptor) {
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
|
|||||||
public class OverloadResolver {
|
public class OverloadResolver {
|
||||||
@NotNull private final BindingTrace trace;
|
@NotNull private final BindingTrace trace;
|
||||||
@NotNull private final OverloadFilter overloadFilter;
|
@NotNull private final OverloadFilter overloadFilter;
|
||||||
@NotNull private final MainFunctionDetector mainFunctionDetector;
|
|
||||||
|
|
||||||
public OverloadResolver(
|
public OverloadResolver(
|
||||||
@NotNull BindingTrace trace,
|
@NotNull BindingTrace trace,
|
||||||
@@ -44,8 +43,6 @@ public class OverloadResolver {
|
|||||||
) {
|
) {
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
this.overloadFilter = overloadFilter;
|
this.overloadFilter = overloadFilter;
|
||||||
|
|
||||||
mainFunctionDetector = new MainFunctionDetector(trace.getBindingContext());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void process(@NotNull BodiesResolveContext c) {
|
public void process(@NotNull BodiesResolveContext c) {
|
||||||
@@ -160,7 +157,7 @@ public class OverloadResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Set<Pair<KtDeclaration, CallableMemberDescriptor>> findRedeclarations(@NotNull Collection<? extends CallableMemberDescriptor> members) {
|
private static Set<Pair<KtDeclaration, CallableMemberDescriptor>> findRedeclarations(@NotNull Collection<? extends CallableMemberDescriptor> members) {
|
||||||
Set<Pair<KtDeclaration, CallableMemberDescriptor>> redeclarations = Sets.newLinkedHashSet();
|
Set<Pair<KtDeclaration, CallableMemberDescriptor>> redeclarations = Sets.newLinkedHashSet();
|
||||||
for (CallableMemberDescriptor member : members) {
|
for (CallableMemberDescriptor member : members) {
|
||||||
for (CallableMemberDescriptor member2 : members) {
|
for (CallableMemberDescriptor member2 : members) {
|
||||||
@@ -195,13 +192,15 @@ public class OverloadResolver {
|
|||||||
member.getContainingDeclaration().getContainingDeclaration().equals(member2.getContainingDeclaration().getContainingDeclaration());
|
member.getContainingDeclaration().getContainingDeclaration().equals(member2.getContainingDeclaration().getContainingDeclaration());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTopLevelMainInDifferentFiles(@NotNull CallableMemberDescriptor member, @NotNull CallableMemberDescriptor member2) {
|
private static boolean isTopLevelMainInDifferentFiles(@NotNull CallableMemberDescriptor member, @NotNull CallableMemberDescriptor member2) {
|
||||||
if (!DescriptorToSourceUtils.isTopLevelMainFunction(member, mainFunctionDetector) ||
|
if (!MainFunctionDetector.isMain(member) ||
|
||||||
!DescriptorToSourceUtils.isTopLevelMainFunction(member2, mainFunctionDetector)) {
|
!MainFunctionDetector.isMain(member2)) {
|
||||||
return false;
|
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,
|
private void reportRedeclarations(@NotNull String functionContainer,
|
||||||
|
|||||||
+6
@@ -395,6 +395,12 @@ public class ExperimentalIncrementalJpsTestGenerated extends AbstractExperimenta
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("mainRedeclaration")
|
||||||
|
public void testMainRedeclaration() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("moveClass")
|
@TestMetadata("moveClass")
|
||||||
public void testMoveClass() throws Exception {
|
public void testMoveClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/moveClass/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/moveClass/");
|
||||||
|
|||||||
@@ -395,6 +395,12 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("mainRedeclaration")
|
||||||
|
public void testMainRedeclaration() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/mainRedeclaration/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("moveClass")
|
@TestMetadata("moveClass")
|
||||||
public void testMoveClass() throws Exception {
|
public void testMoveClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/moveClass/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/moveClass/");
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
fun main(args: Array<String>) = println("a")
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
fun main(args: Array<String>) = println("A")
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
fun main(args: Array<String>) = println("b")
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user