Skip to content

Commit

Permalink
misc kdoc progress (#59)
Browse files Browse the repository at this point in the history
* kdoc WIP

* misc kdoc progress

* Update build.gradle.kts

* Update TangleGraph.kt

* Update tangle.kt

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
RBusarow and kodiakhq[bot] authored Jul 22, 2021
1 parent dfbda73 commit 1402de3
Show file tree
Hide file tree
Showing 15 changed files with 269 additions and 23 deletions.
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ buildscript {
classpath("com.vanniktech:gradle-maven-publish-plugin:0.17.0")
classpath("org.jetbrains.kotlinx:kotlinx-knit:0.3.0")
classpath("org.jlleitschuh.gradle:ktlint-gradle:10.1.0")
classpath("com.squareup.anvil:gradle-plugin:2.3.3")
}
}

Expand Down
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ include(
":tangle-gradle-plugin",
":tangle-test-utils",
":tangle-viewmodel-api",
":tangle-viewmodel-api:samples",
":tangle-viewmodel-compiler",
":tangle-viewmodel-compose",
":tangle-viewmodel-tests"
Expand Down
38 changes: 38 additions & 0 deletions tangle-viewmodel-api/samples/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (C) 2021 Rick Busarow
* 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.
*/

plugins {
androidLibrary
kotlin("kapt")
id("com.squareup.anvil")
}

dependencies {

anvil(projects.tangleViewmodelCompiler)

kaptTest(libs.google.dagger.compiler)

testImplementation(libs.google.dagger.api)
testImplementation(libs.junit.vintage)
testImplementation(libs.kotest.assertions)
testImplementation(libs.kotest.properties)
testImplementation(libs.kotest.runner)
testImplementation(libs.kotlinx.coroutines.core)
testImplementation(libs.kotlinx.coroutines.test)
testImplementation(libs.robolectric)
testImplementation(projects.tangleApi)
testImplementation(projects.tangleViewmodelApi)
}
16 changes: 16 additions & 0 deletions tangle-viewmodel-api/samples/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!--
~ Copyright (C) 2021 Rick Busarow
~ 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.
-->

<manifest package="tangle.viewmodel.api.samples"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package samples

import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import tangle.viewmodel.ContributesViewModel
import tangle.viewmodel.VMInject
import tangle.viewmodel.tangle

public class TangleFragmentDelegateSample {

@Sample
public fun byTangleSample() {
class MyFragment : Fragment() {

val viewModel: MyViewModel by tangle()
}
}
}

@ContributesViewModel(Unit::class)
public class MyViewModel @VMInject constructor() : ViewModel()
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (C) 2021 Rick Busarow
* 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 samples

import android.app.Application
import dagger.BindsInstance
import dagger.Component
import tangle.viewmodel.TangleGraph

public class TangleGraphSample {

@Sample
public fun initializeTangleGraph() {
class MyApplication : Application() {

override fun onCreate() {
super.onCreate()

val appComponent = DaggerMyAppComponent.factory()
.create(this)

TangleGraph.init(appComponent)
}
}
}
}

@Component
public interface MyAppComponent {
@Component.Factory
public interface Factory {

public fun create(@BindsInstance application: Application): MyAppComponent
}
}
27 changes: 27 additions & 0 deletions tangle-viewmodel-api/samples/src/test/java/samples/_utils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (C) 2021 Rick Busarow
* 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.
*/

@file:Suppress("EXPERIMENTAL_API_USAGE")

package samples

import io.kotest.matchers.shouldBe
import org.junit.Test

public typealias Sample = Test

public infix fun Any?.shouldPrint(
expected: String
): Unit = toString() shouldBe expected

This file was deleted.

45 changes: 45 additions & 0 deletions tangle-viewmodel-api/src/main/java/tangle/viewmodel/TangleGraph.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package tangle.viewmodel

import tangle.inject.InternalTangleApi

/**
* Holds a reference to the application's Dagger graph,
* so that it can be accessed by [TangleViewModelFactory].
*
* This should be initialized as soon as possible after initializing the AppComponent.
*
* @sample samples.TangleGraphSample.initializeTangleGraph
* @since 0.10.0
*/
public object TangleGraph {

@PublishedApi
@Suppress("ObjectPropertyNaming")
internal val _components: MutableSet<Any> = mutableSetOf()

/**
* Sets a reference to the application's Dagger graph,
* so that it can be accessed by [TangleViewModelFactory].
*
* This should be initialized as soon as possible after initializing the AppComponent.
*
* @sample samples.TangleGraphSample.initializeTangleGraph
* @param component the application-scoped Dagger component
* @since 0.10.0
*/
public fun init(component: Any) {
_components.add(component)
}

/**
* Used to retrieve a Component of a given type.
*
* This is an internal Tangle API and may change at any time.
*
* @since 0.10.0
*/
@InternalTangleApi
public inline fun <reified T> get(): T = _components
.filterIsInstance<T>()
.single()
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,33 @@ package tangle.viewmodel
import androidx.lifecycle.ViewModel
import tangle.inject.InternalTangleApi

/**
* Used to provide a way of retrieving [TangleViewModelSubcomponent.Factory]
* from a main app [Component][dagger.Component].
*
* Also provides [viewModelKeys] for use in the [TangleViewModelFactory]
*
* @since 0.10.0
*/
public interface TangleViewModelComponent {
/**
* Referenced by [TangleViewModelFactory] in order to create
* a scoped [TangleViewModelSubcomponent], in order to access the [TangleViewModelProviderMap].
*
* @since 0.10.0
*/
public val tangleViewModelSubcomponentFactory: TangleViewModelSubcomponent.Factory

/**
* Copy of all the keys contained in [TangleViewModelProviderMap].
* [TangleViewModelProviderMap] is only provided by [TangleViewModelSubcomponent],
* and a new subcomponent needs to be created for each viewModel injection, so it's inefficient
* to create the object before we know if the map holds the [ViewModel].
* The [TangleViewModelFactory] checks this Set in order to determine whether the map
* holds a particular ViewModel type.
*
* @since 0.10.0
*/
@OptIn(InternalTangleApi::class)
@get:TangleViewModelProviderMap.KeySet
public val viewModelKeys: Set<Class<out ViewModel>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import androidx.lifecycle.ViewModelProvider
import androidx.savedstate.SavedStateRegistryOwner
import tangle.inject.InternalTangleApi

/** @suppress */
@InternalTangleApi
public class TangleViewModelFactory(
owner: SavedStateRegistryOwner,
Expand All @@ -31,14 +32,15 @@ public class TangleViewModelFactory(
private val delegateFactory: ViewModelProvider.Factory
) : ViewModelProvider.Factory {

/** @suppress */
private val tangleFactory: AbstractSavedStateViewModelFactory =
object : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
override fun <T : ViewModel?> create(
key: String,
modelClass: Class<T>,
handle: SavedStateHandle
): T {
val component = TangleComponents
val component = TangleGraph
.get<TangleViewModelComponent>()
.tangleViewModelSubcomponentFactory
.create(handle)
Expand All @@ -57,6 +59,7 @@ public class TangleViewModelFactory(
}
}

/** @suppress */
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return if (tangleViewModelKeys.contains(modelClass)) {
tangleFactory.create(modelClass)
Expand All @@ -65,14 +68,16 @@ public class TangleViewModelFactory(
}
}

/** @suppress */
public companion object {

/** @suppress */
public operator fun invoke(
owner: SavedStateRegistryOwner,
defaultArgs: Bundle?,
defaultFactory: ViewModelProvider.Factory
): ViewModelProvider.Factory {
val keys = TangleComponents.get<TangleViewModelComponent>()
val keys = TangleGraph.get<TangleViewModelComponent>()
.viewModelKeys

return TangleViewModelFactory(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
package tangle.viewmodel

import androidx.lifecycle.ViewModel
import javax.inject.Qualifier

/**
* Qualifier for the internal `Map<KClass<ViewModel>, ViewModel>>`
* used in Tangle's [ViewModel][androidx.lifecycle.ViewModel] multi-binding.
*
* This is an internal Tangle API and should not be referenced directly.
*
* @since 0.10.0
*/
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.FIELD, AnnotationTarget.FUNCTION)
public annotation class TangleViewModelProviderMap {

/**
* Qualifier for all the keys contained in [TangleViewModelProviderMap].
* [TangleViewModelProviderMap] is only provided by [TangleViewModelSubcomponent],
* and a new subcomponent needs to be created for each viewModel injection, so it's inefficient
* to create the object before we know if the map holds the [ViewModel].
* The [TangleViewModelFactory] checks this Set in order to determine whether the map
* holds a particular ViewModel type.
*
* This is an internal Tangle API and should not be referenced directly.
*
* @since 0.10.0
*/
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.FIELD, AnnotationTarget.FUNCTION)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,25 @@ import androidx.lifecycle.ViewModel
import tangle.inject.InternalTangleApi
import javax.inject.Provider

/**
* Internal-use [Subcomponent][dagger.Subcomponent] which provides a map
* of [ViewModel]s to the [TangleViewModelFactory].
*
* A new Subcomponent is created each time a `ViewModel` is injected,
* and the Subcomponent is scoped to the corresponding [LifecycleOwner][androidx.lifecycle.LifecycleOwner].
*
* @since 0.10.0
*/
public interface TangleViewModelSubcomponent {
/** @suppress */
@OptIn(InternalTangleApi::class)
@get:TangleViewModelProviderMap
public val viewModelProviderMap:
Map<Class<out ViewModel>, Provider<@JvmSuppressWildcards ViewModel>>

/** @suppress */
public interface Factory {
/** @suppress */
public fun create(savedStateHandle: SavedStateHandle):
TangleViewModelSubcomponent
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import androidx.lifecycle.ViewModel
import dagger.MapKey
import kotlin.reflect.KClass

/** @suppress */
@Target(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
Expand Down
Loading

0 comments on commit 1402de3

Please sign in to comment.