From bbd8fb8b2324d24dcdf2a21132c3c2e5b1c2147a Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 10 Sep 2019 17:17:22 +0300 Subject: [PATCH] JavacWrapper: add support for JvmPackageName annotation This fixes previously added testWithStdLib/streams.kt test --- .../cli/jvm/compiler/KotlinCoreEnvironment.kt | 2 +- .../cli/jvm/javac/JavacWrapperRegistrar.kt | 6 ++- .../jetbrains/kotlin/javac/JavacWrapper.kt | 41 +++++++++++++--- .../symbols/MappedSymbolBasedPackage.kt | 39 +++++++++++++++ .../symbols/SimpleSymbolBasedPackage.kt | 49 +++++++++++++++++++ .../wrappers/symbols/SymbolBasedPackage.kt | 46 ++--------------- 6 files changed, 132 insertions(+), 51 deletions(-) create mode 100644 compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/MappedSymbolBasedPackage.kt create mode 100644 compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SimpleSymbolBasedPackage.kt diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index 17faf5b3dbd..a02ff1ac3fc 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -319,7 +319,7 @@ class KotlinCoreEnvironment private constructor( ): Boolean { return JavacWrapperRegistrar.registerJavac( projectEnvironment.project, configuration, javaFiles, kotlinFiles, arguments, bootClasspath, sourcePath, - LightClassGenerationSupport.getInstance(project) + LightClassGenerationSupport.getInstance(project), packagePartProviders ) } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/javac/JavacWrapperRegistrar.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/javac/JavacWrapperRegistrar.kt index cc62dcc996c..797183e86af 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/javac/JavacWrapperRegistrar.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/javac/JavacWrapperRegistrar.kt @@ -21,6 +21,7 @@ import com.sun.tools.javac.util.Context import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR +import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.JVMConfigurationKeys @@ -39,7 +40,8 @@ object JavacWrapperRegistrar { arguments: Array?, bootClasspath: List?, sourcePath: List?, - lightClassGenerationSupport: LightClassGenerationSupport + lightClassGenerationSupport: LightClassGenerationSupport, + packagePartsProviders: List ): Boolean { val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) @@ -60,7 +62,7 @@ object JavacWrapperRegistrar { val javacWrapper = JavacWrapper( javaFiles, kotlinFiles, arguments, jvmClasspathRoots, bootClasspath, sourcePath, - kotlinSupertypesResolver, compileJava, outputDirectory, context + kotlinSupertypesResolver, packagePartsProviders, compileJava, outputDirectory, context ) project.registerService(JavacWrapper::class.java, javacWrapper) 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 84ee2bc3a09..d73ac0dc709 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavacWrapper.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavacWrapper.kt @@ -37,13 +37,12 @@ import com.sun.tools.javac.util.Context import com.sun.tools.javac.util.Log import com.sun.tools.javac.util.Names import com.sun.tools.javac.util.Options +import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider import org.jetbrains.kotlin.javac.resolve.ClassifierResolver import org.jetbrains.kotlin.javac.resolve.IdentifierResolver import org.jetbrains.kotlin.javac.resolve.KotlinClassifiersCache import org.jetbrains.kotlin.javac.resolve.classId -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.symbols.* import org.jetbrains.kotlin.javac.wrappers.trees.* import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.name.* @@ -65,6 +64,7 @@ class JavacWrapper( bootClasspath: List?, sourcePath: List?, val kotlinResolver: JavacWrapperKotlinResolver, + private val packagePartsProviders: List, private val compileJava: Boolean, private val outputDirectory: File?, private val context: Context @@ -229,7 +229,7 @@ class JavacWrapper( fun findSubPackages(fqName: FqName): List = symbols.packages .filterKeys { it.toString().startsWith("$fqName.") } - .map { SymbolBasedPackage(it.value, this) } + + .map { SimpleSymbolBasedPackage(it.value, this) } + javaPackages .filterKeys { it.isSubpackageOf(fqName) && it != fqName } .map { it.value } @@ -301,12 +301,39 @@ class JavacWrapper( private fun findPackageInSymbols(fqName: String): SymbolBasedPackage? { if (symbolBasedPackagesCache.containsKey(fqName)) return symbolBasedPackagesCache[fqName] - elements.getPackageElement(fqName)?.let { symbol -> - SymbolBasedPackage(symbol, this) - }.let { symbolBasedPackage -> + fun findSimplePackageInSymbols(fqName: String): SimpleSymbolBasedPackage? { + elements.getPackageElement(fqName)?.let { symbol -> + SimpleSymbolBasedPackage(symbol, this) + }.let { symbolBasedPackage -> + symbolBasedPackagesCache[fqName] = symbolBasedPackage + return symbolBasedPackage + } + } + + val mappedPackages = mutableListOf() + for (provider in packagePartsProviders) { + val jvmPackageNames = provider.findPackageParts(fqName) + .map { it.substringBeforeLast("/").replace('/', '.') }.filter { it != fqName }.distinct() + // TODO: check situation with multiple package parts like this (search by FQ name of 'p1') + // FILE: foo.kt + // @file:JvmPackageName("aaa") + // package p1 + // fun foo() {} + // ------------ + // FILE: bar.kt + // package aaa + // fun bar() {} + mappedPackages += jvmPackageNames.mapNotNull { jvmPackageName -> + findSimplePackageInSymbols(jvmPackageName) + } + } + if (mappedPackages.isNotEmpty()) { + val symbolBasedPackage = MappedSymbolBasedPackage(FqName(fqName), mappedPackages, this) symbolBasedPackagesCache[fqName] = symbolBasedPackage return symbolBasedPackage } + + return findSimplePackageInSymbols(fqName) } private fun JavacFileManager.setClassPathForCompilation(outDir: File?) = apply { diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/MappedSymbolBasedPackage.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/MappedSymbolBasedPackage.kt new file mode 100644 index 00000000000..2363ae9b43e --- /dev/null +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/MappedSymbolBasedPackage.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.javac.wrappers.symbols + +import org.jetbrains.kotlin.javac.JavacWrapper +import org.jetbrains.kotlin.load.java.structure.* +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import javax.lang.model.element.PackageElement + +// Useful only for packages with JvmPackageName annotation +class MappedSymbolBasedPackage( + private val originalFqName: FqName, + private val childrenPackages: List, + javac: JavacWrapper +) : SymbolBasedElement(childrenPackages.first().element, javac), SymbolBasedPackage { + override val fqName: FqName + get() = originalFqName + + override val subPackages: Collection + get() = childrenPackages.flatMap { javac.findSubPackages(it.fqName) } + + + override val annotations: Collection + get() = childrenPackages.map { childrenPackage -> + childrenPackage.element.annotationMirrors.map { annotationMirror -> SymbolBasedAnnotation(annotationMirror, javac) } + }.flatten() + + override val annotationsByFqName: Map by buildLazyValueForMap() + + // @JvmPackageName-annotated files cannot have classes + override fun getClasses(nameFilter: (Name) -> Boolean): List = emptyList() + + override fun toString() = originalFqName.toString() + +} \ No newline at end of file diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SimpleSymbolBasedPackage.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SimpleSymbolBasedPackage.kt new file mode 100644 index 00000000000..713aad8c5ba --- /dev/null +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SimpleSymbolBasedPackage.kt @@ -0,0 +1,49 @@ +/* + * 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.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.buildLazyValueForMap +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import javax.lang.model.element.PackageElement + +class SimpleSymbolBasedPackage( + element: PackageElement, + javac: JavacWrapper +) : SymbolBasedElement(element, javac), SymbolBasedPackage { + + override val fqName: FqName + get() = FqName(element.qualifiedName.toString()) + + override val subPackages: Collection + get() = javac.findSubPackages(fqName) + + + 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() + +} 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 a758ecdbc7b..ad41365f560 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 @@ -1,50 +1,14 @@ /* - * 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ 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 -class SymbolBasedPackage( - element: PackageElement, - javac: JavacWrapper -) : SymbolBasedElement(element, javac), JavaPackage, MapBasedJavaAnnotationOwner { - - override val fqName: FqName - get() = FqName(element.qualifiedName.toString()) - - override val subPackages: Collection - get() = javac.findSubPackages(fqName) - - - 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() - -} +interface SymbolBasedPackage : JavaPackage, MapBasedJavaAnnotationOwner { + val element: PackageElement +} \ No newline at end of file