• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 Google LLC
3  * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.google.devtools.ksp.processor
19 
20 import com.google.devtools.ksp.closestClassDeclaration
21 import com.google.devtools.ksp.getClassDeclarationByName
22 import com.google.devtools.ksp.processing.Resolver
23 import com.google.devtools.ksp.symbol.*
24 
25 @Suppress("unused") // used by tests
26 class OverrideeProcessor : AbstractTestProcessor() {
27     private val results = mutableListOf<String>()
28 
toResultnull29     override fun toResult() = results
30 
31     override fun process(resolver: Resolver): List<KSAnnotated> {
32         logSubject(resolver, "NoOverride")
33         logSubject(resolver, "Subject")
34         logSubject(resolver, "JavaSubject.Subject")
35         logSubject(resolver, "lib.Subject")
36         logSubject(resolver, "ConflictingSubject1")
37         logSubject(resolver, "ConflictingSubject2")
38         logSubject(resolver, "ConflictingSubject3")
39         logSubject(resolver, "ConflictingSubject4")
40         logSubject(resolver, "OverrideOrder1")
41         logSubject(resolver, "OverrideOrder2")
42         logSubject(resolver, "JavaAccessorImpl")
43         logSubject(resolver, "JavaAnno")
44         logSubject(resolver, "JavaAnnos")
45         logSubject(resolver, "PrimaryConstructorOverride")
46         return emptyList()
47     }
48 
logSubjectnull49     private fun logSubject(resolver: Resolver, qName: String) {
50         results.add("$qName:")
51         val subject = resolver.getClassDeclarationByName(qName)!!
52         subject.declarations.filterIsInstance<KSClassDeclaration>().forEach {
53             logClass(it)
54         }
55         logClass(subject)
56     }
57 
logClassnull58     private fun logClass(subject: KSClassDeclaration) {
59         subject.declarations.filterIsInstance<KSPropertyDeclaration>()
60             .forEach {
61                 checkOverridee(it)
62             }
63         subject.declarations.filterIsInstance<KSFunctionDeclaration>()
64             .filterNot { it.simpleName.asString() in IGNORED_METHOD_NAMES }
65             .forEach {
66                 checkOverridee(it)
67             }
68     }
69 
checkOverrideenull70     private fun checkOverridee(declaration: KSDeclaration) {
71         val signature = if (declaration is KSPropertyDeclaration) declaration.toSignature() else
72             (declaration as KSFunctionDeclaration).toSignature()
73         val overrideeSignature = if (declaration is KSPropertyDeclaration) declaration.findOverridee()?.toSignature()
74         else (declaration as KSFunctionDeclaration).findOverridee()?.toSignature()
75         results.add("$signature -> $overrideeSignature")
76     }
77 
toSignaturenull78     private fun KSDeclaration.toSignature(): String {
79         return when (this) {
80             is KSFunctionDeclaration -> this.toSignature()
81             is KSPropertyDeclaration -> this.toSignature()
82             else -> throw IllegalStateException()
83         }
84     }
85 
KSFunctionDeclarationnull86     private fun KSFunctionDeclaration.toSignature(): String {
87         val self = this
88         return buildString {
89             append(self.closestClassDeclaration()?.simpleName?.asString())
90             append(".")
91             append(self.simpleName.asString())
92             append(
93                 self.parameters.joinToString(", ", prefix = "(", postfix = ")") {
94                     "${it.name?.asString()}:${it.type.resolve().declaration.simpleName.asString()}"
95                 }
96             )
97         }
98     }
99 
toSignaturenull100     private fun KSPropertyDeclaration.toSignature(): String {
101         val self = this
102         return buildString {
103             append(self.closestClassDeclaration()?.simpleName?.asString())
104             append(".")
105             append(self.simpleName.asString())
106         }
107     }
108 
109     companion object {
110         // ignore these methods as we receive syntetics of it from compiled code
111         private val IGNORED_METHOD_NAMES = listOf("equals", "hashCode", "toString", "<init>")
112     }
113 }
114