From 79e14f88e4a453e073a79ef6e32cb8377ad1094a Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Sun, 2 Jul 2017 15:17:46 +0300 Subject: [PATCH] Support package level annotations in Java #KT-10942 In Progress --- .../JavaElementCollectionFromPsiArrayUtil.kt | 2 +- .../java/structure/impl/JavaPackageImpl.kt | 12 +- .../jetbrains/kotlin/javac/JavacWrapper.kt | 19 ++- .../wrappers/symbols/SymbolBasedPackage.kt | 13 +- .../wrappers/trees/TreeBasedAnnotation.kt | 17 ++- .../javac/wrappers/trees/TreeBasedClass.kt | 2 +- .../javac/wrappers/trees/TreeBasedPackage.kt | 12 +- .../loadJavaPackageAnnotations/test/A.java | 5 + .../loadJavaPackageAnnotations/test/Ann.java | 7 ++ .../test/package-info.java | 2 + .../jetbrains/kotlin/test/MockLibraryUtil.kt | 24 +++- .../LoadJavaPackageAnnotationsTest.kt | 112 ++++++++++++++++++ .../descriptors/LazyJavaPackageFragment.kt | 6 + .../load/java/structure/javaElements.kt | 1 + .../structure/reflect/ReflectJavaPackage.kt | 9 ++ 15 files changed, 222 insertions(+), 21 deletions(-) create mode 100644 compiler/testData/loadJavaPackageAnnotations/test/A.java create mode 100644 compiler/testData/loadJavaPackageAnnotations/test/Ann.java create mode 100644 compiler/testData/loadJavaPackageAnnotations/test/package-info.java create mode 100644 compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaPackageAnnotationsTest.kt diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaElementCollectionFromPsiArrayUtil.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaElementCollectionFromPsiArrayUtil.kt index 3c77d1144ca..92cfc8fcdea 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaElementCollectionFromPsiArrayUtil.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaElementCollectionFromPsiArrayUtil.kt @@ -64,7 +64,7 @@ internal fun typeParameters(typeParameters: Array): List): Collection = classTypes.convert(::JavaClassifierTypeImpl) -internal fun annotations(annotations: Array): Collection = +internal fun annotations(annotations: Array): Collection = annotations.convert(::JavaAnnotationImpl) internal fun namedAnnotationArguments(nameValuePairs: Array): Collection = diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaPackageImpl.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaPackageImpl.kt index ffe636a3fa8..361c79d6de4 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaPackageImpl.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaPackageImpl.kt @@ -18,12 +18,13 @@ package org.jetbrains.kotlin.load.java.structure.impl import com.intellij.psi.PsiPackage import com.intellij.psi.search.GlobalSearchScope -import org.jetbrains.kotlin.load.java.structure.JavaClass -import org.jetbrains.kotlin.load.java.structure.JavaPackage +import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -class JavaPackageImpl(psiPackage: PsiPackage, private val scope: GlobalSearchScope) : JavaElementImpl(psiPackage), JavaPackage { +class JavaPackageImpl( + psiPackage: PsiPackage, private val scope: GlobalSearchScope +) : JavaElementImpl(psiPackage), JavaPackage, MapBasedJavaAnnotationOwner { override fun getClasses(nameFilter: (Name) -> Boolean): Collection { val psiClasses = psi.getClasses(scope).filter { @@ -38,4 +39,9 @@ class JavaPackageImpl(psiPackage: PsiPackage, private val scope: GlobalSearchSco override val fqName: FqName get() = FqName(psi.qualifiedName) + + override val annotations: Collection + get() = org.jetbrains.kotlin.load.java.structure.impl.annotations(psi.annotationList?.annotations.orEmpty()) + + override val annotationsByFqName: Map by buildLazyValueForMap() } diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavacWrapper.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavacWrapper.kt index a06f6802ef7..683c5d7529d 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavacWrapper.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavacWrapper.kt @@ -43,10 +43,8 @@ import com.sun.tools.javac.util.Options import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedClass import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedClassifierType import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedPackage -import org.jetbrains.kotlin.javac.wrappers.trees.TreeBasedClass -import org.jetbrains.kotlin.javac.wrappers.trees.TreeBasedPackage -import org.jetbrains.kotlin.javac.wrappers.trees.TreePathResolverCache -import org.jetbrains.kotlin.javac.wrappers.trees.computeClassId +import org.jetbrains.kotlin.javac.wrappers.trees.* +import org.jetbrains.kotlin.load.java.structure.JavaAnnotation import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaClassifier import org.jetbrains.kotlin.load.java.structure.JavaPackage @@ -142,6 +140,14 @@ class JavacWrapper( } .associateBy(TreeBasedPackage::fqName) + private val packageSourceAnnotations = compilationUnits + .filter { + it.sourceFile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE) && + it.packageName != null + }.associateBy({ FqName(it.packageName!!.toString()) }) { compilationUnit -> + compilationUnit.packageAnnotations.map { TreeBasedAnnotation(it, compilationUnit, this) } + } + private val kotlinClassifiersCache = KotlinClassifiersCache(if (javaFiles.isNotEmpty()) kotlinFiles else emptyList(), this) private val treePathResolverCache = TreePathResolverCache(this) private val symbolBasedClassesCache = hashMapOf() @@ -212,6 +218,9 @@ class JavacWrapper( .filterKeys { it.isSubpackageOf(fqName) && it != fqName } .map { it.value } + fun getPackageAnnotationsFromSources(fqName: FqName): List = + packageSourceAnnotations[fqName] ?: emptyList() + fun findClassesFromPackage(fqName: FqName): List = javaClasses .filterKeys { it?.parentOrNull() == fqName } @@ -329,4 +338,4 @@ class JavacWrapper( return symbol.let { SymbolBasedClass(it, this@JavacWrapper, it.classfile) } } -} \ No newline at end of file +} diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedPackage.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedPackage.kt index 2ab2d00573d..023da82099f 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedPackage.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedPackage.kt @@ -17,7 +17,10 @@ package org.jetbrains.kotlin.javac.wrappers.symbols import org.jetbrains.kotlin.javac.JavacWrapper +import org.jetbrains.kotlin.load.java.structure.JavaAnnotation import org.jetbrains.kotlin.load.java.structure.JavaPackage +import org.jetbrains.kotlin.load.java.structure.MapBasedJavaAnnotationOwner +import org.jetbrains.kotlin.load.java.structure.buildLazyValueForMap import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import javax.lang.model.element.PackageElement @@ -25,7 +28,7 @@ import javax.lang.model.element.PackageElement class SymbolBasedPackage( element: PackageElement, javac: JavacWrapper -) : SymbolBasedElement(element, javac), JavaPackage { +) : SymbolBasedElement(element, javac), JavaPackage, MapBasedJavaAnnotationOwner { override val fqName: FqName get() = FqName(element.qualifiedName.toString()) @@ -33,9 +36,15 @@ class SymbolBasedPackage( override val subPackages: Collection get() = javac.findSubPackages(FqName(element.qualifiedName.toString())) + + override val annotations: Collection + get() = element.annotationMirrors.map { SymbolBasedAnnotation(it, javac) } + + override val annotationsByFqName: Map by buildLazyValueForMap() + override fun getClasses(nameFilter: (Name) -> Boolean) = javac.findClassesFromPackage(fqName).filter { nameFilter(it.name) } override fun toString() = element.qualifiedName.toString() -} \ No newline at end of file +} diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedAnnotation.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedAnnotation.kt index 293482d01be..0bdf7f699eb 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedAnnotation.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedAnnotation.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.javac.wrappers.trees +import com.sun.source.tree.CompilationUnitTree import com.sun.source.util.TreePath import com.sun.tools.javac.tree.JCTree import org.jetbrains.kotlin.javac.JavacWrapper @@ -27,11 +28,17 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name class TreeBasedAnnotation( - val annotation: JCTree.JCAnnotation, - val treePath: TreePath, - val javac: JavacWrapper + private val annotation: JCTree.JCAnnotation, + private val compilationUnit: CompilationUnitTree, + private val javac: JavacWrapper ) : JavaElement, JavaAnnotation { + constructor( + annotation: JCTree.JCAnnotation, + treePath: TreePath, + javac: JavacWrapper + ) : this(annotation, treePath.compilationUnit, javac) + override val arguments: Collection get() = annotation.arguments.map { TreeBasedAnnotationArgument(Name.identifier(it.toString())) } @@ -39,8 +46,8 @@ class TreeBasedAnnotation( get() = resolve()?.computeClassId() override fun resolve() = - javac.resolve(TreePath.getPath(treePath.compilationUnit, annotation.annotationType)) as? JavaClass + javac.resolve(TreePath.getPath(compilationUnit, annotation.annotationType)) as? JavaClass } -class TreeBasedAnnotationArgument(override val name: Name) : JavaAnnotationArgument, JavaElement \ No newline at end of file +class TreeBasedAnnotationArgument(override val name: Name) : JavaAnnotationArgument, JavaElement diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedClass.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedClass.kt index 153fe189ee2..9d7601e1741 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedClass.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedClass.kt @@ -154,4 +154,4 @@ class TreeBasedClass( override fun findInnerClass(name: Name) = innerClasses[name] -} \ No newline at end of file +} diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedPackage.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedPackage.kt index 226697ba440..94b8ea4c98e 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedPackage.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedPackage.kt @@ -18,12 +18,15 @@ package org.jetbrains.kotlin.javac.wrappers.trees import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.kotlin.javac.JavacWrapper +import org.jetbrains.kotlin.load.java.structure.JavaAnnotation import org.jetbrains.kotlin.load.java.structure.JavaPackage +import org.jetbrains.kotlin.load.java.structure.MapBasedJavaAnnotationOwner +import org.jetbrains.kotlin.load.java.structure.buildLazyValueForMap import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import javax.tools.JavaFileObject -class TreeBasedPackage(val name: String, val javac: JavacWrapper, val file: JavaFileObject) : JavaPackage { +class TreeBasedPackage(val name: String, val javac: JavacWrapper, val file: JavaFileObject) : JavaPackage, MapBasedJavaAnnotationOwner { override val fqName: FqName get() = FqName(name) @@ -38,10 +41,15 @@ class TreeBasedPackage(val name: String, val javac: JavacWrapper, val file: Java override fun getClasses(nameFilter: (Name) -> Boolean) = javac.findClassesFromPackage(fqName).filter { nameFilter(it.fqName!!.shortName()) } + override val annotations + get() = javac.getPackageAnnotationsFromSources(fqName) + + override val annotationsByFqName: Map by buildLazyValueForMap() + override fun equals(other: Any?) = (other as? TreeBasedPackage)?.name == name override fun hashCode() = name.hashCode() override fun toString() = name -} \ No newline at end of file +} diff --git a/compiler/testData/loadJavaPackageAnnotations/test/A.java b/compiler/testData/loadJavaPackageAnnotations/test/A.java new file mode 100644 index 00000000000..cad0c4a7ddf --- /dev/null +++ b/compiler/testData/loadJavaPackageAnnotations/test/A.java @@ -0,0 +1,5 @@ +package test; + +public class A { + +} diff --git a/compiler/testData/loadJavaPackageAnnotations/test/Ann.java b/compiler/testData/loadJavaPackageAnnotations/test/Ann.java new file mode 100644 index 00000000000..39868308262 --- /dev/null +++ b/compiler/testData/loadJavaPackageAnnotations/test/Ann.java @@ -0,0 +1,7 @@ +package test; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target(ElementType.PACKAGE) +public @interface Ann { +} diff --git a/compiler/testData/loadJavaPackageAnnotations/test/package-info.java b/compiler/testData/loadJavaPackageAnnotations/test/package-info.java new file mode 100644 index 00000000000..571f3607970 --- /dev/null +++ b/compiler/testData/loadJavaPackageAnnotations/test/package-info.java @@ -0,0 +1,2 @@ +@Ann +package test; diff --git a/compiler/tests-common/org/jetbrains/kotlin/test/MockLibraryUtil.kt b/compiler/tests-common/org/jetbrains/kotlin/test/MockLibraryUtil.kt index d97d9e5f1a8..bc9b803f0db 100644 --- a/compiler/tests-common/org/jetbrains/kotlin/test/MockLibraryUtil.kt +++ b/compiler/tests-common/org/jetbrains/kotlin/test/MockLibraryUtil.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.preloading.ClassPreloadingUtils import org.jetbrains.kotlin.preloading.Preloader import org.jetbrains.kotlin.utils.PathUtil +import org.junit.Assert import org.junit.Assert.assertEquals import java.io.ByteArrayOutputStream import java.io.File @@ -45,12 +46,29 @@ object MockLibraryUtil { sourcesPath: String, jarName: String, addSources: Boolean = false, + allowKotlinSources: Boolean = true, extraOptions: List = emptyList(), extraClasspath: List = emptyList(), useJava9: Boolean = false ): File { - return compileLibraryToJar(sourcesPath, KotlinTestUtils.tmpDir("testLibrary-" + jarName), jarName, addSources, - extraOptions, extraClasspath, useJava9) + return compileLibraryToJar( + sourcesPath, KotlinTestUtils.tmpDir("testLibrary-" + jarName), jarName, addSources,allowKotlinSources, extraOptions, extraClasspath + , useJava9)} + + @JvmStatic + @JvmOverloads + fun compileJavaFilesLibraryToJar( + sourcesPath: String, + jarName: String, + addSources: Boolean = false, + extraOptions: List = emptyList(), + extraClasspath: List = emptyList() + ): File { + return compileJvmLibraryToJar( + sourcesPath, jarName, addSources, + allowKotlinSources = false, + extraClasspath = extraClasspath, extraOptions = extraOptions + ) } @JvmStatic @@ -60,6 +78,7 @@ object MockLibraryUtil { contentDir: File, jarName: String, addSources: Boolean = false, + allowKotlinSources: Boolean = true, extraOptions: List = emptyList(), extraClasspath: List = emptyList(), useJava9: Boolean = false @@ -69,6 +88,7 @@ object MockLibraryUtil { val srcFile = File(sourcesPath) val kotlinFiles = FileUtil.findFilesByMask(Pattern.compile(".*\\.kt"), srcFile) if (srcFile.isFile || kotlinFiles.isNotEmpty()) { + Assert.assertTrue("Only java files are expected", allowKotlinSources) compileKotlin(sourcesPath, classesDir, extraOptions, *extraClasspath.toTypedArray()) } diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaPackageAnnotationsTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaPackageAnnotationsTest.kt new file mode 100644 index 00000000000..3f41f83d342 --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaPackageAnnotationsTest.kt @@ -0,0 +1,112 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * 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 org.jetbrains.kotlin.jvm.compiler + +import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.jetbrains.kotlin.cli.jvm.config.addJavaSourceRoots +import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoot +import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.config.JVMConfigurationKeys +import org.jetbrains.kotlin.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil +import org.jetbrains.kotlin.test.ConfigurationKind +import org.jetbrains.kotlin.test.KotlinTestUtils +import org.jetbrains.kotlin.test.MockLibraryUtil +import org.jetbrains.kotlin.test.TestJdkKind +import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase +import java.io.File + +class LoadJavaPackageAnnotationsTest : KtUsefulTestCase() { + companion object { + private val TEST_DATA_PATH = "compiler/testData/loadJavaPackageAnnotations/" + } + + private fun doTest(useJavac: Boolean, configurator: (CompilerConfiguration) -> Unit) { + val environment = + KotlinCoreEnvironment.createForTests( + myTestRootDisposable, + KotlinTestUtils.newConfiguration( + ConfigurationKind.ALL, TestJdkKind.FULL_JDK, KotlinTestUtils.getAnnotationsJar() + ).also { + if (useJavac) { + it.put(JVMConfigurationKeys.USE_JAVAC, true) + } + configurator(it) + }, + EnvironmentConfigFiles.JVM_CONFIG_FILES + ).apply { + if (useJavac) { + registerJavac() + } + } + val moduleDescriptor = JvmResolveUtil.analyze( + environment + ).moduleDescriptor + + val packageFragmentDescriptor = + moduleDescriptor.getPackage(FqName("test")).fragments + .singleOrNull { + it.getMemberScope().getContributedClassifier(Name.identifier("A"), NoLookupLocation.FROM_TEST) != null + }.let { assertInstanceOf(it, LazyJavaPackageFragment::class.java) } + + val annotation = packageFragmentDescriptor.getPackageAnnotations().findAnnotation(FqName("test.Ann")) + assertNotNull(annotation) + + val singleAnnotation = packageFragmentDescriptor.getPackageAnnotations().singleOrNull() + assertNotNull(singleAnnotation) + + val annotationFqName = singleAnnotation!!.type.constructor.declarationDescriptor?.fqNameSafe + + assertEquals(FqName("test.Ann"), annotationFqName) + } + + fun testAnnotationFromSource() { + doTest(useJavac = false) { + it.addJavaSourceRoots(listOf(File(TEST_DATA_PATH))) + } + } + + fun testAnnotationFromSourceWithJavac() { + doTest(useJavac = true) { + it.addJavaSourceRoots(listOf(File(TEST_DATA_PATH))) + } + } + + fun testAnnotationFromCompiledCode() { + val jar = prepareJar() + + doTest(useJavac = false) { + it.addJvmClasspathRoot(jar) + } + } + + fun testAnnotationFromCompiledCodeWithJavac() { + val jar = prepareJar() + + doTest(useJavac = true) { + it.addJvmClasspathRoot(jar) + } + } + + private fun prepareJar() = + MockLibraryUtil.compileJavaFilesLibraryToJar(TEST_DATA_PATH, "result.jar") +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt index afdf97e2ad1..f7fceb9bf81 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext +import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaPackage import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement @@ -48,6 +49,11 @@ class LazyJavaPackageFragment( onRecursiveCall = listOf() ) + private val packageAnnotations = c.resolveAnnotations(jPackage) + + // Test only method + fun getPackageAnnotations() = packageAnnotations + internal fun getSubPackageFqNames(): List = subPackages() internal fun findClassifierByJavaClass(jClass: JavaClass): ClassDescriptor? = scope.javaScope.findClassifierByJavaClass(jClass) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/structure/javaElements.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/structure/javaElements.kt index 66acc744689..1e9ecd88d6a 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/structure/javaElements.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/structure/javaElements.kt @@ -63,6 +63,7 @@ fun JavaAnnotationOwner.buildLazyValueForMap() = lazy { annotations.associateBy { it.classId?.asSingleFqName() } } +interface JavaPackage : JavaElement, JavaAnnotationOwner { val fqName: FqName val subPackages: Collection diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaPackage.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaPackage.kt index 090b2dc60da..e7a6fa1971a 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaPackage.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaPackage.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.load.java.structure.reflect +import org.jetbrains.kotlin.load.java.structure.JavaAnnotation import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaPackage import org.jetbrains.kotlin.name.FqName @@ -33,6 +34,14 @@ class ReflectJavaPackage(override val fqName: FqName) : ReflectJavaElement(), Ja return listOf() } + // TODO: support it if possible + override val annotations get() = emptyList() + + override fun findAnnotation(fqName: FqName) = null + + override val isDeprecatedInJavaDoc: Boolean + get() = false + override fun equals(other: Any?) = other is ReflectJavaPackage && fqName == other.fqName override fun hashCode() = fqName.hashCode()