Skip to content

Commit

Permalink
Use a single toString implementation for protocol nodes (#2345)
Browse files Browse the repository at this point in the history
This saves even more. For emoji sample:

 - Before: 11299596
 - After: 10953834
  • Loading branch information
JakeWharton authored Oct 1, 2024
1 parent ebd7259 commit 26d5056
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 25 deletions.
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 @@ -330,6 +330,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 @@ -528,22 +537,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})"
}

0 comments on commit 26d5056

Please sign in to comment.