Fix Kotlin facet autodetection so that it actually works and stores the correct language/API level based on project dependencies

This commit is contained in:
Dmitry Jemerov
2017-02-15 14:36:33 +01:00
parent 3bc322c2ce
commit 7704310359
5 changed files with 29 additions and 10 deletions
@@ -23,6 +23,7 @@ import org.jetbrains.jps.model.java.impl.JavaSdkUtil;
import java.io.File;
import java.util.List;
import java.util.regex.Pattern;
public class PathUtil {
@@ -41,6 +42,8 @@ public class PathUtil {
public static final String KOTLIN_JAVA_RUNTIME_SRC_JAR = "kotlin-runtime-sources.jar";
public static final String KOTLIN_COMPILER_JAR = "kotlin-compiler.jar";
public static final Pattern KOTLIN_RUNTIME_JAR_PATTERN = Pattern.compile("kotlin-(stdlib|runtime)(-\\d[\\d.]+(-.+)?)?\\.jar");
public static final String HOME_FOLDER_NAME = "kotlinc";
private static final File NO_PATH = new File("<no_path>");
@@ -21,7 +21,6 @@ import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.utils.LibraryUtils;
import org.jetbrains.kotlin.utils.PathUtil;
import java.util.List;
@@ -39,6 +38,11 @@ public class JavaRuntimeDetectionUtil {
@Nullable
public static VirtualFile getRuntimeJar(@NotNull List<VirtualFile> classesRoots) {
return LibraryUtils.getJarFile(classesRoots, PathUtil.KOTLIN_JAVA_RUNTIME_JAR);
for (VirtualFile root : classesRoots) {
if (PathUtil.KOTLIN_RUNTIME_JAR_PATTERN.matcher(root.getName()).matches()) {
return root;
}
}
return null;
}
}
@@ -43,7 +43,7 @@ private val multiPlatformProjectsArg: String by lazy {
"-" + CommonCompilerArguments::multiPlatform.annotations.filterIsInstance<Argument>().single().value
}
private fun Module.getAndCacheLanguageLevelByDependencies(): LanguageVersion {
fun Module.getAndCacheLanguageLevelByDependencies(): LanguageVersion {
val languageLevel = getLibraryLanguageLevel(
this,
null,
@@ -38,6 +38,7 @@ import com.intellij.psi.search.GlobalSearchScope
import com.intellij.util.indexing.FileBasedIndex
import com.intellij.util.ui.update.MergingUpdateQueue
import com.intellij.util.ui.update.Update
import org.jetbrains.kotlin.utils.ifEmpty
import java.util.*
// Based on com.intellij.framework.detection.impl.FrameworkDetectionManager
@@ -137,9 +138,11 @@ class FacetConfigurator(
if (FrameworkDetectionUtil.removeDisabled(newDescriptions, oldDescriptions).isEmpty()) return
val framework = getValidDetectedFramework() ?: return
FrameworkDetectionUtil.setupFrameworks(listOf(framework), PlatformModifiableModelsProvider(), DefaultModulesProvider(myProject))
myDetectedFrameworksData!!.putExistentFrameworkFiles(id, framework.relatedFiles)
val validFrameworks = getValidDetectedFrameworks().ifEmpty { return }
FrameworkDetectionUtil.setupFrameworks(frameworks, PlatformModifiableModelsProvider(), DefaultModulesProvider(myProject))
for (framework in validFrameworks) {
myDetectedFrameworksData!!.putExistentFrameworkFiles(id, framework.relatedFiles)
}
}
private fun runDetector(detectorId: Int?,
@@ -167,12 +170,12 @@ class FacetConfigurator(
return frameworks
}
private fun getValidDetectedFramework(): DetectedFrameworkDescription? {
val id = myDetectedFrameworksData!!.detectorsForDetectedFrameworks.singleOrNull() ?: return null
private fun getValidDetectedFrameworks(): List<DetectedFrameworkDescription> {
val id = myDetectedFrameworksData!!.detectorsForDetectedFrameworks.singleOrNull() ?: return emptyList()
val index = FileBasedIndex.getInstance()
val excludesConfiguration = DetectionExcludesConfiguration.getInstance(myProject)
val frameworks = runDetector(id, index, excludesConfiguration, false)
return FrameworkDetectionUtil.removeDisabled(frameworks).singleOrNull()
return FrameworkDetectionUtil.removeDisabled(frameworks)
}
private fun ensureIndexIsUpToDate(detectors: Collection<Int>) {
@@ -21,8 +21,10 @@ import com.intellij.framework.detection.FacetBasedFrameworkDetector
import com.intellij.framework.detection.FileContentPattern
import com.intellij.framework.detection.FrameworkDetectionContext
import com.intellij.framework.detection.impl.FrameworkDetectorRegistry
import com.intellij.openapi.roots.ModifiableRootModel
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.project.getAndCacheLanguageLevelByDependencies
class KotlinFrameworkDetector : FacetBasedFrameworkDetector<KotlinFacet, KotlinFacetConfiguration>(DETECTOR_ID) {
companion object {
@@ -47,4 +49,11 @@ class KotlinFrameworkDetector : FacetBasedFrameworkDetector<KotlinFacet, KotlinF
newFiles: Collection<VirtualFile>,
context: FrameworkDetectionContext
) = super.detect(newFiles, context)
}
override fun setupFacet(facet: KotlinFacet, model: ModifiableRootModel?) {
model?.module?.let { module ->
facet.configuration.settings.initializeIfNeeded(module, model)
module.getAndCacheLanguageLevelByDependencies()
}
}
}