diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassFileFactory.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassFileFactory.java index b5d753e810d..52eff0173a0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassFileFactory.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassFileFactory.java @@ -21,12 +21,14 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; +import kotlin.KotlinPackage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import org.jetbrains.kotlin.backend.common.output.OutputFile; import org.jetbrains.kotlin.backend.common.output.OutputFileCollection; import org.jetbrains.kotlin.codegen.state.GenerationState; +import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils; import org.jetbrains.kotlin.load.kotlin.PackageParts; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.psi.JetFile; @@ -92,14 +94,23 @@ public class ClassFileFactory implements OutputFileCollection { final JvmPackageTable.PackageTable.Builder builder = JvmPackageTable.PackageTable.newBuilder(); String outputFilePath = getMappingFileName(state.getModuleName()); + List parts = ContainerUtil.newArrayList(); + Set sourceFiles = new HashSet(); + for (PackageCodegen codegen : values) { - PackageParts.Companion.serialize(codegen.getPackageParts(), builder); + parts.add(codegen.getPackageParts()); + + // TODO extract common logic + sourceFiles.addAll(toIoFilesIgnoringNonPhysical(PackagePartClassUtils.getFilesWithCallables(codegen.getFiles()))); + } + + for (PackageParts part : CodegenPackage.addCompiledPartsAndSort(parts, state)) { + PackageParts.Companion.serialize(part, builder); } if (builder.getPackagePartsCount() != 0) { - state.getProgress().reportOutput(Collections.emptyList(), new File(outputFilePath)); - //TODO: source files? - generators.put(outputFilePath, new OutAndSourceFileList(Collections.emptyList()) { + state.getProgress().reportOutput(sourceFiles, new File(outputFilePath)); + generators.put(outputFilePath, new OutAndSourceFileList(KotlinPackage.toList(sourceFiles)) { @Override public byte[] asBytes(ClassBuilderFactory factory) { try { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackageCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackageCodegen.java index 56824eb61d4..5627a57eeb1 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackageCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackageCodegen.java @@ -35,9 +35,6 @@ import org.jetbrains.kotlin.codegen.context.MethodContext; import org.jetbrains.kotlin.codegen.context.PackageContext; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.config.IncrementalCompilation; -import org.jetbrains.kotlin.load.kotlin.KotlinPackage; -import org.jetbrains.kotlin.load.kotlin.PackageParts; -import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus; import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor; @@ -45,8 +42,10 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticUtils; import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.java.JvmAnnotationNames; import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils; +import org.jetbrains.kotlin.load.kotlin.PackageParts; import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider; import org.jetbrains.kotlin.name.FqName; +import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.MemberComparator; @@ -427,4 +426,8 @@ public class PackageCodegen { public PackageParts getPackageParts() { return packageParts; } + + public Collection getFiles() { + return files; + } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/classFileUtils.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/classFileUtils.kt index 6be14eb4987..9ed21a31ff7 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/classFileUtils.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/classFileUtils.kt @@ -17,6 +17,9 @@ package org.jetbrains.kotlin.codegen import org.jetbrains.kotlin.backend.common.output.OutputFile +import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.load.kotlin.ModuleMapping +import org.jetbrains.kotlin.load.kotlin.PackageParts fun ClassFileFactory.getClassFiles(): Iterable { return asList().filterClassFiles() @@ -24,4 +27,32 @@ fun ClassFileFactory.getClassFiles(): Iterable { fun List.filterClassFiles(): Iterable { return filter { it.relativePath.endsWith(".class") } -} \ No newline at end of file +} + +fun List.addCompiledPartsAndSort(state: GenerationState): List = + addCompiledParts(state).sortedBy { it.packageFqName } + +private fun List.addCompiledParts(state: GenerationState): List { + if (state.incrementalCompilationComponents == null || state.moduleId == null) return this + + val incrementalCache = state.incrementalCompilationComponents.getIncrementalCache(state.moduleId) + val moduleMappingData = incrementalCache.getModuleMappingData() ?: return this + + val mapping = ModuleMapping(moduleMappingData) + + incrementalCache.getObsoletePackageParts().forEach { + val i = it.lastIndexOf('/') + val qualifier = if (i == -1) "" else it.substring(0, i).replace('/', '.') + val name = it.substring(i + 1) + mapping.findPackageParts(qualifier)?.run { parts.remove(name) } + } + + return (this + mapping.packageFqName2Parts.values()) + .groupBy { it.packageFqName } + .map { + val (packageFqName, packageParts) = it + val newPackageParts = PackageParts(packageFqName) + packageParts.forEach { newPackageParts.parts.addAll(it.parts) } + newPackageParts + } +}