From 902fe1f5ce3273e8b02880566e17f7828e61db39 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 11 Jul 2017 14:52:31 +0200 Subject: [PATCH] Implement explicit library kind for JS libraries, don't autodetect --- .../framework/CommonLibraryDetectionUtil.kt | 9 +- .../framework/JsLibraryStdDetectionUtil.kt | 7 +- .../KotlinJavaScriptLibraryDetectionUtil.kt | 77 ---------------- .../kotlin/idea/framework/LibraryKinds.kt | 40 +++++++++ idea/src/META-INF/plugin.xml | 3 +- .../kotlin/idea/PluginStartupComponent.java | 2 - .../KotlinJsModuleConfigurator.kt | 6 ++ .../KotlinWithLibraryConfigurator.kt | 13 ++- ...stomLibraryDescriptorWithDeferredConfig.kt | 4 +- .../idea/framework/JSLibraryStdDescription.kt | 6 +- .../JSLibraryStdPresentationProvider.java | 50 ----------- .../kotlin/idea/framework/JSLibraryType.kt | 88 +++++++++++++++++++ 12 files changed, 156 insertions(+), 149 deletions(-) delete mode 100644 idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/KotlinJavaScriptLibraryDetectionUtil.kt create mode 100644 idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/LibraryKinds.kt delete mode 100644 idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryStdPresentationProvider.java create mode 100644 idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryType.kt diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/CommonLibraryDetectionUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/CommonLibraryDetectionUtil.kt index ba91aa214f5..f15afc068ba 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/CommonLibraryDetectionUtil.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/CommonLibraryDetectionUtil.kt @@ -33,7 +33,9 @@ import org.jetbrains.kotlin.serialization.deserialization.MetadataPackageFragmen object CommonLibraryDetectionUtil { @JvmStatic fun getLibraryPlatform(library: Library): TargetPlatform { - if (library is LibraryEx && library.isDisposed) return JvmPlatform + library as? LibraryEx ?: return JvmPlatform + if (library.isDisposed) return JvmPlatform + if (library.kind is JSLibraryKind) return JsPlatform for (root in library.getFiles(OrderRootType.CLASSES)) { ProgressManager.checkCanceled() @@ -42,17 +44,12 @@ object CommonLibraryDetectionUtil { if (hasCommonMetadata == true) { return TargetPlatform.Default } - val hasJSMetadata = JarUserDataManager.hasFileWithProperty(KotlinJavaScriptLibraryDetectionUtil.HasKotlinJSMetadataInJar, root) - if (hasJSMetadata == true) { - return JsPlatform - } var platform: TargetPlatform? = null VfsUtilCore.processFilesRecursively(root) { file -> when { file.fileType == JavaClassFileType.INSTANCE -> platform = JvmPlatform isKotlinMetadataFile(file) -> platform = TargetPlatform.Default - KotlinJavaScriptLibraryDetectionUtil.isJsFileWithMetadata(file) -> platform = JsPlatform } platform == null diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/JsLibraryStdDetectionUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/JsLibraryStdDetectionUtil.kt index fe435e39334..e85fa95e61f 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/JsLibraryStdDetectionUtil.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/JsLibraryStdDetectionUtil.kt @@ -34,12 +34,11 @@ object JsLibraryStdDetectionUtil { private val IS_JS_LIBRARY_STD_LIB = Key.create("IS_JS_LIBRARY_STD_LIB") fun hasJsStdlibJar(library: Library): Boolean { - if (library is LibraryEx && library.isDisposed) return false - - if (!KotlinJavaScriptLibraryDetectionUtil.isKotlinJavaScriptLibrary(library)) return false + if (library !is LibraryEx || library.isDisposed) return false + if (library.kind !is JSLibraryKind) return false val classes = Arrays.asList(*library.getFiles(OrderRootType.CLASSES)) - return getJsLibraryStdVersion(classes) != null + return getJsStdLibJar(classes) != null } fun getJsLibraryStdVersion(library: Library): String? = getJsLibraryStdVersion(library.getFiles(OrderRootType.CLASSES).toList()) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/KotlinJavaScriptLibraryDetectionUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/KotlinJavaScriptLibraryDetectionUtil.kt deleted file mode 100644 index 1a8d03ccbb3..00000000000 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/KotlinJavaScriptLibraryDetectionUtil.kt +++ /dev/null @@ -1,77 +0,0 @@ - -/* - * Copyright 2010-2016 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.kotlin.idea.framework - -import com.intellij.openapi.progress.ProgressManager -import com.intellij.openapi.roots.OrderRootType -import com.intellij.openapi.roots.impl.libraries.LibraryEx -import com.intellij.openapi.roots.libraries.Library -import com.intellij.openapi.vfs.VfsUtilCore -import com.intellij.openapi.vfs.VirtualFile -import org.jetbrains.kotlin.idea.caches.JarUserDataManager -import org.jetbrains.kotlin.js.JavaScript -import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils -import java.util.zip.ZipException - -object KotlinJavaScriptLibraryDetectionUtil { - @JvmStatic fun isKotlinJavaScriptLibrary(library: Library): Boolean { - if (library is LibraryEx && library.isDisposed) return false - - return isKotlinJavaScriptLibrary(library.getFiles(OrderRootType.CLASSES).toList()) - } - - @JvmStatic fun isKotlinJavaScriptLibrary(classesRoots: List): Boolean { - // Prevent clashing with java runtime - if (JavaRuntimeDetectionUtil.getRuntimeJar(classesRoots) != null) return false - - classesRoots.forEach { root -> - ProgressManager.checkCanceled() - val hasMetadata = HasKotlinJSMetadataInJar.hasMetadataFromCache(root) - if (hasMetadata != null) { - return hasMetadata - } - - if (!VfsUtilCore.processFilesRecursively(root) { !isJsFileWithMetadata(it) }) { - return true - } - } - - return false - } - - fun isJsFileWithMetadata(file: VirtualFile): Boolean { - if (!file.isDirectory && JavaScript.EXTENSION == file.extension) { - val content = try { - file.contentsToByteArray(false) - } - catch (e: ZipException) { - throw RuntimeException("file:${file.path} isDirectory: ${file.isDirectory}, exists: ${file.exists()}", e) - } - - return KotlinJavascriptMetadataUtils.hasMetadata(String(content)) - } - - return false - } - - object HasKotlinJSMetadataInJar : JarUserDataManager.JarBooleanPropertyCounter(HasKotlinJSMetadataInJar::class.simpleName!!) { - override fun hasProperty(file: VirtualFile) = KotlinJavaScriptLibraryDetectionUtil.isJsFileWithMetadata(file) - - fun hasMetadataFromCache(root: VirtualFile): Boolean? = JarUserDataManager.hasFileWithProperty(HasKotlinJSMetadataInJar, root) - } -} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/LibraryKinds.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/LibraryKinds.kt new file mode 100644 index 00000000000..8580ffa4562 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/LibraryKinds.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2017 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. + */ + +/* + * Copyright 2010-2017 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.kotlin.idea.framework + +import com.intellij.openapi.roots.libraries.DummyLibraryProperties +import com.intellij.openapi.roots.libraries.PersistentLibraryKind + +object JSLibraryKind : PersistentLibraryKind("kotlin.js") { + override fun createDefaultProperties() = DummyLibraryProperties.INSTANCE!! +} \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 12719ca678c..fa1f200f3bb 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -671,7 +671,6 @@ - @@ -823,6 +822,8 @@ + + org.jetbrains.kotlin.idea.intentions.FoldInitializerAndIfToElvisIntention Kotlin diff --git a/idea/src/org/jetbrains/kotlin/idea/PluginStartupComponent.java b/idea/src/org/jetbrains/kotlin/idea/PluginStartupComponent.java index e8a3fadaeb8..880b9026e78 100644 --- a/idea/src/org/jetbrains/kotlin/idea/PluginStartupComponent.java +++ b/idea/src/org/jetbrains/kotlin/idea/PluginStartupComponent.java @@ -32,7 +32,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.idea.caches.JarUserDataManager; import org.jetbrains.kotlin.idea.debugger.filter.DebuggerFiltersUtilKt; import org.jetbrains.kotlin.idea.framework.CommonLibraryDetectionUtil; -import org.jetbrains.kotlin.idea.framework.KotlinJavaScriptLibraryDetectionUtil; import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinTodoSearcher; import org.jetbrains.kotlin.utils.PathUtil; @@ -62,7 +61,6 @@ public class PluginStartupComponent implements ApplicationComponent { ThreadTrackerPatcherForTeamCityTesting.INSTANCE.patchThreadTracker(); } - JarUserDataManager.INSTANCE.register(KotlinJavaScriptLibraryDetectionUtil.HasKotlinJSMetadataInJar.INSTANCE); JarUserDataManager.INSTANCE.register(CommonLibraryDetectionUtil.HasCommonKotlinMetadataInJar.INSTANCE); DebuggerFiltersUtilKt.addKotlinStdlibDebugFilterIfNeeded(); diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJsModuleConfigurator.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJsModuleConfigurator.kt index 5d98540f314..5ac358412cd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJsModuleConfigurator.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinJsModuleConfigurator.kt @@ -18,8 +18,11 @@ package org.jetbrains.kotlin.idea.configuration import com.intellij.openapi.module.Module import com.intellij.openapi.projectRoots.Sdk +import com.intellij.openapi.roots.libraries.DummyLibraryProperties import com.intellij.openapi.roots.libraries.Library +import com.intellij.openapi.roots.libraries.LibraryType import org.jetbrains.kotlin.idea.framework.JSLibraryStdDescription +import org.jetbrains.kotlin.idea.framework.JSLibraryType import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor import org.jetbrains.kotlin.idea.versions.isKotlinJsRuntime import org.jetbrains.kotlin.js.JavaScript @@ -56,6 +59,9 @@ open class KotlinJsModuleConfigurator : KotlinWithLibraryConfigurator() { override val libraryMatcher: (Library) -> Boolean = ::isKotlinJsRuntime + override val libraryType: LibraryType? + get() = JSLibraryType.getInstance() + companion object { const val NAME = JavaScript.LOWER_NAME } diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt index d95fd5e9ab6..412dc5f3f8b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt @@ -22,8 +22,7 @@ import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.project.Project import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.roots.* -import com.intellij.openapi.roots.libraries.Library -import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar +import com.intellij.openapi.roots.libraries.* import com.intellij.openapi.vfs.JarFileSystem import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.openapi.vfs.VfsUtil @@ -48,6 +47,10 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj protected abstract val libraryCaption: String + open val libraryType: LibraryType? = null + + protected val libraryKind: PersistentLibraryKind<*>? = libraryType?.kind + override fun getStatus(module: Module): ConfigureKotlinStatus { if (!isApplicable(module)) { return ConfigureKotlinStatus.NON_APPLICABLE @@ -222,7 +225,11 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj ): Library { val table = LibraryTablesRegistrar.getInstance().getLibraryTable(project) val library = runWriteAction { - table.createLibrary(libraryName) + table.modifiableModel.run { + val library = createLibrary(libraryName, libraryKind) + commit() + library + } } collector.addMessage(library.name!! + " library was created") diff --git a/idea/src/org/jetbrains/kotlin/idea/framework/CustomLibraryDescriptorWithDeferredConfig.kt b/idea/src/org/jetbrains/kotlin/idea/framework/CustomLibraryDescriptorWithDeferredConfig.kt index 254afcc8e7a..987cfe85de0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/framework/CustomLibraryDescriptorWithDeferredConfig.kt +++ b/idea/src/org/jetbrains/kotlin/idea/framework/CustomLibraryDescriptorWithDeferredConfig.kt @@ -16,12 +16,12 @@ package org.jetbrains.kotlin.idea.framework -import com.intellij.framework.library.LibraryVersionProperties import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.roots.ModifiableRootModel import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.roots.libraries.DummyLibraryProperties import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.roots.libraries.LibraryKind import com.intellij.openapi.roots.libraries.NewLibraryConfiguration @@ -212,7 +212,7 @@ abstract class CustomLibraryDescriptorWithDeferredConfig } protected fun createConfiguration(libraryFiles: List, librarySourceFiles: List): NewLibraryConfiguration { - return object : NewLibraryConfiguration(libraryName, null, LibraryVersionProperties()) { + return object : NewLibraryConfiguration(libraryName, configurator.libraryType, DummyLibraryProperties.INSTANCE) { override fun addRoots(editor: LibraryEditor) { for (libraryFile in libraryFiles) { editor.addRoot(VfsUtil.getUrlForLibraryRoot(libraryFile), OrderRootType.CLASSES) diff --git a/idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryStdDescription.kt b/idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryStdDescription.kt index b93ff8b1b37..442163cade9 100644 --- a/idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryStdDescription.kt +++ b/idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryStdDescription.kt @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.idea.framework import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.libraries.LibraryKind import com.intellij.openapi.roots.libraries.NewLibraryConfiguration import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.idea.configuration.KotlinJsModuleConfigurator @@ -32,7 +31,7 @@ class JSLibraryStdDescription(project: Project?) : LIBRARY_NAME, DIALOG_TITLE, LIBRARY_CAPTION, - KOTLIN_JAVASCRIPT_KIND, + JSLibraryKind, SUITABLE_LIBRARY_KINDS) { @TestOnly @@ -41,12 +40,11 @@ class JSLibraryStdDescription(project: Project?) : } companion object { - val KOTLIN_JAVASCRIPT_KIND = LibraryKind.create("kotlin-js-stdlib") val LIBRARY_NAME = "KotlinJavaScript" val JAVA_SCRIPT_LIBRARY_CREATION = "JavaScript Library Creation" val DIALOG_TITLE = "Create Kotlin JavaScript Library" val LIBRARY_CAPTION = "Kotlin JavaScript Library" - val SUITABLE_LIBRARY_KINDS = setOf(KOTLIN_JAVASCRIPT_KIND) + val SUITABLE_LIBRARY_KINDS = setOf(JSLibraryKind) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryStdPresentationProvider.java b/idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryStdPresentationProvider.java deleted file mode 100644 index 9833755f6ce..00000000000 --- a/idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryStdPresentationProvider.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.idea.framework; - -import com.intellij.framework.library.LibraryVersionProperties; -import com.intellij.openapi.roots.libraries.LibraryPresentationProvider; -import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.idea.KotlinIcons; - -import javax.swing.*; -import java.util.List; - -public class JSLibraryStdPresentationProvider extends LibraryPresentationProvider { - public static JSLibraryStdPresentationProvider getInstance() { - return LibraryPresentationProvider.EP_NAME.findExtension(JSLibraryStdPresentationProvider.class); - } - - protected JSLibraryStdPresentationProvider() { - super(JSLibraryStdDescription.Companion.getKOTLIN_JAVASCRIPT_KIND()); - } - - @Nullable - @Override - public Icon getIcon(@Nullable LibraryVersionProperties properties) { - return KotlinIcons.SMALL_LOGO; - } - - @Nullable - @Override - public LibraryVersionProperties detect(@NotNull List classesRoots) { - String version = JsLibraryStdDetectionUtil.INSTANCE.getJsLibraryStdVersion(classesRoots); - return version == null ? null : new LibraryVersionProperties(version); - } -} diff --git a/idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryType.kt b/idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryType.kt new file mode 100644 index 00000000000..21b08f531ed --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/framework/JSLibraryType.kt @@ -0,0 +1,88 @@ +/* + * Copyright 2010-2017 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.kotlin.idea.framework + +import com.intellij.openapi.extensions.Extensions +import com.intellij.openapi.fileChooser.FileChooserDescriptor +import com.intellij.openapi.fileChooser.FileElement +import com.intellij.openapi.fileTypes.PlainTextFileType +import com.intellij.openapi.project.Project +import com.intellij.openapi.project.ProjectBundle +import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.roots.libraries.DummyLibraryProperties +import com.intellij.openapi.roots.libraries.LibraryType +import com.intellij.openapi.roots.libraries.LibraryTypeService +import com.intellij.openapi.roots.libraries.NewLibraryConfiguration +import com.intellij.openapi.roots.libraries.ui.FileTypeBasedRootFilter +import com.intellij.openapi.roots.libraries.ui.LibraryEditorComponent +import com.intellij.openapi.roots.libraries.ui.RootDetector +import com.intellij.openapi.roots.ui.configuration.libraryEditor.DefaultLibraryRootsComponentDescriptor +import com.intellij.openapi.util.text.StringUtil +import com.intellij.openapi.vfs.VirtualFile +import org.jetbrains.kotlin.idea.KotlinFileType +import org.jetbrains.kotlin.idea.KotlinIcons +import javax.swing.JComponent + +class JSLibraryType : LibraryType(JSLibraryKind) { + override fun createPropertiesEditor(editorComponent: LibraryEditorComponent) = null + + override fun getCreateActionName() = "Kotlin/JS" + + override fun createNewLibrary(parentComponent: JComponent, + contextDirectory: VirtualFile?, + project: Project): NewLibraryConfiguration? { + return LibraryTypeService.getInstance().createLibraryFromFiles(RootsComponentDescriptor, + parentComponent, contextDirectory, this, + project) + } + + override fun getIcon(properties: DummyLibraryProperties?) = KotlinIcons.SMALL_LOGO + + companion object { + fun getInstance() = Extensions.findExtension(EP_NAME, JSLibraryType::class.java) + } + + object RootsComponentDescriptor : DefaultLibraryRootsComponentDescriptor() { + override fun createAttachFilesChooserDescriptor(libraryName: String?): FileChooserDescriptor { + val descriptor = FileChooserDescriptor(true, true, true, false, true, true).withFileFilter { + FileElement.isArchive(it) || isAcceptedForJsLibrary(it.extension) + } + descriptor.title = if (StringUtil.isEmpty(libraryName)) + ProjectBundle.message("library.attach.files.action") + else + ProjectBundle.message("library.attach.files.to.library.action", libraryName!!) + descriptor.description = ProjectBundle.message("library.java.attach.files.description") + return descriptor + } + + override fun getRootTypes() = arrayOf(OrderRootType.CLASSES, OrderRootType.SOURCES) + + override fun getRootDetectors(): List { + return arrayListOf( + JSRootFilter, + FileTypeBasedRootFilter(OrderRootType.SOURCES, false, KotlinFileType.INSTANCE, "sources") + ) + } + } + + object JSRootFilter : FileTypeBasedRootFilter(OrderRootType.CLASSES, false, PlainTextFileType.INSTANCE, "JS files") { + override fun isFileAccepted(virtualFile: VirtualFile) = isAcceptedForJsLibrary(virtualFile.extension) + + } +} + +private fun isAcceptedForJsLibrary(extension: String?) = extension == "js" || extension == "kjsm"