diff --git a/plugins/filePrediction/resources/META-INF/plugin.xml b/plugins/filePrediction/resources/META-INF/plugin.xml
index 2a657ee7cd74..83ec650e3fd9 100644
--- a/plugins/filePrediction/resources/META-INF/plugin.xml
+++ b/plugins/filePrediction/resources/META-INF/plugin.xml
@@ -33,6 +33,7 @@
+
diff --git a/plugins/filePrediction/src/com/intellij/filePrediction/features/FilePredictionGeneralFeatures.kt b/plugins/filePrediction/src/com/intellij/filePrediction/features/FilePredictionGeneralFeatures.kt
index 3e3ad845a312..92cca3b4f9fd 100644
--- a/plugins/filePrediction/src/com/intellij/filePrediction/features/FilePredictionGeneralFeatures.kt
+++ b/plugins/filePrediction/src/com/intellij/filePrediction/features/FilePredictionGeneralFeatures.kt
@@ -3,39 +3,18 @@ package com.intellij.filePrediction.features
import com.intellij.filePrediction.features.FilePredictionFeature.Companion.binary
import com.intellij.filePrediction.features.FilePredictionFeature.Companion.fileType
-import com.intellij.filePrediction.features.FilePredictionFeature.Companion.numerical
import com.intellij.filePrediction.references.ExternalReferencesResult
import com.intellij.internal.statistic.collectors.fus.fileTypes.FileTypeUsagesCollector
-import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project
-import com.intellij.openapi.project.guessProjectDir
-import com.intellij.openapi.roots.FileIndexFacade
-import com.intellij.openapi.util.SystemInfo
-import com.intellij.openapi.util.io.FileUtil
-import com.intellij.openapi.util.text.StringUtil
-import com.intellij.openapi.util.text.StringUtil.toLowerCase
import com.intellij.openapi.vfs.VirtualFile
-import com.intellij.testFramework.LightVirtualFile
-import com.intellij.util.PathUtil
import com.intellij.util.ThreeState
-import java.io.File
-class FilePredictionGeneralFeatures: FilePredictionFeatureProvider {
+class FilePredictionGeneralFeatures : FilePredictionFeatureProvider {
companion object {
private val FEATURES = arrayListOf(
- "excluded",
"file_type",
- "in_library",
- "in_project",
"in_ref",
- "in_source",
- "light",
- "name_prefix",
- "path_prefix",
- "prev_file_type",
- "relative_path_prefix",
- "same_dir",
- "same_module"
+ "prev_file_type"
)
}
@@ -53,57 +32,10 @@ class FilePredictionGeneralFeatures: FilePredictionFeatureProvider {
result["in_ref"] = binary(isInRef == ThreeState.YES)
}
- addFileTypeFeatures(result, newFile, prevFile)
- ApplicationManager.getApplication().runReadAction {
- if (newFile.isValid) {
- val fileIndex = FileIndexFacade.getInstance(project)
- result["in_project"] = binary(fileIndex.isInProjectScope(newFile))
- result["in_source"] = binary(fileIndex.isInSource(newFile))
- result["in_library"] = binary(fileIndex.isInLibraryClasses(newFile) || fileIndex.isInLibrarySource(newFile))
- result["excluded"] = binary(fileIndex.isExcludedFile(newFile))
-
- if (prevFile != null && prevFile.isValid) {
- val newModule = fileIndex.getModuleForFile(newFile)
- result["same_module"] = binary(newModule != null && newModule == fileIndex.getModuleForFile(prevFile))
- }
- result["light"] = binary(newFile is LightVirtualFile)
- }
- }
-
- if (prevFile != null) {
- val newFileName = unify(newFile.name)
- val newFilePath = unify(newFile.path)
- val prevFileName = unify(prevFile.name)
- result["name_prefix"] = numerical(StringUtil.commonPrefixLength(newFileName, prevFileName))
-
- val prevFilePath = unify(prevFile.path)
- result["path_prefix"] = numerical(StringUtil.commonPrefixLength(newFilePath, prevFilePath))
-
- if (!project.isDisposed) {
- val baseDir = project.guessProjectDir()?.path?.let { unify(it) }
- if (baseDir != null) {
- val newRelativePath = FileUtil.getRelativePath(baseDir, newFilePath, File.separatorChar, false)
- val prevRelativePath = FileUtil.getRelativePath(baseDir, prevFilePath, File.separatorChar, false)
- if (newRelativePath != null && prevRelativePath != null) {
- result["relative_path_prefix"] = numerical(StringUtil.commonPrefixLength(newRelativePath, prevRelativePath))
- }
- }
- }
- result["same_dir"] = binary(PathUtil.getParentPath(newFilePath) == PathUtil.getParentPath(prevFilePath))
- }
- return result
- }
-
- private fun addFileTypeFeatures(result: MutableMap, newFile: VirtualFile, prevFile: VirtualFile?) {
result["file_type"] = fileType(FileTypeUsagesCollector.getSafeFileTypeName(newFile.fileType))
-
if (prevFile != null) {
result["prev_file_type"] = fileType(FileTypeUsagesCollector.getSafeFileTypeName(prevFile.fileType))
}
- }
-
- private fun unify(path: String) : String {
- val caseSensitive = SystemInfo.isFileSystemCaseSensitive
- return if (caseSensitive) FileUtil.getNameWithoutExtension(path) else FileUtil.getNameWithoutExtension(toLowerCase(path))
+ return result
}
}
diff --git a/plugins/filePrediction/src/com/intellij/filePrediction/features/FilePredictionSimilarityFeatures.kt b/plugins/filePrediction/src/com/intellij/filePrediction/features/FilePredictionSimilarityFeatures.kt
new file mode 100644
index 000000000000..80bed305fd2f
--- /dev/null
+++ b/plugins/filePrediction/src/com/intellij/filePrediction/features/FilePredictionSimilarityFeatures.kt
@@ -0,0 +1,89 @@
+// Copyright 2000-2020 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 com.intellij.filePrediction.features
+
+import com.intellij.filePrediction.features.FilePredictionFeature.Companion.binary
+import com.intellij.filePrediction.features.FilePredictionFeature.Companion.numerical
+import com.intellij.filePrediction.references.ExternalReferencesResult
+import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.project.guessProjectDir
+import com.intellij.openapi.roots.FileIndexFacade
+import com.intellij.openapi.util.SystemInfo
+import com.intellij.openapi.util.io.FileUtil
+import com.intellij.openapi.util.text.StringUtil
+import com.intellij.openapi.util.text.StringUtil.toLowerCase
+import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.testFramework.LightVirtualFile
+import com.intellij.util.PathUtil
+import java.io.File
+
+class FilePredictionSimilarityFeatures : FilePredictionFeatureProvider {
+ companion object {
+ private val FEATURES = arrayListOf(
+ "excluded",
+ "in_library",
+ "in_project",
+ "in_source",
+ "light",
+ "name_prefix",
+ "path_prefix",
+ "relative_path_prefix",
+ "same_dir",
+ "same_module"
+ )
+ }
+
+ override fun getName(): String = "similarity"
+
+ override fun getFeatures(): List = FEATURES
+
+ override fun calculateFileFeatures(project: Project,
+ newFile: VirtualFile,
+ prevFile: VirtualFile?,
+ refs: ExternalReferencesResult): Map {
+ val result = HashMap()
+ ApplicationManager.getApplication().runReadAction {
+ if (newFile.isValid) {
+ val fileIndex = FileIndexFacade.getInstance(project)
+ result["in_project"] = binary(fileIndex.isInProjectScope(newFile))
+ result["in_source"] = binary(fileIndex.isInSource(newFile))
+ result["in_library"] = binary(fileIndex.isInLibraryClasses(newFile) || fileIndex.isInLibrarySource(newFile))
+ result["excluded"] = binary(fileIndex.isExcludedFile(newFile))
+
+ if (prevFile != null && prevFile.isValid) {
+ val newModule = fileIndex.getModuleForFile(newFile)
+ result["same_module"] = binary(newModule != null && newModule == fileIndex.getModuleForFile(prevFile))
+ }
+ result["light"] = binary(newFile is LightVirtualFile)
+ }
+ }
+
+ if (prevFile != null) {
+ val newFileName = unify(newFile.name)
+ val newFilePath = unify(newFile.path)
+ val prevFileName = unify(prevFile.name)
+ result["name_prefix"] = numerical(StringUtil.commonPrefixLength(newFileName, prevFileName))
+
+ val prevFilePath = unify(prevFile.path)
+ result["path_prefix"] = numerical(StringUtil.commonPrefixLength(newFilePath, prevFilePath))
+
+ if (!project.isDisposed) {
+ val baseDir = project.guessProjectDir()?.path?.let { unify(it) }
+ if (baseDir != null) {
+ val newRelativePath = FileUtil.getRelativePath(baseDir, newFilePath, File.separatorChar, false)
+ val prevRelativePath = FileUtil.getRelativePath(baseDir, prevFilePath, File.separatorChar, false)
+ if (newRelativePath != null && prevRelativePath != null) {
+ result["relative_path_prefix"] = numerical(StringUtil.commonPrefixLength(newRelativePath, prevRelativePath))
+ }
+ }
+ }
+ result["same_dir"] = binary(PathUtil.getParentPath(newFilePath) == PathUtil.getParentPath(prevFilePath))
+ }
+ return result
+ }
+
+ private fun unify(path: String): String {
+ val caseSensitive = SystemInfo.isFileSystemCaseSensitive
+ return if (caseSensitive) FileUtil.getNameWithoutExtension(path) else FileUtil.getNameWithoutExtension(toLowerCase(path))
+ }
+}
diff --git a/plugins/filePrediction/test/com/intellij/filePrediction/features/FilePredictionGeneralFeaturesTest.kt b/plugins/filePrediction/test/com/intellij/filePrediction/features/FilePredictionCommonFeaturesTest.kt
similarity index 83%
rename from plugins/filePrediction/test/com/intellij/filePrediction/features/FilePredictionGeneralFeaturesTest.kt
rename to plugins/filePrediction/test/com/intellij/filePrediction/features/FilePredictionCommonFeaturesTest.kt
index cff8820f3ade..3deae0ad393a 100644
--- a/plugins/filePrediction/test/com/intellij/filePrediction/features/FilePredictionGeneralFeaturesTest.kt
+++ b/plugins/filePrediction/test/com/intellij/filePrediction/features/FilePredictionCommonFeaturesTest.kt
@@ -18,31 +18,52 @@ import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import java.io.File
-class FilePredictionGeneralFeaturesTest : CodeInsightFixtureTestCase>() {
- private fun doTestGeneralFeatures(prevPath: String, newPath: String, featuresProvider: FileFeaturesProducer) {
+class FilePredictionCommonFeaturesTest : CodeInsightFixtureTestCase>() {
+ private fun doTestSimilarityFeatures(prevPath: String,
+ newPath: String,
+ expected: FileFeaturesProducer) {
+ doTestFeatures(
+ prevPath, newPath,
+ listOf(FilePredictionSimilarityFeatures()),
+ expected
+ )
+ }
+
+ private fun doTestFeatures(prevPath: String, newPath: String,
+ providers: List,
+ expectedFeaturesProvider: FileFeaturesProducer) {
val prevFile = myFixture.addFileToProject(prevPath, "PREVIOUS FILE")
val nextFile = myFixture.addFileToProject(newPath, "NEXT FILE")
- val provider = FilePredictionGeneralFeatures()
- val actual = provider.calculateFileFeatures(
- myFixture.project, nextFile.virtualFile, prevFile.virtualFile, FAILED_COMPUTATION
- )
- val expected = featuresProvider.produce(myFixture.project)
+ val actual: MutableMap = hashMapOf()
+ for (provider in providers) {
+ val features = provider.calculateFileFeatures(
+ myFixture.project, nextFile.virtualFile, prevFile.virtualFile, FAILED_COMPUTATION
+ )
+ actual.putAll(features)
+ }
+
+ val expected = expectedFeaturesProvider.produce(myFixture.project)
for (feature in expected.entries) {
assertTrue("Cannot find feature '${feature.key}' in $actual", actual.containsKey(feature.key))
assertEquals("The value of feature '${feature.key}' is different from expected", feature.value, actual[feature.key])
}
}
- private fun doTestGeneralFeatures(newPath: String, configurator: ProjectConfigurator, featuresProvider: FileFeaturesProducer) {
+ private fun doTestSimilarityFeatures(newPath: String, configurator: ProjectConfigurator, featuresProvider: FileFeaturesProducer) {
+ doTestFeatures(FilePredictionSimilarityFeatures(), newPath, configurator, featuresProvider)
+ }
+
+ private fun doTestFeatures(provider: FilePredictionFeatureProvider,
+ newPath: String, configurator: ProjectConfigurator,
+ expectedFeaturesProvider: FileFeaturesProducer) {
val nextFile = myFixture.addFileToProject(newPath, "NEXT FILE")
configurator.configure(myFixture.project, myModule)
- val provider = FilePredictionGeneralFeatures()
val actual = provider.calculateFileFeatures(
myFixture.project, nextFile.virtualFile, null, FAILED_COMPUTATION
)
- val expected = featuresProvider.produce(myFixture.project)
+ val expected = expectedFeaturesProvider.produce(myFixture.project)
for (feature in expected.entries) {
assertTrue("Cannot find feature '${feature.key}' in $actual", actual.containsKey(feature.key))
assertEquals("The value of feature '${feature.key}' is different from expected", feature.value, actual[feature.key])
@@ -50,7 +71,7 @@ class FilePredictionGeneralFeaturesTest : CodeInsightFixtureTestCase