BuilderFactoryForDuplicateSignatureDiagnostics: report diagnostics lazily

This commit is contained in:
Pavel V. Talanov
2015-12-02 16:06:30 +03:00
parent 05a62c5892
commit d20fb5ddd7
2 changed files with 47 additions and 4 deletions
@@ -53,8 +53,18 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
// Avoid errors when some classes are not loaded for some reason // Avoid errors when some classes are not loaded for some reason
private val typeMapper = JetTypeMapper(bindingContext, ClassBuilderMode.LIGHT_CLASSES, fileClassesProvider, incrementalCache, moduleName) 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) { 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 noOwnImplementations = data.signatureOrigins.all { it.originKind in EXTERNAL_SOURCES_KINDS }
val elements = LinkedHashSet<PsiElement>() val elements = LinkedHashSet<PsiElement>()
@@ -82,6 +92,14 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
classOrigin: JvmDeclarationOrigin, classOrigin: JvmDeclarationOrigin,
classInternalName: String?, classInternalName: String?,
signatures: MultiMap<RawSignature, JvmDeclarationOrigin> signatures: MultiMap<RawSignature, JvmDeclarationOrigin>
) {
reportDiagnosticsTasks.add { reportClashingSignaturesInHierarchy(classOrigin, classInternalName, signatures) }
}
private fun reportClashingSignaturesInHierarchy(
classOrigin: JvmDeclarationOrigin,
classInternalName: String?,
signatures: MultiMap<RawSignature, JvmDeclarationOrigin>
) { ) {
val descriptor = classOrigin.descriptor val descriptor = classOrigin.descriptor
if (descriptor !is ClassDescriptor) return if (descriptor !is ClassDescriptor) return
@@ -165,7 +183,7 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
return groupedBySignature return groupedBySignature
} }
public fun isOrOverridesSamAdapter(descriptor: CallableMemberDescriptor): Boolean { private fun isOrOverridesSamAdapter(descriptor: CallableMemberDescriptor): Boolean {
if (descriptor is SamAdapterDescriptor<*>) return true if (descriptor is SamAdapterDescriptor<*>) return true
return descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE return descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE
@@ -17,6 +17,8 @@
package org.jetbrains.kotlin.codegen.state package org.jetbrains.kotlin.codegen.state
import com.intellij.openapi.project.Project 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.builtins.ReflectionTypes
import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.`when`.MappingsClassesForWhenByEnum 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.codegen.optimization.OptimizationClassBuilderFactory
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.ScriptDescriptor import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.modules.TargetId import org.jetbrains.kotlin.modules.TargetId
@@ -96,7 +99,10 @@ public class GenerationState @JvmOverloads constructor(
private var used = false private var used = false
public val diagnostics: DiagnosticSink get() = extraJvmDiagnosticsTrace 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 moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module)
public val classBuilderMode: ClassBuilderMode = builderFactory.getClassBuilderMode() public val classBuilderMode: ClassBuilderMode = builderFactory.getClassBuilderMode()
@@ -110,6 +116,7 @@ public class GenerationState @JvmOverloads constructor(
public val reflectionTypes: ReflectionTypes = ReflectionTypes(module) public val reflectionTypes: ReflectionTypes = ReflectionTypes(module)
public val jvmRuntimeTypes: JvmRuntimeTypes = JvmRuntimeTypes() public val jvmRuntimeTypes: JvmRuntimeTypes = JvmRuntimeTypes()
public val factory: ClassFileFactory public val factory: ClassFileFactory
private val duplicateSignatureFactory: BuilderFactoryForDuplicateSignatureDiagnostics
public val replSpecific = ForRepl() public val replSpecific = ForRepl()
@@ -135,12 +142,13 @@ public class GenerationState @JvmOverloads constructor(
init { init {
val optimizationClassBuilderFactory = OptimizationClassBuilderFactory(builderFactory, disableOptimization) val optimizationClassBuilderFactory = OptimizationClassBuilderFactory(builderFactory, disableOptimization)
var interceptedBuilderFactory: ClassBuilderFactory = BuilderFactoryForDuplicateSignatureDiagnostics( duplicateSignatureFactory = BuilderFactoryForDuplicateSignatureDiagnostics(
optimizationClassBuilderFactory, this.bindingContext, diagnostics, fileClassesProvider, optimizationClassBuilderFactory, this.bindingContext, diagnostics, fileClassesProvider,
getIncrementalCacheForThisTarget(), getIncrementalCacheForThisTarget(),
this.moduleName) this.moduleName)
interceptedBuilderFactory = BuilderFactoryForDuplicateClassNameDiagnostics(interceptedBuilderFactory, diagnostics); var interceptedBuilderFactory: ClassBuilderFactory
= BuilderFactoryForDuplicateClassNameDiagnostics(duplicateSignatureFactory, diagnostics)
val interceptExtensions = ClassBuilderInterceptorExtension.getInstances(project) val interceptExtensions = ClassBuilderInterceptorExtension.getInstances(project)
@@ -168,3 +176,20 @@ public class GenerationState @JvmOverloads constructor(
interceptedBuilderFactory.close() 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<Diagnostic> = 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()
}