Refactor and rename CodegenUtil.getDeclarationsToGenerate

Move logic regarding expect classes to the only relevant call site at
PackageCodegenImpl, and return the list of members to remove code
duplication at remaining call sites
This commit is contained in:
Alexander Udalov
2019-02-07 19:20:27 +01:00
parent 4487c7a988
commit 3d1858a8c5
7 changed files with 63 additions and 96 deletions
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
@@ -169,23 +168,19 @@ object CodegenUtil {
} }
/** /**
* Returns declarations in the given [file] which should be generated by the back-end. This includes all declarations * Returns functions, properties and type aliases in the given [file] which should be generated by the back-end.
* minus all expected declarations (except annotation classes annotated with @OptionalExpectation).
*/ */
@JvmStatic @JvmStatic
fun getDeclarationsToGenerate(file: KtFile, bindingContext: BindingContext): List<KtDeclaration> = fun getMemberDeclarationsToGenerate(file: KtFile): List<KtDeclaration> =
file.declarations.filter(fun(declaration: KtDeclaration): Boolean { file.declarations.filter { declaration ->
if (!declaration.hasExpectModifier()) return true !declaration.hasExpectModifier() && (declaration is KtNamedFunction || declaration is KtProperty || declaration is KtTypeAlias)
}
if (declaration is KtClass) { @JvmStatic
val descriptor = bindingContext.get(BindingContext.CLASS, declaration) fun getMemberDescriptorsToGenerate(file: KtFile, bindingContext: BindingContext): List<MemberDescriptor> =
if (descriptor != null && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(descriptor)) { getMemberDeclarationsToGenerate(file).mapNotNull { declaration ->
return true bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration) as MemberDescriptor?
} }
}
return false
})
@JvmStatic @JvmStatic
fun findExpectedFunctionForActual(descriptor: FunctionDescriptor): FunctionDescriptor? { fun findExpectedFunctionForActual(descriptor: FunctionDescriptor): FunctionDescriptor? {
@@ -34,7 +34,10 @@ import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtScript
import org.jetbrains.kotlin.psi.KtTypeAlias
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
@@ -85,7 +88,7 @@ class MultifileClassCodegenImpl(
private val partInternalNamesSorted = run { private val partInternalNamesSorted = run {
val partInternalNamesSet = hashSetOf<String>() val partInternalNamesSet = hashSetOf<String>()
for (file in files) { for (file in files) {
if (file.hasDeclarationsForPartClass(state.bindingContext)) { if (file.hasDeclarationsForPartClass()) {
partInternalNamesSet.add(JvmFileClassUtil.getFileClassInternalName(file)) partInternalNamesSet.add(JvmFileClassUtil.getFileClassInternalName(file))
} }
} }
@@ -122,7 +125,7 @@ class MultifileClassCodegenImpl(
val singleSourceFile = val singleSourceFile =
if (previouslyCompiledCallables.isEmpty()) if (previouslyCompiledCallables.isEmpty())
files.singleOrNull { it.hasDeclarationsForPartClass(state.bindingContext) } files.singleOrNull { it.hasDeclarationsForPartClass() }
else else
null null
@@ -209,9 +212,7 @@ class MultifileClassCodegenImpl(
generateNonPartClassDeclarations(file, partContext) generateNonPartClassDeclarations(file, partContext)
if (!state.generateDeclaredClassFilter.shouldGeneratePackagePart(file) || if (!state.generateDeclaredClassFilter.shouldGeneratePackagePart(file) || !file.hasDeclarationsForPartClass()) return
!file.hasDeclarationsForPartClass(state.bindingContext)
) return
state.factory.packagePartRegistry.addPart(packageFragment.fqName, partType.internalName, facadeClassType.internalName) state.factory.packagePartRegistry.addPart(packageFragment.fqName, partType.internalName, facadeClassType.internalName)
@@ -245,26 +246,18 @@ class MultifileClassCodegenImpl(
private fun addDelegateGenerationTasksForDeclarationsInFile(file: KtFile, packageFragment: PackageFragmentDescriptor, partType: Type) { private fun addDelegateGenerationTasksForDeclarationsInFile(file: KtFile, packageFragment: PackageFragmentDescriptor, partType: Type) {
val facadeContext = state.rootContext.intoMultifileClass(packageFragment, facadeClassType, partType) val facadeContext = state.rootContext.intoMultifileClass(packageFragment, facadeClassType, partType)
val memberCodegen = createCodegenForDelegatesInMultifileFacade(facadeContext) val memberCodegen = createCodegenForDelegatesInMultifileFacade(facadeContext)
for (declaration in CodegenUtil.getDeclarationsToGenerate(file, state.bindingContext)) { for (declaration in CodegenUtil.getMemberDeclarationsToGenerate(file)) {
if (shouldGenerateInFacade(declaration)) { // In light classes, we intentionally do not analyze type aliases, since they're metadata-only
val descriptor = state.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration) if (declaration is KtTypeAlias && !state.classBuilderMode.generateMetadata) continue
if (descriptor !is MemberDescriptor) {
throw AssertionError("Expected callable member, was " + descriptor + " for " + declaration.text) val descriptor = state.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
} if (descriptor !is MemberDescriptor) {
addDelegateGenerationTaskIfNeeded(descriptor, { memberCodegen.genSimpleMember(declaration) }) throw AssertionError("Expected callable member, was " + descriptor + " for " + declaration.text)
} }
addDelegateGenerationTaskIfNeeded(descriptor) { memberCodegen.genSimpleMember(declaration) }
} }
} }
private fun shouldGenerateInFacade(declaration: KtDeclaration): Boolean {
if (declaration is KtNamedFunction || declaration is KtProperty) return true
// In light classes, we intentionally do not analyze type aliases, since they're metadata-only
if (declaration is KtTypeAlias && state.classBuilderMode.generateMetadata) return true
return false
}
private fun shouldGenerateInFacade(descriptor: MemberDescriptor): Boolean { private fun shouldGenerateInFacade(descriptor: MemberDescriptor): Boolean {
if (Visibilities.isPrivate(descriptor.visibility)) return false if (Visibilities.isPrivate(descriptor.visibility)) return false
if (AsmUtil.getVisibilityAccessFlag(descriptor) == Opcodes.ACC_PRIVATE) return false if (AsmUtil.getVisibilityAccessFlag(descriptor) == Opcodes.ACC_PRIVATE) return false
@@ -386,8 +379,8 @@ class MultifileClassCodegenImpl(
return fragments.firstOrNull() return fragments.firstOrNull()
} }
private fun KtFile.hasDeclarationsForPartClass(bindingContext: BindingContext) = private fun KtFile.hasDeclarationsForPartClass() =
CodegenUtil.getDeclarationsToGenerate(this, bindingContext).any { it is KtProperty || it is KtFunction || it is KtTypeAlias } CodegenUtil.getMemberDeclarationsToGenerate(this).isNotEmpty()
private fun getCompiledPackageFragment( private fun getCompiledPackageFragment(
facadeFqName: FqName, state: GenerationState facadeFqName: FqName, state: GenerationState
@@ -24,9 +24,7 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtTypeAlias
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
@@ -82,10 +80,8 @@ class MultifileClassPartCodegen(
} }
override fun generateBody() { override fun generateBody() {
for (declaration in CodegenUtil.getDeclarationsToGenerate(element, state.bindingContext)) { for (declaration in CodegenUtil.getMemberDeclarationsToGenerate(element)) {
if (declaration is KtNamedFunction || declaration is KtProperty || declaration is KtTypeAlias) { genSimpleMember(declaration)
genSimpleMember(declaration)
}
} }
if (state.classBuilderMode.generateBodies) { if (state.classBuilderMode.generateBodies) {
@@ -25,13 +25,20 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.CodegenUtil; import org.jetbrains.kotlin.backend.common.CodegenUtil;
import org.jetbrains.kotlin.codegen.context.PackageContext; import org.jetbrains.kotlin.codegen.context.PackageContext;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
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.JvmFileClassInfo; import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil; import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus; import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.KtClassOrObject;
import org.jetbrains.kotlin.psi.KtDeclaration;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.psi.KtScript;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.resolve.lazy.descriptors.PackageDescriptorUtilKt; import org.jetbrains.kotlin.resolve.lazy.descriptors.PackageDescriptorUtilKt;
import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.Type;
@@ -91,15 +98,16 @@ public class PackageCodegenImpl implements PackageCodegen {
Type fileClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.getFileClassFqName()); Type fileClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.getFileClassFqName());
PackageContext packagePartContext = state.getRootContext().intoPackagePart(packageFragment, fileClassType, file); PackageContext packagePartContext = state.getRootContext().intoPackagePart(packageFragment, fileClassType, file);
boolean generatePackagePart = false;
List<KtClassOrObject> classOrObjects = new ArrayList<>(); List<KtClassOrObject> classOrObjects = new ArrayList<>();
for (KtDeclaration declaration : CodegenUtil.getDeclarationsToGenerate(file, state.getBindingContext())) { for (KtDeclaration declaration : file.getDeclarations()) {
if (isFilePartDeclaration(declaration)) { if (declaration instanceof KtClassOrObject) {
generatePackagePart = true; ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, declaration);
} if (PsiUtilsKt.hasExpectModifier(declaration) &&
else if (declaration instanceof KtClassOrObject) { (descriptor == null || !ExpectedActualDeclarationChecker.shouldGenerateExpectClass(descriptor))) {
continue;
}
KtClassOrObject classOrObject = (KtClassOrObject) declaration; KtClassOrObject classOrObject = (KtClassOrObject) declaration;
if (state.getGenerateDeclaredClassFilter().shouldGenerateClass(classOrObject)) { if (state.getGenerateDeclaredClassFilter().shouldGenerateClass(classOrObject)) {
classOrObjects.add(classOrObject); classOrObjects.add(classOrObject);
@@ -115,7 +123,9 @@ public class PackageCodegenImpl implements PackageCodegen {
} }
generateClassesAndObjectsInFile(classOrObjects, packagePartContext); generateClassesAndObjectsInFile(classOrObjects, packagePartContext);
if (!generatePackagePart || !state.getGenerateDeclaredClassFilter().shouldGeneratePackagePart(file)) return; if (!state.getGenerateDeclaredClassFilter().shouldGeneratePackagePart(file)) return;
if (CodegenUtil.getMemberDeclarationsToGenerate(file).isEmpty()) return;
state.getFactory().getPackagePartRegistry().addPart(packageFragment.getFqName(), fileClassType.getInternalName(), null); state.getFactory().getPackagePartRegistry().addPart(packageFragment.getFqName(), fileClassType.getInternalName(), null);
@@ -124,10 +134,6 @@ public class PackageCodegenImpl implements PackageCodegen {
new PackagePartCodegen(builder, file, fileClassType, packagePartContext, state).generate(); new PackagePartCodegen(builder, file, fileClassType, packagePartContext, state).generate();
} }
public static boolean isFilePartDeclaration(KtDeclaration declaration) {
return declaration instanceof KtProperty || declaration instanceof KtNamedFunction || declaration instanceof KtTypeAlias;
}
@Nullable @Nullable
private PackageFragmentDescriptor getOnlyPackageFragment(@NotNull FqName expectedPackageFqName) { private PackageFragmentDescriptor getOnlyPackageFragment(@NotNull FqName expectedPackageFqName) {
SmartList<PackageFragmentDescriptor> fragments = new SmartList<>(); SmartList<PackageFragmentDescriptor> fragments = new SmartList<>();
@@ -19,13 +19,12 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.util.ArrayUtil; import com.intellij.util.ArrayUtil;
import kotlin.Pair; import kotlin.Pair;
import kotlin.Unit; import kotlin.Unit;
import kotlin.collections.CollectionsKt;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.backend.common.CodegenUtil; import org.jetbrains.kotlin.backend.common.CodegenUtil;
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext; import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension; import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.MemberDescriptor;
import org.jetbrains.kotlin.descriptors.annotations.Annotated; import org.jetbrains.kotlin.descriptors.annotations.Annotated;
import org.jetbrains.kotlin.descriptors.annotations.AnnotatedImpl; import org.jetbrains.kotlin.descriptors.annotations.AnnotatedImpl;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
@@ -33,7 +32,9 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader; import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
import org.jetbrains.kotlin.metadata.ProtoBuf; import org.jetbrains.kotlin.metadata.ProtoBuf;
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.KtAnnotationEntry;
import org.jetbrains.kotlin.psi.KtDeclaration;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.jvm.JvmClassName; import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
import org.jetbrains.kotlin.serialization.DescriptorSerializer; import org.jetbrains.kotlin.serialization.DescriptorSerializer;
@@ -90,10 +91,8 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
@Override @Override
protected void generateBody() { protected void generateBody() {
for (KtDeclaration declaration : CodegenUtil.getDeclarationsToGenerate(element, state.getBindingContext())) { for (KtDeclaration declaration : CodegenUtil.getMemberDeclarationsToGenerate(element)) {
if (declaration instanceof KtNamedFunction || declaration instanceof KtProperty || declaration instanceof KtTypeAlias) { genSimpleMember(declaration);
genSimpleMember(declaration);
}
} }
if (state.getClassBuilderMode().generateBodies) { if (state.getClassBuilderMode().generateBodies) {
@@ -122,21 +121,7 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
@NotNull MemberCodegen<? extends KtFile> codegen, @NotNull MemberCodegen<? extends KtFile> codegen,
@NotNull Type packagePartType @NotNull Type packagePartType
) { ) {
BindingContext bindingContext = codegen.bindingContext; List<MemberDescriptor> members = CodegenUtil.getMemberDescriptorsToGenerate(codegen.element, codegen.bindingContext);
List<KtDeclaration> allDeclarations = CodegenUtil.getDeclarationsToGenerate(codegen.element, bindingContext);
List<DeclarationDescriptor> members = CollectionsKt.mapNotNull(allDeclarations, declaration -> {
if (declaration instanceof KtNamedFunction) {
return bindingContext.get(BindingContext.FUNCTION, declaration);
}
else if (declaration instanceof KtProperty) {
return bindingContext.get(BindingContext.VARIABLE, declaration);
}
else if (declaration instanceof KtTypeAlias) {
return bindingContext.get(BindingContext.TYPE_ALIAS, declaration);
}
return null;
});
JvmSerializerExtension extension = new JvmSerializerExtension(codegen.v.getSerializationBindings(), codegen.state); JvmSerializerExtension extension = new JvmSerializerExtension(codegen.v.getSerializationBindings(), codegen.state);
DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(extension); DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(extension);
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.codegen; package org.jetbrains.kotlin.codegen;
import kotlin.collections.CollectionsKt;
import kotlin.text.StringsKt; import kotlin.text.StringsKt;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.backend.common.CodegenUtil; import org.jetbrains.kotlin.backend.common.CodegenUtil;
@@ -181,10 +180,7 @@ public class SamWrapperCodegen {
@NotNull KtFile containingFile, @NotNull KtFile containingFile,
CallableMemberDescriptor contextDescriptor CallableMemberDescriptor contextDescriptor
) { ) {
boolean hasPackagePartClass = CollectionsKt.any( boolean hasPackagePartClass = !CodegenUtil.getMemberDeclarationsToGenerate(containingFile).isEmpty();
CodegenUtil.getDeclarationsToGenerate(containingFile, state.getBindingContext()),
PackageCodegenImpl::isFilePartDeclaration
);
FqName filePartFqName = JvmFileClassUtil.getFileClassInfoNoResolve(containingFile).getFileClassFqName(); FqName filePartFqName = JvmFileClassUtil.getFileClassInfoNoResolve(containingFile).getFileClassFqName();
FqName outermostOwner; FqName outermostOwner;
@@ -12,8 +12,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.TestsRuntimeError; import org.jetbrains.kotlin.TestsRuntimeError;
import org.jetbrains.kotlin.backend.common.CodegenUtil; import org.jetbrains.kotlin.backend.common.CodegenUtil;
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil; import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.test.InTextDirectivesUtils; import org.jetbrains.kotlin.test.InTextDirectivesUtils;
import org.jetbrains.kotlin.test.TargetBackend; import org.jetbrains.kotlin.test.TargetBackend;
import org.jetbrains.kotlin.utils.ExceptionUtilsKt; import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
@@ -29,7 +28,7 @@ import static org.jetbrains.kotlin.test.clientserver.TestProcessServerKt.getGene
public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase { public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {
public static final boolean IGNORE_EXPECTED_FAILURES = private static final boolean IGNORE_EXPECTED_FAILURES =
Boolean.getBoolean("kotlin.suppress.expected.test.failures"); Boolean.getBoolean("kotlin.suppress.expected.test.failures");
@Override @Override
@@ -103,7 +102,7 @@ public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {
// If there are many files, the first 'box(): String' function will be executed. // If there are many files, the first 'box(): String' function will be executed.
GeneratedClassLoader generatedClassLoader = generateAndCreateClassLoader(reportProblems); GeneratedClassLoader generatedClassLoader = generateAndCreateClassLoader(reportProblems);
for (KtFile firstFile : myFiles.getPsiFiles()) { for (KtFile firstFile : myFiles.getPsiFiles()) {
String className = getFacadeFqName(firstFile, classFileFactory.getGenerationState().getBindingContext()); String className = getFacadeFqName(firstFile);
if (className == null) continue; if (className == null) continue;
Class<?> aClass = getGeneratedClass(generatedClassLoader, className); Class<?> aClass = getGeneratedClass(generatedClassLoader, className);
try { try {
@@ -127,13 +126,10 @@ public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {
} }
@Nullable @Nullable
private static String getFacadeFqName(@NotNull KtFile firstFile, @NotNull BindingContext bindingContext) { private static String getFacadeFqName(@NotNull KtFile file) {
for (KtDeclaration declaration : CodegenUtil.getDeclarationsToGenerate(firstFile, bindingContext)) { return CodegenUtil.getMemberDeclarationsToGenerate(file).isEmpty()
if (declaration instanceof KtProperty || declaration instanceof KtNamedFunction || declaration instanceof KtTypeAlias) { ? null
return JvmFileClassUtil.getFileClassInfoNoResolve(firstFile).getFacadeClassFqName().asString(); : JvmFileClassUtil.getFileClassInfoNoResolve(file).getFacadeClassFqName().asString();
}
}
return null;
} }
protected TargetBackend getBackend() { protected TargetBackend getBackend() {