blob: 1e48d3e78fac9877f49657bb14449e2d22c0702c [file]
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.gradle.config
import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil.*
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.IndexNotReadyException
import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMember
import com.intellij.psi.PsiReference
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.UseScopeEnlarger
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.psi.util.PsiUtilCore
import com.intellij.util.Processor
import org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager
import org.jetbrains.plugins.gradle.util.GradleConstants
/**
* @author Vladislav.Soroka
*/
class GradleUseScopeEnlarger : UseScopeEnlarger() {
override fun getAdditionalUseScope(element: PsiElement): SearchScope? {
return try {
getScope(element)
}
catch (e: IndexNotReadyException) {
null
}
}
companion object {
private fun getScope(element: PsiElement): SearchScope? {
val virtualFile = PsiUtilCore.getVirtualFile(element.containingFile) ?: return null
val fileIndex = ProjectRootManager.getInstance(element.project).fileIndex
val module = fileIndex.getModuleForFile(virtualFile) ?: return null
if (!isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return null
val rootProjectPath = getExternalRootProjectPath(module) ?: return null
return if (!isApplicable(element, module, rootProjectPath, virtualFile, fileIndex)) null
else object : GlobalSearchScope(element.project) {
override fun contains(file: VirtualFile): Boolean {
return GradleConstants.EXTENSION == file.extension || file.name.endsWith(GradleConstants.KOTLIN_DSL_SCRIPT_EXTENSION)
}
override fun isSearchInModuleContent(aModule: Module) = rootProjectPath == getExternalRootProjectPath(module)
override fun isSearchInLibraries() = false
}
}
private fun isApplicable(element: PsiElement,
module: Module,
rootProjectPath: String,
virtualFile: VirtualFile,
fileIndex: ProjectFileIndex): Boolean {
val projectPath = getExternalProjectPath(module) ?: return false
if (projectPath.endsWith("/buildSrc")) return true
val sourceRoot = fileIndex.getSourceRootForFile(virtualFile)
return sourceRoot in GradleBuildClasspathManager.getInstance(element.project).getModuleClasspathEntries(rootProjectPath)
}
fun search(element: PsiMember, consumer: Processor<PsiReference>) {
val scope: SearchScope = ReadAction.compute<SearchScope, RuntimeException> { getScope(element) } ?: return
val newParams = ReferencesSearch.SearchParameters(element, scope, true)
ReferencesSearch.search(newParams).forEach(consumer)
}
}
}