Refactor ProjectRootsUtil

Account for cases when there library source files under classes root
This commit is contained in:
Pavel V. Talanov
2014-12-09 17:41:42 +03:00
parent ba22c3d790
commit 256e9a6b86
3 changed files with 28 additions and 22 deletions
@@ -74,6 +74,6 @@ public class JetSourceFilterScope extends DelegatingGlobalSearchScope {
return false; return false;
} }
return ProjectRootsUtil.isInSources(project, file, includeLibrarySourceFiles, includeClassFiles, index); return ProjectRootsUtil.isInContent(project, file, true, includeLibrarySourceFiles, includeClassFiles, index);
} }
} }
@@ -24,58 +24,64 @@ import org.jetbrains.jet.plugin.configuration.JetModuleTypeManager
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiDirectory import com.intellij.psi.PsiDirectory
import com.intellij.openapi.roots.FileIndex
import com.intellij.ide.highlighter.JavaClassFileType import com.intellij.ide.highlighter.JavaClassFileType
public object ProjectRootsUtil { public object ProjectRootsUtil {
platformStatic platformStatic
public fun isInSources(project: Project, public fun isInContent(project: Project, file: VirtualFile, includeProjectSource: Boolean,
file: VirtualFile, includeLibrarySource: Boolean, includeLibraryClasses: Boolean,
includeLibrarySources: Boolean,
withLibraryClassesRoots: Boolean,
fileIndex: ProjectFileIndex = ProjectFileIndex.SERVICE.getInstance(project)): Boolean { fileIndex: ProjectFileIndex = ProjectFileIndex.SERVICE.getInstance(project)): Boolean {
if (fileIndex.isInSourceContent(file)) { if (includeProjectSource && fileIndex.isInSourceContent(file)) {
return !JetModuleTypeManager.getInstance()!!.isKtFileInGradleProjectInWrongFolder(file, project) return !JetModuleTypeManager.getInstance()!!.isKtFileInGradleProjectInWrongFolder(file, project)
} }
if (!includeLibraryClasses && !includeLibrarySource) return false
return (withLibraryClassesRoots && fileIndex.isInLibraryClasses(file)) // NOTE: the following is a workaround for cases when class files are under library source roots and source files are under class roots
|| (includeLibrarySources && fileIndex.isInLibrarySource(file)) val isClassFile = file.getFileType() == JavaClassFileType.INSTANCE
return (includeLibraryClasses && isClassFile && fileIndex.isInLibraryClasses(file))
|| (includeLibrarySource && !isClassFile && fileIndex.isInLibrarySource(file))
} }
platformStatic platformStatic
public fun isInSource( public fun isInContent(
element: PsiElement, element: PsiElement,
includeLibrarySources: Boolean, includeProjectSource: Boolean,
withLibraryClassesRoots: Boolean = false includeLibrarySource: Boolean,
includeLibraryClasses: Boolean
): Boolean { ): Boolean {
return runReadAction { (): Boolean -> return runReadAction {(): Boolean ->
val virtualFile = when(element) { val virtualFile = when (element) {
is PsiDirectory -> element.getVirtualFile() is PsiDirectory -> element.getVirtualFile()
else -> element.getContainingFile()?.getVirtualFile() else -> element.getContainingFile()?.getVirtualFile()
} ?: return@runReadAction false } ?: return@runReadAction false
val project = element.getProject() val project = element.getProject()
return@runReadAction isInSources(project, virtualFile, includeLibrarySources, withLibraryClassesRoots) return@runReadAction isInContent(project, virtualFile, includeProjectSource, includeLibrarySource, includeLibraryClasses)
} }
} }
platformStatic platformStatic
public fun isInProjectSource(element: PsiElement): Boolean { public fun isInProjectSource(element: PsiElement): Boolean {
return isInSource(element, false) return isInContent(element, includeProjectSource = true, includeLibrarySource = false, includeLibraryClasses = false)
} }
platformStatic platformStatic
public fun isInProjectOrLibSource(element: PsiElement): Boolean { public fun isInProjectOrLibSource(element: PsiElement): Boolean {
return isInSource(element, true) return isInContent(element, includeProjectSource = true, includeLibrarySource = true, includeLibraryClasses = false)
} }
platformStatic platformStatic
public fun isLibraryClassFile(fileIndex: ProjectFileIndex, virtualFile: VirtualFile): Boolean { public fun isInProjectOrLibraryContent(element: PsiElement): Boolean {
return fileIndex.isInLibraryClasses(virtualFile) && virtualFile.getFileType() == JavaClassFileType.INSTANCE return isInContent(element, includeProjectSource = true, includeLibrarySource = true, includeLibraryClasses = true)
} }
platformStatic platformStatic
public fun isLibraryFile(fileIndex: ProjectFileIndex, virtualFile: VirtualFile): Boolean { public fun isLibraryClassFile(project: Project, file: VirtualFile): Boolean {
return fileIndex.isInLibraryClasses(virtualFile) || fileIndex.isInLibrarySource(virtualFile) return isInContent(project, file, includeProjectSource = false, includeLibrarySource = false, includeLibraryClasses = true)
}
platformStatic
public fun isLibraryFile(project: Project, file: VirtualFile): Boolean {
return isInContent(project, file, includeProjectSource = false, includeLibrarySource = true, includeLibraryClasses = true)
} }
} }
@@ -390,7 +390,7 @@ public fun PsiElement.canRefactor(): Boolean {
is PsiPackage -> is PsiPackage ->
getDirectories().any { it.canRefactor() } getDirectories().any { it.canRefactor() }
is JetElement, is PsiDirectory -> is JetElement, is PsiDirectory ->
isWritable() && ProjectRootsUtil.isInSource(element = this, includeLibrarySources = false) isWritable() && ProjectRootsUtil.isInProjectSource(this)
else -> else ->
false false
} }