Skip to content

Commit

Permalink
Merge branch 'cashapp:trunk' into fix_test_app
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonButov authored Oct 4, 2024
2 parents 8349503 + cceda78 commit f79fc34
Show file tree
Hide file tree
Showing 130 changed files with 962 additions and 881 deletions.
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
# Change Log

## [Unreleased]
[Unreleased]: https://github.com/cashapp/redwood/compare/0.13.0...HEAD
[Unreleased]: https://github.com/cashapp/redwood/compare/0.15.0...HEAD

New:
- Nothing yet!

Changed:
- Drop support for non-incremental layouts in `Row` and `Column`.

Fixed:
- Fix a layout bug where children of fixed-with `Row` containers were assigned the wrong width.


## [0.15.0] - 2024-09-30
[0.15.0]: https://github.com/cashapp/redwood/releases/tag/0.15.0

New:
- Default expressions can now be used directly in the schema rather than using the `@Default` annotation. The annotation has been deprecated, and will be removed in the next release.
Expand All @@ -16,6 +29,7 @@ Fixed:
- Breaking the last remaining retain cycle in `UIViewLazyList`.
- Don't leak the `DisplayLink` when a `TreehouseApp` is stopped on iOS.
- Correctly handle dynamic size changes for child widgets of `Box`, `Column`, and `Row`.
- Don't clip elements of `Column` and `Row` layouts whose unbounded size exceeds the container size.
- Correctly implement margins for `Box` on iOS.
- Correctly handle dynamic updates to modifiers on `Column` and `Row`.

Expand Down
7 changes: 7 additions & 0 deletions build-support-ksp-processor/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
plugins {
kotlin("jvm")
}

dependencies {
implementation(libs.kotlin.kspApi)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2024 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package app.cash.redwood.buildsupportksp

import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
import com.google.devtools.ksp.symbol.KSAnnotated

class RedwoodSymbolProcessor(
private val environment: SymbolProcessorEnvironment,
) : SymbolProcessor {
override fun process(resolver: Resolver): List<KSAnnotated> {
SnapshotTestProcessor(environment).process(resolver)

return listOf() // No more rounds of annotation processing.
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (C) 2024 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package app.cash.redwood.buildsupportksp

import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
import com.google.devtools.ksp.processing.SymbolProcessorProvider

class RedwoodSymbolProcessorProvider : SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment) =
RedwoodSymbolProcessor(environment)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2024 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package app.cash.redwood.buildsupportksp

import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
import com.google.devtools.ksp.symbol.KSFunctionDeclaration

/** Confirm all snapshot `@Test` functions also have names starting with `test`. */
internal class SnapshotTestProcessor(
private val environment: SymbolProcessorEnvironment,
) {
fun process(resolver: Resolver) {
// Only run on the first round.
if (!resolver.getNewFiles().iterator().hasNext()) return

checkAllTests(resolver)
}

private fun checkAllTests(resolver: Resolver) {
for (symbol in resolver.getSymbolsWithAnnotation("org.junit.Test")) {
when {
symbol !is KSFunctionDeclaration -> {
environment.logger.info("Unexpected @Test", symbol)
}

!symbol.simpleName.asString().startsWith("test") -> {
environment.logger.error("Expected @Test to start with 'test'", symbol)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
app.cash.redwood.buildsupportksp.RedwoodSymbolProcessorProvider
1 change: 1 addition & 0 deletions build-support/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ apply plugin: 'com.android.lint'
dependencies {
compileOnly gradleApi()
implementation libs.kotlin.gradlePlugin
implementation libs.kotlin.kspGradlePlugin
implementation libs.gradleMavenPublishPlugin
implementation libs.dokkaPlugin
implementation libs.spotlessPlugin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ interface RedwoodBuildExtension {
fun TaskContainer.generateComposeHelpers(packageName: String): TaskProvider<CopyPastaTask>

fun TaskContainer.generateFlexboxHelpers(packageName: String): TaskProvider<CopyPastaTask>

/** Confirm all snapshot `@Test` functions also have names starting with `test`. */
fun sharedSnapshotTests()
}

enum class TargetGroup {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
private const val REDWOOD_GROUP_ID = "app.cash.redwood"

// HEY! If you change the major version update release.yaml doc folder.
private const val REDWOOD_VERSION = "0.15.0-SNAPSHOT"
private const val REDWOOD_VERSION = "0.16.0-SNAPSHOT"

private val isCiEnvironment = System.getenv("CI") == "true"

Expand Down Expand Up @@ -524,6 +524,8 @@ private class RedwoodBuildExtensionImpl(private val project: Project) : RedwoodB
klib.strictValidation = isCiEnvironment

nonPublicMarkers += listOf(
// Codegen-specific API only supports the exact same version as which did the generation.
"app.cash.redwood.RedwoodCodegenApi",
// The yoga module is an implementation detail of our layouts.
"app.cash.redwood.yoga.RedwoodYogaApi",
)
Expand Down Expand Up @@ -647,6 +649,11 @@ private class RedwoodBuildExtensionImpl(private val project: Project) : RedwoodB
it.packageName.set(packageName)
}
}

override fun sharedSnapshotTests() {
project.plugins.apply("com.google.devtools.ksp")
project.dependencies.add("kspJvm", project.project(":build-support-ksp-processor"))
}
}

private val ziplineAttribute = Attribute.of("zipline", String::class.java)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,32 +98,36 @@ internal fun CrossAxisAlignment.toAlignSelf() = when (this) {
*
* Also also note that `Float.NaN` is used by these properties, and that `Float.NaN != Float.NaN`.
* So even deciding whether a value has changed is tricky.
*
* Returns true if the node became dirty as a consequence of this call.
*/
internal fun Node.applyModifier(parentModifier: Modifier, density: Density) {
internal fun Node.applyModifier(parentModifier: Modifier, density: Density): Boolean {
val wasDirty = isDirty()

// Avoid unnecessary mutations to the Node because it marks itself dirty its properties change.
var oldMarginStart = marginStart
val oldMarginStart = marginStart
var newMarginStart = Float.NaN
var oldMarginEnd = marginEnd
val oldMarginEnd = marginEnd
var newMarginEnd = Float.NaN
var oldMarginTop = marginTop
val oldMarginTop = marginTop
var newMarginTop = Float.NaN
var oldMarginBottom = marginBottom
val oldMarginBottom = marginBottom
var newMarginBottom = Float.NaN
var oldAlignSelf = alignSelf
val oldAlignSelf = alignSelf
var newAlignSelf = AlignSelf.Auto
var oldRequestedMinWidth = requestedMinWidth
val oldRequestedMinWidth = requestedMinWidth
var newRequestedMinWidth = Float.NaN
var oldRequestedMaxWidth = requestedMaxWidth
val oldRequestedMaxWidth = requestedMaxWidth
var newRequestedMaxWidth = Float.NaN
var oldRequestedMinHeight = requestedMinHeight
val oldRequestedMinHeight = requestedMinHeight
var newRequestedMinHeight = Float.NaN
var oldRequestedMaxHeight = requestedMaxHeight
val oldRequestedMaxHeight = requestedMaxHeight
var newRequestedMaxHeight = Float.NaN
var oldFlexGrow = flexGrow
val oldFlexGrow = flexGrow
var newFlexGrow = 0f
var oldFlexShrink = flexShrink
val oldFlexShrink = flexShrink
var newFlexShrink = 0f
var oldFlexBasis = flexBasis
val oldFlexBasis = flexBasis
var newFlexBasis = -1f

parentModifier.forEachScoped { childModifier ->
Expand Down Expand Up @@ -193,6 +197,8 @@ internal fun Node.applyModifier(parentModifier: Modifier, density: Density) {
if (newFlexGrow neq oldFlexGrow) flexGrow = newFlexGrow
if (newFlexShrink neq oldFlexShrink) flexShrink = newFlexShrink
if (newFlexBasis neq oldFlexBasis) flexBasis = newFlexBasis

return !wasDirty && isDirty()
}

/**
Expand Down
11 changes: 7 additions & 4 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ kotlin = "2.0.20"
kotlinx-coroutines = "1.9.0"
kotlinx-serialization = "1.7.3"
androidx-activity = "1.9.2"
androidx-compose-ui = "1.7.2"
androidx-compose-ui = "1.7.3"
jbCompose = "1.6.11"
lint = "31.6.1"
ksp = "2.0.20-1.0.25"
lint = "31.7.0"
paparazzi = "1.3.2"
zipline = "1.17.0"
coil = "3.0.0-alpha10"
Expand All @@ -16,6 +17,8 @@ kotlin-compiler = { module = "org.jetbrains.kotlin:kotlin-compiler", version.ref
kotlin-compilerEmbeddable = { module = "org.jetbrains.kotlin:kotlin-compiler-embeddable", version.ref = "kotlin" }
kotlin-composePlugin = { module = "org.jetbrains.kotlin:compose-compiler-gradle-plugin", version.ref = "kotlin" }
kotlin-gradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
kotlin-kspApi = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" }
kotlin-kspGradlePlugin = { module = "com.google.devtools.ksp:symbol-processing-gradle-plugin", version.ref = "ksp" }
kotlin-serializationPlugin = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" }
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
Expand Down Expand Up @@ -65,7 +68,7 @@ jetbrains-compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "
jetbrains-compose-ui-tooling = { module = "org.jetbrains.compose.ui:ui-tooling", version.ref = "jbCompose" }
jetbrains-compose-ui-tooling-preview = { module = "org.jetbrains.compose.ui:ui-tooling-preview", version.ref = "jbCompose" }

androidGradlePlugin = { module = "com.android.tools.build:gradle", version = "8.6.1" }
androidGradlePlugin = { module = "com.android.tools.build:gradle", version = "8.7.0" }
kotlinPoet = { module = "com.squareup:kotlinpoet", version = "1.18.1" }
clikt = "com.github.ajalt.clikt:clikt:5.0.0"
junit = { module = "junit:junit", version = "4.13.2" }
Expand All @@ -87,7 +90,7 @@ coil-core = { module = "io.coil-kt.coil3:coil", version.ref = "coil" }
coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coil" }
turbine = "app.cash.turbine:turbine:1.1.0"
ktlint = "com.pinterest.ktlint:ktlint-cli:1.3.1"
ktlintComposeRules = "io.nlopez.compose.rules:ktlint:0.4.12"
ktlintComposeRules = "io.nlopez.compose.rules:ktlint:0.4.15"
googleJavaFormat = "com.google.googlejavaformat:google-java-format:1.23.0"
poko-gradlePlugin = "dev.drewhamilton.poko:poko-gradle-plugin:0.17.1"

Expand Down
36 changes: 0 additions & 36 deletions redwood-compose/api/android/redwood-compose.api
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,12 @@ public final class app/cash/redwood/compose/BackHandlerKt {
public static final fun getLocalOnBackPressedDispatcher ()Landroidx/compose/runtime/ProvidableCompositionLocal;
}

public abstract interface class app/cash/redwood/compose/Node {
}

public abstract interface class app/cash/redwood/compose/RedwoodApplier {
public abstract fun getWidgetSystem ()Lapp/cash/redwood/widget/WidgetSystem;
public abstract fun recordChanged (Lapp/cash/redwood/widget/Widget;)V
}

public final class app/cash/redwood/compose/RedwoodComposeContent {
public static final field $stable I
public static final field Companion Lapp/cash/redwood/compose/RedwoodComposeContent$Companion;
public fun <init> ()V
public final fun Children (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
}

public final class app/cash/redwood/compose/RedwoodComposeContent$Companion {
public final fun getInstance ()Lapp/cash/redwood/compose/RedwoodComposeContent;
}

public abstract interface class app/cash/redwood/compose/RedwoodComposition {
public abstract fun cancel ()V
public abstract fun setContent (Lkotlin/jvm/functions/Function2;)V
}

public final class app/cash/redwood/compose/RedwoodCompositionKt {
public static final fun RedwoodComposeNode (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;I)V
public static final fun RedwoodComposition (Lkotlinx/coroutines/CoroutineScope;Lapp/cash/redwood/widget/RedwoodView;Lapp/cash/redwood/widget/WidgetSystem;Lkotlin/jvm/functions/Function0;)Lapp/cash/redwood/compose/RedwoodComposition;
public static final fun RedwoodComposition (Lkotlinx/coroutines/CoroutineScope;Lapp/cash/redwood/widget/Widget$Children;Lapp/cash/redwood/ui/OnBackPressedDispatcher;Landroidx/compose/runtime/saveable/SaveableStateRegistry;Lkotlinx/coroutines/flow/StateFlow;Lapp/cash/redwood/widget/WidgetSystem;Lkotlin/jvm/functions/Function0;)Lapp/cash/redwood/compose/RedwoodComposition;
public static synthetic fun RedwoodComposition$default (Lkotlinx/coroutines/CoroutineScope;Lapp/cash/redwood/widget/RedwoodView;Lapp/cash/redwood/widget/WidgetSystem;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lapp/cash/redwood/compose/RedwoodComposition;
Expand All @@ -63,22 +43,6 @@ public final class app/cash/redwood/compose/UiConfigurationKt {
public static final fun getLocalUiConfiguration ()Landroidx/compose/runtime/ProvidableCompositionLocal;
}

public final class app/cash/redwood/compose/WidgetNode : app/cash/redwood/compose/Node {
public static final field $stable I
public static final field Companion Lapp/cash/redwood/compose/WidgetNode$Companion;
public fun <init> (Lapp/cash/redwood/compose/RedwoodApplier;Lapp/cash/redwood/widget/Widget;)V
public final fun getContainer ()Lapp/cash/redwood/widget/Widget$Children;
public final fun getIndex ()I
public final fun getWidget ()Lapp/cash/redwood/widget/Widget;
public final fun recordChanged ()V
public final fun setContainer (Lapp/cash/redwood/widget/Widget$Children;)V
public final fun setIndex (I)V
}

public final class app/cash/redwood/compose/WidgetNode$Companion {
public final fun getSetModifiers ()Lkotlin/jvm/functions/Function2;
}

public final class app/cash/redwood/compose/WidgetVersionKt {
public static final fun getLocalWidgetVersion ()Landroidx/compose/runtime/ProvidableCompositionLocal;
public static final fun getWidgetVersion (Landroidx/compose/runtime/Composer;I)I
Expand Down
Loading

0 comments on commit f79fc34

Please sign in to comment.