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

Use a single toString implementation for protocol nodes #2345

Merged
merged 1 commit into from
Oct 1, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion redwood-protocol-host/api/redwood-protocol-host.api
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ public abstract class app/cash/redwood/protocol/host/ProtocolNode {
public abstract fun detach ()V
public final fun getId-0HhLjSo ()I
public abstract fun getWidget ()Lapp/cash/redwood/widget/Widget;
public abstract fun getWidgetName ()Ljava/lang/String;
public abstract fun getWidgetTag-BlhN7y0 ()I
public final fun setId-ou3jOuA (I)V
public abstract fun toString ()Ljava/lang/String;
public final fun toString ()Ljava/lang/String;
public final fun updateModifier (Lapp/cash/redwood/Modifier;)V
public fun visitIds (Lapp/cash/redwood/protocol/host/IdVisitor;)V
}
Expand Down
4 changes: 3 additions & 1 deletion redwood-protocol-host/api/redwood-protocol-host.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ abstract class <#A: kotlin/Any> app.cash.redwood.protocol.host/ProtocolNode { //

abstract val widget // app.cash.redwood.protocol.host/ProtocolNode.widget|{}widget[0]
abstract fun <get-widget>(): app.cash.redwood.widget/Widget<#A> // app.cash.redwood.protocol.host/ProtocolNode.widget.<get-widget>|<get-widget>(){}[0]
abstract val widgetName // app.cash.redwood.protocol.host/ProtocolNode.widgetName|{}widgetName[0]
abstract fun <get-widgetName>(): kotlin/String // app.cash.redwood.protocol.host/ProtocolNode.widgetName.<get-widgetName>|<get-widgetName>(){}[0]
abstract val widgetTag // app.cash.redwood.protocol.host/ProtocolNode.widgetTag|{}widgetTag[0]
abstract fun <get-widgetTag>(): app.cash.redwood.protocol/WidgetTag // app.cash.redwood.protocol.host/ProtocolNode.widgetTag.<get-widgetTag>|<get-widgetTag>(){}[0]

Expand All @@ -52,7 +54,7 @@ abstract class <#A: kotlin/Any> app.cash.redwood.protocol.host/ProtocolNode { //
abstract fun apply(app.cash.redwood.protocol/PropertyChange, app.cash.redwood.protocol.host/UiEventSink) // app.cash.redwood.protocol.host/ProtocolNode.apply|apply(app.cash.redwood.protocol.PropertyChange;app.cash.redwood.protocol.host.UiEventSink){}[0]
abstract fun children(app.cash.redwood.protocol/ChildrenTag): app.cash.redwood.protocol.host/ProtocolChildren<#A>? // app.cash.redwood.protocol.host/ProtocolNode.children|children(app.cash.redwood.protocol.ChildrenTag){}[0]
abstract fun detach() // app.cash.redwood.protocol.host/ProtocolNode.detach|detach(){}[0]
abstract fun toString(): kotlin/String // app.cash.redwood.protocol.host/ProtocolNode.toString|toString(){}[0]
final fun toString(): kotlin/String // app.cash.redwood.protocol.host/ProtocolNode.toString|toString(){}[0]
final fun updateModifier(app.cash.redwood/Modifier) // app.cash.redwood.protocol.host/ProtocolNode.updateModifier|updateModifier(app.cash.redwood.Modifier){}[0]
open fun visitIds(app.cash.redwood.protocol.host/IdVisitor) // app.cash.redwood.protocol.host/ProtocolNode.visitIds|visitIds(app.cash.redwood.protocol.host.IdVisitor){}[0]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,8 @@ private class RootProtocolNode<W : Any>(
Widget<W> {
override val widgetTag: WidgetTag get() = UnknownWidgetTag

override val widgetName: String get() = "RootProtocolNode"

private val children = ProtocolChildren(children)

override fun apply(change: PropertyChange, eventSink: UiEventSink) {
Expand Down Expand Up @@ -424,8 +426,6 @@ private class RootProtocolNode<W : Any>(
override fun detach() {
children.detach()
}

override fun toString() = "RootProtocolNode"
}

private const val REUSE_MODIFIER_TAG = -4_543_827
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public abstract class ProtocolNode<W : Any>(
) {
public abstract val widgetTag: WidgetTag

public abstract val widgetName: String

public abstract val widget: Widget<W>

/** The index of [widget] within its parent [container]. */
Expand Down Expand Up @@ -78,7 +80,14 @@ public abstract class ProtocolNode<W : Any>(
public abstract fun detach()

/** Human-readable name of this node along with [id] and [widgetTag]. */
public abstract override fun toString(): String
public final override fun toString(): String = buildString {
append(widgetName)
append("(id=")
append(id.value)
append(", tag=")
append(widgetTag.value)
append(")")
}
}

/** @suppress */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class ChildrenNodeIndexTest {
@OptIn(RedwoodCodegenApi::class)
private class WidgetNode(override val widget: StringWidget) : ProtocolNode<String>(Id(1)) {
override val widgetTag: WidgetTag get() = WidgetTag(1)
override val widgetName: String get() = "WidgetNode"

override fun apply(change: PropertyChange, eventSink: UiEventSink) {
throw UnsupportedOperationException()
Expand All @@ -139,8 +140,6 @@ private class WidgetNode(override val widget: StringWidget) : ProtocolNode<Strin

override fun detach() {
}

override fun toString() = "WidgetNode"
}

private class StringWidget(override val value: String) : Widget<String> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,15 @@ internal fun generateProtocolNode(
)
.build(),
)
.addProperty(
PropertySpec.builder("widgetName", STRING, OVERRIDE)
.getter(
FunSpec.getterBuilder()
.addStatement("return %S", widget.type.flatName)
.build(),
)
.build(),
)
.addProperty(
PropertySpec.builder("_widget", widgetType.copy(nullable = true), PRIVATE)
.mutable(true)
Expand Down Expand Up @@ -526,22 +535,6 @@ internal fun generateProtocolNode(
.addStatement("_widget = null")
.build(),
)
.addFunction(
FunSpec.builder("toString")
.addModifiers(OVERRIDE)
.returns(STRING)
// This explicit string builder usage allows sharing of strings in dex.
// See https://jakewharton.com/the-economics-of-generated-code/#string-duplication.
.beginControlFlow("return buildString")
.addStatement("append(%S)", type.simpleName)
.addStatement("""append("(id=")""")
.addStatement("append(id.value)")
.addStatement("""append(", tag=")""")
.addStatement("append(%L)", widget.tag)
.addStatement("append(')')")
.endControlFlow()
.build(),
)
.build(),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ internal class FakeProtocolNode(
id: Id,
override val widgetTag: WidgetTag,
) : ProtocolNode<FakeWidget>(id) {
override val widgetName: String get() = "FakeProtocolNode"

override val widget = FakeWidget()

override fun apply(change: PropertyChange, eventSink: UiEventSink) {
Expand All @@ -50,6 +52,4 @@ internal class FakeProtocolNode(

override fun detach() {
}

override fun toString() = "FakeProtocolNode(id=${id.value}, tag=${widgetTag.value})"
}