Reformat MultifileClassCodegen, fix inspections

This commit is contained in:
Alexander Udalov
2019-02-28 12:28:22 +01:00
parent 670b06ae97
commit ea21cda4df
2 changed files with 59 additions and 67 deletions
@@ -18,8 +18,6 @@ package org.jetbrains.kotlin.codegen
import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.util.ArrayUtil
import com.intellij.util.SmartList
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.context.MethodContext import org.jetbrains.kotlin.codegen.context.MethodContext
@@ -51,6 +49,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.org.objectweb.asm.MethodVisitor 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
@@ -72,15 +71,15 @@ class MultifileClassCodegenImpl(
private val compiledPackageFragment = getCompiledPackageFragment(facadeFqName, state) private val compiledPackageFragment = getCompiledPackageFragment(facadeFqName, state)
private val previouslyCompiledCallables = private val previouslyCompiledCallables =
if (compiledPackageFragment == null) if (compiledPackageFragment == null)
emptyList<DeserializedCallableMemberDescriptor>() emptyList()
else else
getDeserializedCallables(compiledPackageFragment) getDeserializedCallables(compiledPackageFragment)
private fun getDeserializedCallables(compiledPackageFragment: PackageFragmentDescriptor) = private fun getDeserializedCallables(compiledPackageFragment: PackageFragmentDescriptor) =
compiledPackageFragment.getMemberScope() compiledPackageFragment.getMemberScope()
.getContributedDescriptors(DescriptorKindFilter.CALLABLES, MemberScope.ALL_NAME_FILTER) .getContributedDescriptors(DescriptorKindFilter.CALLABLES, MemberScope.ALL_NAME_FILTER)
.filterIsInstance<DeserializedCallableMemberDescriptor>() .filterIsInstance<DeserializedCallableMemberDescriptor>()
private val shouldGeneratePartHierarchy = private val shouldGeneratePartHierarchy =
state.languageVersionSettings.getFlag(JvmAnalysisFlags.inheritMultifileParts) state.languageVersionSettings.getFlag(JvmAnalysisFlags.inheritMultifileParts)
@@ -100,7 +99,7 @@ class MultifileClassCodegenImpl(
private val superClassForInheritedPart = run { private val superClassForInheritedPart = run {
val result = hashMapOf<String, String>() val result = hashMapOf<String, String>()
for (i in 1 ..partInternalNamesSorted.size - 1) { for (i in 1 until partInternalNamesSorted.size) {
result[partInternalNamesSorted[i]] = partInternalNamesSorted[i - 1] result[partInternalNamesSorted[i]] = partInternalNamesSorted[i - 1]
} }
result result
@@ -115,29 +114,23 @@ class MultifileClassCodegenImpl(
J_L_OBJECT J_L_OBJECT
private val classBuilder = ClassBuilderOnDemand { private val classBuilder = ClassBuilderOnDemand {
val originFile = files.firstOrNull()
val actualPackageFragment = packageFragment val actualPackageFragment = packageFragment
?: compiledPackageFragment ?: compiledPackageFragment
?: throw AssertionError("No package fragment for multifile facade $facadeFqName; files: $files") ?: throw AssertionError("No package fragment for multifile facade $facadeFqName; files: $files")
val declarationOrigin = MultifileClass(originFile, actualPackageFragment)
val singleSourceFile = val singleSourceFile =
if (previouslyCompiledCallables.isEmpty()) if (previouslyCompiledCallables.isEmpty())
files.singleOrNull { it.hasDeclarationsForPartClass() } files.singleOrNull { it.hasDeclarationsForPartClass() }
else else
null null
val superClassForFacade = val superClassForFacade = if (shouldGeneratePartHierarchy) partInternalNamesSorted.last() else J_L_OBJECT
if (shouldGeneratePartHierarchy)
partInternalNamesSorted.last()
else
J_L_OBJECT
state.factory.newVisitor(declarationOrigin, facadeClassType, files).apply { state.factory.newVisitor(MultifileClass(files.firstOrNull(), actualPackageFragment), facadeClassType, files).apply {
defineClass(singleSourceFile, state.classFileVersion, FACADE_CLASS_ATTRIBUTES, defineClass(
facadeClassType.internalName, null, superClassForFacade, ArrayUtil.EMPTY_STRING_ARRAY) singleSourceFile, state.classFileVersion, FACADE_CLASS_ATTRIBUTES,
facadeClassType.internalName, null, superClassForFacade, emptyArray()
)
if (singleSourceFile != null) { if (singleSourceFile != null) {
visitSource(singleSourceFile.name, null) visitSource(singleSourceFile.name, null)
} }
@@ -162,7 +155,7 @@ class MultifileClassCodegenImpl(
generateDelegatesToPreviouslyCompiledParts() generateDelegatesToPreviouslyCompiledParts()
if (!partInternalNamesSorted.isEmpty()) { if (partInternalNamesSorted.isNotEmpty()) {
generateMultifileFacadeClass() generateMultifileFacadeClass()
} }
@@ -175,16 +168,12 @@ class MultifileClassCodegenImpl(
try { try {
generatePart(file) generatePart(file)
state.afterIndependentPart() state.afterIndependentPart()
} } catch (e: ProcessCanceledException) {
catch (e: ProcessCanceledException) {
throw e throw e
} } catch (e: Throwable) {
catch (e: Throwable) { errorHandler.reportException(e, file.virtualFile?.url ?: "no file")
val vFile = file.virtualFile
errorHandler.reportException(e, if (vFile == null) "no file" else vFile.url)
DiagnosticUtils.throwIfRunningOnServer(e) DiagnosticUtils.throwIfRunningOnServer(e)
if (ApplicationManager.getApplication().isInternal) { if (ApplicationManager.getApplication().isInternal) {
//noinspection CallToPrintStackTrace
e.printStackTrace() e.printStackTrace()
} }
} }
@@ -205,7 +194,7 @@ class MultifileClassCodegenImpl(
private fun generatePart(file: KtFile) { private fun generatePart(file: KtFile) {
val packageFragment = this.packageFragment val packageFragment = this.packageFragment
?: throw AssertionError("File part $file of $facadeFqName: no package fragment") ?: throw AssertionError("File part $file of $facadeFqName: no package fragment")
val partType = Type.getObjectType(JvmFileClassUtil.getFileClassInternalName(file)) val partType = Type.getObjectType(JvmFileClassUtil.getFileClassInternalName(file))
val partContext = state.rootContext.intoMultifileClassPart(packageFragment, facadeClassType, partType, file) val partContext = state.rootContext.intoMultifileClassPart(packageFragment, facadeClassType, partType, file)
@@ -219,10 +208,7 @@ class MultifileClassCodegenImpl(
val builder = state.factory.newVisitor(MultifileClassPart(file, packageFragment), partType, file) val builder = state.factory.newVisitor(MultifileClassPart(file, packageFragment), partType, file)
MultifileClassPartCodegen( MultifileClassPartCodegen(
builder, file, packageFragment, builder, file, packageFragment, getSuperClassForPart(partType.internalName), shouldGeneratePartHierarchy, partContext, state
getSuperClassForPart(partType.internalName),
shouldGeneratePartHierarchy,
partContext, state
).generate() ).generate()
addDelegateGenerationTasksForDeclarationsInFile(file, packageFragment, partType) addDelegateGenerationTasksForDeclarationsInFile(file, packageFragment, partType)
@@ -284,14 +270,14 @@ class MultifileClassCodegenImpl(
val partFqName = JvmFileClassUtil.getPartFqNameForDeserialized(callable) val partFqName = JvmFileClassUtil.getPartFqNameForDeserialized(callable)
val partType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(partFqName) val partType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(partFqName)
addDelegateGenerationTaskIfNeeded(callable, { generateDelegateToCompiledMember(callable, compiledPackageFragment, partType) }) addDelegateGenerationTaskIfNeeded(callable) { generateDelegateToCompiledMember(callable, compiledPackageFragment, partType) }
} }
} }
private fun generateDelegateToCompiledMember( private fun generateDelegateToCompiledMember(
member: CallableMemberDescriptor, member: CallableMemberDescriptor,
compiledPackageFragment: PackageFragmentDescriptor, compiledPackageFragment: PackageFragmentDescriptor,
partType: Type partType: Type
) { ) {
val context = state.rootContext.intoMultifileClass(compiledPackageFragment, facadeClassType, partType) val context = state.rootContext.intoMultifileClass(compiledPackageFragment, facadeClassType, partType)
@@ -302,7 +288,8 @@ class MultifileClassCodegenImpl(
memberCodegen.functionCodegen.generateMethod(OtherOrigin(member), member, DelegateToCompiledMemberGenerationStrategy) memberCodegen.functionCodegen.generateMethod(OtherOrigin(member), member, DelegateToCompiledMemberGenerationStrategy)
memberCodegen.functionCodegen.generateDefaultIfNeeded( memberCodegen.functionCodegen.generateDefaultIfNeeded(
context.intoFunction(member), member, OwnerKind.PACKAGE, DefaultParameterValueLoader.DEFAULT, null) context.intoFunction(member), member, OwnerKind.PACKAGE, DefaultParameterValueLoader.DEFAULT, null
)
memberCodegen.functionCodegen.generateOverloadsWithDefaultValues(null, member, member) memberCodegen.functionCodegen.generateOverloadsWithDefaultValues(null, member, member)
} }
@@ -310,7 +297,7 @@ class MultifileClassCodegenImpl(
memberCodegen.propertyCodegen.generateInPackageFacade(member) memberCodegen.propertyCodegen.generateInPackageFacade(member)
} }
else -> { else -> {
throw IllegalStateException("Unexpected member: " + member) throw IllegalStateException("Unexpected member: $member")
} }
} }
} }
@@ -320,7 +307,9 @@ class MultifileClassCodegenImpl(
throw IllegalStateException("shouldn't be called") throw IllegalStateException("shouldn't be called")
} }
override fun generateBody(mv: MethodVisitor, frameMap: FrameMap, signature: JvmMethodSignature, context: MethodContext, parentCodegen: MemberCodegen<*>) { override fun generateBody(
mv: MethodVisitor, frameMap: FrameMap, signature: JvmMethodSignature, context: MethodContext, parentCodegen: MemberCodegen<*>
) {
throw IllegalStateException("shouldn't be called") throw IllegalStateException("shouldn't be called")
} }
} }
@@ -344,11 +333,11 @@ class MultifileClassCodegenImpl(
} }
private fun createCodegenForDelegatesInMultifileFacade(facadeContext: FieldOwnerContext<*>): MemberCodegen<KtFile> = private fun createCodegenForDelegatesInMultifileFacade(facadeContext: FieldOwnerContext<*>): MemberCodegen<KtFile> =
object : MemberCodegen<KtFile>(state, null, facadeContext, null, classBuilder) { object : MemberCodegen<KtFile>(state, null, facadeContext, null, classBuilder) {
override fun generateDeclaration() = throw UnsupportedOperationException() override fun generateDeclaration() = throw UnsupportedOperationException()
override fun generateBody() = throw UnsupportedOperationException() override fun generateBody() = throw UnsupportedOperationException()
override fun generateKotlinMetadataAnnotation() = throw UnsupportedOperationException() override fun generateKotlinMetadataAnnotation() = throw UnsupportedOperationException()
} }
private fun done() { private fun done() {
classBuilder.done() classBuilder.done()
@@ -359,13 +348,17 @@ class MultifileClassCodegenImpl(
companion object { companion object {
private val J_L_OBJECT = AsmTypes.OBJECT_TYPE.internalName private val J_L_OBJECT = AsmTypes.OBJECT_TYPE.internalName
private val FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL or Opcodes.ACC_SUPER private const val FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL or Opcodes.ACC_SUPER
private fun getOnlyPackageFragment(packageFqName: FqName, files: Collection<KtFile>, moduleDescriptor: ModuleDescriptor): PackageFragmentDescriptor? { private fun getOnlyPackageFragment(
packageFqName: FqName,
files: Collection<KtFile>,
moduleDescriptor: ModuleDescriptor
): PackageFragmentDescriptor? {
val fragments = SmartList<PackageFragmentDescriptor>() val fragments = SmartList<PackageFragmentDescriptor>()
for (file in files) { for (file in files) {
val fragment = moduleDescriptor.findPackageFragmentForFile(file) val fragment = moduleDescriptor.findPackageFragmentForFile(file)
?: throw AssertionError("package fragment is null for " + file + "\n" + file.text) ?: throw AssertionError("package fragment is null for " + file + "\n" + file.text)
assert(packageFqName == fragment.fqName) { "expected package fq name: " + packageFqName + ", actual: " + fragment.fqName } assert(packageFqName == fragment.fqName) { "expected package fq name: " + packageFqName + ", actual: " + fragment.fqName }
@@ -383,16 +376,15 @@ class MultifileClassCodegenImpl(
CodegenUtil.getMemberDeclarationsToGenerate(this).isNotEmpty() CodegenUtil.getMemberDeclarationsToGenerate(this).isNotEmpty()
private fun getCompiledPackageFragment( private fun getCompiledPackageFragment(
facadeFqName: FqName, state: GenerationState facadeFqName: FqName, state: GenerationState
): IncrementalPackageFragmentProvider.IncrementalMultifileClassPackageFragment? { ): IncrementalPackageFragmentProvider.IncrementalMultifileClassPackageFragment? {
if (!IncrementalCompilation.isEnabledForJvm()) return null if (!IncrementalCompilation.isEnabledForJvm()) return null
val packageFqName = facadeFqName.parent() val packageFqName = facadeFqName.parent()
val incrementalPackageFragment = state.module.getPackage(packageFqName).fragments.firstOrNull { fragment -> 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?
} as IncrementalPackageFragmentProvider.IncrementalPackageFragment?
return incrementalPackageFragment?.getPackageFragmentForMultifileClass(facadeFqName) return incrementalPackageFragment?.getPackageFragmentForMultifileClass(facadeFqName)
} }
@@ -29,13 +29,13 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
class MultifileClassPartCodegen( class MultifileClassPartCodegen(
v: ClassBuilder, v: ClassBuilder,
file: KtFile, file: KtFile,
private val packageFragment: PackageFragmentDescriptor, private val packageFragment: PackageFragmentDescriptor,
private val superClassInternalName: String, private val superClassInternalName: String,
private val shouldGeneratePartHierarchy: Boolean, private val shouldGeneratePartHierarchy: Boolean,
partContext: MultifileClassPartContext, partContext: MultifileClassPartContext,
state: GenerationState state: GenerationState
) : MemberCodegen<KtFile>(state, null, partContext, file, v) { ) : MemberCodegen<KtFile>(state, null, partContext, file, v) {
private val partType = partContext.filePartType private val partType = partContext.filePartType
private val facadeClassType = partContext.multifileClassType private val facadeClassType = partContext.multifileClassType