From d20fb5ddd7402ac98d4d8fe45d278b2855f1fd87 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Wed, 2 Dec 2015 16:06:30 +0300 Subject: [PATCH] BuilderFactoryForDuplicateSignatureDiagnostics: report diagnostics lazily --- ...FactoryForDuplicateSignatureDiagnostics.kt | 20 +++++++++++- .../kotlin/codegen/state/GenerationState.kt | 31 +++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt index 9d8b376cc29..aa335626f04 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt @@ -53,8 +53,18 @@ class BuilderFactoryForDuplicateSignatureDiagnostics( // Avoid errors when some classes are not loaded for some reason private val typeMapper = JetTypeMapper(bindingContext, ClassBuilderMode.LIGHT_CLASSES, fileClassesProvider, incrementalCache, moduleName) + private val reportDiagnosticsTasks = ArrayList<() -> Unit>() + + fun reportDiagnostics() { + reportDiagnosticsTasks.forEach { it() } + reportDiagnosticsTasks.clear() + } override fun handleClashingSignatures(data: ConflictingJvmDeclarationsData) { + reportDiagnosticsTasks.add { reportConflictingJvmSignatures(data) } + } + + private fun reportConflictingJvmSignatures(data: ConflictingJvmDeclarationsData) { val noOwnImplementations = data.signatureOrigins.all { it.originKind in EXTERNAL_SOURCES_KINDS } val elements = LinkedHashSet() @@ -82,6 +92,14 @@ class BuilderFactoryForDuplicateSignatureDiagnostics( classOrigin: JvmDeclarationOrigin, classInternalName: String?, signatures: MultiMap + ) { + reportDiagnosticsTasks.add { reportClashingSignaturesInHierarchy(classOrigin, classInternalName, signatures) } + } + + private fun reportClashingSignaturesInHierarchy( + classOrigin: JvmDeclarationOrigin, + classInternalName: String?, + signatures: MultiMap ) { val descriptor = classOrigin.descriptor if (descriptor !is ClassDescriptor) return @@ -165,7 +183,7 @@ class BuilderFactoryForDuplicateSignatureDiagnostics( return groupedBySignature } - public fun isOrOverridesSamAdapter(descriptor: CallableMemberDescriptor): Boolean { + private fun isOrOverridesSamAdapter(descriptor: CallableMemberDescriptor): Boolean { if (descriptor is SamAdapterDescriptor<*>) return true return descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt index e4d350361ef..99e7641c78b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt @@ -17,6 +17,8 @@ package org.jetbrains.kotlin.codegen.state import com.intellij.openapi.project.Project +import com.intellij.openapi.util.ModificationTracker +import com.intellij.psi.PsiElement import org.jetbrains.kotlin.builtins.ReflectionTypes import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.`when`.MappingsClassesForWhenByEnum @@ -28,6 +30,7 @@ import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods import org.jetbrains.kotlin.codegen.optimization.OptimizationClassBuilderFactory import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ScriptDescriptor +import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.modules.TargetId @@ -96,7 +99,10 @@ public class GenerationState @JvmOverloads constructor( private var used = false public val diagnostics: DiagnosticSink get() = extraJvmDiagnosticsTrace - public val collectedExtraJvmDiagnostics: Diagnostics get() = extraJvmDiagnosticsTrace.bindingContext.diagnostics + public val collectedExtraJvmDiagnostics: Diagnostics = LazyJvmDiagnostics { + duplicateSignatureFactory.reportDiagnostics() + extraJvmDiagnosticsTrace.bindingContext.diagnostics + } public val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module) public val classBuilderMode: ClassBuilderMode = builderFactory.getClassBuilderMode() @@ -110,6 +116,7 @@ public class GenerationState @JvmOverloads constructor( public val reflectionTypes: ReflectionTypes = ReflectionTypes(module) public val jvmRuntimeTypes: JvmRuntimeTypes = JvmRuntimeTypes() public val factory: ClassFileFactory + private val duplicateSignatureFactory: BuilderFactoryForDuplicateSignatureDiagnostics public val replSpecific = ForRepl() @@ -135,12 +142,13 @@ public class GenerationState @JvmOverloads constructor( init { val optimizationClassBuilderFactory = OptimizationClassBuilderFactory(builderFactory, disableOptimization) - var interceptedBuilderFactory: ClassBuilderFactory = BuilderFactoryForDuplicateSignatureDiagnostics( + duplicateSignatureFactory = BuilderFactoryForDuplicateSignatureDiagnostics( optimizationClassBuilderFactory, this.bindingContext, diagnostics, fileClassesProvider, getIncrementalCacheForThisTarget(), this.moduleName) - interceptedBuilderFactory = BuilderFactoryForDuplicateClassNameDiagnostics(interceptedBuilderFactory, diagnostics); + var interceptedBuilderFactory: ClassBuilderFactory + = BuilderFactoryForDuplicateClassNameDiagnostics(duplicateSignatureFactory, diagnostics) val interceptExtensions = ClassBuilderInterceptorExtension.getInstances(project) @@ -168,3 +176,20 @@ public class GenerationState @JvmOverloads constructor( interceptedBuilderFactory.close() } } + +private class LazyJvmDiagnostics(compute: () -> Diagnostics): Diagnostics { + private val delegate by lazy(LazyThreadSafetyMode.SYNCHRONIZED, compute) + + override val modificationTracker: ModificationTracker + get() = delegate.modificationTracker + + override fun all(): Collection = delegate.all() + + override fun forElement(psiElement: PsiElement) = delegate.forElement(psiElement) + + override fun isEmpty() = delegate.isEmpty() + + override fun noSuppression() = delegate.noSuppression() + + override fun iterator() = delegate.iterator() +}