use MainFunctionDetector in order to check for main function

This commit is contained in:
Michael Nedzelsky
2015-10-15 18:31:05 +03:00
parent e2c7ba7f40
commit 114d19e6d9
4 changed files with 22 additions and 27 deletions
@@ -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
@@ -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) {
@@ -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<Pair<JetDeclaration, CallableMemberDescriptor>> redeclarations) {
for (Pair<JetDeclaration, CallableMemberDescriptor> 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) {
@@ -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<ValueParameterDescriptor> 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<FqName> result) {
FqName fqName = packageView.getFqName();
if (!fqName.isRoot()) {