[FIR] Fix the TODO in FirConflictsHelpers
According to https://github.com/Kotlin/KEEP/blob/master/proposals/enhancing-main-convention.md#rules-and-semantics, only main function without args may avoid `CONFLICTING_OVERLOADS`, but since the jps/jps-plugin/testData/incremental/withJava/other/mainRedeclaration test dates back to 2015, this is not the current behavior.
This commit is contained in:
committed by
Space Team
parent
3014c7b353
commit
8541143d6f
+41
-7
@@ -6,15 +6,22 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers
|
||||
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirMethodOfAnyImplementedInInterfaceChecker.appendRepresentation
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirMethodOfAnyImplementedInInterfaceChecker.appendRepresentationAfterCallableId
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirMethodOfAnyImplementedInInterfaceChecker.appendRepresentationBeforeCallableId
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirNameConflictsTracker
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl.Companion.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl.Companion.DEFAULT_STATUS_FOR_SUSPEND_MAIN_FUNCTION
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.modifiersRepresentation
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
@@ -22,9 +29,9 @@ import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.util.ListMultimap
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.SmartSet
|
||||
|
||||
@@ -32,6 +39,34 @@ internal class FirDefaultDeclarationPresenter : FirDeclarationPresenter
|
||||
|
||||
private val NO_NAME_PROVIDED = Name.special("<no name provided>")
|
||||
|
||||
private val MAIN_FUNCTION_SHAPES = setOf(
|
||||
"<>[]():kotlin/Unit",
|
||||
"<>[](kotlin/Array<kotlin/String,>,):kotlin/Unit",
|
||||
"<>[](vararg kotlin/String,):kotlin/Unit",
|
||||
)
|
||||
|
||||
val DEFAULT_STATUS_FOR_NORMAL_MAIN_FUNCTION = DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS
|
||||
|
||||
private val FirSimpleFunction.hasMainFunctionStatus
|
||||
get() = when (status.modifiersRepresentation) {
|
||||
DEFAULT_STATUS_FOR_NORMAL_MAIN_FUNCTION.modifiersRepresentation,
|
||||
DEFAULT_STATUS_FOR_SUSPEND_MAIN_FUNCTION.modifiersRepresentation -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
private val CallableId.isTopLevel get() = className == null
|
||||
|
||||
private val FirSimpleFunction.representsMainFunctionAllowingConflictingOverloads
|
||||
get(): Boolean = when {
|
||||
name != StandardNames.MAIN || !symbol.callableId.isTopLevel || !hasMainFunctionStatus -> false
|
||||
else -> buildString {
|
||||
appendRepresentationBeforeCallableId(this@representsMainFunctionAllowingConflictingOverloads)
|
||||
appendRepresentationAfterCallableId(this@representsMainFunctionAllowingConflictingOverloads)
|
||||
append(':')
|
||||
appendRepresentation(returnTypeRef)
|
||||
} in MAIN_FUNCTION_SHAPES
|
||||
}
|
||||
|
||||
// - see testEnumValuesValueOf.
|
||||
// it generates a static function that has
|
||||
// the same signature as the function defined
|
||||
@@ -211,12 +246,11 @@ class FirDeclarationInspector {
|
||||
|
||||
private fun areCompatibleMainFunctions(
|
||||
declaration1: FirDeclaration, file1: FirFile, declaration2: FirDeclaration, file2: FirFile?
|
||||
): Boolean {
|
||||
// TODO: proper main function detector
|
||||
if (declaration1 !is FirSimpleFunction || declaration2 !is FirSimpleFunction) return false
|
||||
if (declaration1.name.asString() != "main" || declaration2.name.asString() != "main") return false
|
||||
return file1 != file2
|
||||
}
|
||||
) = file1 != file2
|
||||
&& declaration1 is FirSimpleFunction
|
||||
&& declaration2 is FirSimpleFunction
|
||||
&& declaration1.representsMainFunctionAllowingConflictingOverloads
|
||||
&& declaration2.representsMainFunctionAllowingConflictingOverloads
|
||||
|
||||
private fun collectExternalConflict(
|
||||
declaration: FirDeclaration,
|
||||
|
||||
+10
-2
@@ -158,7 +158,7 @@ interface FirDeclarationPresenter {
|
||||
}
|
||||
}
|
||||
|
||||
fun represent(it: FirSimpleFunction) = buildString {
|
||||
fun StringBuilder.appendRepresentationBeforeCallableId(it: FirSimpleFunction) {
|
||||
it.contextReceivers.forEach {
|
||||
appendRepresentation(it)
|
||||
append(',')
|
||||
@@ -175,7 +175,9 @@ interface FirDeclarationPresenter {
|
||||
}
|
||||
append(']')
|
||||
appendOperatorTag(it)
|
||||
appendRepresentation(it.symbol.callableId)
|
||||
}
|
||||
|
||||
fun StringBuilder.appendRepresentationAfterCallableId(it: FirSimpleFunction) {
|
||||
append('(')
|
||||
it.valueParameters.forEach {
|
||||
appendRepresentation(it)
|
||||
@@ -184,6 +186,12 @@ interface FirDeclarationPresenter {
|
||||
append(')')
|
||||
}
|
||||
|
||||
fun represent(it: FirSimpleFunction) = buildString {
|
||||
appendRepresentationBeforeCallableId(it)
|
||||
appendRepresentation(it.symbol.callableId)
|
||||
appendRepresentationAfterCallableId(it)
|
||||
}
|
||||
|
||||
fun represent(it: FirTypeAlias) = buildString {
|
||||
append('[')
|
||||
append(']')
|
||||
|
||||
+11
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
||||
import org.jetbrains.kotlin.fir.FirPureAbstractElement
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl.Modifier.*
|
||||
@@ -22,6 +23,9 @@ open class FirDeclarationStatusImpl(
|
||||
override val source: KtSourceElement? get() = null
|
||||
protected var flags: Int = HAS_STABLE_PARAMETER_NAMES.mask
|
||||
|
||||
@FirImplementationDetail
|
||||
internal val rawFlags get() = flags
|
||||
|
||||
operator fun get(modifier: Modifier): Boolean = (flags and modifier.mask) != 0
|
||||
|
||||
operator fun set(modifier: Modifier, value: Boolean) {
|
||||
@@ -182,3 +186,10 @@ open class FirDeclarationStatusImpl(
|
||||
return FirResolvedDeclarationStatusImpl(visibility, modality, effectiveVisibility, flags)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(FirImplementationDetail::class)
|
||||
val FirDeclarationStatus.modifiersRepresentation: Any
|
||||
get() = when (this) {
|
||||
is FirDeclarationStatusImpl -> rawFlags
|
||||
else -> error("Generating modifier representations for ${this::class.simpleName} is not supported")
|
||||
}
|
||||
|
||||
+5
@@ -28,6 +28,11 @@ class FirResolvedDeclarationStatusImpl(
|
||||
Modality.FINAL,
|
||||
EffectiveVisibility.Public
|
||||
).apply { isSuspend = true }
|
||||
val DEFAULT_STATUS_FOR_SUSPEND_MAIN_FUNCTION = FirResolvedDeclarationStatusImpl(
|
||||
Visibilities.Public,
|
||||
Modality.FINAL,
|
||||
EffectiveVisibility.Public
|
||||
).apply { isSuspend = true }
|
||||
}
|
||||
|
||||
internal constructor(
|
||||
|
||||
@@ -36,6 +36,8 @@ object StandardNames {
|
||||
|
||||
@JvmField val NAME = Name.identifier("name")
|
||||
|
||||
@JvmField val MAIN = Name.identifier("main")
|
||||
|
||||
@JvmField val NEXT_CHAR = Name.identifier("nextChar")
|
||||
|
||||
@JvmField val IMPLICIT_LAMBDA_PARAMETER_NAME = Name.identifier("it")
|
||||
|
||||
Reference in New Issue
Block a user