Fix line markers for actual enum entries

#KT-22632 Fixed
This commit is contained in:
Pavel V. Talanov
2018-03-29 16:16:36 +02:00
parent e66768cbb3
commit de71598794
9 changed files with 58 additions and 6 deletions
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
import org.jetbrains.kotlin.idea.KotlinIcons.ACTUAL
import org.jetbrains.kotlin.idea.KotlinIcons.EXPECT
import org.jetbrains.kotlin.idea.caches.lightClasses.KtLightClassForDecompiledDeclaration
import org.jetbrains.kotlin.idea.util.isActualDeclaration
import org.jetbrains.kotlin.idea.util.hasMatchingExpected
import org.jetbrains.kotlin.idea.util.isExpectDeclaration
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
@@ -137,7 +137,7 @@ private fun Icon.addExpectActualMarker(element: PsiElement): Icon {
val declaration = (element as? KtNamedDeclaration) ?: return this
val additionalIcon = when {
declaration.isExpectDeclaration() -> EXPECT
declaration.isActualDeclaration() -> ACTUAL
declaration.hasMatchingExpected() -> ACTUAL
else -> return this
}
return RowIcon(2).apply {
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
@@ -114,8 +115,14 @@ private fun KtClassOrObject.isExpected(): Boolean {
return this.hasExpectModifier() || this.descriptor.safeAs<ClassDescriptor>()?.isExpect == true
}
fun KtDeclaration.isActualDeclaration(): Boolean {
fun KtDeclaration.hasMatchingExpected() = (toDescriptor() as? MemberDescriptor)?.expectedDescriptor() != null
fun KtDeclaration.isEffectivelyActual(): Boolean {
if (hasActualModifier()) return true
return (toDescriptor() as? MemberDescriptor)?.isActual == true
val descriptor = toDescriptor() as? MemberDescriptor ?: return false
return descriptor.isActual || descriptor.isEnumEntryInActual()
}
private fun MemberDescriptor.isEnumEntryInActual() =
(DescriptorUtils.isEnumEntry(this) && (containingDeclaration as? MemberDescriptor)?.isActual == true)
@@ -35,7 +35,7 @@ class KotlinExpectOrActualGotoRelatedProvider : GotoRelatedProvider() {
val declaration = psiElement.getParentOfTypeAndBranch<KtNamedDeclaration> { nameIdentifier } ?: return emptyList()
val targets = when {
declaration.isExpectDeclaration() -> declaration.actualsForExpected()
declaration.isActualDeclaration() -> listOfNotNull(declaration.expectedDeclarationIfAny())
declaration.isEffectivelyActual() -> listOfNotNull(declaration.expectedDeclarationIfAny())
else -> emptyList()
}
return targets.map(::ActualOrExpectGotoRelatedItem)
@@ -123,7 +123,7 @@ class KotlinLineMarkerProvider : LineMarkerProvider {
if (element.isExpectDeclaration()) {
collectActualMarkers(element, result)
}
else if (element.isActualDeclaration()) {
else if (element.isEffectivelyActual()) {
collectExpectedMarkers(element, result)
}
}
@@ -0,0 +1,9 @@
// !CHECK_HIGHLIGHTING
package test
expect enum class Enum {
A,
B,
C
}
@@ -0,0 +1,8 @@
package test
actual enum class <lineMarker>Enum</lineMarker> {
<lineMarker>A</lineMarker>,
<lineMarker>B</lineMarker>,
<lineMarker>C</lineMarker>,
D
}
@@ -0,0 +1,7 @@
package test
expect enum class <lineMarker>Enum</lineMarker> {
<lineMarker>A</lineMarker>,
<lineMarker>B</lineMarker>,
<lineMarker>C</lineMarker>
}
@@ -0,0 +1,9 @@
// !CHECK_HIGHLIGHTING
package test
actual enum class Enum {
A,
B,
C,
D
}
@@ -21,10 +21,22 @@ import java.util.regex.Pattern;
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class MultiModuleLineMarkerTestGenerated extends AbstractMultiModuleLineMarkerTest {
@TestMetadata("actualEnumEntries")
public void testActualEnumEntries() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/multiModuleLineMarker/actualEnumEntries/");
doTest(fileName);
}
public void testAllFilesPresentInMultiModuleLineMarker() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/multiModuleLineMarker"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, false);
}
@TestMetadata("expectEnumEntries")
public void testExpectEnumEntries() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/multiModuleLineMarker/expectEnumEntries/");
doTest(fileName);
}
@TestMetadata("fromActualAnnotation")
public void testFromActualAnnotation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/multiModuleLineMarker/fromActualAnnotation/");