Skip to content

Commit 2e92074

Browse files
Spotless
1 parent 74c18d5 commit 2e92074

File tree

23 files changed

+147
-99
lines changed

23 files changed

+147
-99
lines changed

app/src/main/java/io/getstream/android/core/sample/client/StreamClient.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import io.getstream.android.core.api.socket.monitor.StreamHealthMonitor
3737
import io.getstream.android.core.api.subscribe.StreamSubscriptionManager
3838
import kotlinx.coroutines.CoroutineScope
3939

40-
/**
40+
/**
4141
* Creates a [createStreamClient] instance with the given configuration and dependencies.
4242
*
4343
* @param scope The coroutine scope.

buildSrc/src/main/kotlin/io/getstream/core/Configuration.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* https://github.com/GetStream/stream-feeds-android/blob/main/LICENSE
8+
* https://github.com/GetStream/stream-core-android/blob/main/LICENSE
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,

stream-android-core-annotations/src/main/java/io/getstream/android/core/annotations/StreamApiMarkers.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ annotation class StreamInternalApi
8888
annotation class StreamDelicateApi(val message: String)
8989

9090
/**
91-
* Marks APIs that are part of the **Stream core SDK layer**.
92-
* This API can be safely published and used by other Stream SDKs. They can also be propagated and exposed via
93-
* public APIs of the product SDKs.
91+
* Marks APIs that are part of the **Stream core SDK layer**. This API can be safely published and
92+
* used by other Stream SDKs. They can also be propagated and exposed via public APIs of the product
93+
* SDKs.
9494
*/
9595
@Target(
9696
AnnotationTarget.CLASS,

stream-android-core-lint/src/main/java/io/getstream/android/core/lint/StreamIssueRegistry.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class StreamIssueRegistry : IssueRegistry() {
3434
KeepInstanceDetector.ISSUE,
3535
SuspendRunCatchingDetector.ISSUE,
3636
ExposeAsStateFlowDetector.ISSUE,
37-
StreamApiExplicitMarkerDetector.ISSUE
37+
StreamApiExplicitMarkerDetector.ISSUE,
3838
)
3939

4040
override val vendor =
Lines changed: 133 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
/*
2+
* Copyright (c) 2014-2025 Stream.io Inc. All rights reserved.
3+
*
4+
* Licensed under the Stream License;
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://github.com/GetStream/stream-core-android/blob/main/LICENSE
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
116
package io.getstream.android.core.lint.detectors
217

318
import com.android.tools.lint.client.api.UElementHandler
@@ -8,38 +23,38 @@ import org.jetbrains.uast.*
823

924
class StreamApiExplicitMarkerDetector : Detector(), Detector.UastScanner {
1025

11-
override fun getApplicableUastTypes() = listOf(
12-
UClass::class.java, UMethod::class.java, UField::class.java, UFile::class.java
13-
)
26+
override fun getApplicableUastTypes() =
27+
listOf(UClass::class.java, UMethod::class.java, UField::class.java, UFile::class.java)
1428

15-
override fun createUastHandler(context: JavaContext) = object : UElementHandler() {
16-
override fun visitClass(node: UClass) {
17-
val uFile = node.getContainingUFileOrNull() ?: return
18-
if (!context.packageMatchesConfig(uFile.packageName)) return
19-
checkUAnnotated(context, node, node.sourcePsi as? KtDeclaration)
20-
}
29+
override fun createUastHandler(context: JavaContext) =
30+
object : UElementHandler() {
31+
override fun visitClass(node: UClass) {
32+
val uFile = node.getContainingUFileOrNull() ?: return
33+
if (!context.packageMatchesConfig(uFile.packageName)) return
34+
checkUAnnotated(context, node, node.sourcePsi as? KtDeclaration)
35+
}
2136

22-
override fun visitMethod(node: UMethod) {
23-
val uFile = node.getContainingUFileOrNull() ?: return
24-
if (!context.packageMatchesConfig(uFile.packageName)) return
25-
checkUAnnotated(context, node, node.sourcePsi as? KtNamedFunction)
26-
}
37+
override fun visitMethod(node: UMethod) {
38+
val uFile = node.getContainingUFileOrNull() ?: return
39+
if (!context.packageMatchesConfig(uFile.packageName)) return
40+
checkUAnnotated(context, node, node.sourcePsi as? KtNamedFunction)
41+
}
2742

28-
override fun visitField(node: UField) {
29-
val uFile = node.getContainingUFileOrNull() ?: return
30-
if (!context.packageMatchesConfig(uFile.packageName)) return
31-
checkUAnnotated(context, node, node.sourcePsi as? KtProperty)
32-
}
43+
override fun visitField(node: UField) {
44+
val uFile = node.getContainingUFileOrNull() ?: return
45+
if (!context.packageMatchesConfig(uFile.packageName)) return
46+
checkUAnnotated(context, node, node.sourcePsi as? KtProperty)
47+
}
3348

34-
override fun visitFile(node: UFile) {
35-
val ktFile = node.sourcePsi as? KtFile ?: return
36-
val pkg = ktFile.packageFqName.asString()
37-
if (!context.packageMatchesConfig(pkg)) return
38-
ktFile.declarations.filterIsInstance<KtTypeAlias>().forEach { alias ->
39-
checkTypeAlias(context, alias)
49+
override fun visitFile(node: UFile) {
50+
val ktFile = node.sourcePsi as? KtFile ?: return
51+
val pkg = ktFile.packageFqName.asString()
52+
if (!context.packageMatchesConfig(pkg)) return
53+
ktFile.declarations.filterIsInstance<KtTypeAlias>().forEach { alias ->
54+
checkTypeAlias(context, alias)
55+
}
4056
}
4157
}
42-
}
4358

4459
private fun checkUAnnotated(context: JavaContext, u: UElement, kt: KtDeclaration?) {
4560
kt ?: return
@@ -58,33 +73,69 @@ class StreamApiExplicitMarkerDetector : Detector(), Detector.UastScanner {
5873

5974
private fun reportWithDualFix(context: JavaContext, node: KtTypeAlias, decl: KtDeclaration) {
6075
val loc = context.getLocation(decl)
61-
val fixPublished = LintFix.create().name("Annotate with @$PUBLISHED_SIMPLE")
62-
.replace().range(loc).pattern("^").with("@$PUBLISHED_FQ\n")
63-
.reformat(true).shortenNames().autoFix().build()
64-
val fixInternal = LintFix.create().name("Annotate with @$INTERNAL_SIMPLE")
65-
.replace().range(loc).pattern("^").with("@$INTERNAL_FQ\n")
66-
.reformat(true).shortenNames().autoFix().build()
76+
val fixPublished =
77+
LintFix.create()
78+
.name("Annotate with @$PUBLISHED_SIMPLE")
79+
.replace()
80+
.range(loc)
81+
.pattern("^")
82+
.with("@$PUBLISHED_FQ\n")
83+
.reformat(true)
84+
.shortenNames()
85+
.autoFix()
86+
.build()
87+
val fixInternal =
88+
LintFix.create()
89+
.name("Annotate with @$INTERNAL_SIMPLE")
90+
.replace()
91+
.range(loc)
92+
.pattern("^")
93+
.with("@$INTERNAL_FQ\n")
94+
.reformat(true)
95+
.shortenNames()
96+
.autoFix()
97+
.build()
6798

6899
context.report(
69-
ISSUE, node, loc,
100+
ISSUE,
101+
node,
102+
loc,
70103
"Public API must be explicitly marked with @$PUBLISHED_SIMPLE or @$INTERNAL_SIMPLE.",
71-
LintFix.create().group(fixPublished, fixInternal)
104+
LintFix.create().group(fixPublished, fixInternal),
72105
)
73106
}
74107

75108
private fun reportWithDualFix(context: JavaContext, node: UElement, decl: KtDeclaration) {
76109
val loc = context.getLocation(decl)
77-
val fixPublished = LintFix.create().name("Annotate with @$PUBLISHED_SIMPLE")
78-
.replace().range(loc).pattern("^").with("@$PUBLISHED_FQ\n")
79-
.reformat(true).shortenNames().autoFix().build()
80-
val fixInternal = LintFix.create().name("Annotate with @$INTERNAL_SIMPLE")
81-
.replace().range(loc).pattern("^").with("@$INTERNAL_FQ\n")
82-
.reformat(true).shortenNames().autoFix().build()
110+
val fixPublished =
111+
LintFix.create()
112+
.name("Annotate with @$PUBLISHED_SIMPLE")
113+
.replace()
114+
.range(loc)
115+
.pattern("^")
116+
.with("@$PUBLISHED_FQ\n")
117+
.reformat(true)
118+
.shortenNames()
119+
.autoFix()
120+
.build()
121+
val fixInternal =
122+
LintFix.create()
123+
.name("Annotate with @$INTERNAL_SIMPLE")
124+
.replace()
125+
.range(loc)
126+
.pattern("^")
127+
.with("@$INTERNAL_FQ\n")
128+
.reformat(true)
129+
.shortenNames()
130+
.autoFix()
131+
.build()
83132

84133
context.report(
85-
ISSUE, node, loc,
134+
ISSUE,
135+
node,
136+
loc,
86137
"Public API must be explicitly marked with @$PUBLISHED_SIMPLE or @$INTERNAL_SIMPLE.",
87-
LintFix.create().group(fixPublished, fixInternal)
138+
LintFix.create().group(fixPublished, fixInternal),
88139
)
89140
}
90141

@@ -94,16 +145,13 @@ class StreamApiExplicitMarkerDetector : Detector(), Detector.UastScanner {
94145
val patterns = configuredPackageGlobs()
95146

96147
// Default if not configured → only io.getstream.android.core.*
97-
val effectivePatterns = patterns.ifEmpty {
98-
listOf("io.getstream.android.core.api")
99-
}
148+
val effectivePatterns = patterns.ifEmpty { listOf("io.getstream.android.core.api") }
100149

101150
val included = effectivePatterns.any { pkgMatchesGlob(pkg, it) }
102151
val excluded = packageMatchesExcludeConfig(pkg)
103152
return included && !excluded
104153
}
105154

106-
107155
private fun JavaContext.packageMatchesExcludeConfig(pkg: String): Boolean {
108156
val raw = configuration.getOption(ISSUE, OPTION_PACKAGES_EXCLUDE.name, "")?.trim().orEmpty()
109157
if (raw.isEmpty()) return false
@@ -142,7 +190,7 @@ class StreamApiExplicitMarkerDetector : Detector(), Detector.UastScanner {
142190
private fun KtAnnotated.hasAnyAnnotationPsi(simpleNames: Set<String>): Boolean =
143191
annotationEntries.any { entry ->
144192
entry.shortName?.asString() in simpleNames ||
145-
entry.typeReference?.text in simpleNames // handles rare fully-qualified usage
193+
entry.typeReference?.text in simpleNames // handles rare fully-qualified usage
146194
}
147195

148196
private fun UElement.getContainingUFileOrNull(): UFile? {
@@ -157,10 +205,11 @@ class StreamApiExplicitMarkerDetector : Detector(), Detector.UastScanner {
157205
private fun KtDeclaration.isTopLevelPublic(): Boolean {
158206
if (parent !is KtFile) return false
159207
val mods = modifierList
160-
val isPublic = mods?.hasModifier(KtTokens.PUBLIC_KEYWORD) == true ||
208+
val isPublic =
209+
mods?.hasModifier(KtTokens.PUBLIC_KEYWORD) == true ||
161210
!(mods?.hasModifier(KtTokens.PRIVATE_KEYWORD) == true ||
162-
mods?.hasModifier(KtTokens.PROTECTED_KEYWORD) == true ||
163-
mods?.hasModifier(KtTokens.INTERNAL_KEYWORD) == true)
211+
mods?.hasModifier(KtTokens.PROTECTED_KEYWORD) == true ||
212+
mods?.hasModifier(KtTokens.INTERNAL_KEYWORD) == true)
164213
return isPublic
165214
}
166215

@@ -172,40 +221,50 @@ class StreamApiExplicitMarkerDetector : Detector(), Detector.UastScanner {
172221
private val MARKERS = setOf(PUBLISHED_FQ, INTERNAL_FQ)
173222
private val MARKERS_SIMPLE = setOf(PUBLISHED_SIMPLE, INTERNAL_SIMPLE)
174223

175-
private val OPTION_PACKAGES = StringOption(
176-
name = "packages",
177-
description = "Comma-separated package **glob** patterns where the rule applies.",
178-
explanation = """
224+
private val OPTION_PACKAGES =
225+
StringOption(
226+
name = "packages",
227+
description = "Comma-separated package **glob** patterns where the rule applies.",
228+
explanation =
229+
"""
179230
Supports wildcards: '*' (any sequence) and '?' (single char).
180231
Examples:
181232
- 'io.getstream.android.core.api'
182233
- 'io.getstream.android.core.*.api'
183234
- 'io.getstream.android.*'
184-
""".trimIndent()
185-
)
186-
187-
private val OPTION_PACKAGES_EXCLUDE = StringOption(
188-
name = "exclude_packages",
189-
description = "Comma-separated package **glob** patterns to exclude from the rule.",
190-
explanation = """
235+
"""
236+
.trimIndent(),
237+
)
238+
239+
private val OPTION_PACKAGES_EXCLUDE =
240+
StringOption(
241+
name = "exclude_packages",
242+
description = "Comma-separated package **glob** patterns to exclude from the rule.",
243+
explanation =
244+
"""
191245
Same glob syntax as 'packages'. Evaluated after includes.
192-
""".trimIndent()
193-
)
246+
"""
247+
.trimIndent(),
248+
)
194249

195-
private val IMPLEMENTATION = Implementation(
196-
StreamApiExplicitMarkerDetector::class.java,
197-
Scope.JAVA_FILE_SCOPE
198-
)
250+
private val IMPLEMENTATION =
251+
Implementation(StreamApiExplicitMarkerDetector::class.java, Scope.JAVA_FILE_SCOPE)
199252

200253
@JvmField
201-
val ISSUE: Issue = Issue.create(
202-
"StreamApiExplicitMarkerMissing",
203-
"Public API must be explicitly marked",
204-
"""
254+
val ISSUE: Issue =
255+
Issue.create(
256+
"StreamApiExplicitMarkerMissing",
257+
"Public API must be explicitly marked",
258+
"""
205259
To prevent accidental exposure, all top-level public declarations must be explicitly \
206260
marked as @StreamPublishedApi (allowed to leak) or @StreamInternalApi (not allowed to leak).
207-
""".trimIndent(),
208-
Category.CORRECTNESS, 7, Severity.ERROR, IMPLEMENTATION
209-
).setOptions(listOf(OPTION_PACKAGES, OPTION_PACKAGES_EXCLUDE))
261+
"""
262+
.trimIndent(),
263+
Category.CORRECTNESS,
264+
7,
265+
Severity.ERROR,
266+
IMPLEMENTATION,
267+
)
268+
.setOptions(listOf(OPTION_PACKAGES, OPTION_PACKAGES_EXCLUDE))
210269
}
211270
}

stream-android-core/src/main/java/io/getstream/android/core/api/http/StreamOkHttpInterceptors.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import io.getstream.android.core.internal.http.interceptor.StreamClientInfoInter
2727
import io.getstream.android.core.internal.http.interceptor.StreamConnectionIdInterceptor
2828
import io.getstream.android.core.internal.http.interceptor.StreamEndpointErrorInterceptor
2929
import okhttp3.Interceptor
30+
3031
/**
3132
* Provides a set of OkHttp interceptors for use with the Stream SDKs.
3233
*

stream-android-core/src/main/java/io/getstream/android/core/api/model/StreamTypedKey.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ public data class StreamTypedKey<T>(val id: Any) {
3232
* @return A new [StreamTypedKey] with the given [id] and type [T].
3333
* @receiver id The unique identifier for the key.
3434
*/
35-
public inline fun <reified T> Any.asStreamTypedKey(): StreamTypedKey<T> = StreamTypedKey(this)
35+
public inline fun <reified T> Any.asStreamTypedKey(): StreamTypedKey<T> =
36+
StreamTypedKey(this)
3637

3738
/**
3839
* Creates a new [StreamTypedKey] with a random [id] and type [T].

stream-android-core/src/main/java/io/getstream/android/core/api/model/event/StreamClientWsEvent.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,4 @@ package io.getstream.android.core.api.model.event
1818
import io.getstream.android.core.annotations.StreamInternalApi
1919

2020
/** Represents a WebSocket event for the Stream client. */
21-
@StreamInternalApi
22-
public interface StreamClientWsEvent
21+
@StreamInternalApi public interface StreamClientWsEvent

stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamToken.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
package io.getstream.android.core.api.model.value
1717

18-
import android.annotation.SuppressLint
1918
import io.getstream.android.core.annotations.StreamPublishedApi
2019

2120
/**

stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamUserId.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
package io.getstream.android.core.api.model.value
1717

18-
import android.annotation.SuppressLint
1918
import io.getstream.android.core.annotations.StreamPublishedApi
2019

2120
/**

0 commit comments

Comments
 (0)