Compare commits

...

14 Commits

Author SHA1 Message Date
Pavel V. Talanov
c6538e6a7c Show all errors action 2014-09-18 15:08:43 +04:00
Pavel V. Talanov
0455e3c888 FIX 2014-09-17 21:04:21 +04:00
Pavel V. Talanov
a90e204a28 Log when libraries cache is dropped because of ProcessCanceledException
Hope it can give insight on how often this happens
2014-09-17 18:22:55 +04:00
Pavel V. Talanov
d00e860db7 Create composite exception tracker when delegating ModuleResolverProvider
Avoid dropping delegate caches when exception (i.e. ProcessCancelled) is thrown in delegating provider
2014-09-17 18:22:53 +04:00
Pavel V. Talanov
f70cef7b55 Delegate to global cache when building ModuleResolverProvider for synthetic files 2014-09-17 18:22:51 +04:00
Pavel V. Talanov
ef4a45ec19 Libraries cache drops only on roots change 2014-09-17 18:22:49 +04:00
Pavel V. Talanov
9117d90946 Synthetic files cache delegates to libraries cache 2014-09-17 18:22:47 +04:00
Pavel V. Talanov
44bff013a3 Split global cache in KotlinCacheService into separate caches for libraries and for modules 2014-09-17 18:22:46 +04:00
Pavel V. Talanov
cda6184e46 Reuse both storage manager and exception tracker when delegating to ModuleResolverProvider 2014-09-17 18:22:40 +04:00
Pavel V. Talanov
f67dc19e17 Allow to provide delegate ModuleResolverProvider when computing resolve sessions for bodies 2014-09-17 18:21:58 +04:00
Pavel V. Talanov
2b691886f9 Implement IdeaModuleInfo.dependsOn() 2014-09-17 18:20:47 +04:00
Pavel V. Talanov
b92a010bcc Minor: extract property in KotlinResolveCache 2014-09-17 18:20:45 +04:00
Pavel V. Talanov
82396691e8 Minor: fix typo in file name 2014-09-17 18:20:44 +04:00
Pavel V. Talanov
433ca8e6c6 Allow to provide precomputed analyzers when creating ResolverForProject 2014-09-17 18:20:42 +04:00
14 changed files with 370 additions and 60 deletions

View File

@@ -26,4 +26,12 @@
name='com.intellij.openapi.roots.ProjectFileIndex.SERVICE com.intellij.openapi.roots.ProjectFileIndex getInstance(com.intellij.openapi.project.Project)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.openapi.roots.ProjectRootManager com.intellij.openapi.roots.ProjectRootManager getInstance(com.intellij.openapi.project.Project)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.openapi.roots.ProjectRootModificationTracker com.intellij.openapi.roots.ProjectRootModificationTracker getInstance(com.intellij.openapi.project.Project)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
</root>

View File

@@ -3,7 +3,11 @@
name='com.intellij.psi.util.CachedValueProvider.Result com.intellij.psi.util.CachedValueProvider.Result&lt;T&gt; create(T, java.lang.Object...)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
<item
name='com.intellij.psi.util.CachedValueProvider.Result com.intellij.psi.util.CachedValueProvider.Result&lt;T&gt; create(T, java.util.Collection&lt;?&gt;)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.psi.util.CachedValuesManager com.intellij.psi.util.CachedValue&lt;T&gt; createCachedValue(com.intellij.psi.util.CachedValueProvider&lt;T&gt;, boolean)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>

View File

@@ -38,15 +38,23 @@ public trait ResolverForModule {
public trait ResolverForProject<M : ModuleInfo, R : ResolverForModule> {
public fun resolverForModule(moduleInfo: M): R
public fun descriptorForModule(moduleInfo: M): ModuleDescriptor
val allModules: Collection<M>
}
public class EmptyResolverForProject<M : ModuleInfo, R : ResolverForModule> : ResolverForProject<M, R> {
override fun resolverForModule(moduleInfo: M): R = throw IllegalStateException("Should not be called for $moduleInfo")
override fun descriptorForModule(moduleInfo: M) = throw IllegalStateException("Should not be called for $moduleInfo")
override val allModules: Collection<M> = listOf()
}
public class ResolverForProjectImpl<M : ModuleInfo, R : ResolverForModule>(
val descriptorByModule: Map<M, ModuleDescriptorImpl>
val descriptorByModule: Map<M, ModuleDescriptorImpl>,
val delegateResolver: ResolverForProject<M, R> = EmptyResolverForProject()
) : ResolverForProject<M, R> {
val resolverByModuleDescriptor: MutableMap<ModuleDescriptor, R> = HashMap()
private val allModules: Collection<M> by Delegates.lazy {
descriptorByModule.keySet()
override val allModules: Collection<M> by Delegates.lazy {
(descriptorByModule.keySet() + delegateResolver.allModules).toSet()
}
private fun assertCorrectModuleInfo(moduleInfo: M) {
@@ -57,13 +65,13 @@ public class ResolverForProjectImpl<M : ModuleInfo, R : ResolverForModule>(
override fun resolverForModule(moduleInfo: M): R {
assertCorrectModuleInfo(moduleInfo)
val descriptor = descriptorByModule[moduleInfo]!!
val descriptor = descriptorByModule[moduleInfo] ?: return delegateResolver.resolverForModule(moduleInfo)
return resolverByModuleDescriptor[descriptor]!!
}
override fun descriptorForModule(moduleInfo: M): ModuleDescriptorImpl {
assertCorrectModuleInfo(moduleInfo)
return descriptorByModule[moduleInfo]!!
return descriptorByModule[moduleInfo] ?: return delegateResolver.descriptorForModule(moduleInfo) as ModuleDescriptorImpl
}
}
@@ -111,7 +119,8 @@ public trait AnalyzerFacade<out A : ResolverForModule, in P : PlatformAnalysisPa
project: Project,
modules: Collection<M>,
modulesContent: (M) -> ModuleContent,
platformParameters: P
platformParameters: P,
delegateResolver: ResolverForProject<M, A> = EmptyResolverForProject()
): ResolverForProject<M, A> {
fun createResolverForProject(): ResolverForProjectImpl<M, A> {
@@ -120,7 +129,7 @@ public trait AnalyzerFacade<out A : ResolverForModule, in P : PlatformAnalysisPa
module ->
descriptorByModule[module] = ModuleDescriptorImpl(module.name, defaultImports, platformToKotlinClassMap)
}
return ResolverForProjectImpl(descriptorByModule)
return ResolverForProjectImpl(descriptorByModule, delegateResolver)
}
val resolverForProject = createResolverForProject()

View File

@@ -20,7 +20,7 @@ import com.intellij.openapi.util.ModificationTracker
import java.util.concurrent.atomic.AtomicLong
import org.jetbrains.jet.utils.rethrow
public class ExceptionTracker : ModificationTracker, LockBasedStorageManager.ExceptionHandlingStrategy {
public open class ExceptionTracker : ModificationTracker, LockBasedStorageManager.ExceptionHandlingStrategy {
private val cancelledTracker: AtomicLong = AtomicLong()
override fun handleException(throwable: Throwable): RuntimeException {

View File

@@ -421,4 +421,11 @@ public class LockBasedStorageManager implements StorageManager {
}
}
@NotNull
public static LockBasedStorageManager createDelegatingWithSameLock(
@NotNull LockBasedStorageManager base,
@NotNull ExceptionHandlingStrategy newStrategy
) {
return new LockBasedStorageManager(getPointOfConstruction(), newStrategy, base.lock);
}
}

View File

@@ -36,6 +36,7 @@ import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.jet.utils.emptyOrSingletonList
import com.intellij.openapi.roots.OrderEnumerator
import java.util.HashSet
public abstract class IdeaModuleInfo : ModuleInfo {
abstract fun contentScope(): GlobalSearchScope
@@ -151,4 +152,23 @@ private data class LibraryWithoutSourceScope(project: Project, private val libra
//TODO: (module refactoring) android sdk has modified scope
private data class SdkScope(project: Project, private val sdk: Sdk) :
LibraryScopeBase(project, sdk.getRootProvider().getFiles(OrderRootType.CLASSES), array<VirtualFile>())
LibraryScopeBase(project, sdk.getRootProvider().getFiles(OrderRootType.CLASSES), array<VirtualFile>())
private fun IdeaModuleInfo.dependsOn(other: IdeaModuleInfo): Boolean {
val processed = HashSet<ModuleInfo>()
val toProcess = arrayListOf<ModuleInfo>(this)
while (toProcess.notEmpty) {
val elem = toProcess.remove(0)
if (elem in processed) continue
if (elem == other) return true
toProcess.addAll(elem.dependencies())
processed.add(elem)
}
return false
}
private fun IdeaModuleInfo.isLibraryClasses() = this is SdkInfo || this is LibraryInfo

View File

@@ -33,12 +33,10 @@ import org.jetbrains.jet.plugin.project.TargetPlatform.*
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies
import org.jetbrains.jet.plugin.project.TargetPlatformDetector
import org.jetbrains.jet.lang.psi.JetCodeFragment
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
import org.jetbrains.jet.lang.resolve.DescriptorUtils
import org.jetbrains.jet.context.GlobalContext
import org.jetbrains.jet.plugin.stubindex.JetSourceFilterScope
import com.intellij.psi.PsiElement
import org.jetbrains.jet.utils.keysToMap
import com.intellij.openapi.roots.ProjectRootModificationTracker
import java.util.HashSet
private val LOG = Logger.getInstance(javaClass<KotlinCacheService>())
@@ -65,30 +63,61 @@ public class KotlinCacheService(val project: Project) {
public fun getInstance(project: Project): KotlinCacheService = ServiceManager.getService(project, javaClass<KotlinCacheService>())!!
}
private fun globalResolveSessionProvider(platform: TargetPlatform, syntheticFiles: Collection<JetFile> = listOf()):
() -> CachedValueProvider.Result<ModuleResolverProvider> = {
fun globalResolveSessionProvider(
platform: TargetPlatform,
dependencies: Collection<Any>,
moduleFilter: (IdeaModuleInfo, modulesWithSyntheticFiles: Collection<IdeaModuleInfo>) -> Boolean,
reuseDataFromCache: KotlinResolveCache? = null,
syntheticFiles: Collection<JetFile> = listOf(),
logProcessCanceled: Boolean = false
): () -> CachedValueProvider.Result<ModuleResolverProvider> = {
val analyzerFacade = AnalyzerFacadeProvider.getAnalyzerFacade(platform)
val moduleMapping = createModuleResolverProvider(project, analyzerFacade, syntheticFiles)
CachedValueProvider.Result.create(
moduleMapping,
PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT,
moduleMapping.exceptionTracker
)
val delegateResolverProvider = reuseDataFromCache?.moduleResolverProvider ?: EmptyModuleResolverProvider
val globalContext = (delegateResolverProvider as? ModuleResolverProviderImpl)?.globalContext
?.withCompositeExceptionTrackerUnderSameLock()
?: GlobalContext(logProcessCanceled)
val moduleResolverProvider = createModuleResolverProvider(
project, globalContext, analyzerFacade, syntheticFiles, delegateResolverProvider, moduleFilter
)
val allDependencies = dependencies + listOf(moduleResolverProvider.exceptionTracker)
CachedValueProvider.Result.create(moduleResolverProvider, allDependencies)
}
private val globalCachesPerPlatform = mapOf(
JVM to KotlinResolveCache(project, globalResolveSessionProvider(JVM)),
JS to KotlinResolveCache(project, globalResolveSessionProvider(JS))
)
private val globalCachesPerPlatform = listOf(JVM, JS).keysToMap { platform -> GlobalCache(platform) }
private inner class GlobalCache(platform: TargetPlatform) {
val librariesCache = KotlinResolveCache(
project, globalResolveSessionProvider(platform,
moduleFilter = { (module, _) -> module.isLibraryClasses() },
logProcessCanceled = true,
dependencies = listOf(ProjectRootModificationTracker.getInstance(project)))
)
val modulesCache = KotlinResolveCache(
project, globalResolveSessionProvider(platform,
reuseDataFromCache = librariesCache,
moduleFilter = { (module, _) -> !module.isLibraryClasses() },
dependencies = listOf(PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT))
)
}
private fun getGlobalCache(platform: TargetPlatform) = globalCachesPerPlatform[platform]!!.modulesCache
private val syntheticFileCaches = object : SLRUCache<JetFile, KotlinResolveCache>(2, 3) {
override fun createValue(file: JetFile?): KotlinResolveCache {
val targetPlatform = TargetPlatformDetector.getPlatform(file!!)
val dependentModules = file.getModuleInfo().getDependentModules()
return KotlinResolveCache(
project,
globalResolveSessionProvider(
TargetPlatformDetector.getPlatform(file!!),
listOf(file)
targetPlatform,
syntheticFiles = listOf(file),
reuseDataFromCache = getGlobalCache(targetPlatform),
moduleFilter = {(module, modulesWithSyntheticFiles) ->
module in dependentModules
},
dependencies = listOf(PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT)
)
)
}
@@ -101,7 +130,7 @@ public class KotlinCacheService(val project: Project) {
}
public fun getGlobalLazyResolveSession(file: JetFile, platform: TargetPlatform): ResolveSessionForBodies {
return globalCachesPerPlatform[platform]!!.getLazyResolveSession(file)
return getGlobalCache(platform).getLazyResolveSession(file)
}
public fun getLazyResolveSession(element: JetElement): ResolveSessionForBodies {
@@ -121,8 +150,7 @@ public class KotlinCacheService(val project: Project) {
return getCacheForSyntheticFile(firstFile).getAnalysisResultsForElements(elements)
}
val resolveCache = globalCachesPerPlatform[TargetPlatformDetector.getPlatform(firstFile)]!!
return resolveCache.getAnalysisResultsForElements(elements)
return getGlobalCache(TargetPlatformDetector.getPlatform(firstFile)).getAnalysisResultsForElements(elements)
}
private fun isFileInScope(jetFile: JetFile): Boolean {
@@ -138,6 +166,6 @@ public class KotlinCacheService(val project: Project) {
}
public fun <T> get(extension: CacheExtension<T>): T {
return globalCachesPerPlatform[extension.platform]!![extension]
return getGlobalCache(extension.platform)[extension]
}
}

View File

@@ -73,22 +73,25 @@ public trait CacheExtension<T> {
private class KotlinResolveCache(
val project: Project,
setupProvider: () -> CachedValueProvider.Result<ModuleResolverProvider>
computeModuleResolverProvider: () -> CachedValueProvider.Result<ModuleResolverProvider>
) {
private val resolverCache = SynchronizedCachedValue(project, setupProvider, trackValue = false)
private val resolverCache = SynchronizedCachedValue(project, computeModuleResolverProvider, trackValue = false)
val moduleResolverProvider: ModuleResolverProvider
get() = resolverCache.getValue()
public fun getLazyResolveSession(element: JetElement): ResolveSessionForBodies {
return resolverCache.getValue().resolveSessionForBodiesByModule(element.getModuleInfo())
return moduleResolverProvider.resolveSessionForBodiesByModule(element.getModuleInfo())
}
public fun <T> get(extension: CacheExtension<T>): T {
return extension.getData(resolverCache.getValue())
return extension.getData(moduleResolverProvider)
}
private val analysisResults = CachedValuesManager.getManager(project).createCachedValue(
{
val resolverProvider = resolverCache.getValue()
val resolverProvider = moduleResolverProvider
val results = object : SLRUCache<JetFile, PerFileAnalysisCache>(2, 3) {
override fun createValue(file: JetFile?): PerFileAnalysisCache {
return PerFileAnalysisCache(file!!, resolverProvider.resolveSessionForBodiesByModule(file.getModuleInfo()))
@@ -169,7 +172,7 @@ private class PerFileAnalysisCache(val file: JetFile, val resolveSession: Resolv
return AnalyzeExhaust.EMPTY
}
ApplicationUtils.warnTimeConsuming(LOG)
// ApplicationUtils.warnTimeConsuming(LOG)
try {
return KotlinResolveDataProvider.analyze(project, resolveSession, analyzableElement)

View File

@@ -17,7 +17,6 @@
package org.jetbrains.jet.plugin.caches.resolve
import com.intellij.openapi.project.Project
import org.jetbrains.jet.context.GlobalContext
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.module.ModuleManager
import org.jetbrains.jet.utils.keysToMap
@@ -26,7 +25,6 @@ import org.jetbrains.jet.plugin.project.ResolveSessionForBodies
import org.jetbrains.jet.lang.resolve.java.JvmPlatformParameters
import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaClassImpl
import com.intellij.openapi.roots.JdkOrderEntry
import org.jetbrains.kotlin.util.sure
import org.jetbrains.jet.analyzer.AnalyzerFacade
import org.jetbrains.jet.analyzer.ResolverForModule
import org.jetbrains.jet.lang.psi.*
@@ -34,23 +32,29 @@ import org.jetbrains.jet.storage.ExceptionTracker
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass
import org.jetbrains.jet.analyzer.ResolverForProject
import org.jetbrains.jet.analyzer.ModuleContent
import org.jetbrains.jet.analyzer.PlatformAnalysisParameters
import org.jetbrains.jet.plugin.caches.resolve
import org.jetbrains.jet.analyzer.EmptyResolverForProject
import org.jetbrains.jet.context.GlobalContextImpl
fun createModuleResolverProvider(
project: Project,
globalContext: GlobalContextImpl,
analyzerFacade: AnalyzerFacade<ResolverForModule, JvmPlatformParameters>,
syntheticFiles: Collection<JetFile>
syntheticFiles: Collection<JetFile>,
delegateProvider: ModuleResolverProvider,
moduleFilter: (IdeaModuleInfo, modulesWithSyntheticFiles: Collection<IdeaModuleInfo>) -> Boolean
): ModuleResolverProvider {
val allModuleInfos = collectAllModuleInfosFromIdeaModel(project).toHashSet()
val globalContext = GlobalContext()
val syntheticFilesByModule = syntheticFiles.groupBy { it.getModuleInfo() }
val syntheticFilesModules = syntheticFilesByModule.keySet()
allModuleInfos.addAll(syntheticFilesModules)
val modulesToCreateResolversFor = allModuleInfos.filter {
moduleFilter(it, syntheticFilesModules)
}
fun createResolverForProject(): ResolverForProject<IdeaModuleInfo, ResolverForModule> {
val syntheticFilesByModule = syntheticFiles.groupBy { it.getModuleInfo() }
allModuleInfos.addAll(syntheticFilesByModule.keySet())
val modulesContent = {(module: IdeaModuleInfo) ->
ModuleContent(syntheticFilesByModule[module] ?: listOf(), module.contentScope())
}
@@ -62,22 +66,23 @@ fun createModuleResolverProvider(
}
val resolverForProject = analyzerFacade.setupResolverForProject(
globalContext, project, allModuleInfos, modulesContent, jvmPlatformParameters
globalContext, project, modulesToCreateResolversFor, modulesContent, jvmPlatformParameters, delegateProvider.resolverForProject
)
return resolverForProject
}
val resolverForProject = createResolverForProject()
val moduleToBodiesResolveSession = allModuleInfos.keysToMap {
val moduleToBodiesResolveSession = modulesToCreateResolversFor.keysToMap {
module ->
val analyzer = resolverForProject.resolverForModule(module)
ResolveSessionForBodies(project, analyzer.lazyResolveSession)
}
return ModuleResolverProvider(
return ModuleResolverProviderImpl(
resolverForProject,
moduleToBodiesResolveSession,
globalContext.exceptionTracker
globalContext,
delegateProvider
)
}
@@ -106,14 +111,33 @@ private fun collectAllModuleInfosFromIdeaModel(project: Project): List<IdeaModul
return collectAllModuleInfos
}
class ModuleResolverProvider(
private val resolverForProject: ResolverForProject<IdeaModuleInfo, *>,
private val bodiesResolveByModule: Map<IdeaModuleInfo, ResolveSessionForBodies>,
val exceptionTracker: ExceptionTracker
) {
trait ModuleResolverProvider {
val exceptionTracker: ExceptionTracker
fun resolverByModule(module: IdeaModuleInfo): ResolverForModule = resolverForProject.resolverForModule(module)
fun resolveSessionForBodiesByModule(module: IdeaModuleInfo): ResolveSessionForBodies
val resolverForProject: ResolverForProject<IdeaModuleInfo, ResolverForModule>
}
fun resolveSessionForBodiesByModule(module: IdeaModuleInfo) =
//NOTE: if this assert fails in production, additional information can be obtained by logging on the call site
bodiesResolveByModule[module] ?: throw AssertionError("Requested data for $module not contained in this resolver.")
object EmptyModuleResolverProvider: ModuleResolverProvider {
override val exceptionTracker: ExceptionTracker
get() = throw IllegalStateException("Should not be called")
override fun resolveSessionForBodiesByModule(module: IdeaModuleInfo): ResolveSessionForBodies
= throw IllegalStateException("Trying to obtain resolve session for unknown $module")
override val resolverForProject: ResolverForProject<IdeaModuleInfo, ResolverForModule> = EmptyResolverForProject()
}
class ModuleResolverProviderImpl(
override val resolverForProject: ResolverForProject<IdeaModuleInfo, ResolverForModule>,
private val bodiesResolveByModule: Map<IdeaModuleInfo, ResolveSessionForBodies>,
val globalContext: GlobalContextImpl,
val delegateProvider: ModuleResolverProvider = EmptyModuleResolverProvider
): ModuleResolverProvider {
override val exceptionTracker: ExceptionTracker = globalContext.exceptionTracker
override fun resolveSessionForBodiesByModule(module: IdeaModuleInfo): ResolveSessionForBodies =
bodiesResolveByModule[module] ?:
delegateProvider.resolveSessionForBodiesByModule(module)
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.caches.resolve
import org.jetbrains.jet.context.GlobalContextImpl
import org.jetbrains.jet.storage.LockBasedStorageManager
import org.jetbrains.jet.storage.ExceptionTracker
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.diagnostic.Logger
fun GlobalContextImpl.withCompositeExceptionTrackerUnderSameLock(): GlobalContextImpl {
val newExceptionTracker = CompositeExceptionTracker(this.exceptionTracker)
val newStorageManager = LockBasedStorageManager.createDelegatingWithSameLock(this.storageManager, newExceptionTracker)
return GlobalContextImpl(newStorageManager, newExceptionTracker)
}
private class CompositeExceptionTracker(val delegate: ExceptionTracker) : ExceptionTracker() {
override fun getModificationCount(): Long {
return super.getModificationCount() + delegate.getModificationCount()
}
}
private class ExceptionTrackerWithProcessCanceledReport() : ExceptionTracker() {
override fun handleException(throwable: Throwable): RuntimeException {
if (throwable is ProcessCanceledException) {
LOG.info("ProcessCancelException was thrown while analyzing libraries. Cache has to be rebuilt.")
}
throw super.handleException(throwable)
}
class object {
val LOG = Logger.getInstance(javaClass<ExceptionTrackerWithProcessCanceledReport>())
}
}
public fun GlobalContext(logProcessCanceled: Boolean): GlobalContextImpl {
val tracker = if (logProcessCanceled) ExceptionTrackerWithProcessCanceledReport() else ExceptionTracker()
return GlobalContextImpl(LockBasedStorageManager.createWithExceptionHandling(tracker), tracker)
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.caches.resolve
import com.intellij.openapi.module.Module
import com.intellij.util.containers.MultiMap
import com.intellij.openapi.project.Project
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ModuleOrderEntry
import gnu.trove.THashSet
import com.intellij.util.containers.Queue
fun IdeaModuleInfo.getDependentModules(): Set<IdeaModuleInfo> {
if (this is ModuleTestSourceInfo) {
return getDependentsByModule(this.module, true).toSet()
}
else if (this is ModuleProductionSourceInfo) {
return getDependentsByModule(this.module, false).toSet()
}
else {
//TODO:
return setOf()
}
}
private fun getDependentsByModule(module: Module, includeTests: Boolean): Collection<IdeaModuleInfo> {
val dependents = getDependents(module)
if (includeTests) {
return dependents.flatMap { listOf(module.testSourceInfo(), module.productionSourceInfo()) }
}
else {
return dependents.map { module.productionSourceInfo() }
}
}
private fun getDependents(module: Module): Set<Module> {
val result = THashSet<Module>()
result.add(module)
val processedExporting = THashSet<Module>()
val index = getModuleIndex(module.getProject())
val walkingQueue = Queue<Module>(10)
walkingQueue.addLast(module)
while (!walkingQueue.isEmpty()) {
val current = walkingQueue.pullFirst()
processedExporting.add(current!!)
result.addAll(index.plainUsages.get(current))
for (dependent in index.exportingUsages.get(current)) {
result.add(dependent)
if (processedExporting.add(dependent)) {
walkingQueue.addLast(dependent)
}
}
}
return result
}
private class ModuleIndex {
val plainUsages = MultiMap.create<Module, Module>()
val exportingUsages = MultiMap.create<Module, Module>()
}
private fun getModuleIndex(project: Project): ModuleIndex {
val index = ModuleIndex()
for (module in ModuleManager.getInstance(project).getModules()) {
for (orderEntry in ModuleRootManager.getInstance(module).getOrderEntries()) {
if (orderEntry is ModuleOrderEntry) {
val referenced = (orderEntry as ModuleOrderEntry).getModule()
if (referenced != null) {
val map = if ((orderEntry as ModuleOrderEntry).isExported()) index.exportingUsages else index.plainUsages
map.putValue(referenced, module)
}
}
}
}
return index
}

View File

@@ -71,6 +71,10 @@
<keyboard-shortcut keymap="$default" first-keystroke="control alt shift J"/>
<add-to-group group-id="CodeMenu" anchor="last"/>
</action>
<action id="ShowAllErrors" class="org.jetbrains.jet.plugin.actions.ShowAllErrors"
text="Show All Errors">
<add-to-group group-id="CodeMenu" anchor="last"/>
</action>
<group id="EditorGutterKotlinPopupMenu">
<action id="ShowKotlinSignatures" class="org.jetbrains.jet.plugin.ktSignature.ShowKotlinSignaturesAction"/>

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.actions
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import org.jetbrains.jet.plugin.project.PluginJetFilesProvider
import com.intellij.openapi.actionSystem.CommonDataKeys
import org.jetbrains.jet.plugin.caches.resolve.getAnalysisResults
import org.jetbrains.jet.lang.diagnostics.Severity
import org.jetbrains.jet.plugin.highlighter.IdeErrorMessages
class ShowAllErrors : AnAction("Show all errors") {
override fun actionPerformed(e: AnActionEvent?) {
val project = CommonDataKeys.PROJECT.getData(e!!.getDataContext())!!
PluginJetFilesProvider.allFilesInProject(project).forEach { file ->
//println("\nFILE: " + + "\n")
val bindingContext = file.getAnalysisResults().getBindingContext()
val errors = bindingContext.getDiagnostics().filter {
it.getSeverity() == Severity.ERROR
}
if (errors.isNotEmpty()) {
val message = errors.filter { it.getPsiFile() == file }.map {
file.getVirtualFile()!!.getCanonicalPath() + " : " + IdeErrorMessages.RENDERER.render(it)
}.joinToString("\n")
println(message)
}
}
}
override fun update(e: AnActionEvent?) {
e!!.getPresentation().setVisible(true)
e.getPresentation().setEnabled(true)
}
}