From 1d73c9f63d0fee42563afaaa929997d302d0aa2f Mon Sep 17 00:00:00 2001 From: Jiaxiang Chen Date: Mon, 5 Apr 2021 22:40:29 -0700 Subject: [PATCH] Add Resolver.getDeclarationsFromPackage() API for getting declarations with a given package name. --- .../devtools/ksp/processing/Resolver.kt | 9 +++ .../ksp/processing/impl/ResolverImpl.kt | 10 +++ .../ksp/processor/GetPackageProcessor.kt | 29 ++++++++ .../ksp/test/KotlinKSPTestGenerated.java | 5 ++ compiler-plugin/testData/api/getPackage.kt | 69 +++++++++++++++++++ 5 files changed, 122 insertions(+) create mode 100644 compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processor/GetPackageProcessor.kt create mode 100644 compiler-plugin/testData/api/getPackage.kt diff --git a/api/src/main/kotlin/com/google/devtools/ksp/processing/Resolver.kt b/api/src/main/kotlin/com/google/devtools/ksp/processing/Resolver.kt index 08c164d0ff..c8d7b0f122 100644 --- a/api/src/main/kotlin/com/google/devtools/ksp/processing/Resolver.kt +++ b/api/src/main/kotlin/com/google/devtools/ksp/processing/Resolver.kt @@ -211,4 +211,13 @@ interface Resolver { */ @KspExperimental fun getJvmCheckedException(function: KSFunctionDeclaration): Sequence + + /** + * Returns declarations with the given package name. + * @param packageName the package name to look up. + * @return A sequence of [KSDeclaration] with matching package name. + * This will return declarations from both dependencies and source. + */ + @KspExperimental + fun getDeclarationsFromPackage(packageName: String): Sequence } diff --git a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt index d72ea14eaa..18ef9a93c3 100644 --- a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt +++ b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt @@ -41,6 +41,7 @@ import org.jetbrains.kotlin.container.ComponentProvider import org.jetbrains.kotlin.container.get import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.load.java.components.TypeUsage import org.jetbrains.kotlin.load.java.descriptors.JavaForKotlinOverridePropertyDescriptor @@ -595,6 +596,15 @@ class ResolverImpl( } } + @KspExperimental + override fun getDeclarationsFromPackage(packageName: String): Sequence { + module.getPackage(FqName(packageName)).memberScope + val res = (module as ModuleDescriptorImpl).packageFragmentProvider.packageFragments(FqName(packageName)) + .flatMap{ it.getMemberScope().getContributedDescriptors() } + .mapNotNull { (it as? MemberDescriptor)?.toKSDeclaration() } + return res.asSequence() + } + override fun getTypeArgument(typeRef: KSTypeReference, variance: Variance): KSTypeArgument { return KSTypeArgumentLiteImpl.getCached(typeRef, variance) } diff --git a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processor/GetPackageProcessor.kt b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processor/GetPackageProcessor.kt new file mode 100644 index 0000000000..3337948b84 --- /dev/null +++ b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processor/GetPackageProcessor.kt @@ -0,0 +1,29 @@ +package com.google.devtools.ksp.processor + +import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.processing.Resolver +import com.google.devtools.ksp.symbol.KSAnnotated + +class GetPackageProcessor : AbstractTestProcessor() { + val results = mutableListOf() + + override fun toResult(): List { + return results + } + + @KspExperimental + override fun process(resolver: Resolver): List { + addPackage("lib1", resolver) + addPackage("lib2", resolver) + addPackage("main", resolver) + return emptyList() + } + + @KspExperimental + private fun addPackage(name: String, resolver: Resolver) { + results.add("symbols from package $name") + resolver.getDeclarationsFromPackage(name).forEach { + results.add("${it.qualifiedName?.asString() ?: "error"} ${it.origin}") + } + } +} diff --git a/compiler-plugin/src/test/java/com/google/devtools/ksp/test/KotlinKSPTestGenerated.java b/compiler-plugin/src/test/java/com/google/devtools/ksp/test/KotlinKSPTestGenerated.java index 73fada154e..b191705d6a 100644 --- a/compiler-plugin/src/test/java/com/google/devtools/ksp/test/KotlinKSPTestGenerated.java +++ b/compiler-plugin/src/test/java/com/google/devtools/ksp/test/KotlinKSPTestGenerated.java @@ -127,6 +127,11 @@ public void testFunctionTypeAlias() throws Exception { runTest("testData/api/functionTypeAlias.kt"); } + @TestMetadata("getPackage.kt") + public void testGetPackage() throws Exception { + runTest("testData/api/getPackage.kt"); + } + @TestMetadata("getSymbolsFromAnnotation.kt") public void testGetSymbolsFromAnnotation() throws Exception { runTest("testData/api/getSymbolsFromAnnotation.kt"); diff --git a/compiler-plugin/testData/api/getPackage.kt b/compiler-plugin/testData/api/getPackage.kt new file mode 100644 index 0000000000..b7c08e4578 --- /dev/null +++ b/compiler-plugin/testData/api/getPackage.kt @@ -0,0 +1,69 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * + * 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. + */ + +// TEST PROCESSOR: GetPackageProcessor +// EXPECTED: +// symbols from package lib1 +// lib1.FooInSource KOTLIN +// lib1.propInSource KOTLIN +// lib1.Bar CLASS +// lib1.Foo CLASS +// lib1.funcFoo CLASS +// symbols from package lib2 +// lib2.Foo CLASS +// lib2.a CLASS +// symbols from package main +// main.KotlinMain KOTLIN +// END + +// MODULE: lib1 +// FILE: foo.kt +package lib1 + +class Foo + +fun funcFoo(): Int { + return 1 +} + +// FILE: Bar.java +package lib1; + +class Bar {} + +// MODULE: lib2 +// FILE: foo.kt +package lib2 + +class Foo + +val a = 0 + +// FILE: Bar.java + +class Bar {} + +// MODULE: main(lib1, lib2) +// FILE: a.kt +package lib1 +class FooInSource + +val propInSource = 1 +// FILE: main.kt +package main + +class KotlinMain