Skip to content

Commit

Permalink
REF: Render generic parameters for associated types in `Implement Mem…
Browse files Browse the repository at this point in the history
…bers`
  • Loading branch information
mchernyavsky committed Oct 18, 2021
1 parent a7aff69 commit 6ea0bd2
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 16 deletions.
44 changes: 36 additions & 8 deletions src/main/kotlin/org/rust/ide/presentation/RsPsiRenderer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ fun RsPsiRenderer.renderValueParameterList(list: RsValueParameterList): String =
fun RsPsiRenderer.renderFunctionSignature(fn: RsFunction): String =
buildString { appendFunctionSignature(this, fn) }

fun RsPsiRenderer.renderTypeAliasSignature(ta: RsTypeAlias, renderBounds: Boolean): String =
buildString { appendTypeAliasSignature(this, ta, renderBounds) }

data class PsiRenderingOptions(
val renderLifetimes: Boolean = true,
/** Related to [RsPsiRenderer.appendFunctionSignature] */
Expand Down Expand Up @@ -114,10 +117,24 @@ open class RsPsiRenderer(
}
val whereClause = fn.whereClause
if (whereClause != null && renderGenericsAndWhere) {
sb.append(" where ")
whereClause.wherePredList.joinToWithBuffer(sb, separator = ", ") {
appendWherePred(sb, this)
}
appendWhereClause(sb, whereClause)
}
}

open fun appendTypeAliasSignature(sb: StringBuilder, ta: RsTypeAlias, renderBounds: Boolean) {
sb.append("type ")
sb.append(ta.escapedName ?: "")
val typeParameterList = ta.typeParameterList
if (typeParameterList != null && renderGenericsAndWhere) {
appendTypeParameterList(sb, typeParameterList)
}
val whereClause = ta.whereClause
if (whereClause != null && renderGenericsAndWhere) {
appendWhereClause(sb, whereClause)
}
val typeParamBounds = ta.typeParamBounds
if (typeParamBounds != null && renderBounds) {
appendTypeParamBounds(sb, typeParamBounds)
}
}

Expand All @@ -138,14 +155,25 @@ open class RsPsiRenderer(
appendTypeReference(sb, type)
val typeParamBounds = pred.typeParamBounds
if (typeParamBounds != null) {
sb.append(": ")
typeParamBounds.polyboundList.joinToWithBuffer(sb, " + ") {
appendPolybound(sb, this)
}
appendTypeParamBounds(sb, typeParamBounds)
}
}
}

private fun appendWhereClause(sb: StringBuilder, whereClause: RsWhereClause) {
sb.append(" where ")
whereClause.wherePredList.joinToWithBuffer(sb, separator = ", ") {
appendWherePred(sb, this)
}
}

private fun appendTypeParamBounds(sb: StringBuilder, bounds: RsTypeParamBounds) {
sb.append(": ")
bounds.polyboundList.joinToWithBuffer(sb, " + ") {
appendPolybound(sb, this)
}
}

open fun appendTypeParameterList(sb: StringBuilder, list: RsTypeParameterList) {
sb.append("<")
list.stubChildrenOfType<RsElement>().joinToWithBuffer(sb, separator = ", ") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiWhiteSpace
import org.rust.ide.presentation.ImportingPsiRenderer
import org.rust.ide.presentation.PsiRenderingOptions
import org.rust.ide.presentation.renderFunctionSignature
import org.rust.ide.presentation.renderTypeReference
import org.rust.ide.presentation.*
import org.rust.ide.settings.RsCodeInsightSettings
import org.rust.ide.utils.import.ImportCandidate
import org.rust.ide.utils.import.import
Expand All @@ -29,8 +26,8 @@ import org.rust.lang.core.types.type
import org.rust.openapiext.checkReadAccessAllowed
import org.rust.openapiext.checkWriteAccessAllowed
import org.rust.openapiext.checkWriteAccessNotAllowed
import kotlin.math.max
import org.rust.openapiext.selectElement
import kotlin.math.max

fun generateTraitMembers(impl: RsImplItem, editor: Editor?) {
checkWriteAccessNotAllowed()
Expand Down Expand Up @@ -216,7 +213,7 @@ class MembersGenerator(
"const ${element.nameLikeElement.text}: ${element.typeReference?.renderTypeReference() ?: "_"} = ${initialValue.text};"
}
is RsTypeAlias ->
"type ${element.escapedName} = ();"
"${element.renderTypeAliasSignature()} = ();"
is RsFunction ->
"${element.renderFunctionSignature()} {\n todo!()\n }"
else ->
Expand All @@ -225,5 +222,6 @@ class MembersGenerator(
}

private fun RsFunction.renderFunctionSignature(): String = renderer.renderFunctionSignature(this)
private fun RsTypeAlias.renderTypeAliasSignature(): String = renderer.renderTypeAliasSignature(this, renderBounds = false)
private fun RsTypeReference.renderTypeReference(): String = renderer.renderTypeReference(this)
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ import javax.swing.JTree

class RsTraitMemberChooserMember(val base: MemberChooserObjectBase, val member: RsAbstractable) : ClassMember {
private val text: String = when (member) {
is RsFunction ->
is RsFunction, is RsTypeAlias ->
member.presentationInfo?.projectStructureItemText ?: ""
is RsTypeAlias -> "${member.name}"
is RsConstant -> "${member.name}: ${member.typeReference?.text}"
else -> error("Unknown trait member: $member")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1774,6 +1774,30 @@ class ImplementMembersHandlerTest : RsTestBase() {
}
""")

fun `test associated type`() = doTest("""
trait Foo {
type A<'a, T> where T: 'a;
type B: Sized;
}
struct S;
impl Foo for S {
/*caret*/
}
""", listOf(
ImplementMemberSelection("A<'a, T> where T: 'a", byDefault = true),
ImplementMemberSelection("B: Sized", byDefault = true)
), """
trait Foo {
type A<'a, T> where T: 'a;
type B: Sized;
}
struct S;
impl Foo for S {
type A<'a, T> where T: 'a = ();
type B = ();
}
""")

private data class ImplementMemberSelection(val member: String, val byDefault: Boolean, val isSelected: Boolean = byDefault)

private fun doTest(
Expand Down

0 comments on commit 6ea0bd2

Please sign in to comment.