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

Implement hierarchy helper functions #190

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Implement helper hierarchy functions
  • Loading branch information
Maxime Michel committed Jul 22, 2022
commit 9b5343912810658e96dcb35c0fcea1b78cd576d9
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,4 @@ fun String.sanitizePackageName(): String {
}

private val humps = "(?<=.)(?=\\p{Upper})".toRegex()
fun String.toSnakeCase() = replace(humps, "_").lowercase(Locale.US)

fun String.asNavGraphName(): String {
var lower = this.lowercase(Locale.US)
lower = lower.replace("navgraph", "")
return this.substring(0, lower.length).replaceFirstChar { it.lowercase() }
}
fun String.toSnakeCase() = replace(humps, "_").lowercase(Locale.US)
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ data class NavGraphGeneratingParams(
val destinations: List<GeneratedDestination>,
val startRouteFieldName: String,
val nestedNavGraphRoutes: List<String>,
val requireOptInAnnotationTypes: Set<Importable>,
val parent: String?
val requireOptInAnnotationTypes: Set<Importable>
)
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import com.ramcosta.composedestinations.codegen.templates.core.setOfImportable
const val DESTINATION_NAME = "[DESTINATION_NAME]"
const val BASE_ROUTE = "[ROUTE_ID]"
const val COMPOSED_ROUTE = "[COMPOSED_ROUTE]"
const val DESTINATION_PARENT = "[DESTINATION_PARENT]"
const val NAV_ARGUMENTS = "[NAV_ARGUMENTS]"
const val DEEP_LINKS = "[DEEP_LINKS]"
const val DESTINATION_STYLE = "[DESTINATION_STYLE]"
Expand Down Expand Up @@ -48,8 +47,6 @@ ${REQUIRE_OPT_IN_ANNOTATIONS_PLACEHOLDER}object $DESTINATION_NAME : $SUPERTYPE {
override val baseRoute = "$BASE_ROUTE"

override val route = $COMPOSED_ROUTE

override val parent = $DESTINATION_PARENT
$NAV_ARGUMENTS$DEEP_LINKS$DESTINATION_STYLE
@Composable
override fun DestinationScope<$NAV_ARGS_CLASS_SIMPLE_NAME>.Content(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,39 @@ data class $GENERATED_NAV_GRAPH(
override val route: String,
override val startRoute: Route,
val destinations: List<$typeAliasDestination>,
override val nestedNavGraphs: List<$GENERATED_NAV_GRAPH> = emptyList(),
override val parent: String?
override val nestedNavGraphs: List<$GENERATED_NAV_GRAPH> = emptyList()
): $CORE_NAV_GRAPH_SPEC {
override val destinationsByRoute: Map<String, $typeAliasDestination> = destinations.associateBy { it.route }
}

val DestinationSpec<*>.parent: NavGraph
get() {
val parent = NavGraphs.all.find {
it.destinations.contains(this)
}

return parent
?: throw InvalidObjectException("The calling object should always have a parent!")
/**
* Return the parent of this [Destination][DestinationSpec] by searching through the [NavGraph]s in
* the [NavGraphs] object.
*
* This variable should **NEVER** be null. If `first { ... }` throws a [NoSuchElementException], it
* means this [Destination][DestinationSpec] somehow isn't part of a [NavGraph].
*/
val $CORE_DESTINATION_SPEC<*>.parent: $GENERATED_NAV_GRAPH
get() = $GENERATED_NAV_GRAPHS_OBJECT.all.first {
it.destinations.contains(this)
}

val $CORE_NAV_GRAPH_SPEC.parent: NavGraph?
get() = NavGraphs.all.find {
/**
* Return the parent of this [NavGraphSpec] by searching through the [NavGraph]s'
* [NavGraph.nestedNavGraphs] in the [NavGraphs] object.
*/
val $CORE_NAV_GRAPH_SPEC.parent: $GENERATED_NAV_GRAPH?
get() = $GENERATED_NAV_GRAPHS_OBJECT.all.find {
it.nestedNavGraphs.contains(this)
}

/**
* Provides a sequence of the [DestinationSpec]'s hierarchy. The hierarchy starts with this
* [DestinationSpec]'s [parent][DestinationSpec.parent] [NavGraph], then that graph's parent, and up
* the hierarchy until you've reached the root navigation graph.
*/
val $CORE_DESTINATION_SPEC<*>.hierarchy: Sequence<$GENERATED_NAV_GRAPH>
get() = generateSequence(this.parent) { it.parent }

/**
* If this [Route] is a [$typeAliasDestination], returns it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ class SingleDestinationWriter(
.replace(BASE_ROUTE, destination.cleanRoute)
.replace(NAV_ARGS_CLASS_SIMPLE_NAME, navArgsDataClassName())
.replace(COMPOSED_ROUTE, constructRouteFieldCode())
.replace(DESTINATION_PARENT, parentNavGraph())
.replace(NAV_ARGUMENTS, navArgumentsDeclarationCode())
.replace(DEEP_LINKS, deepLinksDeclarationCode())
.replace(DESTINATION_STYLE, destinationStyle())
Expand Down Expand Up @@ -354,30 +353,6 @@ class SingleDestinationWriter(
).write()
}

private fun parentNavGraph(): String {
return when (val navGraph = destination.navGraphInfo) {
is NavGraphInfo.Legacy -> {
// Get the NavGraph object from its route
importableHelper.addAndGetPlaceholder(
Importable(
navGraph.navGraphRoute,
"$codeGenBasePackageName.$GENERATED_NAV_GRAPHS_OBJECT.${navGraph.navGraphRoute}"
)
)
}
is NavGraphInfo.AnnotatedSource -> {
// Get the NavGraph object from its route too
navGraph.graphType.toString()
importableHelper.addAndGetPlaceholder(
Importable(
navGraph.graphType.simpleName.asNavGraphName(),
"$codeGenBasePackageName.$GENERATED_NAV_GRAPHS_OBJECT.${navGraph.graphType.simpleName.asNavGraphName()}"
)
)
}
}
}

private fun navArgumentsDeclarationCode(): String {
val code = StringBuilder()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,13 @@ class LegacyNavGraphsSingleObjectWriter(
val nestedGraphsAnchor = "[NESTED_GRAPHS]"
val requireOptInAnnotationsAnchor = "[REQUIRE_OPT_IN_ANNOTATIONS_ANCHOR]"

val parent = if (route == "root") "null" else "\"${navGraphParams.parent}\""

return """
| ${requireOptInAnnotationsAnchor}val ${navGraphFieldName(route)} = $GENERATED_NAV_GRAPH(
| route = "$route",
| startRoute = ${startRouteFieldName},
| destinations = listOf(
| $destinationsAnchor
| )${if (nestedNavGraphRoutes.isEmpty()) "" else ",\n|\t\t$nestedGraphsAnchor"},
| parent = $parent
| )${if (nestedNavGraphRoutes.isEmpty()) "" else ",\n|\t\t$nestedGraphsAnchor"}
| )
""".trimMargin()
.replace(destinationsAnchor, destinationsInsideList(destinations))
Expand Down Expand Up @@ -158,8 +155,7 @@ class LegacyNavGraphsSingleObjectWriter(
destinations = it.value,
startRouteFieldName = legacyStartingDestination(navGraphRoute, it.value),
nestedNavGraphRoutes = emptyList(),
requireOptInAnnotationTypes = requireOptInClassTypes,
parent = it.key
requireOptInAnnotationTypes = requireOptInClassTypes
)
)
}
Expand All @@ -172,8 +168,7 @@ class LegacyNavGraphsSingleObjectWriter(
nestedNavGraphRoutes = nestedNavGraphs,
requireOptInAnnotationTypes = rootDestinations.orEmpty()
.requireOptInAnnotationClassTypes()
.apply { addAll(nestedNavGraphsRequireOptInAnnotations) },
parent = null
.apply { addAll(nestedNavGraphsRequireOptInAnnotations) }
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ class NavGraphsSingleObjectWriter(
nestedNavGraphs.forEach {
addAll(destinationsByNavGraphParams[it]!!.requireOptInAnnotationClassTypes())
}
},
parent = rawGraph.parent?.simpleName?.asNavGraphName()
}
)
}

Expand Down Expand Up @@ -115,16 +114,13 @@ class NavGraphsSingleObjectWriter(
val nestedGraphsAnchor = "[NESTED_GRAPHS]"
val requireOptInAnnotationsAnchor = "[REQUIRE_OPT_IN_ANNOTATIONS_ANCHOR]"

val parent = if (route == "root") "null" else "\"${navGraphParams.parent}\""

return """
| ${requireOptInAnnotationsAnchor}val ${navGraphFieldName(route)} = $GENERATED_NAV_GRAPH(
| route = "$route",
| startRoute = ${startRouteFieldName},
| destinations = listOf(
| $destinationsAnchor
| )${if (nestedNavGraphRoutes.isEmpty()) "" else ",\n|\t\t$nestedGraphsAnchor"},
| parent = $parent
| )${if (nestedNavGraphRoutes.isEmpty()) "" else ",\n|\t\t$nestedGraphsAnchor"}
| )
""".trimMargin()
.replace(destinationsAnchor, destinationsInsideList(destinations))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ infix fun <T> DestinationSpec<T>.routedIn(navGraph: NavGraphSpec): DestinationSp
override val route = "${navGraph.route}/${[email protected]}"

override val originalDestination = [email protected]

override val parent: NavGraphSpec = navGraph
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,6 @@ interface DestinationSpec<T> : Route {
*/
val deepLinks: List<NavDeepLink> get() = emptyList()

/**
* The parent [NavGraph][NavGraphSpec] of the current destination
*/
val parent: NavGraphSpec

/**
* Style of this destination. It can be one of:
* - [DestinationStyle.Default]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ interface NavGraphSpec: Direction, Route {
*/
val startRoute: Route

/**
* The parent route of the current NavGraph if any
*/
val parent: String?

/**
* All destinations which belong to this navigation graph
* by their route
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.ramcosta.composedestinations.spec.DestinationSpec
import com.ramcosta.samples.playground.R
import com.ramcosta.samples.playground.ui.screens.NavGraph
import com.ramcosta.samples.playground.ui.screens.NavGraphs
import com.ramcosta.samples.playground.ui.screens.destinations.*
import java.io.InvalidObjectException

@Composable
fun DirectionDestination.DrawerContent(
Expand Down Expand Up @@ -59,13 +55,4 @@ val Destination.title
TestScreenDestination -> null
TestScreen2Destination -> null
}
}

val DestinationSpec<*>.parent: NavGraph
get() {
val parent = NavGraphs.all.find {
it.destinations.contains(this)
}

return parent ?: throw InvalidObjectException("The calling object should always have a parent!")
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.ramcosta.samples.playground.ui.screens.settings

import android.widget.Toast
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.Button
Expand All @@ -10,16 +9,12 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.result.ResultBackNavigator
import com.ramcosta.composedestinations.spec.DestinationSpec
import com.ramcosta.composedestinations.spec.DestinationStyle
import com.ramcosta.composedestinations.spec.NavGraphSpec
import com.ramcosta.samples.playground.commons.SettingsNavGraph
import com.ramcosta.samples.playground.commons.findDestinationParentNavGraph
import com.ramcosta.samples.playground.commons.requireTitle
import com.ramcosta.samples.playground.ui.screens.destinations.ThemeSettingsDestination
import com.ramcosta.samples.playground.ui.screens.profile.SerializableExampleWithNavTypeSerializer
Expand All @@ -31,10 +26,6 @@ fun ColumnScope.ThemeSettings(
viewModel: SettingsViewModel,
resultNavigator: ResultBackNavigator<SerializableExampleWithNavTypeSerializer>
) {
val context = LocalContext.current

Toast.makeText(context, "Hierarchy: ${ThemeSettingsDestination.findDestinationParentNavGraph()}", Toast.LENGTH_LONG).show()

Box(
Modifier
.fillMaxWidth()
Expand Down
18 changes: 0 additions & 18 deletions sample/src/main/java/com/ramcosta/destinations/sample/TempUtils.kt

This file was deleted.