diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/RemoteLookupTrackerClient.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/RemoteLookupTrackerClient.kt index 8c3f244a131..88e9b839bc0 100644 --- a/compiler/daemon/src/org/jetbrains/kotlin/daemon/RemoteLookupTrackerClient.kt +++ b/compiler/daemon/src/org/jetbrains/kotlin/daemon/RemoteLookupTrackerClient.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.daemon import com.intellij.util.containers.StringInterner +import gnu.trove.THashMap import gnu.trove.THashSet import org.jetbrains.kotlin.daemon.common.CompilerCallbackServicesFacade import org.jetbrains.kotlin.daemon.common.DummyProfiler @@ -27,10 +28,15 @@ import org.jetbrains.kotlin.incremental.components.Position import org.jetbrains.kotlin.incremental.components.ScopeKind -class RemoteLookupTrackerClient(val facade: CompilerCallbackServicesFacade, eventManager: EventManager, val profiler: Profiler = DummyProfiler()) : LookupTracker { +class RemoteLookupTrackerClient( + val facade: CompilerCallbackServicesFacade, + eventManager: EventManager, + val profiler: Profiler = DummyProfiler() +) : LookupTracker { private val isDoNothing = profiler.withMeasure(this) { facade.lookupTracker_isDoNothing() } - private val lookups = THashSet() + // Map: FileName -> (ScopeFqName -> Set) + private val lookups = THashMap>>() private val interner = StringInterner() override val requiresPosition: Boolean = profiler.withMeasure(this) { facade.lookupTracker_requiresPosition() } @@ -38,11 +44,16 @@ class RemoteLookupTrackerClient(val facade: CompilerCallbackServicesFacade, even override fun record(filePath: String, position: Position, scopeFqName: String, scopeKind: ScopeKind, name: String) { if (isDoNothing) return - val internedFilePath = interner.intern(filePath) - val internedScopeFqName = interner.intern(scopeFqName) + val internedSymbolFqName = interner.intern(scopeFqName) val internedName = interner.intern(name) - lookups.add(LookupInfo(internedFilePath, position, internedScopeFqName, scopeKind, internedName)) + val objectToPut: Any = + if (requiresPosition) + LookupInfo(filePath, position, scopeFqName, scopeKind, name) + else + internedName + + lookups.getOrPut(filePath, ::THashMap).getOrPut(internedSymbolFqName, ::THashSet).add(objectToPut) } init { @@ -50,11 +61,24 @@ class RemoteLookupTrackerClient(val facade: CompilerCallbackServicesFacade, even } private fun flush() { - if (isDoNothing || lookups.isEmpty()) return + if (isDoNothing || lookups.isEmpty) return profiler.withMeasure(this) { - // Converting to list is intentional because THashSet may lead to serialization-related problems - facade.lookupTracker_record(lookups.toList()) + facade.lookupTracker_record( + lookups.flatMap { (filePath, lookupsByFile) -> + lookupsByFile.flatMap { (scopeFqName, lookupsByScopeFqName) -> + lookupsByScopeFqName.map { lookupInfoOrString -> + if (requiresPosition) + lookupInfoOrString as LookupInfo + else + LookupInfo( + filePath, Position.NO_POSITION, scopeFqName, ScopeKind.CLASSIFIER, + lookupInfoOrString as String + ) + } + } + } + ) } lookups.clear()