Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REF: Render generic parameters for associated types in Implement Members #7977

Merged
merged 1 commit into from
Feb 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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 @@ -57,6 +57,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 @@ -112,10 +115,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 @@ -136,14 +153,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.ImportCandidateBase
import org.rust.ide.utils.import.import
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 @@ -1792,6 +1792,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