1616package com.airbnb.deeplinkdispatch
1717
1818import androidx.room.compiler.processing.XAnnotation
19+ import androidx.room.compiler.processing.XAnnotationValue
1920import androidx.room.compiler.processing.XElement
2021import androidx.room.compiler.processing.XExecutableParameterElement
2122import androidx.room.compiler.processing.XFiler
@@ -34,6 +35,7 @@ import com.airbnb.deeplinkdispatch.base.Utils.isConfigurablePathSegment
3435import com.airbnb.deeplinkdispatch.handler.DeepLinkParamType
3536import com.airbnb.deeplinkdispatch.handler.DeeplinkParam
3637import com.airbnb.deeplinkdispatch.handler.TypeConverters
38+ import com.google.devtools.ksp.processing.Resolver
3739import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
3840import com.squareup.javapoet.ClassName
3941import com.squareup.javapoet.CodeBlock
@@ -123,19 +125,31 @@ class DeepLinkProcessor(symbolProcessorEnvironment: SymbolProcessorEnvironment?
123125 override fun process (
124126 annotations : Set <XTypeElement >? ,
125127 environment : XProcessingEnv ,
126- round : XRoundEnv
128+ round : XRoundEnv ,
129+ resolver : Resolver ? ,
127130 ) {
128131 try {
132+ // source -> https://github.com/google/ksp/issues/2225
133+ val customAnnotations = resolver
134+ ?.getSymbolsWithAnnotation(DEEP_LINK_SPEC_CLASS .simpleName ? : " " )
135+ ?.filterIsInstance<XTypeElement >()
136+ ?.toList() ? : emptyList()
137+
138+ val prefixes = customAnnotationPrefixes(customAnnotations)
139+
140+
129141 // If we run KSP or this is configured to be incremental we need to rely on the
130142 // incrementalMetadata for custom annotations. If not filter them out of the
131143 // set of annotations we were given.
132- val customAnnotations = if (incrementalMetadata.incremental ||
144+ /* val customAnnotations = if (incrementalMetadata.incremental ||
133145 environment.backend == XProcessingEnv.Backend.KSP
134146 ) {
135147 incrementalMetadata.customAnnotations
136148 } else {
137149 annotations?.filterAnnotatedAnnotations(DeepLinkSpec::class) ?: emptySet()
138150 }
151+ */
152+
139153 val allDeepLinkAnnotatedElements =
140154 customAnnotations.flatMap { round.getElementsAnnotatedWith(it.qualifiedName) } +
141155 round.getElementsAnnotatedWith(DEEP_LINK_CLASS )
@@ -168,7 +182,7 @@ class DeepLinkProcessor(symbolProcessorEnvironment: SymbolProcessorEnvironment?
168182 annotatedMethodElements = annotatedMethodElements,
169183 annotatedObjectElements = annotatedObjectElements,
170184 deepLinkElements = collectDeepLinkElements(
171- prefixes = customAnnotationPrefixes(customAnnotations) ,
185+ prefixes = prefixes ,
172186 classElementsToProcess = annotatedClassElements,
173187 objectElementsToProcess = annotatedObjectElements,
174188 methodElementsToProcess = annotatedMethodElements,
@@ -222,18 +236,21 @@ class DeepLinkProcessor(symbolProcessorEnvironment: SymbolProcessorEnvironment?
222236 uri = uri,
223237 element = element
224238 )
239+
225240 element is XTypeElement && element.isActivity() ->
226241 DeepLinkAnnotatedElement .ActivityAnnotatedElement (
227242 uri = uri,
228243 element = element
229244 )
245+
230246 element is XTypeElement && element.isHandler() -> {
231247 verifyHandlerMatchArgs(element, uri)
232248 DeepLinkAnnotatedElement .HandlerAnnotatedElement (
233249 uri = uri,
234250 element = element
235251 )
236252 }
253+
237254 else -> error(
238255 " Internal error: Elements can only be 'MethodAnnotatedElement', " +
239256 " 'ActivityAnnotatedElement' or 'HandlerAnnotatedElement'"
@@ -255,7 +272,8 @@ class DeepLinkProcessor(symbolProcessorEnvironment: SymbolProcessorEnvironment?
255272 return getAllDeeplinkUrIsFromCustomDeepLinksOnElement(
256273 element = element,
257274 prefixesMap = prefixes
258- ) + (element.getAnnotation(DEEP_LINK_CLASS )?.value?.value?.toList() ? : emptyList())
275+ ) + (element.getAnnotation(DEEP_LINK_CLASS )?.getAsStringList(" value" )?.toList()
276+ ? : emptyList())
259277 }
260278
261279 private fun verifyCass (classElement : XTypeElement ) {
@@ -331,6 +349,7 @@ class DeepLinkProcessor(symbolProcessorEnvironment: SymbolProcessorEnvironment?
331349 )
332350 }
333351 val allArgParameters = argsConstructor.parameters
352+
334353 val allPathParameters = allArgParameters.filterAnnotationType(DeepLinkParamType .Path )
335354 val allQueryParameters = allArgParameters.filterAnnotationType(DeepLinkParamType .Query )
336355 if (allPathParameters.size + allQueryParameters.size != allArgParameters.size) {
@@ -344,7 +363,7 @@ class DeepLinkProcessor(symbolProcessorEnvironment: SymbolProcessorEnvironment?
344363 val deepLinkUriTemplate = DeepLinkUri .parseTemplate(uriTemplate)
345364 val templateHostPathSchemePlaceholders = deepLinkUriTemplate.schemeHostPathPlaceholders
346365 val annotatedPathParameterNames = allPathParameters.mapNotNull {
347- it.getAnnotation(DeeplinkParam ::class )?.value?. name
366+ it.getAnnotation(DeeplinkParam ::class )?.getAsString( " name" )
348367 }.toSet()
349368 val annotatedPathParametersThatAreNotInUrlTemplate =
350369 annotatedPathParameterNames.filter { ! templateHostPathSchemePlaceholders.contains(it) }
@@ -360,14 +379,23 @@ class DeepLinkProcessor(symbolProcessorEnvironment: SymbolProcessorEnvironment?
360379
361380 private fun List<XExecutableParameterElement>.filterAnnotationType (
362381 deepLinkParamType : DeepLinkParamType
363- ) =
364- filter { argParameter ->
365- argParameter.getAllAnnotations().find { annotation ->
366- annotation.qualifiedName == DeeplinkParam ::class .qualifiedName
367- }?.annotationValues?.any { annotationValue ->
368- annotationValue.value.toString() == deepLinkParamType.toString()
369- } ? : false
370- }
382+ ) = filter { param ->
383+ val deeplinkAnn = param.getAllAnnotations()
384+ .firstOrNull { it.qualifiedName == DeeplinkParam ::class .qualifiedName }
385+ ? : return @filter false
386+
387+ val enumArgValue = deeplinkAnn.annotationValues
388+ .firstOrNull { it.name == " type" }
389+ ?.value
390+ ?.let { v ->
391+ when (v) {
392+ is Enum <* > -> v.name
393+ else -> v.toString().substringAfterLast(' .' )
394+ }
395+ }
396+
397+ enumArgValue == deepLinkParamType.name
398+ }
371399
372400 private fun verifyObjectElement (element : XTypeElement ) {
373401 if (! element.isHandler()) {
@@ -389,17 +417,20 @@ class DeepLinkProcessor(symbolProcessorEnvironment: SymbolProcessorEnvironment?
389417 }
390418 }
391419
392- private fun customAnnotationPrefixes (customAnnotations : Set <XTypeElement >): Map <XType , Array <String >> {
393- return customAnnotations.map { customAnnotationTypeElement ->
420+ private fun customAnnotationPrefixes (customAnnotations : List <XTypeElement >): Map <XType , Array <String >> {
421+ return customAnnotations.associate { customAnnotationTypeElement ->
394422 if (! customAnnotationTypeElement.isAnnotationClass()) {
395423 logError(
396424 element = customAnnotationTypeElement,
397425 message = " Only annotation types can be annotated with @${DEEP_LINK_SPEC_CLASS .simpleName} "
398426 )
399427 }
400- val prefix: Array <String > =
401- customAnnotationTypeElement.getAnnotation(DEEP_LINK_SPEC_CLASS )
402- ?.let { it.value.prefix } ? : emptyArray()
428+ val prefix: Array <String > = customAnnotationTypeElement
429+ .getAnnotation(DEEP_LINK_SPEC_CLASS )
430+ ?.getAsStringList(" prefix" )
431+ ?.toTypedArray()
432+ ? : emptyArray()
433+
403434 if (prefix.hasEmptyOrNullString()) {
404435 logError(
405436 element = customAnnotationTypeElement,
@@ -411,7 +442,7 @@ class DeepLinkProcessor(symbolProcessorEnvironment: SymbolProcessorEnvironment?
411442 message = " Prefix property cannot be empty"
412443 )
413444 customAnnotationTypeElement.type to prefix
414- }.toMap()
445+ }
415446 }
416447
417448 private fun verifyAnnotatedType (
@@ -443,7 +474,7 @@ class DeepLinkProcessor(symbolProcessorEnvironment: SymbolProcessorEnvironment?
443474 logError(
444475 element = it.value.first().enclosingTypeElement,
445476 message = " Only one @DeepLinkHandler annotated element allowed per package!" +
446- " ${it.key} has ${it.value.joinToString { it.qualifiedName }} ." ,
477+ " ${it.key} has ${it.value.joinToString { it.qualifiedName }} ." ,
447478 )
448479 }
449480 return false
@@ -727,6 +758,7 @@ class DeepLinkProcessor(symbolProcessorEnvironment: SymbolProcessorEnvironment?
727758 ? : " "
728759 )
729760 )
761+
730762 is DeepLinkAnnotatedElement .MethodAnnotatedElement ->
731763 urisTrie.addToTrie(
732764 DeepLinkEntry .MethodDeeplinkEntry (
@@ -736,6 +768,7 @@ class DeepLinkProcessor(symbolProcessorEnvironment: SymbolProcessorEnvironment?
736768 method = element.method
737769 )
738770 )
771+
739772 is DeepLinkAnnotatedElement .HandlerAnnotatedElement ->
740773 urisTrie.addToTrie(
741774 DeepLinkEntry .HandlerDeepLinkEntry (
@@ -866,13 +899,13 @@ class DeepLinkProcessor(symbolProcessorEnvironment: SymbolProcessorEnvironment?
866899 prefixesMap : Map <XType , Array <String >>
867900 ): List <String > {
868901 return element.findAnnotatedAnnotation<DeepLinkSpec >().flatMap { customAnnotation ->
869- val suffixes = customAnnotation.getAsList<String >(" value" )
902+ val suffixes = customAnnotation.getAsList<XAnnotationValue >(" value" )
870903 val prefixes = prefixesMap[customAnnotation.type]
871904 ? : throw DeepLinkProcessorException (
872905 " Unable to find annotation '${customAnnotation.qualifiedName} ' you must " +
873- " update 'deepLink.customAnnotations' within the build.gradle"
906+ " update 'deepLink.customAnnotations' within the build.gradle"
874907 )
875- prefixes.flatMap { prefix -> suffixes.map { suffix -> prefix + suffix } }
908+ prefixes.flatMap { prefix -> suffixes.map { suffix -> prefix + suffix.asString() } }
876909 }
877910 }
878911
0 commit comments