Support JvmPackageName annotation in binary format

The main changes are in jvm_package_table.proto and ModuleMapping.kt.
With JvmPackageName, package parts can now have a JVM package name that
differs from their Kotlin name. So, in addition to the old package parts
which were stored as short names + short name of multifile facade (we
can't change this because of compatibility with old compilers), we now
store separately those package parts, which have a different JVM package
name. The format is optimized to avoid storing any package name more
than once as a string.

Another notable change is in KotlinCliJavaFileManagerImpl, where we now
load .kotlin_module files when determining whether or not a package
exists. Before this change, no PsiPackage (and thus, no JavaPackage and
eventually, no LazyJavaPackageFragment) was created unless there was at
least one file in the corresponding directory. Now we also create
packages if they are "mapped" to other JVM packages, i.e. if all package
parts in them have been annotated with JvmPackageName.

Most of the other changes are refactorings to allow internal names of
package parts/multifile classes where previously there were only short
names.
This commit is contained in:
Alexander Udalov
2017-09-06 15:14:47 +03:00
parent d07b628e0c
commit 70ae1596fb
44 changed files with 2614 additions and 657 deletions
@@ -197,9 +197,9 @@ public class ClassFileFactory implements OutputFileCollection {
private PackagePartRegistry buildNewPackagePartRegistry(@NotNull FqName packageFqName) {
String packageFqNameAsString = packageFqName.asString();
return (partShortName, facadeShortName) -> {
return (partInternalName, facadeInternalName) -> {
PackageParts packageParts = partsGroupedByPackage.computeIfAbsent(packageFqNameAsString, PackageParts::new);
packageParts.addPart(partShortName, facadeShortName);
packageParts.addPart(partInternalName, facadeInternalName);
};
}
@@ -209,7 +209,7 @@ class MultifileClassCodegenImpl(
if (!state.generateDeclaredClassFilter.shouldGeneratePackagePart(file) || !file.hasDeclarationsForPartClass()) return
packagePartRegistry.addPart(partType.internalName.substringAfterLast('/'), facadeClassType.internalName.substringAfterLast('/'))
packagePartRegistry.addPart(partType.internalName, facadeClassType.internalName)
val builder = state.factory.newVisitor(MultifileClassPart(file, packageFragment), partType, file)
@@ -20,7 +20,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.SmartList;
import kotlin.text.StringsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.context.PackageContext;
@@ -123,8 +122,7 @@ public class PackageCodegenImpl implements PackageCodegen {
if (!generatePackagePart || !state.getGenerateDeclaredClassFilter().shouldGeneratePackagePart(file)) return;
String name = fileClassType.getInternalName();
packagePartRegistry.addPart(StringsKt.substringAfterLast(name, '/', name), null);
packagePartRegistry.addPart(fileClassType.getInternalName(), null);
ClassBuilder builder = state.getFactory().newVisitor(JvmDeclarationOriginKt.PackagePart(file, packageFragment), fileClassType, file);
@@ -17,5 +17,5 @@
package org.jetbrains.kotlin.codegen
interface PackagePartRegistry {
fun addPart(partShortName: String, facadeShortName: String?)
fun addPart(partInternalName: String, facadeInternalName: String?)
}
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
import org.jetbrains.kotlin.load.kotlin.PackageParts
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.jvm.JvmPackageTable
import java.io.ByteArrayOutputStream
@@ -43,9 +44,8 @@ private fun Iterable<PackageParts>.addCompiledParts(state: GenerationState): Lis
val mapping = ModuleMapping.create(moduleMappingData, "<incremental>", state.deserializationConfiguration)
incrementalCache.getObsoletePackageParts().forEach { internalName ->
val qualifier = internalName.substringBeforeLast('/', "").replace('/', '.')
val name = internalName.substringAfterLast('/')
mapping.findPackageParts(qualifier)?.removePart(name)
val qualifier = JvmClassName.byInternalName(internalName).packageFqName.asString()
mapping.findPackageParts(qualifier)?.removePart(internalName)
}
return (this + mapping.packageFqName2Parts.values)
@@ -253,12 +253,13 @@ public class KotlinTypeMapper {
@NotNull
private static ContainingClassesInfo forPackageMember(
@NotNull FqName packageFqName,
@NotNull String facadeClassName,
@NotNull String implClassName
@NotNull JvmClassName facadeName,
@NotNull JvmClassName partName
) {
return new ContainingClassesInfo(ClassId.topLevel(packageFqName.child(Name.identifier(facadeClassName))),
ClassId.topLevel(packageFqName.child(Name.identifier(implClassName))));
return new ContainingClassesInfo(
ClassId.topLevel(facadeName.getFqNameForTopLevelClassMaybeWithDollars()),
ClassId.topLevel(partName.getFqNameForTopLevelClassMaybeWithDollars())
);
}
@NotNull
@@ -326,27 +327,24 @@ public class KotlinTypeMapper {
return new ContainingClassesInfo(FAKE_CLASS_ID_FOR_BUILTINS, FAKE_CLASS_ID_FOR_BUILTINS);
}
Name implClassName = UtilKt.getImplClassNameForDeserialized(descriptor);
JvmClassName implClassName = UtilKt.getImplClassNameForDeserialized(descriptor);
assert implClassName != null : "No implClassName for " + descriptor;
String implSimpleName = implClassName.asString();
String facadeSimpleName;
JvmClassName facadeName;
if (containingDeclaration instanceof LazyJavaPackageFragment) {
facadeSimpleName = ((LazyJavaPackageFragment) containingDeclaration).getFacadeSimpleNameForPartSimpleName(implSimpleName);
if (facadeSimpleName == null) return null;
facadeName = ((LazyJavaPackageFragment) containingDeclaration).getFacadeNameForPartName(implClassName);
if (facadeName == null) return null;
}
else if (containingDeclaration instanceof IncrementalMultifileClassPackageFragment) {
facadeSimpleName = ((IncrementalMultifileClassPackageFragment) containingDeclaration).getMultifileClassName().asString();
facadeName = ((IncrementalMultifileClassPackageFragment) containingDeclaration).getFacadeName();
}
else {
throw new AssertionError("Unexpected package fragment for " + descriptor + ": " +
containingDeclaration + " (" + containingDeclaration.getClass().getSimpleName() + ")");
}
return ContainingClassesInfo.forPackageMember(
((PackageFragmentDescriptor) containingDeclaration).getFqName(), facadeSimpleName, implSimpleName
);
return ContainingClassesInfo.forPackageMember(facadeName, implClassName);
}
@NotNull
@@ -47,12 +47,19 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
private val perfCounter = PerformanceCounter.create("Find Java class")
private lateinit var index: JvmDependenciesIndex
private lateinit var singleJavaFileRootsIndex: SingleJavaFileRootsIndex
private lateinit var packagePartProviders: List<JvmPackagePartProvider>
private val topLevelClassesCache: MutableMap<FqName, VirtualFile?> = THashMap()
private val allScope = GlobalSearchScope.allScope(myPsiManager.project)
private var useFastClassFilesReading = false
fun initialize(index: JvmDependenciesIndex, singleJavaFileRootsIndex: SingleJavaFileRootsIndex, useFastClassFilesReading: Boolean) {
fun initialize(
index: JvmDependenciesIndex,
packagePartProviders: List<JvmPackagePartProvider>,
singleJavaFileRootsIndex: SingleJavaFileRootsIndex,
useFastClassFilesReading: Boolean
) {
this.index = index
this.packagePartProviders = packagePartProviders
this.singleJavaFileRootsIndex = singleJavaFileRootsIndex
this.useFastClassFilesReading = useFastClassFilesReading
}
@@ -180,6 +187,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
//abort on first found
false
}
if (!found) {
found = packagePartProviders.any { it.findPackageParts(packageName).isNotEmpty() }
}
if (!found) {
found = singleJavaFileRootsIndex.findJavaSourceClasses(packageFqName).isNotEmpty()
}
@@ -234,6 +234,7 @@ class KotlinCoreEnvironment private constructor(
(ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl).initialize(
rootsIndex,
packagePartProviders,
SingleJavaFileRootsIndex(singleJavaFileRoots),
configuration.getBoolean(JVMConfigurationKeys.USE_FAST_CLASS_FILES_READING)
)
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.fileClasses
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.load.java.descriptors.getImplClassNameForDeserialized
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.name.FqName
@@ -39,10 +38,9 @@ object JvmFileClassUtil {
private const val MULTIFILE_PART_NAME_DELIMITER = "__"
fun getPartFqNameForDeserialized(descriptor: DeserializedMemberDescriptor): FqName {
val implClassName = descriptor.getImplClassNameForDeserialized() ?: error("No implClassName for $descriptor")
return (descriptor.containingDeclaration as PackageFragmentDescriptor).fqName.child(implClassName)
}
fun getPartFqNameForDeserialized(descriptor: DeserializedMemberDescriptor): FqName =
descriptor.getImplClassNameForDeserialized()?.fqNameForTopLevelClassMaybeWithDollars
?: error("No implClassName for $descriptor")
@JvmStatic
fun getFileClassInternalName(file: KtFile): String =
@@ -64,36 +64,33 @@ class IncrementalPackageFragmentProvider(
get() = this@IncrementalPackageFragmentProvider.target
fun getPackageFragmentForMultifileClass(multifileClassFqName: FqName): IncrementalMultifileClassPackageFragment? {
val facadeInternalName = JvmClassName.byFqNameWithoutInnerClasses(multifileClassFqName).internalName
val partsNames = incrementalCache.getStableMultifileFacadeParts(facadeInternalName) ?: return null
return IncrementalMultifileClassPackageFragment(multifileClassFqName, partsNames)
val facadeName = JvmClassName.byFqNameWithoutInnerClasses(multifileClassFqName)
val partsNames = incrementalCache.getStableMultifileFacadeParts(facadeName.internalName) ?: return null
return IncrementalMultifileClassPackageFragment(facadeName, partsNames, multifileClassFqName.parent())
}
override fun getMemberScope(): MemberScope = MemberScope.Empty
}
inner class IncrementalMultifileClassPackageFragment(
private val multifileClassFqName: FqName,
val partsInternalNames: Collection<String>
) : PackageFragmentDescriptorImpl(moduleDescriptor, multifileClassFqName.parent()) {
val facadeName: JvmClassName,
val partsInternalNames: Collection<String>,
packageFqName: FqName
) : PackageFragmentDescriptorImpl(moduleDescriptor, packageFqName) {
private val memberScope = storageManager.createLazyValue {
ChainedMemberScope.create(
"Member scope for incremental compilation: union of multifile class parts data for $multifileClassFqName",
"Member scope for incremental compilation: union of multifile class parts data for $facadeName",
partsInternalNames.mapNotNull { internalName ->
incrementalCache.getPackagePartData(internalName)?.let { (data, strings) ->
val (nameResolver, packageProto) = JvmProtoBufUtil.readPackageDataFrom(data, strings)
val jvmBinaryClass = kotlinClassFinder.findKotlinClass(
ClassId.topLevel(FqName(internalName.replace('/', '.')))
)
val partName = JvmClassName.byInternalName(internalName)
val jvmBinaryClass =
kotlinClassFinder.findKotlinClass(ClassId.topLevel(partName.fqNameForTopLevelClassMaybeWithDollars))
DeserializedPackageMemberScope(
this, packageProto, nameResolver,
JvmPackagePartSource(
JvmClassName.byInternalName(internalName),
JvmClassName.byFqNameWithoutInnerClasses(multifileClassFqName.asString()),
knownJvmBinaryClass = jvmBinaryClass
),
JvmPackagePartSource(partName, facadeName, knownJvmBinaryClass = jvmBinaryClass),
deserializationComponents, classNames = { emptyList() }
)
}
@@ -101,9 +98,6 @@ class IncrementalPackageFragmentProvider(
)
}
val multifileClassName: Name
get() = multifileClassFqName.shortName()
override fun getMemberScope() = memberScope()
}
}
@@ -18,9 +18,7 @@ package org.jetbrains.kotlin.resolve.jvm
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorNonRoot
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.load.java.descriptors.getImplClassNameForDeserialized
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.OverloadFilter
@@ -42,14 +40,8 @@ object JvmOverloadFilter : OverloadFilter {
if (overload is ConstructorDescriptor) continue
if (overload !is DeserializedCallableMemberDescriptor) continue
val containingDeclaration = overload.containingDeclaration
if (containingDeclaration !is PackageFragmentDescriptor) {
throw AssertionError("Package member expected; got $overload with containing declaration $containingDeclaration")
}
val implClassName = overload.getImplClassNameForDeserialized() ?: throw AssertionError("No implClassName: $overload")
val implClassFQN = containingDeclaration.fqName.child(implClassName)
if (!sourceClassesFQNs.contains(implClassFQN)) {
val implClassFQN = JvmFileClassUtil.getPartFqNameForDeserialized(overload)
if (implClassFQN !in sourceClassesFQNs) {
result.add(overload)
}
}
@@ -0,0 +1,18 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// LANGUAGE_VERSION: 1.2
// FILE: foo.kt
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
@file:JvmPackageName("jjj")
fun f(): String = "O"
val g: String? get() = "K"
inline fun i(block: () -> String) = block()
// FILE: bar.kt
fun box(): String = i { f() + g }
@@ -0,0 +1,19 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// LANGUAGE_VERSION: 1.2
// FILE: foo.kt
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
@file:JvmPackageName("jjj")
@file:JvmName("Foooo")
fun f(): String = "O"
val g: String? get() = "K"
inline fun i(block: () -> String) = block()
// FILE: bar.kt
fun box(): String = i { f() + g }
@@ -0,0 +1,25 @@
// IGNORE_BACKEND: NATIVE
// FILE: A.kt
// LANGUAGE_VERSION: 1.2
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@file:JvmPackageName("bar")
package foo
fun f() = "OK"
var v: Int = 1
inline fun i(block: () -> Unit) = block()
// FILE: B.kt
import foo.*
fun box(): String {
v = 2
if (v != 2) return "Fail"
i { v = 3 }
if (v != 3) return "Fail"
return f()
}
@@ -0,0 +1,18 @@
// IGNORE_BACKEND: NATIVE
// FILE: A.kt
// LANGUAGE_VERSION: 1.2
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@file:JvmPackageName("bar")
fun f() = "OK"
var v: Int = 1
// FILE: B.kt
fun box(): String {
v = 2
if (v != 2) return "Fail"
return f()
}
@@ -0,0 +1,22 @@
// IGNORE_BACKEND: NATIVE
// FILE: A.kt
// LANGUAGE_VERSION: 1.2
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@file:JvmPackageName("bar")
@file:JvmName("Baz")
package foo
fun f() = "OK"
var v: Int = 1
// FILE: B.kt
import foo.*
fun box(): String {
v = 2
if (v != 2) return "Fail"
return f()
}
@@ -0,0 +1,5 @@
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@file:JvmPackageName("j")
package bar
fun file0() {}
@@ -0,0 +1,6 @@
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@file:JvmName("JJ")
@file:JvmPackageName("jj")
package bar
fun jj() {}
@@ -0,0 +1,3 @@
package foo
fun file1() {}
@@ -0,0 +1,5 @@
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@file:JvmPackageName("jjj")
package foo
fun file2() {}
@@ -0,0 +1,5 @@
@file:JvmMultifileClass
@file:JvmName("MultiFoo")
package foo
fun multiFile1() {}
@@ -0,0 +1,7 @@
bar
j/BarAsJKt
jj/JJ
foo
foo/MultiFoo__FooMultiFileKt (foo/MultiFoo)
foo/FooKt
jjj/FooAsJJJKt
@@ -0,0 +1,5 @@
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@file:JvmPackageName("foo.jvm")
package foo
fun foo1() {}
@@ -0,0 +1,5 @@
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@file:JvmPackageName("foo.jvm")
package foo
fun foo2() {}
@@ -0,0 +1,5 @@
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@file:JvmPackageName("foo.jvm")
package foo
fun foo3() {}
@@ -0,0 +1,4 @@
foo
foo/jvm/Foo1Kt
foo/jvm/Foo2Kt
foo/jvm/Foo3Kt
@@ -1,10 +1,10 @@
bar
MultiBar__BarMultiFilePart1Kt (MultiBar)
MultiBar__BarMultiFilePart2Kt (MultiBar)
BarFileFacade1Kt
bar/MultiBar__BarMultiFilePart1Kt (bar/MultiBar)
bar/MultiBar__BarMultiFilePart2Kt (bar/MultiBar)
bar/BarFileFacade1Kt
foo
AnotherMultiFoo__AnotherFooMultiFilePart1Kt (AnotherMultiFoo)
MultiFoo__FooMultiFilePart1Kt (MultiFoo)
MultiFoo__FooMultiFilePart2Kt (MultiFoo)
FooFileFacade1Kt
FooFileFacade2Kt
foo/AnotherMultiFoo__AnotherFooMultiFilePart1Kt (foo/AnotherMultiFoo)
foo/MultiFoo__FooMultiFilePart1Kt (foo/MultiFoo)
foo/MultiFoo__FooMultiFilePart2Kt (foo/MultiFoo)
foo/FooFileFacade1Kt
foo/FooFileFacade2Kt
@@ -10409,11 +10409,23 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmPackageName"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("rootPackage.kt")
public void testRootPackage() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/rootPackage.kt");
doTest(fileName);
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/simple.kt");
doTest(fileName);
}
@TestMetadata("withJvmName.kt")
public void testWithJvmName() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/withJvmName.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/jvmStatic")
@@ -204,6 +204,7 @@ class KotlinCliJavaFileManagerTest : KotlinTestWithEnvironment() {
val root = StandardFileSystems.local().findFileByPath(javaFilesDir.path)!!
coreJavaFileManager.initialize(
JvmDependenciesIndexImpl(listOf(JavaRoot(root, JavaRoot.RootType.SOURCE))),
emptyList(),
SingleJavaFileRootsIndex(emptyList()),
useFastClassFilesReading = true
)
@@ -10409,11 +10409,23 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmPackageName"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("rootPackage.kt")
public void testRootPackage() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/rootPackage.kt");
doTest(fileName);
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/simple.kt");
doTest(fileName);
}
@TestMetadata("withJvmName.kt")
public void testWithJvmName() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/withJvmName.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/jvmStatic")
@@ -138,6 +138,24 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
doTest(fileName);
}
@TestMetadata("jvmPackageName.kt")
public void testJvmPackageName() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/jvmPackageName.kt");
doTest(fileName);
}
@TestMetadata("jvmPackageNameInRootPackage.kt")
public void testJvmPackageNameInRootPackage() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/jvmPackageNameInRootPackage.kt");
doTest(fileName);
}
@TestMetadata("jvmPackageNameWithJvmName.kt")
public void testJvmPackageNameWithJvmName() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/jvmPackageNameWithJvmName.kt");
doTest(fileName);
}
@TestMetadata("jvmStaticInObject.kt")
public void testJvmStaticInObject() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/jvmStaticInObject.kt");
@@ -19,14 +19,21 @@ package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.cli.AbstractCliTest
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
import java.io.File
class JvmPackageTableTest : KtUsefulTestCase() {
private fun doTest(relativeDirectory: String) {
private fun doTest(
relativeDirectory: String,
compileWith: LanguageVersion = LanguageVersion.LATEST_STABLE,
loadWith: LanguageVersion = LanguageVersion.LATEST_STABLE
) {
val directory = KotlinTestUtils.getTestDataPathBase() + relativeDirectory
val tmpdir = KotlinTestUtils.tmpDir(this::class.simpleName)
@@ -34,14 +41,17 @@ class JvmPackageTableTest : KtUsefulTestCase() {
val (output, exitCode) = AbstractCliTest.executeCompilerGrabOutput(K2JVMCompiler(), listOf(
directory,
"-d", tmpdir.path,
"-module-name", moduleName
"-module-name", moduleName,
"-language-version", compileWith.versionString
))
System.err.println(output) // normally output is empty
assertEquals("Compilation should complete successfully", ExitCode.OK, exitCode)
val mapping = ModuleMapping.create(
File(tmpdir, "META-INF/$moduleName.${ModuleMapping.MAPPING_FILE_EXT}").readBytes(), "test",
DeserializationConfiguration.Default
CompilerDeserializationConfiguration(
LanguageVersionSettingsImpl(loadWith, ApiVersion.createByLanguageVersion(loadWith))
)
)
val result = buildString {
for ((fqName, packageParts) in mapping.packageFqName2Parts) {
@@ -66,4 +76,14 @@ class JvmPackageTableTest : KtUsefulTestCase() {
fun testSimple() {
doTest("/jvmPackageTable/simple")
}
fun testJvmPackageName() {
doTest("/jvmPackageTable/jvmPackageName",
compileWith = LanguageVersion.KOTLIN_1_2, loadWith = LanguageVersion.KOTLIN_1_2)
}
fun testJvmPackageNameManyParts() {
doTest("/jvmPackageTable/jvmPackageNameManyParts",
compileWith = LanguageVersion.KOTLIN_1_2, loadWith = LanguageVersion.KOTLIN_1_2)
}
}
@@ -10409,11 +10409,23 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmPackageName"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("rootPackage.kt")
public void testRootPackage() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/rootPackage.kt");
doTest(fileName);
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/simple.kt");
doTest(fileName);
}
@TestMetadata("withJvmName.kt")
public void testWithJvmName() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmPackageName/withJvmName.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/jvmStatic")