Migration to expect/actual: highlighter markers

This commit is contained in:
Mikhail Glukhikh
2017-09-14 19:15:59 +03:00
parent 2d0ac0011a
commit 74f81f38ba
16 changed files with 105 additions and 105 deletions
@@ -34,7 +34,7 @@ import org.jetbrains.kotlin.psi.KtPsiUtil
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
import org.jetbrains.kotlin.resolve.BindingTraceContext
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.diagnostics.SimpleDiagnostics
val ModuleDescriptor.sourceKind: SourceKind
@@ -68,7 +68,7 @@ class PlatformHeaderAnnotator : Annotator {
val trace = BindingTraceContext()
for (module in implementingModules) {
HeaderImplDeclarationChecker.checkHeaderDeclarationHasImplementation(declaration, descriptor, trace, module)
ExpectedActualDeclarationChecker.checkExpectedDeclarationHasActual(declaration, descriptor, trace, module)
}
val suppressionCache = KotlinCacheService.getInstance(declaration.project).getSuppressionCache()
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.highlighter.allImplementingCompatibleModules
import org.jetbrains.kotlin.idea.highlighter.markers.implementationsOf
import org.jetbrains.kotlin.idea.highlighter.markers.actualsFor
import org.jetbrains.kotlin.idea.project.targetPlatform
import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.resolve.BindingContext
@@ -57,7 +57,7 @@ private fun AnnotationWithTarget.isExpectOfAnnotation(fqName: String, implModule
return implModules
.any { module ->
module.implementationsOf(annotationClass, checkCompatible = false)
module.actualsFor(annotationClass, checkCompatible = false)
.filterIsInstance<TypeAliasDescriptor>()
.any { it.classDescriptor?.fqNameSafe?.asString() == fqName }
}
@@ -26,66 +26,66 @@ import org.jetbrains.kotlin.idea.highlighter.allImplementingCompatibleModules
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.getMultiTargetPlatform
import java.awt.event.MouseEvent
fun ModuleDescriptor.hasImplementationsOf(descriptor: MemberDescriptor) =
implementationsOf(descriptor).isNotEmpty()
fun ModuleDescriptor.hasActualsFor(descriptor: MemberDescriptor) =
actualsFor(descriptor).isNotEmpty()
fun ModuleDescriptor.implementationsOf(descriptor: MemberDescriptor, checkCompatible: Boolean = true): List<DeclarationDescriptor> =
with(HeaderImplDeclarationChecker) {
fun ModuleDescriptor.actualsFor(descriptor: MemberDescriptor, checkCompatible: Boolean = true): List<DeclarationDescriptor> =
with(ExpectedActualDeclarationChecker) {
if (checkCompatible) {
descriptor.findCompatibleImplForHeader(this@implementationsOf)
descriptor.findCompatibleActualForExpected(this@actualsFor)
}
else {
descriptor.findAnyImplForHeader(this@implementationsOf)
descriptor.findAnyActualForExpected(this@actualsFor)
}
}
fun getPlatformImplementationTooltip(declaration: KtDeclaration): String? {
fun getPlatformActualTooltip(declaration: KtDeclaration): String? {
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return null
val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
val platformModulesWithImplementation = commonModuleDescriptor.allImplementingCompatibleModules.filter {
it.hasImplementationsOf(descriptor)
val platformModulesWithActuals = commonModuleDescriptor.allImplementingCompatibleModules.filter {
it.hasActualsFor(descriptor)
}
if (platformModulesWithImplementation.isEmpty()) return null
if (platformModulesWithActuals.isEmpty()) return null
return platformModulesWithImplementation.joinToString(prefix = "Has implementations in ") {
return platformModulesWithActuals.joinToString(prefix = "Has actuals in ") {
(it.getMultiTargetPlatform() as MultiTargetPlatform.Specific).platform
}
}
fun navigateToPlatformImplementation(e: MouseEvent?, declaration: KtDeclaration) {
val implementations = declaration.headerImplementations()
if (implementations.isEmpty()) return
fun navigateToPlatformActual(e: MouseEvent?, declaration: KtDeclaration) {
val actuals = declaration.actualsForExpected()
if (actuals.isEmpty()) return
val renderer = DefaultPsiElementCellRenderer()
PsiElementListNavigator.openTargets(e,
implementations.toTypedArray(),
"Choose implementation of ${declaration.name}",
"Implementations of ${declaration.name}",
actuals.toTypedArray(),
"Choose actual for ${declaration.name}",
"Actuals for ${declaration.name}",
renderer)
}
private fun DeclarationDescriptor.headerImplementations(): Collection<DeclarationDescriptor> {
private fun DeclarationDescriptor.actualsForExpected(): Collection<DeclarationDescriptor> {
if (this is MemberDescriptor) {
if (!this.isExpect) return emptyList()
return module.allImplementingCompatibleModules.flatMap { it.implementationsOf(this) }
return module.allImplementingCompatibleModules.flatMap { it.actualsFor(this) }
}
if (this is ValueParameterDescriptor) {
return containingDeclaration.headerImplementations().mapNotNull { (it as? CallableDescriptor)?.valueParameters?.getOrNull(index) }
return containingDeclaration.actualsForExpected().mapNotNull { (it as? CallableDescriptor)?.valueParameters?.getOrNull(index) }
}
return emptyList()
}
internal fun KtDeclaration.headerImplementations(): Set<KtDeclaration> {
return unsafeResolveToDescriptor().headerImplementations().mapNotNullTo(LinkedHashSet()) {
internal fun KtDeclaration.actualsForExpected(): Set<KtDeclaration> {
return unsafeResolveToDescriptor().actualsForExpected().mapNotNullTo(LinkedHashSet()) {
DescriptorToSourceUtils.descriptorToDeclaration(it) as? KtDeclaration
}
}
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.getMultiTargetPlatform
@@ -40,11 +40,11 @@ fun ModuleDescriptor.commonModuleOrNull(): ModuleDescriptor? {
fun ModuleDescriptor.hasDeclarationOf(descriptor: MemberDescriptor) = declarationOf(descriptor) != null
private fun ModuleDescriptor.declarationOf(descriptor: MemberDescriptor): DeclarationDescriptor? =
with(HeaderImplDeclarationChecker) {
descriptor.findCompatibleHeaderForImpl(this@declarationOf).firstOrNull()
with(ExpectedActualDeclarationChecker) {
descriptor.findCompatibleExpectedForActual(this@declarationOf).firstOrNull()
}
fun getHeaderDeclarationTooltip(declaration: KtDeclaration): String? {
fun getExpectedDeclarationTooltip(declaration: KtDeclaration): String? {
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return null
val platformModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
@@ -54,39 +54,39 @@ fun getHeaderDeclarationTooltip(declaration: KtDeclaration): String? {
return "Has declaration in common module"
}
fun navigateToHeaderDeclaration(declaration: KtDeclaration) {
declaration.headerDeclarationIfAny()?.navigate(false)
fun navigateToExpectedDeclaration(declaration: KtDeclaration) {
declaration.expectedDeclarationIfAny()?.navigate(false)
}
internal fun MemberDescriptor.headerDescriptor() = module.commonModuleOrNull()?.declarationOf(this)
internal fun MemberDescriptor.expectedDescriptor() = module.commonModuleOrNull()?.declarationOf(this)
internal fun KtDeclaration.headerDeclarationIfAny(): KtDeclaration? {
val headerDescriptor = (toDescriptor() as? MemberDescriptor)?.headerDescriptor() ?: return null
return DescriptorToSourceUtils.descriptorToDeclaration(headerDescriptor) as? KtDeclaration
internal fun KtDeclaration.expectedDeclarationIfAny(): KtDeclaration? {
val expectedDescriptor = (toDescriptor() as? MemberDescriptor)?.expectedDescriptor() ?: return null
return DescriptorToSourceUtils.descriptorToDeclaration(expectedDescriptor) as? KtDeclaration
}
internal fun KtDeclaration.isExpectOrExpectClassMember() =
internal fun KtDeclaration.isExpectedOrExpectedClassMember() =
hasExpectModifier() || (containingClassOrObject?.hasExpectModifier() ?: false)
internal fun DeclarationDescriptor.liftToHeader(): DeclarationDescriptor? {
internal fun DeclarationDescriptor.liftToExpected(): DeclarationDescriptor? {
if (this is MemberDescriptor) {
return when {
isExpect -> this
isActual -> headerDescriptor()
isActual -> expectedDescriptor()
else -> null
}
}
if (this is ValueParameterDescriptor) {
val containingHeaderDescriptor = containingDeclaration.liftToHeader() as? CallableDescriptor ?: return null
return containingHeaderDescriptor.valueParameters.getOrNull(index)
val containingExpectedDescriptor = containingDeclaration.liftToExpected() as? CallableDescriptor ?: return null
return containingExpectedDescriptor.valueParameters.getOrNull(index)
}
return null
}
internal fun KtDeclaration.liftToHeader(): KtDeclaration? {
internal fun KtDeclaration.liftToExpected(): KtDeclaration? {
val descriptor = resolveToDescriptorIfAny()
val headerDescriptor = descriptor?.liftToHeader() ?: return null
return DescriptorToSourceUtils.descriptorToDeclaration(headerDescriptor) as? KtDeclaration
val expectedDescriptor = descriptor?.liftToExpected() ?: return null
return DescriptorToSourceUtils.descriptorToDeclaration(expectedDescriptor) as? KtDeclaration
}
@@ -101,10 +101,10 @@ class KotlinLineMarkerProvider : LineMarkerProvider {
if (element !is KtNamedDeclaration) continue
if (element.hasExpectModifier()) {
collectImplementationMarkers(element, result)
collectActualMarkers(element, result)
}
else if (element.hasActualModifier()) {
collectHeaderMarkers(element, result)
collectExpectedMarkers(element, result)
}
}
}
@@ -182,22 +182,22 @@ private val OVERRIDDEN_PROPERTY = object : MarkerType(
}
}
private val PLATFORM_IMPLEMENTATION = MarkerType(
"PLATFORM_IMPLEMENTATION",
{ it?.let { getPlatformImplementationTooltip(it.parent as KtDeclaration) } },
private val PLATFORM_ACTUAL = MarkerType(
"PLATFORM_ACTUAL",
{ it?.let { getPlatformActualTooltip(it.parent as KtDeclaration) } },
object : LineMarkerNavigator() {
override fun browse(e: MouseEvent?, element: PsiElement?) {
element?.let { navigateToPlatformImplementation(e, it.parent as KtDeclaration) }
element?.let { navigateToPlatformActual(e, it.parent as KtDeclaration) }
}
}
)
private val HEADER_DECLARATION = MarkerType(
"HEADER_DECLARATION",
{ it?.let { getHeaderDeclarationTooltip(it.parent as KtDeclaration) } },
private val EXPECTED_DECLARATION = MarkerType(
"EXPECTED_DECLARATION",
{ it?.let { getExpectedDeclarationTooltip(it.parent as KtDeclaration) } },
object : LineMarkerNavigator() {
override fun browse(e: MouseEvent?, element: PsiElement?) {
element?.let { navigateToHeaderDeclaration(it.parent as KtDeclaration) }
element?.let { navigateToExpectedDeclaration(it.parent as KtDeclaration) }
}
}
)
@@ -286,13 +286,13 @@ private fun collectOverriddenPropertyAccessors(properties: Collection<KtNamedDec
}
}
private fun collectImplementationMarkers(declaration: KtNamedDeclaration,
result: MutableCollection<LineMarkerInfo<*>>) {
private fun collectActualMarkers(declaration: KtNamedDeclaration,
result: MutableCollection<LineMarkerInfo<*>>) {
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return
val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
if (commonModuleDescriptor.allImplementingCompatibleModules.none { it.hasImplementationsOf(descriptor) }) return
if (commonModuleDescriptor.allImplementingCompatibleModules.none { it.hasActualsFor(descriptor) }) return
val anchor = declaration.nameIdentifier ?: declaration
@@ -301,14 +301,14 @@ private fun collectImplementationMarkers(declaration: KtNamedDeclaration,
anchor.textRange,
KotlinIcons.FROM_HEADER,
Pass.LINE_MARKERS,
PLATFORM_IMPLEMENTATION.tooltip,
PLATFORM_IMPLEMENTATION.navigationHandler,
PLATFORM_ACTUAL.tooltip,
PLATFORM_ACTUAL.navigationHandler,
GutterIconRenderer.Alignment.RIGHT
))
}
private fun collectHeaderMarkers(declaration: KtNamedDeclaration,
result: MutableCollection<LineMarkerInfo<*>>) {
private fun collectExpectedMarkers(declaration: KtNamedDeclaration,
result: MutableCollection<LineMarkerInfo<*>>) {
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return
val platformModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
@@ -322,8 +322,8 @@ private fun collectHeaderMarkers(declaration: KtNamedDeclaration,
anchor.textRange,
KotlinIcons.FROM_IMPL,
Pass.LINE_MARKERS,
HEADER_DECLARATION.tooltip,
HEADER_DECLARATION.navigationHandler,
EXPECTED_DECLARATION.tooltip,
EXPECTED_DECLARATION.navigationHandler,
GutterIconRenderer.Alignment.RIGHT
))
}
@@ -56,7 +56,7 @@ import org.jetbrains.kotlin.idea.core.toDescriptor
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandler
import org.jetbrains.kotlin.idea.highlighter.allImplementingCompatibleModules
import org.jetbrains.kotlin.idea.highlighter.markers.hasImplementationsOf
import org.jetbrains.kotlin.idea.highlighter.markers.hasActualsFor
import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
@@ -334,8 +334,8 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
descriptor as? MemberDescriptor ?: return false
val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
return commonModuleDescriptor.allImplementingCompatibleModules.any { it.hasImplementationsOf(descriptor) } ||
commonModuleDescriptor.hasImplementationsOf(descriptor)
return commonModuleDescriptor.allImplementingCompatibleModules.any { it.hasActualsFor(descriptor) } ||
commonModuleDescriptor.hasActualsFor(descriptor)
}
override fun createOptionsPanel(): JComponent? {
@@ -33,9 +33,9 @@ import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.kotlin.idea.core.*
import org.jetbrains.kotlin.idea.highlighter.markers.headerImplementations
import org.jetbrains.kotlin.idea.highlighter.markers.isExpectOrExpectClassMember
import org.jetbrains.kotlin.idea.highlighter.markers.liftToHeader
import org.jetbrains.kotlin.idea.highlighter.markers.actualsForExpected
import org.jetbrains.kotlin.idea.highlighter.markers.isExpectedOrExpectedClassMember
import org.jetbrains.kotlin.idea.highlighter.markers.liftToExpected
import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.getReturnTypeReference
import org.jetbrains.kotlin.idea.refactoring.withHeaderImplementations
@@ -72,7 +72,7 @@ class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention<KtCallable
override fun applyTo(element: KtCallableDeclaration, editor: Editor?) {
var allowHeader = true
element.liftToHeader()?.headerImplementations()?.let {
element.liftToExpected()?.actualsForExpected()?.let {
if (it.isEmpty()) {
allowHeader = askIfHeaderIsAllowed(element.containingKtFile)
}
@@ -111,7 +111,7 @@ class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention<KtCallable
val descriptor = element.unsafeResolveToDescriptor()
val containingClass = descriptor.containingDeclaration as ClassDescriptor
val isEffectiveHeader = allowHeader && element.isExpectOrExpectClassMember()
val isEffectiveHeader = allowHeader && element.isExpectedOrExpectedClassMember()
val file = element.containingKtFile
val project = file.project
@@ -260,7 +260,7 @@ class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention<KtCallable
element: KtCallableDeclaration,
allowHeader: Boolean = true
): Pair<KtCallableDeclaration, KtExpression?> {
val headerDeclaration = element.liftToHeader() as? KtCallableDeclaration
val headerDeclaration = element.liftToExpected() as? KtCallableDeclaration
if (headerDeclaration != null) {
element.withHeaderImplementations().filterIsInstance<KtCallableDeclaration>().forEach {
if (it != element) {
@@ -35,9 +35,9 @@ import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.core.getDeepestSuperDeclarations
import org.jetbrains.kotlin.idea.core.getDirectlyOverriddenDeclarations
import org.jetbrains.kotlin.idea.highlighter.markers.headerImplementations
import org.jetbrains.kotlin.idea.highlighter.markers.isExpectOrExpectClassMember
import org.jetbrains.kotlin.idea.highlighter.markers.liftToHeader
import org.jetbrains.kotlin.idea.highlighter.markers.actualsForExpected
import org.jetbrains.kotlin.idea.highlighter.markers.isExpectedOrExpectedClassMember
import org.jetbrains.kotlin.idea.highlighter.markers.liftToExpected
import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.psi.KtBlockExpression
import org.jetbrains.kotlin.psi.KtDeclaration
@@ -57,7 +57,7 @@ abstract class CallableRefactoring<out T: CallableDescriptor>(
private val LOG = Logger.getInstance(CallableRefactoring::class.java)
@Suppress("UNCHECKED_CAST")
val callableDescriptor = callableDescriptor.liftToHeader() as? T ?: callableDescriptor
val callableDescriptor = callableDescriptor.liftToExpected() as? T ?: callableDescriptor
private val kind = (callableDescriptor as? CallableMemberDescriptor)?.kind ?: CallableMemberDescriptor.Kind.DECLARATION
@@ -76,7 +76,7 @@ abstract class CallableRefactoring<out T: CallableDescriptor>(
else -> {
throw IllegalStateException("Unexpected callable kind: $kind")
}
}.map { it.liftToHeader() as? CallableDescriptor ?: it }
}.map { it.liftToExpected() as? CallableDescriptor ?: it }
}
private fun showSuperFunctionWarningDialog(superCallables: Collection<CallableDescriptor>,
@@ -184,8 +184,8 @@ abstract class CallableRefactoring<out T: CallableDescriptor>(
fun getAffectedCallables(project: Project, descriptorsForChange: Collection<CallableDescriptor>): List<PsiElement> {
val baseCallables = descriptorsForChange.mapNotNull { DescriptorToSourceUtilsIde.getAnyDeclaration(project, it) }
return baseCallables + baseCallables.flatMapTo(HashSet<PsiElement>()) { callable ->
if (callable is KtDeclaration && callable.isExpectOrExpectClassMember()) {
callable.headerImplementations()
if (callable is KtDeclaration && callable.isExpectedOrExpectedClassMember()) {
callable.actualsForExpected()
}
else {
callable.toLightMethods().flatMap { psiMethod ->
@@ -28,8 +28,8 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.highlighter.markers.headerImplementations
import org.jetbrains.kotlin.idea.highlighter.markers.isExpectOrExpectClassMember
import org.jetbrains.kotlin.idea.highlighter.markers.actualsForExpected
import org.jetbrains.kotlin.idea.highlighter.markers.isExpectedOrExpectedClassMember
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.KotlinCallableDefinitionUsage
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.psi.*
@@ -98,8 +98,8 @@ class KotlinChangeSignatureData(
primaryCallables + primaryCallables.flatMapTo(HashSet<UsageInfo>()) { primaryFunction ->
val primaryDeclaration = primaryFunction.declaration as? KtDeclaration ?: return@flatMapTo emptyList()
if (primaryDeclaration.isExpectOrExpectClassMember()) {
return@flatMapTo primaryDeclaration.headerImplementations().mapNotNull {
if (primaryDeclaration.isExpectedOrExpectedClassMember()) {
return@flatMapTo primaryDeclaration.actualsForExpected().mapNotNull {
val descriptor = it.unsafeResolveToDescriptor()
val callableDescriptor = when (descriptor) {
is CallableDescriptor -> descriptor
@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZE
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.highlighter.markers.headerDescriptor
import org.jetbrains.kotlin.idea.highlighter.markers.expectedDescriptor
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringBundle
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
import org.jetbrains.kotlin.psi.*
@@ -166,7 +166,7 @@ class KotlinChangeSignatureHandler : ChangeSignatureHandler {
var descriptor = getDescriptor(bindingContext, element)
if (descriptor is MemberDescriptor && descriptor.isActual) {
descriptor = descriptor.headerDescriptor() ?: descriptor
descriptor = descriptor.expectedDescriptor() ?: descriptor
}
return when (descriptor) {
@@ -77,8 +77,8 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.core.*
import org.jetbrains.kotlin.idea.core.util.showYesNoCancelDialog
import org.jetbrains.kotlin.idea.highlighter.markers.headerImplementations
import org.jetbrains.kotlin.idea.highlighter.markers.liftToHeader
import org.jetbrains.kotlin.idea.highlighter.markers.actualsForExpected
import org.jetbrains.kotlin.idea.highlighter.markers.liftToExpected
import org.jetbrains.kotlin.idea.intentions.RemoveCurlyBracesFromTemplateIntention
import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinValVar
@@ -968,12 +968,12 @@ fun KtNamedDeclaration.isCompanionMemberOf(klass: KtClassOrObject): Boolean {
}
internal fun KtDeclaration.withHeaderImplementations(): List<KtDeclaration> {
val header = liftToHeader() ?: return listOf(this)
val implementations = header.headerImplementations()
val header = liftToExpected() ?: return listOf(this)
val implementations = header.actualsForExpected()
return listOf(header) + implementations
}
internal fun KtDeclaration.resolveToHeaderDescriptorIfPossible(): DeclarationDescriptor {
val descriptor = unsafeResolveToDescriptor()
return descriptor.liftToHeader() ?: descriptor
return descriptor.liftToExpected() ?: descriptor
}
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.kotlin.idea.highlighter.markers.headerDescriptor
import org.jetbrains.kotlin.idea.highlighter.markers.expectedDescriptor
import org.jetbrains.kotlin.idea.util.getAllAccessibleFunctions
import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
@@ -68,7 +68,7 @@ private fun KtNamedFunction.getOverloads(): Collection<FunctionDescriptor> {
val scope = getResolutionScope(context, resolutionFacade)
val extensionReceiverClass = descriptor.extensionReceiverParameter?.type?.constructor?.declarationDescriptor as? ClassDescriptor
if (descriptor.isActual && descriptor.headerDescriptor() != null) return emptyList()
if (descriptor.isActual && descriptor.expectedDescriptor() != null) return emptyList()
val result = LinkedHashSet<FunctionDescriptor>()
result += scope.getAllAccessibleFunctions(name)
@@ -39,7 +39,7 @@ import org.jetbrains.kotlin.asJava.namedUnwrappedElement
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.kotlin.idea.highlighter.markers.liftToHeader
import org.jetbrains.kotlin.idea.highlighter.markers.liftToExpected
import org.jetbrains.kotlin.idea.refactoring.Pass
import org.jetbrains.kotlin.idea.refactoring.checkSuperMethods
import org.jetbrains.kotlin.idea.refactoring.checkSuperMethodsWithPopup
@@ -108,7 +108,7 @@ class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
get() = originalDeclaration
}
private fun substituteForHeaderOrImpl(element: PsiElement?) = (element?.namedUnwrappedElement as? KtNamedDeclaration)?.liftToHeader()
private fun substituteForHeaderOrImpl(element: PsiElement?) = (element?.namedUnwrappedElement as? KtNamedDeclaration)?.liftToExpected()
override fun substituteElementToRename(element: PsiElement?, editor: Editor?): PsiElement? {
substituteForHeaderOrImpl(element)?.let { return it }
@@ -31,8 +31,8 @@ import org.jetbrains.kotlin.asJava.namedUnwrappedElement
import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
import org.jetbrains.kotlin.idea.highlighter.markers.headerImplementations
import org.jetbrains.kotlin.idea.highlighter.markers.liftToHeader
import org.jetbrains.kotlin.idea.highlighter.markers.actualsForExpected
import org.jetbrains.kotlin.idea.highlighter.markers.liftToExpected
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters
import org.jetbrains.kotlin.idea.search.projectScope
@@ -71,9 +71,9 @@ abstract class RenameKotlinPsiProcessor : RenamePsiElementProcessor() {
val declaration = element.namedUnwrappedElement as? KtNamedDeclaration
if (declaration != null) {
declaration.liftToHeader()?.let { headerDeclaration ->
declaration.liftToExpected()?.let { headerDeclaration ->
allRenames[headerDeclaration] = safeNewName
headerDeclaration.headerImplementations().forEach { allRenames[it] = safeNewName }
headerDeclaration.actualsForExpected().forEach { allRenames[it] = safeNewName }
}
}
}
@@ -40,8 +40,8 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.deleteElementAndCleanParent
import org.jetbrains.kotlin.idea.highlighter.markers.headerImplementations
import org.jetbrains.kotlin.idea.highlighter.markers.liftToHeader
import org.jetbrains.kotlin.idea.highlighter.markers.actualsForExpected
import org.jetbrains.kotlin.idea.highlighter.markers.liftToExpected
import org.jetbrains.kotlin.idea.refactoring.checkSuperMethods
import org.jetbrains.kotlin.idea.refactoring.formatClass
import org.jetbrains.kotlin.idea.refactoring.formatFunction
@@ -362,7 +362,7 @@ class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
override fun prepareForDeletion(element: PsiElement) {
if (element is KtDeclaration) {
element.headerImplementations().forEach {
element.actualsForExpected().forEach {
if (it is KtParameter) {
(it.parent as? KtParameterList)?.removeParameter(it)
}
@@ -415,7 +415,7 @@ class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
): Collection<PsiElement>? {
when (element) {
is KtParameter -> {
val headerParameter = element.liftToHeader() as? KtParameter
val headerParameter = element.liftToExpected() as? KtParameter
if (headerParameter != null && headerParameter != element) {
if (shouldAllowPropagationToHeader(element)) {
return listOf(headerParameter)
@@ -1,3 +1,3 @@
header fun <lineMarker descr="Has implementations in JVM">foo</lineMarker>(): Int
header fun <lineMarker descr="Has actuals in JVM">foo</lineMarker>(): Int
header fun <lineMarker descr="Has implementations in JVM">foo</lineMarker>(arg: Int): Int
header fun <lineMarker descr="Has actuals in JVM">foo</lineMarker>(arg: Int): Int