as42: Additional fixes for AS42 and 202 platform
This commit is contained in:
committed by
Konstantin Tskhovrebov
parent
2df030f583
commit
5ba70b2cbb
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler;
|
||||
|
||||
import com.intellij.DynamicBundle;
|
||||
import com.intellij.codeInsight.ContainerProvider;
|
||||
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
|
||||
import com.intellij.core.JavaCoreApplicationEnvironment;
|
||||
import com.intellij.lang.MetaLanguage;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.psi.FileContextProvider;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.compiled.ClassFileDecompilers;
|
||||
import com.intellij.psi.meta.MetaDataContributor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
|
||||
|
||||
public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnvironment {
|
||||
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
KotlinCoreApplicationEnvironment environment = new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
|
||||
registerExtensionPoints();
|
||||
return environment;
|
||||
}
|
||||
|
||||
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
super(parentDisposable, unitTestMode);
|
||||
}
|
||||
|
||||
private static void registerExtensionPoints() {
|
||||
registerApplicationExtensionPoint(DynamicBundle.LanguageBundleEP.EP_NAME, DynamicBundle.LanguageBundleEP.class);
|
||||
registerApplicationExtensionPoint(FileContextProvider.EP_NAME, FileContextProvider.class);
|
||||
|
||||
registerApplicationExtensionPoint(MetaDataContributor.EP_NAME, MetaDataContributor.class);
|
||||
registerApplicationExtensionPoint(PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
|
||||
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
|
||||
|
||||
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
|
||||
registerApplicationExtensionPoint(ClassFileDecompilers.getInstance().EP_NAME, ClassFileDecompilers.Decompiler.class);
|
||||
|
||||
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
|
||||
|
||||
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(Extensions.getRootArea());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected VirtualFileSystem createJrtFileSystem() {
|
||||
return new CoreJrtFileSystem();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* 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.actions
|
||||
|
||||
import com.intellij.ide.actions.CreateFileFromTemplateAction
|
||||
import com.intellij.ide.actions.CreateFileFromTemplateDialog
|
||||
import com.intellij.ide.actions.CreateFromTemplateAction
|
||||
import com.intellij.ide.fileTemplates.FileTemplate
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager
|
||||
import com.intellij.ide.fileTemplates.actions.AttributesDefaults
|
||||
import com.intellij.ide.fileTemplates.ui.CreateFromTemplateDialog
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys
|
||||
import com.intellij.openapi.editor.LogicalPosition
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.DumbAware
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.ui.InputValidatorEx
|
||||
import com.intellij.psi.PsiDirectory
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||
import org.jetbrains.kotlin.idea.statistics.FUSEventGroups
|
||||
import org.jetbrains.kotlin.idea.statistics.KotlinFUSLogger
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition.Companion.STD_SCRIPT_SUFFIX
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import java.util.*
|
||||
|
||||
class NewKotlinFileAction : CreateFileFromTemplateAction(
|
||||
KotlinBundle.message("action.new.file.text"),
|
||||
KotlinBundle.message("action.new.file.description"),
|
||||
KotlinFileType.INSTANCE.icon
|
||||
), DumbAware {
|
||||
override fun postProcess(createdElement: PsiFile, templateName: String?, customProperties: Map<String, String>?) {
|
||||
super.postProcess(createdElement, templateName, customProperties)
|
||||
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(createdElement!!)
|
||||
|
||||
if (createdElement is KtFile) {
|
||||
if (module != null) {
|
||||
for (hook in NewKotlinFileHook.EP_NAME.extensions) {
|
||||
hook.postProcess(createdElement, module)
|
||||
}
|
||||
}
|
||||
|
||||
val ktClass = createdElement.declarations.singleOrNull() as? KtNamedDeclaration
|
||||
if (ktClass != null) {
|
||||
CreateFromTemplateAction.moveCaretAfterNameIdentifier(ktClass)
|
||||
} else {
|
||||
val editor = FileEditorManager.getInstance(createdElement.project).selectedTextEditor ?: return
|
||||
if (editor.document == createdElement.viewProvider.document) {
|
||||
val lineCount = editor.document.lineCount
|
||||
if (lineCount > 0) {
|
||||
editor.caretModel.moveToLogicalPosition(LogicalPosition(lineCount - 1, 0))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun buildDialog(project: Project, directory: PsiDirectory, builder: CreateFileFromTemplateDialog.Builder) {
|
||||
builder.setTitle(KotlinBundle.message("action.new.file.dialog.title"))
|
||||
.addKind(
|
||||
KotlinBundle.message("action.new.file.dialog.file.title"),
|
||||
KotlinFileType.INSTANCE.icon,
|
||||
"Kotlin File"
|
||||
)
|
||||
.addKind(
|
||||
KotlinBundle.message("action.new.file.dialog.class.title"),
|
||||
KotlinIcons.CLASS,
|
||||
"Kotlin Class"
|
||||
)
|
||||
.addKind(
|
||||
KotlinBundle.message("action.new.file.dialog.interface.title"),
|
||||
KotlinIcons.INTERFACE,
|
||||
"Kotlin Interface"
|
||||
)
|
||||
.addKind(
|
||||
KotlinBundle.message("action.new.file.dialog.enum.title"),
|
||||
KotlinIcons.ENUM,
|
||||
"Kotlin Enum"
|
||||
)
|
||||
.addKind(
|
||||
KotlinBundle.message("action.new.file.dialog.object.title"),
|
||||
KotlinIcons.OBJECT,
|
||||
"Kotlin Object"
|
||||
)
|
||||
|
||||
builder.setValidator(NameValidator)
|
||||
}
|
||||
|
||||
override fun getActionName(directory: PsiDirectory, newName: String, templateName: String): String =
|
||||
KotlinBundle.message("action.new.file.text")
|
||||
|
||||
override fun isAvailable(dataContext: DataContext): Boolean {
|
||||
if (super.isAvailable(dataContext)) {
|
||||
val ideView = LangDataKeys.IDE_VIEW.getData(dataContext)!!
|
||||
val project = PlatformDataKeys.PROJECT.getData(dataContext)!!
|
||||
val projectFileIndex = ProjectRootManager.getInstance(project).fileIndex
|
||||
return ideView.directories.any { projectFileIndex.isInSourceContent(it.virtualFile) }
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = 0
|
||||
|
||||
override fun equals(other: Any?): Boolean = other is NewKotlinFileAction
|
||||
|
||||
override fun startInWriteAction() = false
|
||||
|
||||
override fun createFileFromTemplate(name: String, template: FileTemplate, dir: PsiDirectory) =
|
||||
createFileFromTemplateWithStat(name, template, dir)
|
||||
|
||||
companion object {
|
||||
private object NameValidator : InputValidatorEx {
|
||||
override fun getErrorText(inputString: String): String? {
|
||||
if (inputString.trim().isEmpty()) {
|
||||
return KotlinBundle.message("action.new.file.error.empty.name")
|
||||
}
|
||||
|
||||
val parts: List<String> = inputString.split(*FQNAME_SEPARATORS)
|
||||
if (parts.any { it.trim().isEmpty() }) {
|
||||
return KotlinBundle.message("action.new.file.error.empty.name.part")
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
override fun checkInput(inputString: String): Boolean = true
|
||||
|
||||
override fun canClose(inputString: String): Boolean = getErrorText(inputString) == null
|
||||
}
|
||||
|
||||
@get:TestOnly
|
||||
val nameValidator: InputValidatorEx
|
||||
get() = NameValidator
|
||||
|
||||
private fun findOrCreateTarget(dir: PsiDirectory, name: String, directorySeparators: CharArray): Pair<String, PsiDirectory> {
|
||||
var className = removeKotlinExtensionIfPresent(name)
|
||||
var targetDir = dir
|
||||
|
||||
for (splitChar in directorySeparators) {
|
||||
if (splitChar in className) {
|
||||
val names = className.trim().split(splitChar)
|
||||
|
||||
for (dirName in names.dropLast(1)) {
|
||||
targetDir = targetDir.findSubdirectory(dirName) ?: runWriteAction {
|
||||
targetDir.createSubdirectory(dirName)
|
||||
}
|
||||
}
|
||||
|
||||
className = names.last()
|
||||
break
|
||||
}
|
||||
}
|
||||
return Pair(className, targetDir)
|
||||
}
|
||||
|
||||
private fun removeKotlinExtensionIfPresent(name: String): String = when {
|
||||
name.endsWith(".$KOTLIN_WORKSHEET_EXTENSION") -> name.removeSuffix(".$KOTLIN_WORKSHEET_EXTENSION")
|
||||
name.endsWith(".$STD_SCRIPT_SUFFIX") -> name.removeSuffix(".$STD_SCRIPT_SUFFIX")
|
||||
name.endsWith(".${KotlinFileType.EXTENSION}") -> name.removeSuffix(".${KotlinFileType.EXTENSION}")
|
||||
else -> name
|
||||
}
|
||||
|
||||
private fun createFromTemplate(dir: PsiDirectory, className: String, template: FileTemplate): PsiFile? {
|
||||
val project = dir.project
|
||||
val defaultProperties = FileTemplateManager.getInstance(project).defaultProperties
|
||||
|
||||
val properties = Properties(defaultProperties)
|
||||
|
||||
val element = try {
|
||||
CreateFromTemplateDialog(
|
||||
project, dir, template,
|
||||
AttributesDefaults(className).withFixedName(true),
|
||||
properties
|
||||
).create()
|
||||
} catch (e: IncorrectOperationException) {
|
||||
throw e
|
||||
} catch (e: Exception) {
|
||||
LOG.error(e)
|
||||
return null
|
||||
}
|
||||
|
||||
return element?.containingFile
|
||||
}
|
||||
|
||||
private val FILE_SEPARATORS = charArrayOf('/', '\\')
|
||||
private val FQNAME_SEPARATORS = charArrayOf('/', '\\', '.')
|
||||
|
||||
fun createFileFromTemplateWithStat(name: String, template: FileTemplate, dir: PsiDirectory): PsiFile? {
|
||||
KotlinFUSLogger.log(FUSEventGroups.NewFileTemplate, template.name)
|
||||
return createFileFromTemplate(name, template, dir)
|
||||
}
|
||||
|
||||
|
||||
fun createFileFromTemplate(name: String, template: FileTemplate, dir: PsiDirectory): PsiFile? {
|
||||
val directorySeparators = when (template.name) {
|
||||
"Kotlin File" -> FILE_SEPARATORS
|
||||
else -> FQNAME_SEPARATORS
|
||||
}
|
||||
val (className, targetDir) = findOrCreateTarget(dir, name, directorySeparators)
|
||||
|
||||
val service = DumbService.getInstance(dir.project)
|
||||
service.isAlternativeResolveEnabled = true
|
||||
try {
|
||||
val psiFile = createFromTemplate(targetDir, className, template)
|
||||
if (psiFile is KtFile) {
|
||||
val singleClass = psiFile.declarations.singleOrNull() as? KtClass
|
||||
if (singleClass != null && !singleClass.isEnum() && !singleClass.isInterface() && name.contains("Abstract")) {
|
||||
runWriteAction {
|
||||
singleClass.addModifier(KtTokens.ABSTRACT_KEYWORD)
|
||||
}
|
||||
}
|
||||
}
|
||||
return psiFile
|
||||
} finally {
|
||||
service.isAlternativeResolveEnabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class NewKotlinFileHook {
|
||||
companion object {
|
||||
val EP_NAME: ExtensionPointName<NewKotlinFileHook> =
|
||||
ExtensionPointName.create<NewKotlinFileHook>("org.jetbrains.kotlin.newFileHook")
|
||||
}
|
||||
|
||||
abstract fun postProcess(createdElement: KtFile, module: Module)
|
||||
}
|
||||
+227
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.roots
|
||||
|
||||
import com.intellij.conversion.*
|
||||
import com.intellij.conversion.impl.ConversionContextImpl
|
||||
import com.intellij.conversion.impl.ModuleSettingsImpl
|
||||
import com.intellij.openapi.roots.ExternalProjectSystemRegistry
|
||||
import com.intellij.openapi.roots.OrderRootType
|
||||
import com.intellij.openapi.roots.impl.ContentEntryImpl
|
||||
import com.intellij.openapi.roots.impl.SourceFolderImpl
|
||||
import com.intellij.openapi.roots.impl.libraries.ApplicationLibraryTable
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryImpl
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.roots.libraries.LibraryKind
|
||||
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar
|
||||
import com.intellij.openapi.roots.libraries.PersistentLibraryKind
|
||||
import com.intellij.openapi.vfs.JarFileSystem
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jdom.Element
|
||||
import org.jetbrains.jps.model.JpsElement
|
||||
import org.jetbrains.jps.model.JpsElementFactory
|
||||
import org.jetbrains.jps.model.java.JavaResourceRootType
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootType
|
||||
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
|
||||
import org.jetbrains.jps.model.module.JpsTypedModuleSourceRoot
|
||||
import org.jetbrains.jps.model.serialization.facet.JpsFacetSerializer
|
||||
import org.jetbrains.jps.model.serialization.library.JpsLibraryTableSerializer
|
||||
import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer.*
|
||||
import org.jetbrains.kotlin.config.getFacetPlatformByConfigurationElement
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.core.util.toVirtualFile
|
||||
import org.jetbrains.kotlin.idea.facet.KotlinFacetType
|
||||
import org.jetbrains.kotlin.idea.framework.JavaRuntimeDetectionUtil
|
||||
import org.jetbrains.kotlin.idea.framework.JsLibraryStdDetectionUtil
|
||||
import org.jetbrains.kotlin.idea.framework.getLibraryJar
|
||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
import org.jetbrains.kotlin.platform.js.JsPlatforms
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
|
||||
class KotlinNonJvmSourceRootConverterProvider : ConverterProvider("kotlin-non-jvm-source-roots") {
|
||||
companion object {
|
||||
private val rootTypesToMigrate: List<JpsModuleSourceRootType<*>> = listOf(
|
||||
JavaSourceRootType.SOURCE,
|
||||
JavaSourceRootType.TEST_SOURCE,
|
||||
JavaResourceRootType.RESOURCE,
|
||||
JavaResourceRootType.TEST_RESOURCE
|
||||
)
|
||||
|
||||
// TODO(dsavvinov): review how it behaves in HMPP environment
|
||||
private val PLATFORM_TO_STDLIB_DETECTORS: Map<TargetPlatform, (Array<VirtualFile>) -> Boolean> = mapOf(
|
||||
JvmPlatforms.unspecifiedJvmPlatform to { roots: Array<VirtualFile> -> JavaRuntimeDetectionUtil.getRuntimeJar(roots.toList()) != null },
|
||||
JsPlatforms.defaultJsPlatform to { roots: Array<VirtualFile> -> JsLibraryStdDetectionUtil.getJsStdLibJar(roots.toList()) != null },
|
||||
CommonPlatforms.defaultCommonPlatform to { roots: Array<VirtualFile> ->
|
||||
getLibraryJar(roots, PathUtil.KOTLIN_STDLIB_COMMON_JAR_PATTERN) != null
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
sealed class LibInfo {
|
||||
class ByXml(
|
||||
private val element: Element,
|
||||
private val conversionContext: ConversionContext,
|
||||
private val moduleSettings: ModuleSettings
|
||||
) : LibInfo() {
|
||||
override val explicitKind: PersistentLibraryKind<*>?
|
||||
get() = LibraryKind.findById(element.getAttributeValue("type")) as? PersistentLibraryKind<*>
|
||||
|
||||
override fun getRoots(): Array<VirtualFile> {
|
||||
val contextImpl = conversionContext as? ConversionContextImpl ?: return VirtualFile.EMPTY_ARRAY
|
||||
val moduleSettingsImpl = moduleSettings as? ModuleSettingsImpl ?: return VirtualFile.EMPTY_ARRAY
|
||||
return contextImpl
|
||||
.getClassRoots(element, moduleSettingsImpl)
|
||||
.mapNotNull { it.toVirtualFile()?.let { file -> JarFileSystem.getInstance().getJarRootForLocalFile(file) } }
|
||||
.toTypedArray()
|
||||
}
|
||||
}
|
||||
|
||||
class ByLibrary(private val library: Library) : LibInfo() {
|
||||
override val explicitKind: PersistentLibraryKind<*>?
|
||||
get() = (library as? LibraryEx)?.kind
|
||||
|
||||
override fun getRoots(): Array<VirtualFile> = library.getFiles(OrderRootType.CLASSES)
|
||||
}
|
||||
|
||||
abstract val explicitKind: PersistentLibraryKind<*>?
|
||||
abstract fun getRoots(): Array<VirtualFile>
|
||||
|
||||
val stdlibPlatform: TargetPlatform? by lazy {
|
||||
val roots = getRoots()
|
||||
for ((platform, detector) in PLATFORM_TO_STDLIB_DETECTORS) {
|
||||
if (detector.invoke(roots)) {
|
||||
return@lazy platform
|
||||
}
|
||||
}
|
||||
|
||||
return@lazy null
|
||||
}
|
||||
}
|
||||
|
||||
class ConverterImpl(private val context: ConversionContext) : ProjectConverter() {
|
||||
private val projectLibrariesByName by lazy {
|
||||
context.projectLibrariesSettings.projectLibraries.groupBy { it.getAttributeValue(JpsLibraryTableSerializer.NAME_ATTRIBUTE) }
|
||||
}
|
||||
|
||||
private fun findGlobalLibrary(name: String) = ApplicationLibraryTable.getApplicationTable().getLibraryByName(name)
|
||||
|
||||
private fun findProjectLibrary(name: String) = projectLibrariesByName[name]?.firstOrNull()
|
||||
|
||||
private fun createLibInfo(orderEntryElement: Element, moduleSettings: ModuleSettings): LibInfo? {
|
||||
return when (orderEntryElement.getAttributeValue("type")) {
|
||||
MODULE_LIBRARY_TYPE -> {
|
||||
orderEntryElement.getChild(LIBRARY_TAG)?.let { LibInfo.ByXml(it, context, moduleSettings) }
|
||||
}
|
||||
|
||||
LIBRARY_TYPE -> {
|
||||
val libraryName = orderEntryElement.getAttributeValue(NAME_ATTRIBUTE) ?: return null
|
||||
when (orderEntryElement.getAttributeValue(LEVEL_ATTRIBUTE)) {
|
||||
LibraryTablesRegistrar.PROJECT_LEVEL ->
|
||||
findProjectLibrary(libraryName)?.let { LibInfo.ByXml(it, context, moduleSettings) }
|
||||
LibraryTablesRegistrar.APPLICATION_LEVEL ->
|
||||
findGlobalLibrary(libraryName)?.let { LibInfo.ByLibrary(it) }
|
||||
else ->
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override fun createModuleFileConverter(): ConversionProcessor<ModuleSettings> {
|
||||
return object : ConversionProcessor<ModuleSettings>() {
|
||||
private fun ModuleSettings.detectPlatformByFacet() =
|
||||
getFacetElement(KotlinFacetType.ID)
|
||||
?.getChild(JpsFacetSerializer.CONFIGURATION_TAG)
|
||||
?.getFacetPlatformByConfigurationElement()
|
||||
|
||||
|
||||
private fun ModuleSettings.detectPlatformByDependencies(): TargetPlatform? {
|
||||
var hasCommonStdlib = false
|
||||
|
||||
orderEntries
|
||||
.asSequence()
|
||||
.mapNotNull { createLibInfo(it, this) }
|
||||
.forEach {
|
||||
val stdlibPlatform = it.stdlibPlatform
|
||||
if (stdlibPlatform != null) {
|
||||
if (stdlibPlatform.isCommon()) {
|
||||
hasCommonStdlib = true
|
||||
} else {
|
||||
return stdlibPlatform
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return if (hasCommonStdlib) CommonPlatforms.defaultCommonPlatform else null
|
||||
}
|
||||
|
||||
private fun ModuleSettings.detectPlatform(): TargetPlatform {
|
||||
return detectPlatformByFacet()
|
||||
?: detectPlatformByDependencies()
|
||||
?: JvmPlatforms.unspecifiedJvmPlatform
|
||||
}
|
||||
|
||||
private fun ModuleSettings.getSourceFolderElements(): List<Element> {
|
||||
val rootManagerElement = getComponentElement(ModuleSettings.MODULE_ROOT_MANAGER_COMPONENT) ?: return emptyList()
|
||||
return rootManagerElement
|
||||
.getChildren(ContentEntryImpl.ELEMENT_NAME)
|
||||
.flatMap { it.getChildren(SourceFolderImpl.ELEMENT_NAME) }
|
||||
}
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
private fun ModuleSettings.isExternalModule(): Boolean {
|
||||
return when {
|
||||
rootElement.getAttributeValue(ExternalProjectSystemRegistry.EXTERNAL_SYSTEM_ID_KEY) != null -> true
|
||||
rootElement.getAttributeValue(ExternalProjectSystemRegistry.IS_MAVEN_MODULE_KEY)?.toBoolean() ?: false -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun isConversionNeeded(settings: ModuleSettings): Boolean {
|
||||
if (settings.isExternalModule()) return false
|
||||
|
||||
val hasMigrationRoots = settings.getSourceFolderElements().any {
|
||||
loadSourceRoot(it).rootType in rootTypesToMigrate
|
||||
}
|
||||
if (!hasMigrationRoots) {
|
||||
return false
|
||||
}
|
||||
|
||||
val targetPlatform = settings.detectPlatform()
|
||||
return (!targetPlatform.isJvm())
|
||||
}
|
||||
|
||||
override fun process(settings: ModuleSettings) {
|
||||
for (sourceFolder in settings.getSourceFolderElements()) {
|
||||
val contentRoot = sourceFolder.parent as? Element ?: continue
|
||||
val oldSourceRoot = loadSourceRoot(sourceFolder)
|
||||
val url = sourceFolder.getAttributeValue(URL_ATTRIBUTE)
|
||||
|
||||
val (newRootType, data) = oldSourceRoot.getMigratedSourceRootTypeWithProperties() ?: continue
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val newSourceRoot = JpsElementFactory.getInstance().createModuleSourceRoot(url, newRootType, data)
|
||||
as? JpsTypedModuleSourceRoot<JpsElement> ?: continue
|
||||
|
||||
contentRoot.removeContent(sourceFolder)
|
||||
saveSourceRoot(contentRoot, url, newSourceRoot)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getConversionDescription() =
|
||||
KotlinBundle.message("roots.description.text.update.source.roots.for.non.jvm.modules.in.kotlin.project")
|
||||
|
||||
override fun createConverter(context: ConversionContext) = ConverterImpl(context)
|
||||
}
|
||||
Reference in New Issue
Block a user