aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main/kotlin/translators/psi
diff options
context:
space:
mode:
authorIgnat Beresnev <ignat.beresnev@jetbrains.com>2022-06-17 15:16:03 +0200
committerGitHub <noreply@github.com>2022-06-17 15:16:03 +0200
commit9f67dcf75d3b86fa6e4e352d2cebc4f9e17b8048 (patch)
tree5b30ddf007113d5b3da04390e093dc8023c04c79 /plugins/base/src/main/kotlin/translators/psi
parentb783439932372e823c36776c53cda5bdc8d0ccae (diff)
downloaddokka-9f67dcf75d3b86fa6e4e352d2cebc4f9e17b8048.tar.gz
dokka-9f67dcf75d3b86fa6e4e352d2cebc4f9e17b8048.tar.bz2
dokka-9f67dcf75d3b86fa6e4e352d2cebc4f9e17b8048.zip
Handle more corner cases for inherited accessors (#2532)
Diffstat (limited to 'plugins/base/src/main/kotlin/translators/psi')
-rw-r--r--plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt33
-rw-r--r--plugins/base/src/main/kotlin/translators/psi/PsiAccessorConventionUtil.kt38
2 files changed, 53 insertions, 18 deletions
diff --git a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt
index c20073a4..bef86144 100644
--- a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt
+++ b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt
@@ -17,9 +17,9 @@ import org.jetbrains.dokka.analysis.KotlinAnalysis
import org.jetbrains.dokka.analysis.PsiDocumentableSource
import org.jetbrains.dokka.analysis.from
import org.jetbrains.dokka.base.DokkaBase
-import org.jetbrains.dokka.base.translators.typeConstructorsBeingExceptions
import org.jetbrains.dokka.base.translators.psi.parsers.JavaDocumentationParser
import org.jetbrains.dokka.base.translators.psi.parsers.JavadocParser
+import org.jetbrains.dokka.base.translators.typeConstructorsBeingExceptions
import org.jetbrains.dokka.base.translators.unquotedValue
import org.jetbrains.dokka.links.*
import org.jetbrains.dokka.model.*
@@ -40,12 +40,7 @@ import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
import org.jetbrains.kotlin.idea.base.utils.fqname.getKotlinFqName
-import org.jetbrains.kotlin.load.java.JvmAbi
-import org.jetbrains.kotlin.load.java.propertyNameByGetMethodName
-import org.jetbrains.kotlin.load.java.propertyNamesBySetMethodName
-import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
-import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.io.File
@@ -108,16 +103,6 @@ class DefaultPsiToDocumentableTranslator(
private val cachedBounds = hashMapOf<String, Bound>()
- private fun PsiModifierListOwner.getVisibility() = modifierList?.let {
- val ml = it.children.toList()
- when {
- ml.any { it.text == PsiKeyword.PUBLIC } || it.hasModifierProperty("public") -> JavaVisibility.Public
- ml.any { it.text == PsiKeyword.PROTECTED } || it.hasModifierProperty("protected") -> JavaVisibility.Protected
- ml.any { it.text == PsiKeyword.PRIVATE } || it.hasModifierProperty("private") -> JavaVisibility.Private
- else -> JavaVisibility.Default
- }
- } ?: JavaVisibility.Default
-
private val PsiMethod.hash: Int
get() = "$returnType $name$parameterList".hashCode()
@@ -641,7 +626,7 @@ class DefaultPsiToDocumentableTranslator(
documentation = javadocParser.parseDocumentation(psi).toSourceSetDependent(),
expectPresentInSet = null,
sources = PsiDocumentableSource(psi).toSourceSetDependent(),
- visibility = psi.getVisibility().toSourceSetDependent(),
+ visibility = psi.getVisibility(getter).toSourceSetDependent(),
type = getBound(psi.type),
receiver = null,
setter = setter,
@@ -666,6 +651,10 @@ class DefaultPsiToDocumentableTranslator(
)
}
+ private fun PsiField.getVisibility(getter: DFunction?): Visibility {
+ return getter?.visibility?.get(sourceSetData) ?: this.getVisibility()
+ }
+
private fun Collection<PsiAnnotation>.toListOfAnnotations() =
filter { it !is KtLightAbstractAnnotation }.mapNotNull { it.toAnnotation() }
@@ -740,3 +729,13 @@ class DefaultPsiToDocumentableTranslator(
get() = getChildOfType<PsiJavaCodeReferenceElement>()?.resolve()
}
}
+
+internal fun PsiModifierListOwner.getVisibility() = modifierList?.let {
+ val ml = it.children.toList()
+ when {
+ ml.any { it.text == PsiKeyword.PUBLIC } || it.hasModifierProperty("public") -> JavaVisibility.Public
+ ml.any { it.text == PsiKeyword.PROTECTED } || it.hasModifierProperty("protected") -> JavaVisibility.Protected
+ ml.any { it.text == PsiKeyword.PRIVATE } || it.hasModifierProperty("private") -> JavaVisibility.Private
+ else -> JavaVisibility.Default
+ }
+} ?: JavaVisibility.Default
diff --git a/plugins/base/src/main/kotlin/translators/psi/PsiAccessorConventionUtil.kt b/plugins/base/src/main/kotlin/translators/psi/PsiAccessorConventionUtil.kt
index c2ab8c03..2ab70843 100644
--- a/plugins/base/src/main/kotlin/translators/psi/PsiAccessorConventionUtil.kt
+++ b/plugins/base/src/main/kotlin/translators/psi/PsiAccessorConventionUtil.kt
@@ -3,6 +3,9 @@ package org.jetbrains.dokka.base.translators.psi
import com.intellij.psi.PsiField
import com.intellij.psi.PsiMethod
import org.jetbrains.dokka.base.translators.firstNotNullOfOrNull
+import org.jetbrains.dokka.model.JavaVisibility
+import org.jetbrains.dokka.model.KotlinVisibility
+import org.jetbrains.dokka.model.Visibility
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.propertyNameByGetMethodName
import org.jetbrains.kotlin.load.java.propertyNamesBySetMethodName
@@ -28,9 +31,32 @@ internal fun splitFunctionsAndAccessors(fields: Array<PsiField>, methods: Array<
regularFunctions.add(method)
}
}
+
+ val accessorLookalikes = removeNonAccessorsReturning(accessors)
+ regularFunctions.addAll(accessorLookalikes)
+
return PsiFunctionsHolder(regularFunctions, accessors)
}
+/**
+ * If a field has no getter, it's not accessible as a property from Kotlin's perspective,
+ * but it still might have a setter. In this case, this "setter" should be just a regular function
+ */
+private fun removeNonAccessorsReturning(
+ fieldAccessors: MutableMap<PsiField, MutableList<PsiMethod>>
+): List<PsiMethod> {
+ val nonAccessors = mutableListOf<PsiMethod>()
+ fieldAccessors.entries.removeIf { (field, methods) ->
+ if (methods.size == 1 && methods[0].isSetterFor(field)) {
+ nonAccessors.add(methods[0])
+ true
+ } else {
+ false
+ }
+ }
+ return nonAccessors
+}
+
internal fun PsiMethod.getPossiblePropertyNamesForFunction(): List<String> {
val jvmName = getAnnotation(DescriptorUtils.JVM_NAME.asString())?.findAttributeValue("name")?.text
return jvmName?.let { listOf(jvmName) }
@@ -46,7 +72,9 @@ internal fun PsiMethod.getPossiblePropertyNamesForFunction(): List<String> {
}
internal fun PsiMethod.isAccessorFor(field: PsiField): Boolean {
- return this.isGetterFor(field) || this.isSetterFor(field)
+ return (this.isGetterFor(field) || this.isSetterFor(field))
+ && !field.getVisibility().isPublicAPI()
+ && this.getVisibility().isPublicAPI()
}
internal fun PsiMethod.isGetterFor(field: PsiField): Boolean {
@@ -56,3 +84,11 @@ internal fun PsiMethod.isGetterFor(field: PsiField): Boolean {
internal fun PsiMethod.isSetterFor(field: PsiField): Boolean {
return parameterList.getParameter(0)?.type == field.type
}
+
+internal fun Visibility.isPublicAPI() = when(this) {
+ KotlinVisibility.Public,
+ KotlinVisibility.Protected,
+ JavaVisibility.Public,
+ JavaVisibility.Protected -> true
+ else -> false
+}