Skip to content

Commit 4ec7f85

Browse files
committed
LayoutDSL: Improve component names
With LayoutDSL, all components eventually end up being called just "BoxContainer", "RowContainer", etc. which isn't too useful. This commit adds code to automatically try to guess better names by peeking at the call stack. This allows LayoutDSL-style function components to automatically receive the name of the function. Source-Commit: 8d180e417aa2e1589966466b577542c08f3c0f19
1 parent c4bb60e commit 4ec7f85

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

unstable/layoutdsl/src/main/kotlin/gg/essential/elementa/layoutdsl/containers.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fun LayoutScope.box(modifier: Modifier = Modifier, block: LayoutScope.() -> Unit
2626
}
2727

2828
val container = TransparentBlock().apply {
29-
componentName = "BoxContainer"
29+
automaticComponentName("box")
3030
setWidth(ChildBasedSizeConstraint())
3131
setHeight(ChildBasedSizeConstraint())
3232
}
@@ -46,7 +46,7 @@ fun LayoutScope.row(modifier: Modifier, horizontalArrangement: Arrangement = Arr
4646
}
4747

4848
val rowContainer = TransparentBlock().apply {
49-
componentName = "RowContainer"
49+
automaticComponentName("row")
5050
setWidth(ChildBasedSizeConstraint())
5151
setHeight(ChildBasedMaxSizeConstraint())
5252
}
@@ -68,7 +68,7 @@ fun LayoutScope.column(modifier: Modifier, verticalArrangement: Arrangement = Ar
6868
}
6969

7070
val columnContainer = TransparentBlock().apply {
71-
componentName = "ColumnContainer"
71+
automaticComponentName("column")
7272
setWidth(ChildBasedMaxSizeConstraint())
7373
setHeight(ChildBasedSizeConstraint())
7474
}
@@ -93,7 +93,7 @@ fun LayoutScope.flowContainer(
9393
}
9494

9595
val flowContainer = TransparentBlock().apply {
96-
componentName = "FlowContainer"
96+
automaticComponentName("flowContainer")
9797
setHeight(ChildBasedSizeConstraint())
9898
}
9999

@@ -132,7 +132,7 @@ fun LayoutScope.scrollable(
132132
val content = HollowUIContainer() childOf outer // actually adds to `inner` because ScrollComponent redirects it
133133

134134
outer.apply {
135-
componentName = "scrollable"
135+
automaticComponentName("scrollable")
136136
setWidth(ChildBasedSizeConstraint() boundTo content)
137137
setHeight(ChildBasedSizeConstraint() boundTo content)
138138
}
@@ -165,6 +165,7 @@ fun LayoutScope.floatingBox(
165165
}
166166

167167
val box = box(modifier, block)
168+
box.automaticComponentName("floatingBox")
168169
effect(box) {
169170
box.isFloating = floating()
170171
}

unstable/layoutdsl/src/main/kotlin/gg/essential/elementa/layoutdsl/lazy.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ fun LayoutScope.lazyBox(modifier: Modifier = Modifier.fillParent(), block: Layou
2121
} `else` {
2222
LazyComponent(initialized)(Modifier.fillParent())
2323
}
24+
}.apply {
25+
automaticComponentName("lazyBox")
2426
}
2527
}
2628

unstable/layoutdsl/src/main/kotlin/gg/essential/elementa/layoutdsl/util.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import gg.essential.elementa.dsl.boundTo
66
import gg.essential.elementa.dsl.percent
77
import gg.essential.elementa.dsl.pixels
88
import gg.essential.elementa.effects.Effect
9+
import gg.essential.elementa.utils.elementaDev
910
import gg.essential.elementa.common.Spacer
1011
import java.awt.Color
1112

@@ -32,6 +33,23 @@ internal inline fun <T> Iterable<T>.sumOf(selector: (T) -> Float): Float {
3233
return sum
3334
}
3435

36+
fun UIComponent.automaticComponentName(default: String) {
37+
if (!elementaDev) return
38+
39+
componentName = Throwable().stackTrace
40+
.asSequence()
41+
.filterNot { it.lineNumber == 1 } // synthetic accessor methods
42+
.filterNot { it.methodName.endsWith("\$default") } // synthetic Kotlin defaults methods
43+
.map { it.methodName }
44+
.distinct() // collapse overloads
45+
.drop(1) // "automaticComponentName"
46+
.drop(1) // caller method (e.g. "box")
47+
.firstOrNull()
48+
?.takeUnless { it == "invoke" } // anonymous component (the `block` of `LayoutScope.invoke`)
49+
?.takeUnless { it == "<init>" } // anonymous component (likely direct child of a class component)
50+
?: default
51+
}
52+
3553
fun UIComponent.getChildModifier() =
3654
effects
3755
.filterIsInstance<ChildModifierMarker>()

0 commit comments

Comments
 (0)