Incremental compilation support for multifile classes.
This commit is contained in:
@@ -887,6 +887,17 @@ public class AsmUtil {
|
|||||||
return JvmClassName.byFqNameWithoutInnerClasses(fqName).getInternalName();
|
return JvmClassName.byFqNameWithoutInnerClasses(fqName).getInternalName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static String getSimpleInternalName(@NotNull String internalName) {
|
||||||
|
int lastSlash = internalName.lastIndexOf('/');
|
||||||
|
if (lastSlash >= 0) {
|
||||||
|
return internalName.substring(lastSlash + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return internalName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void putJavaLangClassInstance(@NotNull InstructionAdapter v, @NotNull Type type) {
|
public static void putJavaLangClassInstance(@NotNull InstructionAdapter v, @NotNull Type type) {
|
||||||
if (isPrimitive(type)) {
|
if (isPrimitive(type)) {
|
||||||
v.getstatic(boxType(type).getInternalName(), "TYPE", "Ljava/lang/Class;");
|
v.getstatic(boxType(type).getInternalName(), "TYPE", "Ljava/lang/Class;");
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ public class FunctionCodegen {
|
|||||||
private void writePackageFacadeMethodAnnotationsIfNeeded(MethodVisitor mv) {
|
private void writePackageFacadeMethodAnnotationsIfNeeded(MethodVisitor mv) {
|
||||||
if (owner instanceof PackageFacadeContext) {
|
if (owner instanceof PackageFacadeContext) {
|
||||||
PackageFacadeContext packageFacadeContext = (PackageFacadeContext) owner;
|
PackageFacadeContext packageFacadeContext = (PackageFacadeContext) owner;
|
||||||
Type delegateToClassType = packageFacadeContext.getDelegateToClassType();
|
Type delegateToClassType = packageFacadeContext.getPublicFacadeType();
|
||||||
if (delegateToClassType != null) {
|
if (delegateToClassType != null) {
|
||||||
String className = delegateToClassType.getClassName();
|
String className = delegateToClassType.getClassName();
|
||||||
AnnotationVisitor
|
AnnotationVisitor
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.codegen;
|
package org.jetbrains.kotlin.codegen;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
import com.intellij.util.containers.HashMap;
|
||||||
import com.intellij.util.containers.MultiMap;
|
import com.intellij.util.containers.MultiMap;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
@@ -29,9 +30,7 @@ import org.jetbrains.kotlin.psi.JetScript;
|
|||||||
import org.jetbrains.kotlin.resolve.ScriptNameUtil;
|
import org.jetbrains.kotlin.resolve.ScriptNameUtil;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.registerClassNameForScript;
|
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.registerClassNameForScript;
|
||||||
|
|
||||||
@@ -85,17 +84,18 @@ public class KotlinCodegenFacade {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Set<FqName> obsoleteMultifileClasses = new HashSet<FqName>(state.getObsoleteMultifileClasses());
|
||||||
|
for (FqName multifileClassFqName : Sets.union(filesInMultifileClasses.keySet(), obsoleteMultifileClasses)) {
|
||||||
|
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||||
|
generateMultifileClass(state, multifileClassFqName, filesInMultifileClasses.get(multifileClassFqName), errorHandler);
|
||||||
|
}
|
||||||
|
|
||||||
Set<FqName> packagesWithObsoleteParts = new HashSet<FqName>(state.getPackagesWithObsoleteParts());
|
Set<FqName> packagesWithObsoleteParts = new HashSet<FqName>(state.getPackagesWithObsoleteParts());
|
||||||
for (FqName packageFqName : Sets.union(packagesWithObsoleteParts, filesInPackageClasses.keySet())) {
|
for (FqName packageFqName : Sets.union(packagesWithObsoleteParts, filesInPackageClasses.keySet())) {
|
||||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||||
generatePackage(state, packageFqName, filesInPackageClasses.get(packageFqName), errorHandler);
|
generatePackage(state, packageFqName, filesInPackageClasses.get(packageFqName), errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (FqName multifileClassFqName : filesInMultifileClasses.keySet()) {
|
|
||||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
|
||||||
generateMultifileClass(state, multifileClassFqName, filesInMultifileClasses.get(multifileClassFqName), errorHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||||
state.getFactory().done();
|
state.getFactory().done();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,11 +21,14 @@ import com.intellij.openapi.progress.ProcessCanceledException
|
|||||||
import com.intellij.util.ArrayUtil
|
import com.intellij.util.ArrayUtil
|
||||||
import com.intellij.util.SmartList
|
import com.intellij.util.SmartList
|
||||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
|
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
|
||||||
|
import org.jetbrains.kotlin.codegen.context.MethodContext
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
||||||
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||||
import org.jetbrains.kotlin.fileClasses.getFileClassType
|
import org.jetbrains.kotlin.fileClasses.getFileClassType
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||||
@@ -37,9 +40,18 @@ import org.jetbrains.kotlin.psi.*
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.MemberComparator
|
import org.jetbrains.kotlin.resolve.MemberComparator
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClass
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClass
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClassPart
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClassPart
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||||
|
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
@@ -55,14 +67,19 @@ public class MultifileClassCodegen(
|
|||||||
|
|
||||||
private val packageFragment = getOnlyPackageFragment(facadeFqName.parent(), files, state.bindingContext)
|
private val packageFragment = getOnlyPackageFragment(facadeFqName.parent(), files, state.bindingContext)
|
||||||
|
|
||||||
private val compiledPackageFragment = getCompiledPackageFragment(facadeFqName.parent(), state)
|
private val compiledPackageFragment = getCompiledPackageFragment(facadeFqName, state)
|
||||||
|
|
||||||
|
private val previouslyCompiledCallables =
|
||||||
|
if (compiledPackageFragment == null)
|
||||||
|
emptyList<DeserializedCallableMemberDescriptor>()
|
||||||
|
else
|
||||||
|
getDeserializedCallables(compiledPackageFragment)
|
||||||
|
|
||||||
|
private fun getDeserializedCallables(compiledPackageFragment: PackageFragmentDescriptor) =
|
||||||
|
compiledPackageFragment.getMemberScope().getDescriptors(DescriptorKindFilter.CALLABLES, JetScope.ALL_NAME_FILTER).filterIsInstance<DeserializedCallableMemberDescriptor>()
|
||||||
|
|
||||||
public val packageParts = PackageParts(facadeFqName.parent().asString())
|
public val packageParts = PackageParts(facadeFqName.parent().asString())
|
||||||
|
|
||||||
// TODO incremental compilation support
|
|
||||||
// TODO previouslyCompiledCallables
|
|
||||||
// We can do this (probably without 'compiledPackageFragment') after modifications to part codegen.
|
|
||||||
|
|
||||||
private val classBuilder = ClassBuilderOnDemand {
|
private val classBuilder = ClassBuilderOnDemand {
|
||||||
val originFile = files.firstOrNull()
|
val originFile = files.firstOrNull()
|
||||||
val actualPackageFragment = packageFragment ?:
|
val actualPackageFragment = packageFragment ?:
|
||||||
@@ -72,7 +89,9 @@ public class MultifileClassCodegen(
|
|||||||
val classBuilder = state.factory.newVisitor(declarationOrigin, facadeClassType, files)
|
val classBuilder = state.factory.newVisitor(declarationOrigin, facadeClassType, files)
|
||||||
|
|
||||||
val filesWithCallables = files.filter { it.declarations.any { it is JetNamedFunction || it is JetProperty } }
|
val filesWithCallables = files.filter { it.declarations.any { it is JetNamedFunction || it is JetProperty } }
|
||||||
val singleSourceFile = filesWithCallables.singleOrNull()
|
|
||||||
|
val singleSourceFile = if (previouslyCompiledCallables.isNotEmpty()) null else filesWithCallables.singleOrNull()
|
||||||
|
|
||||||
classBuilder.defineClass(singleSourceFile, Opcodes.V1_6, FACADE_CLASS_ATTRIBUTES,
|
classBuilder.defineClass(singleSourceFile, Opcodes.V1_6, FACADE_CLASS_ATTRIBUTES,
|
||||||
facadeClassType.internalName,
|
facadeClassType.internalName,
|
||||||
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY)
|
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY)
|
||||||
@@ -86,6 +105,20 @@ public class MultifileClassCodegen(
|
|||||||
val generateCallableMemberTasks = HashMap<CallableMemberDescriptor, () -> Unit>()
|
val generateCallableMemberTasks = HashMap<CallableMemberDescriptor, () -> Unit>()
|
||||||
val partFqNames = arrayListOf<FqName>()
|
val partFqNames = arrayListOf<FqName>()
|
||||||
|
|
||||||
|
generateCodeForSourceFiles(errorHandler, generateCallableMemberTasks, partFqNames)
|
||||||
|
|
||||||
|
generateDelegatesToPreviouslyCompiledParts(generateCallableMemberTasks, partFqNames)
|
||||||
|
|
||||||
|
if (!generateCallableMemberTasks.isEmpty()) {
|
||||||
|
generateMultifileFacadeClass(generateCallableMemberTasks, partFqNames)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateCodeForSourceFiles(
|
||||||
|
errorHandler: CompilationErrorHandler,
|
||||||
|
generateCallableMemberTasks: MutableMap<CallableMemberDescriptor, () -> Unit>,
|
||||||
|
partFqNames: MutableList<FqName>
|
||||||
|
) {
|
||||||
for (file in files) {
|
for (file in files) {
|
||||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||||
try {
|
try {
|
||||||
@@ -104,12 +137,6 @@ public class MultifileClassCodegen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateDelegationsToPreviouslyCompiled(generateCallableMemberTasks)
|
|
||||||
|
|
||||||
if (!generateCallableMemberTasks.isEmpty()) {
|
|
||||||
generateMultifileFacadeClass(generateCallableMemberTasks, partFqNames)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateMultifileFacadeClass(
|
private fun generateMultifileFacadeClass(
|
||||||
@@ -187,6 +214,55 @@ public class MultifileClassCodegen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun generateDelegatesToPreviouslyCompiledParts(
|
||||||
|
generateCallableMemberTasks: MutableMap<CallableMemberDescriptor, () -> Unit>,
|
||||||
|
partFqNames: MutableList<FqName>
|
||||||
|
) {
|
||||||
|
if (compiledPackageFragment == null) return
|
||||||
|
|
||||||
|
partFqNames.addAll(compiledPackageFragment.partsNames.map { JvmClassName.byInternalName(it).fqNameForClassNameWithoutDollars })
|
||||||
|
|
||||||
|
for (callable in previouslyCompiledCallables) {
|
||||||
|
val partFqName = JvmFileClassUtil.getPartFqNameForDeserializedCallable(callable)
|
||||||
|
val partType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(partFqName)
|
||||||
|
|
||||||
|
generateCallableMemberTasks[callable] = { generateDelegateToCompiledMember(callable, compiledPackageFragment, partType) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateDelegateToCompiledMember(
|
||||||
|
member: CallableMemberDescriptor,
|
||||||
|
compiledPackageFragment: PackageFragmentDescriptor,
|
||||||
|
partType: Type
|
||||||
|
) {
|
||||||
|
val context = state.rootContext.intoMultifileClass(compiledPackageFragment, facadeClassType, partType)
|
||||||
|
|
||||||
|
val memberCodegen = createCodegenForPartOfMultifileFacade(context)
|
||||||
|
|
||||||
|
when (member) {
|
||||||
|
is DeserializedSimpleFunctionDescriptor -> {
|
||||||
|
memberCodegen.functionCodegen.generateMethod(OtherOrigin(member), member, DelegateToCompiledMemberGenerationStrategy)
|
||||||
|
|
||||||
|
memberCodegen.functionCodegen.generateDefaultIfNeeded(
|
||||||
|
context.intoFunction(member), member, OwnerKind.PACKAGE, DefaultParameterValueLoader.DEFAULT, null)
|
||||||
|
|
||||||
|
memberCodegen.functionCodegen.generateOverloadsWithDefaultValues(null, member, member)
|
||||||
|
}
|
||||||
|
is DeserializedPropertyDescriptor -> {
|
||||||
|
memberCodegen.propertyCodegen.generateInPackageFacade(member)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
throw IllegalStateException("Unexpected member: " + member)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object DelegateToCompiledMemberGenerationStrategy : FunctionGenerationStrategy() {
|
||||||
|
override fun generateBody(mv: MethodVisitor, frameMap: FrameMap, signature: JvmMethodSignature, context: MethodContext, parentCodegen: MemberCodegen<*>) {
|
||||||
|
throw IllegalStateException("shouldn't be called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun generateKotlinPackageReflectionField() {
|
private fun generateKotlinPackageReflectionField() {
|
||||||
val mv = classBuilder.newMethod(JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_STATIC, "<clinit>", "()V", null, null)
|
val mv = classBuilder.newMethod(JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_STATIC, "<clinit>", "()V", null, null)
|
||||||
val method = AsmUtil.method("createKotlinPackage",
|
val method = AsmUtil.method("createKotlinPackage",
|
||||||
@@ -246,12 +322,19 @@ public class MultifileClassCodegen(
|
|||||||
return fragments.firstOrNull()
|
return fragments.firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCompiledPackageFragment(packageFqName: FqName, state: GenerationState): PackageFragmentDescriptor? =
|
private fun getCompiledPackageFragment(facadeFqName: FqName, state: GenerationState):
|
||||||
if (!IncrementalCompilation.isEnabled()) null
|
IncrementalPackageFragmentProvider.IncrementalPackageFragment.IncrementalMultifileClassPackageFragment? {
|
||||||
else state.module.getPackage(packageFqName).fragments.firstOrNull { fragment ->
|
if (!IncrementalCompilation.isEnabled()) return null
|
||||||
|
|
||||||
|
val packageFqName = facadeFqName.parent()
|
||||||
|
|
||||||
|
val incrementalPackageFragment = state.module.getPackage(packageFqName).fragments.firstOrNull { fragment ->
|
||||||
fragment is IncrementalPackageFragmentProvider.IncrementalPackageFragment &&
|
fragment is IncrementalPackageFragmentProvider.IncrementalPackageFragment &&
|
||||||
fragment.target == state.targetId
|
fragment.target == state.targetId
|
||||||
}
|
} as IncrementalPackageFragmentProvider.IncrementalPackageFragment?
|
||||||
|
|
||||||
|
return incrementalPackageFragment?.getPackageFragmentForMultifileClass(facadeFqName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
|
|||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
||||||
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
|
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
|
||||||
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||||
@@ -52,6 +53,7 @@ import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStat
|
|||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
import org.jetbrains.kotlin.resolve.MemberComparator;
|
import org.jetbrains.kotlin.resolve.MemberComparator;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||||
@@ -83,7 +85,7 @@ public class PackageCodegen {
|
|||||||
private final Collection<JetFile> files;
|
private final Collection<JetFile> files;
|
||||||
private final Type packageClassType;
|
private final Type packageClassType;
|
||||||
private final PackageFragmentDescriptor packageFragment;
|
private final PackageFragmentDescriptor packageFragment;
|
||||||
private final PackageFragmentDescriptor compiledPackageFragment;
|
private final IncrementalPackageFragmentProvider.IncrementalPackageFragment compiledPackageFragment;
|
||||||
private final List<DeserializedCallableMemberDescriptor> previouslyCompiledCallables;
|
private final List<DeserializedCallableMemberDescriptor> previouslyCompiledCallables;
|
||||||
|
|
||||||
private final PackageParts packageParts;
|
private final PackageParts packageParts;
|
||||||
@@ -141,7 +143,7 @@ public class PackageCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private PackageFragmentDescriptor getCompiledPackageFragment(@NotNull FqName fqName) {
|
private IncrementalPackageFragmentProvider.IncrementalPackageFragment getCompiledPackageFragment(@NotNull FqName fqName) {
|
||||||
if (!IncrementalCompilation.isEnabled()) {
|
if (!IncrementalCompilation.isEnabled()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -150,7 +152,7 @@ public class PackageCodegen {
|
|||||||
for (PackageFragmentDescriptor fragment : state.getModule().getPackage(fqName).getFragments()) {
|
for (PackageFragmentDescriptor fragment : state.getModule().getPackage(fqName).getFragments()) {
|
||||||
if (fragment instanceof IncrementalPackageFragmentProvider.IncrementalPackageFragment &&
|
if (fragment instanceof IncrementalPackageFragmentProvider.IncrementalPackageFragment &&
|
||||||
((IncrementalPackageFragmentProvider.IncrementalPackageFragment) fragment).getTarget().equals(state.getTargetId())) {
|
((IncrementalPackageFragmentProvider.IncrementalPackageFragment) fragment).getTarget().equals(state.getTargetId())) {
|
||||||
return fragment;
|
return (IncrementalPackageFragmentProvider.IncrementalPackageFragment) fragment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -172,13 +174,12 @@ public class PackageCodegen {
|
|||||||
|
|
||||||
private void generateDelegationsToPreviouslyCompiled(@NotNull @Mutable Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks) {
|
private void generateDelegationsToPreviouslyCompiled(@NotNull @Mutable Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks) {
|
||||||
for (final DeserializedCallableMemberDescriptor member : previouslyCompiledCallables) {
|
for (final DeserializedCallableMemberDescriptor member : previouslyCompiledCallables) {
|
||||||
|
final FqName delegateToFqName = JvmFileClassUtil.getPartFqNameForDeserializedCallable(member);
|
||||||
|
|
||||||
generateCallableMemberTasks.put(member, new Runnable() {
|
generateCallableMemberTasks.put(member, new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
FieldOwnerContext context = state.getRootContext().intoPackageFacade(
|
FieldOwnerContext context = getPackageFacadeContextForPreviouslyCompiled(delegateToFqName);
|
||||||
AsmUtil.asmTypeByFqNameWithoutInnerClasses(PackagePartClassUtils.getPackagePartFqName(member)),
|
|
||||||
compiledPackageFragment
|
|
||||||
);
|
|
||||||
|
|
||||||
MemberCodegen<?> memberCodegen = createCodegenForPartOfPackageFacade(context);
|
MemberCodegen<?> memberCodegen = createCodegenForPartOfPackageFacade(context);
|
||||||
|
|
||||||
@@ -216,6 +217,24 @@ public class PackageCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private FieldOwnerContext getPackageFacadeContextForPreviouslyCompiled(@NotNull FqName delegateToFqName) {
|
||||||
|
Type delegateToType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(delegateToFqName);
|
||||||
|
String partInternalName = JvmClassName.byFqNameWithoutInnerClasses(delegateToFqName).getInternalName();
|
||||||
|
String facadeInternalName = compiledPackageFragment.getMultifileFacade(partInternalName);
|
||||||
|
|
||||||
|
Type publicFacadeType;
|
||||||
|
if (facadeInternalName != null) {
|
||||||
|
FqName facadeFqName = JvmClassName.byInternalName(facadeInternalName).getFqNameForClassNameWithoutDollars();
|
||||||
|
publicFacadeType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(facadeFqName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
publicFacadeType = delegateToType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.getRootContext().intoPackageFacade(delegateToType, compiledPackageFragment, publicFacadeType);
|
||||||
|
}
|
||||||
|
|
||||||
public void generate(@NotNull CompilationErrorHandler errorHandler) {
|
public void generate(@NotNull CompilationErrorHandler errorHandler) {
|
||||||
List<JvmSerializationBindings> bindings = new ArrayList<JvmSerializationBindings>(files.size() + 1);
|
List<JvmSerializationBindings> bindings = new ArrayList<JvmSerializationBindings>(files.size() + 1);
|
||||||
|
|
||||||
@@ -302,12 +321,17 @@ public class PackageCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private ClassBuilder generateFile(@NotNull JetFile file, @NotNull Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks) {
|
private ClassBuilder generateFile(
|
||||||
|
@NotNull JetFile file,
|
||||||
|
@NotNull Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks
|
||||||
|
) {
|
||||||
JvmFileClassInfo fileClassInfo = state.getFileClassesProvider().getFileClassInfo(file);
|
JvmFileClassInfo fileClassInfo = state.getFileClassesProvider().getFileClassInfo(file);
|
||||||
|
|
||||||
if (fileClassInfo.getTEMP_isMultifileClass()) {
|
if (fileClassInfo.getIsMultifileClass()) {
|
||||||
Type fileFacadeType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.getFacadeClassFqName());
|
FqName partClassFqName = fileClassInfo.getFileClassFqName();
|
||||||
addDelegateToFileClassMemberTasks(file, generateCallableMemberTasks, fileFacadeType);
|
Type delegateToType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(partClassFqName);
|
||||||
|
Type publicFacadeType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.getFacadeClassFqName());
|
||||||
|
addDelegateToFileClassMemberTasks(file, generateCallableMemberTasks, delegateToType, publicFacadeType);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,7 +369,7 @@ public class PackageCodegen {
|
|||||||
|
|
||||||
new PackagePartCodegen(builder, file, fileClassType, packagePartContext, state).generate();
|
new PackagePartCodegen(builder, file, fileClassType, packagePartContext, state).generate();
|
||||||
|
|
||||||
addDelegateToFileClassMemberTasks(file, generateCallableMemberTasks, fileClassType);
|
addDelegateToFileClassMemberTasks(file, generateCallableMemberTasks, fileClassType, fileClassType);
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
@@ -353,9 +377,10 @@ public class PackageCodegen {
|
|||||||
private void addDelegateToFileClassMemberTasks(
|
private void addDelegateToFileClassMemberTasks(
|
||||||
@NotNull JetFile file,
|
@NotNull JetFile file,
|
||||||
@NotNull Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks,
|
@NotNull Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks,
|
||||||
@NotNull Type fileClassType
|
@NotNull Type fileClassType,
|
||||||
|
@NotNull Type publicFacadeType
|
||||||
) {
|
) {
|
||||||
FieldOwnerContext packageFacade = state.getRootContext().intoPackageFacade(fileClassType, packageFragment);
|
FieldOwnerContext packageFacade = state.getRootContext().intoPackageFacade(fileClassType, packageFragment, publicFacadeType);
|
||||||
final MemberCodegen<?> memberCodegen = createCodegenForPartOfPackageFacade(packageFacade);
|
final MemberCodegen<?> memberCodegen = createCodegenForPartOfPackageFacade(packageFacade);
|
||||||
|
|
||||||
for (final JetDeclaration declaration : file.getDeclarations()) {
|
for (final JetDeclaration declaration : file.getDeclarations()) {
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ public class PropertyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void generateInPackageFacade(@NotNull DeserializedPropertyDescriptor deserializedProperty) {
|
public void generateInPackageFacade(@NotNull DeserializedPropertyDescriptor deserializedProperty) {
|
||||||
assert context instanceof PackageFacadeContext : "should be called only for generating package facade: " + context;
|
assert context instanceof DelegatingFacadeContext : "should be called only for generating facade: " + context;
|
||||||
gen(null, deserializedProperty, null, null);
|
gen(null, deserializedProperty, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -185,8 +185,8 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public FieldOwnerContext intoPackageFacade(@NotNull Type delegateTo, @NotNull PackageFragmentDescriptor descriptor) {
|
public FieldOwnerContext intoPackageFacade(@NotNull Type delegateTo, @NotNull PackageFragmentDescriptor descriptor, @NotNull Type publicFacadeType) {
|
||||||
return new PackageFacadeContext(descriptor, this, delegateTo);
|
return new PackageFacadeContext(descriptor, this, delegateTo, publicFacadeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -22,13 +22,25 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
|
|||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
|
||||||
public class PackageFacadeContext extends PackageContext implements DelegatingFacadeContext {
|
public class PackageFacadeContext extends PackageContext implements DelegatingFacadeContext {
|
||||||
|
private final Type publicFacadeType;
|
||||||
|
|
||||||
public PackageFacadeContext(
|
public PackageFacadeContext(
|
||||||
@NotNull PackageFragmentDescriptor contextDescriptor,
|
@NotNull PackageFragmentDescriptor contextDescriptor,
|
||||||
@NotNull CodegenContext parent,
|
@NotNull CodegenContext parent,
|
||||||
@NotNull Type packagePartType
|
@NotNull Type packagePartType
|
||||||
|
) {
|
||||||
|
this(contextDescriptor, parent, packagePartType, packagePartType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PackageFacadeContext(
|
||||||
|
@NotNull PackageFragmentDescriptor contextDescriptor,
|
||||||
|
@NotNull CodegenContext parent,
|
||||||
|
@NotNull Type packagePartType,
|
||||||
|
@NotNull Type publicFacadeType
|
||||||
) {
|
) {
|
||||||
super(contextDescriptor, parent, packagePartType);
|
super(contextDescriptor, parent, packagePartType);
|
||||||
|
|
||||||
|
this.publicFacadeType = publicFacadeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -36,4 +48,8 @@ public class PackageFacadeContext extends PackageContext implements DelegatingFa
|
|||||||
public Type getDelegateToClassType() {
|
public Type getDelegateToClassType() {
|
||||||
return getPackagePartType();
|
return getPackagePartType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Type getPublicFacadeType() {
|
||||||
|
return publicFacadeType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,10 +231,10 @@ public class InlineCodegen extends CallGenerator {
|
|||||||
|
|
||||||
SMAP smap;
|
SMAP smap;
|
||||||
if (callDefault) {
|
if (callDefault) {
|
||||||
Type ownerType = typeMapper.mapOwner(functionDescriptor);
|
Type implementationOwner = typeMapper.mapImplementationOwner(functionDescriptor);
|
||||||
FakeMemberCodegen parentCodegen = new FakeMemberCodegen(codegen.getParentCodegen(), inliningFunction,
|
FakeMemberCodegen parentCodegen = new FakeMemberCodegen(codegen.getParentCodegen(), inliningFunction,
|
||||||
(FieldOwnerContext) methodContext.getParentContext(),
|
(FieldOwnerContext) methodContext.getParentContext(),
|
||||||
ownerType.getInternalName());
|
implementationOwner.getInternalName());
|
||||||
FunctionCodegen.generateDefaultImplBody(
|
FunctionCodegen.generateDefaultImplBody(
|
||||||
methodContext, functionDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
|
methodContext, functionDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
|
||||||
inliningFunction, parentCodegen
|
inliningFunction, parentCodegen
|
||||||
@@ -343,7 +343,7 @@ public class InlineCodegen extends CallGenerator {
|
|||||||
new FakeMemberCodegen(codegen.getParentCodegen(), expression,
|
new FakeMemberCodegen(codegen.getParentCodegen(), expression,
|
||||||
(FieldOwnerContext) context.getParentContext(),
|
(FieldOwnerContext) context.getParentContext(),
|
||||||
isLambda ? codegen.getParentCodegen().getClassName()
|
isLambda ? codegen.getParentCodegen().getClassName()
|
||||||
: typeMapper.mapOwner(descriptor).getInternalName());
|
: typeMapper.mapImplementationOwner(descriptor).getInternalName());
|
||||||
|
|
||||||
FunctionGenerationStrategy strategy =
|
FunctionGenerationStrategy strategy =
|
||||||
expression instanceof JetCallableReferenceExpression ?
|
expression instanceof JetCallableReferenceExpression ?
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public class GenerationState @JvmOverloads constructor(
|
|||||||
public val packageFacadesAsMultifileClasses: Boolean = false,
|
public val packageFacadesAsMultifileClasses: Boolean = false,
|
||||||
public val diagnostics: DiagnosticSink = DiagnosticSink.DO_NOTHING,
|
public val diagnostics: DiagnosticSink = DiagnosticSink.DO_NOTHING,
|
||||||
public val packagesWithObsoleteParts: Collection<FqName> = emptySet(),
|
public val packagesWithObsoleteParts: Collection<FqName> = emptySet(),
|
||||||
|
public val obsoleteMultifileClasses: Collection<FqName> = emptySet(),
|
||||||
// for PackageCodegen in incremental compilation mode
|
// for PackageCodegen in incremental compilation mode
|
||||||
public val targetId: TargetId? = null,
|
public val targetId: TargetId? = null,
|
||||||
moduleName: String? = null,
|
moduleName: String? = null,
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
|||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
||||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope;
|
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope;
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider;
|
||||||
import org.jetbrains.kotlin.name.*;
|
import org.jetbrains.kotlin.name.*;
|
||||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
|
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
|
||||||
import org.jetbrains.kotlin.psi.JetExpression;
|
import org.jetbrains.kotlin.psi.JetExpression;
|
||||||
@@ -136,13 +137,23 @@ public class JetTypeMapper {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Type mapOwner(@NotNull DeclarationDescriptor descriptor) {
|
public Type mapOwner(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
return mapOwner(descriptor, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Type mapImplementationOwner(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
return mapOwner(descriptor, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Type mapOwner(@NotNull DeclarationDescriptor descriptor, boolean isImplementation) {
|
||||||
if (isLocalFunction(descriptor)) {
|
if (isLocalFunction(descriptor)) {
|
||||||
return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor);
|
return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||||
if (container instanceof PackageFragmentDescriptor) {
|
if (container instanceof PackageFragmentDescriptor) {
|
||||||
return Type.getObjectType(internalNameForPackage((CallableMemberDescriptor) descriptor));
|
return Type.getObjectType(internalNameForPackageMemberOwner((CallableMemberDescriptor) descriptor, isImplementation));
|
||||||
}
|
}
|
||||||
else if (container instanceof ClassDescriptor) {
|
else if (container instanceof ClassDescriptor) {
|
||||||
return mapClass((ClassDescriptor) container);
|
return mapClass((ClassDescriptor) container);
|
||||||
@@ -156,11 +167,11 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private String internalNameForPackage(@NotNull CallableMemberDescriptor descriptor) {
|
private String internalNameForPackageMemberOwner(@NotNull CallableMemberDescriptor descriptor, boolean isImplementation) {
|
||||||
JetFile file = DescriptorToSourceUtils.getContainingFile(descriptor);
|
JetFile file = DescriptorToSourceUtils.getContainingFile(descriptor);
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
Visibility visibility = descriptor.getVisibility();
|
Visibility visibility = descriptor.getVisibility();
|
||||||
if (descriptor instanceof PropertyDescriptor || Visibilities.isPrivate(visibility)) {
|
if (isImplementation || descriptor instanceof PropertyDescriptor || Visibilities.isPrivate(visibility)) {
|
||||||
return FileClassesPackage.getFileClassInternalName(fileClassesProvider, file);
|
return FileClassesPackage.getFileClassInternalName(fileClassesProvider, file);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -171,7 +182,7 @@ public class JetTypeMapper {
|
|||||||
CallableMemberDescriptor directMember = getDirectMember(descriptor);
|
CallableMemberDescriptor directMember = getDirectMember(descriptor);
|
||||||
|
|
||||||
if (directMember instanceof DeserializedCallableMemberDescriptor) {
|
if (directMember instanceof DeserializedCallableMemberDescriptor) {
|
||||||
String facadeFqName = getPackageMemberOwnerInternalName((DeserializedCallableMemberDescriptor) directMember);
|
String facadeFqName = getPackageMemberOwnerInternalName((DeserializedCallableMemberDescriptor) directMember, isImplementation);
|
||||||
if (facadeFqName != null) return facadeFqName;
|
if (facadeFqName != null) return facadeFqName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +191,7 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static String getPackageMemberOwnerInternalName(@NotNull DeserializedCallableMemberDescriptor descriptor) {
|
private static String getPackageMemberOwnerInternalName(@NotNull DeserializedCallableMemberDescriptor descriptor, boolean isImplementation) {
|
||||||
// XXX This method (and getPackageMemberOwnerShortName) is a dirty hack
|
// XXX This method (and getPackageMemberOwnerShortName) is a dirty hack
|
||||||
// introduced to make stdlib work with package facades built as multifile facades for M13.
|
// introduced to make stdlib work with package facades built as multifile facades for M13.
|
||||||
// We need some safe, concise way to identify multifile facade and multifile part
|
// We need some safe, concise way to identify multifile facade and multifile part
|
||||||
@@ -193,7 +204,7 @@ public class JetTypeMapper {
|
|||||||
assert containingDeclaration instanceof PackageFragmentDescriptor : "Not a top-level member: " + descriptor;
|
assert containingDeclaration instanceof PackageFragmentDescriptor : "Not a top-level member: " + descriptor;
|
||||||
PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration;
|
PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration;
|
||||||
|
|
||||||
String facadeShortName = getPackageMemberOwnerShortName(descriptor);
|
String facadeShortName = getPackageMemberOwnerShortName(descriptor, isImplementation);
|
||||||
if (facadeShortName == null) {
|
if (facadeShortName == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -203,27 +214,40 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static String getPackageMemberOwnerShortName(@NotNull DeserializedCallableMemberDescriptor descriptor) {
|
private static String getPackageMemberOwnerShortName(@NotNull DeserializedCallableMemberDescriptor descriptor, boolean isImplementation) {
|
||||||
// XXX Dirty hack; see getPackageMemberOwnerInternalName above for more details.
|
// XXX Dirty hack; see getPackageMemberOwnerInternalName above for more details.
|
||||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||||
if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
||||||
|
Name implClassName = JvmFileClassUtil.getImplClassName(descriptor);
|
||||||
|
if (isImplementation) {
|
||||||
|
return implClassName.asString();
|
||||||
|
}
|
||||||
|
|
||||||
PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration;
|
PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration;
|
||||||
JetScope scope = packageFragmentDescriptor.getMemberScope();
|
JetScope scope = packageFragmentDescriptor.getMemberScope();
|
||||||
if (scope instanceof AbstractScopeAdapter) {
|
if (scope instanceof AbstractScopeAdapter) {
|
||||||
scope = ((AbstractScopeAdapter) scope).getActualScope();
|
scope = ((AbstractScopeAdapter) scope).getActualScope();
|
||||||
}
|
}
|
||||||
if (scope instanceof LazyJavaPackageScope) {
|
if (scope instanceof LazyJavaPackageScope) {
|
||||||
Name implClassName = JvmFileClassUtil.getImplClassName(descriptor);
|
|
||||||
return ((LazyJavaPackageScope) scope).getFacadeSimpleNameForPartSimpleName(implClassName.asString());
|
return ((LazyJavaPackageScope) scope).getFacadeSimpleNameForPartSimpleName(implClassName.asString());
|
||||||
}
|
}
|
||||||
else if (packageFragmentDescriptor instanceof BuiltinsPackageFragment) {
|
else if (packageFragmentDescriptor instanceof BuiltinsPackageFragment) {
|
||||||
return PackageClassUtils.getPackageClassFqName(packageFragmentDescriptor.getFqName()).shortName().asString();
|
return PackageClassUtils.getPackageClassFqName(packageFragmentDescriptor.getFqName()).shortName().asString();
|
||||||
}
|
}
|
||||||
|
else if (packageFragmentDescriptor instanceof IncrementalPackageFragmentProvider.IncrementalPackageFragment) {
|
||||||
|
IncrementalPackageFragmentProvider.IncrementalPackageFragment incrementalPackageFragment =
|
||||||
|
(IncrementalPackageFragmentProvider.IncrementalPackageFragment) packageFragmentDescriptor;
|
||||||
|
String implClassInternalName = internalNameByFqNameWithoutInnerClasses(
|
||||||
|
packageFragmentDescriptor.getFqName().child(implClassName));
|
||||||
|
String facadeClassInternalName = incrementalPackageFragment.getMultifileFacade(implClassInternalName);
|
||||||
|
if (facadeClassInternalName == null) {
|
||||||
|
return implClassName.asString();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return getSimpleInternalName(facadeClassInternalName);
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// Incremental compilation ends up here. We do not have multifile classes support in incremental so far,
|
|
||||||
// so "use implementation class name" looks like a safe assumption for this case.
|
|
||||||
// However, this should be fixed; see getPackageMemberOwnerInternalName above for more details.
|
|
||||||
Name implClassName = JvmFileClassUtil.getImplClassName(descriptor);
|
|
||||||
return implClassName.asString();
|
return implClassName.asString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -60,6 +60,8 @@ import org.jetbrains.kotlin.resolve.BindingTraceContext;
|
|||||||
import org.jetbrains.kotlin.resolve.ScriptNameUtil;
|
import org.jetbrains.kotlin.resolve.ScriptNameUtil;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM;
|
import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM;
|
||||||
|
import org.jetbrains.kotlin.serialization.PackageData;
|
||||||
|
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil;
|
||||||
import org.jetbrains.kotlin.util.PerformanceCounter;
|
import org.jetbrains.kotlin.util.PerformanceCounter;
|
||||||
import org.jetbrains.kotlin.utils.KotlinPaths;
|
import org.jetbrains.kotlin.utils.KotlinPaths;
|
||||||
|
|
||||||
@@ -368,18 +370,26 @@ public class KotlinToJVMBytecodeCompiler {
|
|||||||
IncrementalCompilationComponents incrementalCompilationComponents = configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS);
|
IncrementalCompilationComponents incrementalCompilationComponents = configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS);
|
||||||
|
|
||||||
Collection<FqName> packagesWithObsoleteParts;
|
Collection<FqName> packagesWithObsoleteParts;
|
||||||
|
List<FqName> obsoleteMultifileClasses;
|
||||||
TargetId targetId = null;
|
TargetId targetId = null;
|
||||||
|
|
||||||
if (module == null || incrementalCompilationComponents == null) {
|
if (module == null || incrementalCompilationComponents == null) {
|
||||||
packagesWithObsoleteParts = Collections.emptySet();
|
packagesWithObsoleteParts = Collections.emptySet();
|
||||||
|
obsoleteMultifileClasses = Collections.emptyList();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
targetId = ModulesPackage.TargetId(module);
|
targetId = ModulesPackage.TargetId(module);
|
||||||
IncrementalCache incrementalCache = incrementalCompilationComponents.getIncrementalCache(targetId);
|
IncrementalCache incrementalCache = incrementalCompilationComponents.getIncrementalCache(targetId);
|
||||||
|
|
||||||
packagesWithObsoleteParts = new HashSet<FqName>();
|
packagesWithObsoleteParts = new HashSet<FqName>();
|
||||||
for (String internalName : incrementalCache.getObsoletePackageParts()) {
|
for (String internalName : incrementalCache.getObsoletePackageParts()) {
|
||||||
packagesWithObsoleteParts.add(JvmClassName.byInternalName(internalName).getPackageFqName());
|
packagesWithObsoleteParts.add(JvmClassName.byInternalName(internalName).getPackageFqName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obsoleteMultifileClasses = new ArrayList<FqName>();
|
||||||
|
for (String obsoleteFacadeInternalName : incrementalCache.getObsoleteMultifileClasses()) {
|
||||||
|
obsoleteMultifileClasses.add(JvmClassName.byInternalName(obsoleteFacadeInternalName).getFqNameForClassNameWithoutDollars());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
BindingTraceContext diagnosticHolder = new BindingTraceContext();
|
BindingTraceContext diagnosticHolder = new BindingTraceContext();
|
||||||
GenerationState generationState = new GenerationState(
|
GenerationState generationState = new GenerationState(
|
||||||
@@ -396,6 +406,7 @@ public class KotlinToJVMBytecodeCompiler {
|
|||||||
configuration.get(JVMConfigurationKeys.PACKAGE_FACADES_AS_MULTIFILE_CLASSES, false),
|
configuration.get(JVMConfigurationKeys.PACKAGE_FACADES_AS_MULTIFILE_CLASSES, false),
|
||||||
diagnosticHolder,
|
diagnosticHolder,
|
||||||
packagesWithObsoleteParts,
|
packagesWithObsoleteParts,
|
||||||
|
obsoleteMultifileClasses,
|
||||||
targetId,
|
targetId,
|
||||||
moduleName,
|
moduleName,
|
||||||
outputDirectory,
|
outputDirectory,
|
||||||
|
|||||||
+31
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||||
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
|
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||||
@@ -35,6 +36,7 @@ import org.jetbrains.kotlin.resolve.scopes.JetScope
|
|||||||
import org.jetbrains.kotlin.serialization.PackageData
|
import org.jetbrains.kotlin.serialization.PackageData
|
||||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
|
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
|
||||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
||||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||||
@@ -135,8 +137,37 @@ public class IncrementalPackageFragmentProvider(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun getPackageFragmentForMultifileClass(multifileClassFqName: FqName): IncrementalMultifileClassPackageFragment? {
|
||||||
|
val facadeInternalName = JvmClassName.byFqNameWithoutInnerClasses(multifileClassFqName).internalName
|
||||||
|
val partsNames = incrementalCache.getStableMultifileFacadeParts(facadeInternalName) ?: return null
|
||||||
|
return IncrementalMultifileClassPackageFragment(multifileClassFqName, partsNames)
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun getMultifileFacade(partInternalName: String): String? {
|
||||||
|
return incrementalCache.getMultifileFacade(partInternalName)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getMemberScope(): JetScope = memberScope()
|
override fun getMemberScope(): JetScope = memberScope()
|
||||||
|
|
||||||
|
public inner class IncrementalMultifileClassPackageFragment(
|
||||||
|
val multifileClassFqName: FqName,
|
||||||
|
val partsNames: Collection<String>
|
||||||
|
) : PackageFragmentDescriptorImpl(moduleDescriptor, multifileClassFqName.parent()) {
|
||||||
|
val memberScope = storageManager.createLazyValue {
|
||||||
|
val partsData = partsNames.map { incrementalCache.getPackagePartData(it) }.filterNotNull()
|
||||||
|
if (partsData.isEmpty())
|
||||||
|
JetScope.Empty
|
||||||
|
else {
|
||||||
|
val scopes = partsData.map { IncrementalPackageScope(JvmProtoBufUtil.readPackageDataFrom(it)) }
|
||||||
|
ChainedScope(this,
|
||||||
|
"Member scope for incremental compilation: union of multifile class parts data for $multifileClassFqName",
|
||||||
|
*scopes.toTypedArray<JetScope>())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMemberScope(): JetScope = memberScope()
|
||||||
|
}
|
||||||
|
|
||||||
private inner class IncrementalPackageScope(val packageData: PackageData) : DeserializedPackageMemberScope(
|
private inner class IncrementalPackageScope(val packageData: PackageData) : DeserializedPackageMemberScope(
|
||||||
this@IncrementalPackageFragment, packageData.packageProto, packageData.nameResolver, deserializationComponents,
|
this@IncrementalPackageFragment, packageData.packageProto, packageData.nameResolver, deserializationComponents,
|
||||||
{ listOf() }
|
{ listOf() }
|
||||||
|
|||||||
+6
@@ -23,6 +23,12 @@ data class JvmPackagePartProto(val data: ByteArray, val strings: Array<String>)
|
|||||||
public interface IncrementalCache {
|
public interface IncrementalCache {
|
||||||
public fun getObsoletePackageParts(): Collection<String>
|
public fun getObsoletePackageParts(): Collection<String>
|
||||||
|
|
||||||
|
public fun getObsoleteMultifileClasses(): Collection<String>
|
||||||
|
|
||||||
|
public fun getStableMultifileFacadeParts(facadeInternalName: String): Collection<String>?
|
||||||
|
|
||||||
|
public fun getMultifileFacade(partInternalName: String): String?
|
||||||
|
|
||||||
public fun getPackagePartData(fqName: String): JvmPackagePartProto?
|
public fun getPackagePartData(fqName: String): JvmPackagePartProto?
|
||||||
|
|
||||||
public fun getModuleMappingData(): ByteArray?
|
public fun getModuleMappingData(): ByteArray?
|
||||||
|
|||||||
+6
@@ -31,6 +31,12 @@ public class RemoteIncrementalCacheServer(val cache: IncrementalCache, port: Int
|
|||||||
|
|
||||||
override fun getObsoletePackageParts(): Collection<String> = cache.getObsoletePackageParts()
|
override fun getObsoletePackageParts(): Collection<String> = cache.getObsoletePackageParts()
|
||||||
|
|
||||||
|
override fun getObsoleteMultifileClassFacades(): Collection<String> = cache.getObsoleteMultifileClasses()
|
||||||
|
|
||||||
|
override fun getMultifileFacadeParts(internalName: String): Collection<String>? = cache.getStableMultifileFacadeParts(internalName)
|
||||||
|
|
||||||
|
override fun getMultifileFacade(partInternalName: String): String? = cache.getMultifileFacade(partInternalName)
|
||||||
|
|
||||||
override fun getPackagePartData(fqName: String): JvmPackagePartProto? = cache.getPackagePartData(fqName)
|
override fun getPackagePartData(fqName: String): JvmPackagePartProto? = cache.getPackagePartData(fqName)
|
||||||
|
|
||||||
override fun getModuleMappingData(): ByteArray? = cache.getModuleMappingData()
|
override fun getModuleMappingData(): ByteArray? = cache.getModuleMappingData()
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ public interface CompileService : Remote {
|
|||||||
@Throws(RemoteException::class)
|
@Throws(RemoteException::class)
|
||||||
public fun getObsoletePackageParts(): Collection<String>
|
public fun getObsoletePackageParts(): Collection<String>
|
||||||
|
|
||||||
|
@Throws(RemoteException::class)
|
||||||
|
public fun getObsoleteMultifileClassFacades(): Collection<String>
|
||||||
|
|
||||||
|
@Throws(RemoteException::class)
|
||||||
|
public fun getMultifileFacade(partInternalName: String): String?
|
||||||
|
|
||||||
@Throws(RemoteException::class)
|
@Throws(RemoteException::class)
|
||||||
public fun getPackagePartData(fqName: String): JvmPackagePartProto?
|
public fun getPackagePartData(fqName: String): JvmPackagePartProto?
|
||||||
|
|
||||||
@@ -48,6 +54,9 @@ public interface CompileService : Remote {
|
|||||||
|
|
||||||
@Throws(RemoteException::class)
|
@Throws(RemoteException::class)
|
||||||
public fun close()
|
public fun close()
|
||||||
|
|
||||||
|
@Throws(RemoteException::class)
|
||||||
|
public fun getMultifileFacadeParts(internalName: String): Collection<String>?
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface RemoteLookupTracker : Remote {
|
public interface RemoteLookupTracker : Remote {
|
||||||
|
|||||||
+6
@@ -21,8 +21,14 @@ import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartPro
|
|||||||
import org.jetbrains.kotlin.rmi.CompileService
|
import org.jetbrains.kotlin.rmi.CompileService
|
||||||
|
|
||||||
public class RemoteIncrementalCacheClient(val cache: CompileService.RemoteIncrementalCache): IncrementalCache {
|
public class RemoteIncrementalCacheClient(val cache: CompileService.RemoteIncrementalCache): IncrementalCache {
|
||||||
|
override fun getObsoleteMultifileClasses(): Collection<String> = cache.getObsoleteMultifileClassFacades()
|
||||||
|
|
||||||
|
override fun getStableMultifileFacadeParts(facadeInternalName: String): Collection<String>? = cache.getMultifileFacadeParts(facadeInternalName)
|
||||||
|
|
||||||
override fun getObsoletePackageParts(): Collection<String> = cache.getObsoletePackageParts()
|
override fun getObsoletePackageParts(): Collection<String> = cache.getObsoletePackageParts()
|
||||||
|
|
||||||
|
override fun getMultifileFacade(partInternalName: String): String? = cache.getMultifileFacade(partInternalName)
|
||||||
|
|
||||||
override fun getPackagePartData(fqName: String): JvmPackagePartProto? = cache.getPackagePartData(fqName)
|
override fun getPackagePartData(fqName: String): JvmPackagePartProto? = cache.getPackagePartData(fqName)
|
||||||
|
|
||||||
override fun getModuleMappingData(): ByteArray? = cache.getModuleMappingData()
|
override fun getModuleMappingData(): ByteArray? = cache.getModuleMappingData()
|
||||||
|
|||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
|
||||||
|
val property = "K"
|
||||||
|
|
||||||
|
inline fun K(body: () -> String): String =
|
||||||
|
body() + property
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
fun main(args: Array<String>) {
|
||||||
|
val ok = K { "O" }
|
||||||
|
if (ok != "OK") throw java.lang.AssertionError("Expected: OK, actual: $ok")
|
||||||
|
}
|
||||||
+6
@@ -113,6 +113,12 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("MultifileClassInlineFunctionAccessingProperty.A.kt")
|
||||||
|
public void testMultifileClassInlineFunctionAccessingProperty() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/MultifileClassInlineFunctionAccessingProperty.A.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("NestedClass.A.kt")
|
@TestMetadata("NestedClass.A.kt")
|
||||||
public void testNestedClass() throws Exception {
|
public void testNestedClass() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/NestedClass.A.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/NestedClass.A.kt");
|
||||||
|
|||||||
@@ -17,10 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.jps.incremental
|
package org.jetbrains.kotlin.jps.incremental
|
||||||
|
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import com.intellij.util.io.BooleanDataDescriptor
|
import com.intellij.util.io.*
|
||||||
import com.intellij.util.io.DataExternalizer
|
|
||||||
import com.intellij.util.io.IOUtil
|
|
||||||
import com.intellij.util.io.KeyDescriptor
|
|
||||||
import gnu.trove.THashSet
|
import gnu.trove.THashSet
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.jps.builders.BuildTarget
|
import org.jetbrains.jps.builders.BuildTarget
|
||||||
@@ -35,12 +32,12 @@ import org.jetbrains.kotlin.jps.build.KotlinBuilder
|
|||||||
import org.jetbrains.kotlin.jps.incremental.storage.BasicMap
|
import org.jetbrains.kotlin.jps.incremental.storage.BasicMap
|
||||||
import org.jetbrains.kotlin.jps.incremental.storage.BasicStringMap
|
import org.jetbrains.kotlin.jps.incremental.storage.BasicStringMap
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||||
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
|
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
|
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind
|
import org.jetbrains.kotlin.load.kotlin.header.*
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind
|
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatiblePackageFacadeKind
|
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName.byInternalName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName.byInternalName
|
||||||
@@ -68,14 +65,17 @@ public class IncrementalCacheImpl(
|
|||||||
companion object {
|
companion object {
|
||||||
val CACHE_EXTENSION = "tab"
|
val CACHE_EXTENSION = "tab"
|
||||||
|
|
||||||
private val PROTO_MAP = "proto"
|
val PROTO_MAP = "proto"
|
||||||
private val CONSTANTS_MAP = "constants"
|
val CONSTANTS_MAP = "constants"
|
||||||
private val INLINE_FUNCTIONS = "inline-functions"
|
val INLINE_FUNCTIONS = "inline-functions"
|
||||||
private val PACKAGE_PARTS = "package-parts"
|
val PACKAGE_PARTS = "package-parts"
|
||||||
private val SOURCE_TO_CLASSES = "source-to-classes"
|
val MULTIFILE_CLASS_FACADES = "multifile-class-facades"
|
||||||
private val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
|
val MULTIFILE_CLASS_PARTS = "multifile-class-parts"
|
||||||
private val DIRTY_INLINE_FUNCTIONS = "dirty-inline-functions"
|
val SOURCE_TO_CLASSES = "source-to-classes"
|
||||||
private val INLINED_TO = "inlined-to"
|
val CLASS_TO_SOURCES = "class-to-sources"
|
||||||
|
val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
|
||||||
|
val DIRTY_INLINE_FUNCTIONS = "dirty-inline-functions"
|
||||||
|
val INLINED_TO = "inlined-to"
|
||||||
|
|
||||||
private val MODULE_MAPPING_FILE_NAME = "." + ModuleMapping.MAPPING_FILE_EXT
|
private val MODULE_MAPPING_FILE_NAME = "." + ModuleMapping.MAPPING_FILE_EXT
|
||||||
}
|
}
|
||||||
@@ -95,6 +95,8 @@ public class IncrementalCacheImpl(
|
|||||||
private val constantsMap = registerMap(ConstantsMap(CONSTANTS_MAP.storageFile))
|
private val constantsMap = registerMap(ConstantsMap(CONSTANTS_MAP.storageFile))
|
||||||
private val inlineFunctionsMap = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
|
private val inlineFunctionsMap = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
|
||||||
private val packagePartMap = registerMap(PackagePartMap(PACKAGE_PARTS.storageFile))
|
private val packagePartMap = registerMap(PackagePartMap(PACKAGE_PARTS.storageFile))
|
||||||
|
private val multifileClassFacadeMap = registerMap(MultifileClassFacadeMap(MULTIFILE_CLASS_FACADES.storageFile))
|
||||||
|
private val multifileClassPartMap = registerMap(MultifileClassPartMap(MULTIFILE_CLASS_PARTS.storageFile))
|
||||||
private val sourceToClassesMap = registerMap(SourceToClassesMap(SOURCE_TO_CLASSES.storageFile))
|
private val sourceToClassesMap = registerMap(SourceToClassesMap(SOURCE_TO_CLASSES.storageFile))
|
||||||
private val dirtyOutputClassesMap = registerMap(DirtyOutputClassesMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
private val dirtyOutputClassesMap = registerMap(DirtyOutputClassesMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
||||||
// TODO: can be removed?
|
// TODO: can be removed?
|
||||||
@@ -196,6 +198,24 @@ public class IncrementalCacheImpl(
|
|||||||
constantsMap.process(kotlinClass) +
|
constantsMap.process(kotlinClass) +
|
||||||
inlineFunctionsMap.process(kotlinClass)
|
inlineFunctionsMap.process(kotlinClass)
|
||||||
}
|
}
|
||||||
|
header.isCompatibleMultifileClassKind() -> {
|
||||||
|
val partNames = getFullNamesOfMultifileClassParts(kotlinClass)
|
||||||
|
multifileClassFacadeMap.add(className, partNames)
|
||||||
|
|
||||||
|
// TODO NO_CHANGES? (delegates only, see package facade)
|
||||||
|
constantsMap.process(kotlinClass) +
|
||||||
|
inlineFunctionsMap.process(kotlinClass)
|
||||||
|
}
|
||||||
|
header.isCompatibleMultifileClassPartKind() -> {
|
||||||
|
assert(sourceFiles.size() == 1) { "Multifile class part from several source files: $sourceFiles" }
|
||||||
|
packagePartMap.addPackagePart(className)
|
||||||
|
val facadeClassName = getInternalNameOfTopLevelClassInTheSamePackage(kotlinClass, header.multifileClassName!!)
|
||||||
|
multifileClassPartMap.add(className.internalName, facadeClassName)
|
||||||
|
|
||||||
|
protoMap.process(kotlinClass, isPackage = true) +
|
||||||
|
constantsMap.process(kotlinClass) +
|
||||||
|
inlineFunctionsMap.process(kotlinClass)
|
||||||
|
}
|
||||||
header.isCompatibleClassKind() && JvmAnnotationNames.KotlinClass.Kind.CLASS == header.classKind ->
|
header.isCompatibleClassKind() && JvmAnnotationNames.KotlinClass.Kind.CLASS == header.classKind ->
|
||||||
protoMap.process(kotlinClass, isPackage = false) +
|
protoMap.process(kotlinClass, isPackage = false) +
|
||||||
constantsMap.process(kotlinClass) +
|
constantsMap.process(kotlinClass) +
|
||||||
@@ -236,6 +256,8 @@ public class IncrementalCacheImpl(
|
|||||||
dirtyClasses.forEach {
|
dirtyClasses.forEach {
|
||||||
protoMap.remove(it)
|
protoMap.remove(it)
|
||||||
packagePartMap.remove(it)
|
packagePartMap.remove(it)
|
||||||
|
multifileClassFacadeMap.remove(it)
|
||||||
|
multifileClassPartMap.remove(it)
|
||||||
constantsMap.remove(it)
|
constantsMap.remove(it)
|
||||||
inlineFunctionsMap.remove(it)
|
inlineFunctionsMap.remove(it)
|
||||||
}
|
}
|
||||||
@@ -256,6 +278,25 @@ public class IncrementalCacheImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getObsoleteMultifileClasses(): Collection<String> {
|
||||||
|
val obsoleteMultifileClasses = linkedSetOf<String>()
|
||||||
|
for (dirtyClass in dirtyOutputClassesMap.getDirtyOutputClasses()) {
|
||||||
|
val dirtyFacade = multifileClassPartMap.getFacadeName(dirtyClass) ?: continue
|
||||||
|
obsoleteMultifileClasses.add(dirtyFacade)
|
||||||
|
}
|
||||||
|
KotlinBuilder.LOG.debug("Obsolete multifile class facades: $obsoleteMultifileClasses")
|
||||||
|
return obsoleteMultifileClasses
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStableMultifileFacadeParts(facadeInternalName: String): Collection<String>? {
|
||||||
|
val partNames = multifileClassFacadeMap.getMultifileClassParts(facadeInternalName) ?: return null
|
||||||
|
return partNames.filter { !dirtyOutputClassesMap.isDirty(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMultifileFacade(partInternalName: String): String? {
|
||||||
|
return multifileClassPartMap.getFacadeName(partInternalName)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getModuleMappingData(): ByteArray? {
|
override fun getModuleMappingData(): ByteArray? {
|
||||||
return protoMap[JvmClassName.byInternalName(MODULE_MAPPING_FILE_NAME)]?.bytes
|
return protoMap[JvmClassName.byInternalName(MODULE_MAPPING_FILE_NAME)]?.bytes
|
||||||
}
|
}
|
||||||
@@ -516,6 +557,36 @@ public class IncrementalCacheImpl(
|
|||||||
override fun dumpValue(value: Boolean) = ""
|
override fun dumpValue(value: Boolean) = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inner class MultifileClassFacadeMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, StringListExternalizer) {
|
||||||
|
public fun add(facadeName: JvmClassName, partNames: List<String>) {
|
||||||
|
storage.put(facadeName.internalName, partNames)
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun getMultifileClassParts(facadeName: String): List<String>? = storage[facadeName]
|
||||||
|
|
||||||
|
public fun remove(className: JvmClassName) {
|
||||||
|
storage.remove(className.internalName)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dumpValue(value: List<String>): String = value.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class MultifileClassPartMap(storageFile: File) : BasicStringMap<String>(storageFile, EnumeratorStringDescriptor.INSTANCE) {
|
||||||
|
public fun add(partName: String, facadeName: String) {
|
||||||
|
storage.put(partName, facadeName)
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun getFacadeName(partName: String): String? {
|
||||||
|
return storage.get(partName)
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun remove(className: JvmClassName) {
|
||||||
|
storage.remove(className.internalName)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dumpValue(value: String): String = value
|
||||||
|
}
|
||||||
|
|
||||||
private inner class SourceToClassesMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, PathStringDescriptor.INSTANCE, StringListExternalizer) {
|
private inner class SourceToClassesMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, PathStringDescriptor.INSTANCE, StringListExternalizer) {
|
||||||
public fun clearOutputsForSource(sourceFile: File) {
|
public fun clearOutputsForSource(sourceFile: File) {
|
||||||
storage.remove(sourceFile.absolutePath)
|
storage.remove(sourceFile.absolutePath)
|
||||||
@@ -543,6 +614,8 @@ public class IncrementalCacheImpl(
|
|||||||
public fun getDirtyOutputClasses(): Collection<String> =
|
public fun getDirtyOutputClasses(): Collection<String> =
|
||||||
storage.keys
|
storage.keys
|
||||||
|
|
||||||
|
public fun isDirty(className: String): Boolean = storage.containsMapping(className)
|
||||||
|
|
||||||
override fun dumpValue(value: Boolean) = ""
|
override fun dumpValue(value: Boolean) = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -631,6 +704,21 @@ private fun ByteArray.md5(): Long {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getInternalNameOfTopLevelClassInTheSamePackage(kotlinClass: KotlinJvmBinaryClass, simpleName: String): String {
|
||||||
|
val classFqName = kotlinClass.classId.packageFqName.child(Name.identifier(simpleName))
|
||||||
|
return JvmClassName.byFqNameWithoutInnerClasses(classFqName).internalName
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getFullNamesOfMultifileClassParts(kotlinClass: LocalFileKotlinClass): List<String> {
|
||||||
|
val classHeader = kotlinClass.classHeader
|
||||||
|
val partClassNames = classHeader.filePartClassNames ?: throw AssertionError("Multifile class has no parts: ${kotlinClass.className}")
|
||||||
|
val fullNames = arrayListOf<String>()
|
||||||
|
for (shortName in partClassNames) {
|
||||||
|
fullNames.add(getInternalNameOfTopLevelClassInTheSamePackage(kotlinClass, shortName))
|
||||||
|
}
|
||||||
|
return fullNames
|
||||||
|
}
|
||||||
|
|
||||||
private abstract class StringMapExternalizer<T> : DataExternalizer<Map<String, T>> {
|
private abstract class StringMapExternalizer<T> : DataExternalizer<Map<String, T>> {
|
||||||
override fun save(out: DataOutput, map: Map<String, T>?) {
|
override fun save(out: DataOutput, map: Map<String, T>?) {
|
||||||
out.writeInt(map!!.size())
|
out.writeInt(map!!.size())
|
||||||
@@ -698,6 +786,9 @@ private object PathCollectionExternalizer : DataExternalizer<Collection<String>>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val File.normalizedPath: String
|
||||||
|
get() = FileUtil.toSystemIndependentName(canonicalPath)
|
||||||
|
|
||||||
@TestOnly
|
@TestOnly
|
||||||
private fun <K : Comparable<K>, V> Map<K, V>.dumpMap(dumpValue: (V)->String): String =
|
private fun <K : Comparable<K>, V> Map<K, V>.dumpMap(dumpValue: (V)->String): String =
|
||||||
StringBuilder {
|
StringBuilder {
|
||||||
|
|||||||
@@ -347,6 +347,54 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multifileClassFileAdded")
|
||||||
|
public void testMultifileClassFileAdded() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/multifileClassFileAdded/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multifileClassFileChanged")
|
||||||
|
public void testMultifileClassFileChanged() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/multifileClassFileChanged/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multifileClassFileMovedToAnotherMultifileClass")
|
||||||
|
public void testMultifileClassFileMovedToAnotherMultifileClass() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/multifileClassFileMovedToAnotherMultifileClass/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multifileClassInlineFunction")
|
||||||
|
public void testMultifileClassInlineFunction() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/multifileClassInlineFunction/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multifileClassInlineFunctionAccessingField")
|
||||||
|
public void testMultifileClassInlineFunctionAccessingField() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/multifileClassInlineFunctionAccessingField/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multifileClassRecreated")
|
||||||
|
public void testMultifileClassRecreated() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/multifileClassRecreated/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multifileClassRecreatedAfterRenaming")
|
||||||
|
public void testMultifileClassRecreatedAfterRenaming() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/multifileClassRecreatedAfterRenaming/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multifileClassRemoved")
|
||||||
|
public void testMultifileClassRemoved() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/multifileClassRemoved/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("multiplePackagesModified")
|
@TestMetadata("multiplePackagesModified")
|
||||||
public void testMultiplePackagesModified() throws Exception {
|
public void testMultiplePackagesModified() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/multiplePackagesModified/");
|
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/multiplePackagesModified/");
|
||||||
|
|||||||
+3
-3
@@ -22,9 +22,7 @@ import com.google.common.io.Files
|
|||||||
import com.google.protobuf.ExtensionRegistry
|
import com.google.protobuf.ExtensionRegistry
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import org.jetbrains.kotlin.jps.incremental.LocalFileKotlinClass
|
import org.jetbrains.kotlin.jps.incremental.LocalFileKotlinClass
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind
|
import org.jetbrains.kotlin.load.kotlin.header.*
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind
|
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatiblePackageFacadeKind
|
|
||||||
import org.jetbrains.kotlin.serialization.DebugProtoBuf
|
import org.jetbrains.kotlin.serialization.DebugProtoBuf
|
||||||
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
||||||
import org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf
|
import org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf
|
||||||
@@ -148,6 +146,8 @@ fun classFileToString(classFile: File): String {
|
|||||||
out.write("\n------ file facade proto -----\n${DebugProtoBuf.Package.parseFrom(input, getExtensionRegistry())}")
|
out.write("\n------ file facade proto -----\n${DebugProtoBuf.Package.parseFrom(input, getExtensionRegistry())}")
|
||||||
classHeader.isCompatibleClassKind() ->
|
classHeader.isCompatibleClassKind() ->
|
||||||
out.write("\n------ class proto -----\n${DebugProtoBuf.Class.parseFrom(input, getExtensionRegistry())}")
|
out.write("\n------ class proto -----\n${DebugProtoBuf.Class.parseFrom(input, getExtensionRegistry())}")
|
||||||
|
classHeader.isCompatibleMultifileClassPartKind() ->
|
||||||
|
out.write("\n------ multi-file part proto -----\n${DebugProtoBuf.Package.parseFrom(input, getExtensionRegistry())}")
|
||||||
|
|
||||||
else -> throw IllegalStateException()
|
else -> throw IllegalStateException()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun a() = "a"
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun b() = "b"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
Compiling files:
|
||||||
|
src/b.kt
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/test/Test.class
|
||||||
|
out/production/module/test/TestPackage.class
|
||||||
|
out/production/module/test/Test__AKt.class
|
||||||
|
out/production/module/test/Test__BKt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/a.kt
|
||||||
|
src/b.kt
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/test/Test.class
|
||||||
|
out/production/module/test/TestPackage.class
|
||||||
|
out/production/module/test/Test__AKt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/a.kt
|
||||||
|
End of files
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun a() = "a"
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun b() = "b"
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun b() = "bcd"
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/test/Test.class
|
||||||
|
out/production/module/test/TestPackage.class
|
||||||
|
out/production/module/test/Test__BKt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/b.kt
|
||||||
|
End of files
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun a() = "a"
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun b() = "b"
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test1") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun b() = "b"
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/test/Test.class
|
||||||
|
out/production/module/test/TestPackage.class
|
||||||
|
out/production/module/test/Test__BKt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/b.kt
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/test/Test.class
|
||||||
|
out/production/module/test/TestPackage.class
|
||||||
|
out/production/module/test/Test__AKt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/a.kt
|
||||||
|
End of files
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/test/TestPackage.class
|
||||||
|
out/production/module/test/UsageKt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/usage.kt
|
||||||
|
End of files
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
inline fun f(body: () -> Unit) {
|
||||||
|
println("i'm inline function")
|
||||||
|
body()
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package other
|
||||||
|
|
||||||
|
inline fun f(body: () -> Unit) {
|
||||||
|
println("i'm other inline function")
|
||||||
|
body()
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
f { println("to be inlined") }
|
||||||
|
other.f { println("to be inlined") }
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
f { println("to be inlined") }
|
||||||
|
other.f { println("to be inlined") }
|
||||||
|
}
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/test/TestPackage.class
|
||||||
|
out/production/module/test/UsageKt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/usage.kt
|
||||||
|
End of files
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
val property = ":)"
|
||||||
|
|
||||||
|
inline fun f(body: () -> Unit) {
|
||||||
|
println("i'm inline function" + property)
|
||||||
|
body()
|
||||||
|
}
|
||||||
jps-plugin/testData/incremental/pureKotlin/multifileClassInlineFunctionAccessingField/inlineOther.kt
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package other
|
||||||
|
|
||||||
|
val property = ":)"
|
||||||
|
|
||||||
|
inline fun f(body: () -> Unit) {
|
||||||
|
println("i'm inline function" + property)
|
||||||
|
body()
|
||||||
|
}
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
f { println("to be inlined") }
|
||||||
|
other.f { println("to be inlined") }
|
||||||
|
}
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
f { println("to be inlined") }
|
||||||
|
other.f { println("to be inlined") }
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun a() = "a"
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun b() = "b"
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/test/Test.class
|
||||||
|
out/production/module/test/TestPackage.class
|
||||||
|
out/production/module/test/Test__AKt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
End of files
|
||||||
|
|
||||||
|
|
||||||
|
Compiling files:
|
||||||
|
src/b.kt
|
||||||
|
End of files
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun a() = "a"
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test2") JvmMultifileClass]
|
||||||
|
package test2
|
||||||
|
|
||||||
|
fun a() = "a"
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun b() = "b"
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/test/Test.class
|
||||||
|
out/production/module/test/TestPackage.class
|
||||||
|
out/production/module/test/Test__AKt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/a.kt
|
||||||
|
End of files
|
||||||
|
|
||||||
|
|
||||||
|
Compiling files:
|
||||||
|
src/b.kt
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/test2/Test2.class
|
||||||
|
out/production/module/test2/Test2Package.class
|
||||||
|
out/production/module/test2/Test2__AKt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/a.kt
|
||||||
|
End of files
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun a() = "a"
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("Test") JvmMultifileClass]
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun b() = "b"
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/test/Test.class
|
||||||
|
out/production/module/test/TestPackage.class
|
||||||
|
out/production/module/test/Test__AKt.class
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/test/Test__BKt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
End of files
|
||||||
Reference in New Issue
Block a user