diff --git a/plugins/kotlin/base/scripting/scripting.k1/src/org/jetbrains/kotlin/idea/core/script/k1/highlighter/ScriptHighlightingExtension.kt b/plugins/kotlin/base/scripting/scripting.k1/src/org/jetbrains/kotlin/idea/core/script/k1/highlighter/ScriptHighlightingExtension.kt index 96a220d7e937..da40410f6d5e 100644 --- a/plugins/kotlin/base/scripting/scripting.k1/src/org/jetbrains/kotlin/idea/core/script/k1/highlighter/ScriptHighlightingExtension.kt +++ b/plugins/kotlin/base/scripting/scripting.k1/src/org/jetbrains/kotlin/idea/core/script/k1/highlighter/ScriptHighlightingExtension.kt @@ -7,6 +7,6 @@ import org.jetbrains.kotlin.scripting.definitions.ScriptConfigurationsProvider class ScriptHighlightingExtension : AbstractKotlinScriptHighlightingExtension { - override fun calculateShouldHighlightScript(file: KtFile): Boolean = + override fun shouldHighlight(file: KtFile): Boolean = ScriptConfigurationsProvider.getInstance(file.project)?.getScriptConfigurationResult(file) != null } \ No newline at end of file diff --git a/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/configurations/impl/MetadataStorageImpl.kt b/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/configurations/impl/MetadataStorageImpl.kt index db706cdb6673..b1cef398cfaa 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/configurations/impl/MetadataStorageImpl.kt +++ b/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/configurations/impl/MetadataStorageImpl.kt @@ -4,7 +4,6 @@ package org.jetbrains.kotlin.idea.core.script.k2.configurations.impl import com.intellij.platform.workspace.storage.WorkspaceEntityInternalApi import com.intellij.platform.workspace.storage.metadata.impl.MetadataStorageBase import com.intellij.platform.workspace.storage.metadata.model.EntityMetadata -import com.intellij.platform.workspace.storage.metadata.model.ExtendableClassMetadata import com.intellij.platform.workspace.storage.metadata.model.FinalClassMetadata import com.intellij.platform.workspace.storage.metadata.model.OwnPropertyMetadata import com.intellij.platform.workspace.storage.metadata.model.StorageTypeMetadata @@ -15,8 +14,8 @@ internal object MetadataStorageImpl : MetadataStorageBase() { override fun initializeMetadata() { val primitiveTypeListNotNullable = ValueTypeMetadata.SimpleType.PrimitiveType(isNullable = false, type = "List") val primitiveTypeStringNotNullable = ValueTypeMetadata.SimpleType.PrimitiveType(isNullable = false, type = "String") - val primitiveTypeBooleanNotNullable = ValueTypeMetadata.SimpleType.PrimitiveType(isNullable = false, type = "Boolean") val primitiveTypeIntNotNullable = ValueTypeMetadata.SimpleType.PrimitiveType(isNullable = false, type = "Int") + val primitiveTypeStringNullable = ValueTypeMetadata.SimpleType.PrimitiveType(isNullable = true, type = "String") var typeMetadata: StorageTypeMetadata @@ -99,240 +98,64 @@ internal object MetadataStorageImpl : MetadataStorageBase() { withDefault = false)), supertypes = listOf("com.intellij.platform.workspace.storage.SymbolicEntityId")))), primitive = primitiveTypeListNotNullable), withDefault = false), - OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "sdk", - valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = false, - typeMetadata = ExtendableClassMetadata.AbstractClassMetadata( - fqName = "com.intellij.platform.workspace.jps.entities.ModuleDependencyItem", - subclasses = listOf(FinalClassMetadata.ObjectMetadata( - fqName = "com.intellij.platform.workspace.jps.entities.ModuleSourceDependency", - properties = listOf(), supertypes = listOf( - "com.intellij.platform.workspace.jps.entities.ModuleDependencyItem", - "java.io.Serializable")), - FinalClassMetadata.ClassMetadata( - fqName = "com.intellij.platform.workspace.jps.entities.SdkDependency", - properties = listOf( - OwnPropertyMetadata( - isComputable = false, - isKey = false, isOpen = false, - name = "sdk", - valueType = ValueTypeMetadata.SimpleType.CustomType( - isNullable = false, - typeMetadata = FinalClassMetadata.ClassMetadata( - fqName = "com.intellij.platform.workspace.jps.entities.SdkId", - properties = listOf( - OwnPropertyMetadata( - isComputable = false, - isKey = false, - isOpen = false, - name = "name", - valueType = primitiveTypeStringNotNullable, - withDefault = false), - OwnPropertyMetadata( - isComputable = false, - isKey = false, - isOpen = false, - name = "presentableName", - valueType = primitiveTypeStringNotNullable, - withDefault = false), - OwnPropertyMetadata( - isComputable = false, - isKey = false, - isOpen = false, - name = "type", - valueType = primitiveTypeStringNotNullable, - withDefault = false)), - supertypes = listOf( - "com.intellij.platform.workspace.storage.SymbolicEntityId"))), - withDefault = false)), - supertypes = listOf( - "com.intellij.platform.workspace.jps.entities.ModuleDependencyItem", - "java.io.Serializable")), - FinalClassMetadata.ObjectMetadata( - fqName = "com.intellij.platform.workspace.jps.entities.InheritedSdkDependency", - properties = listOf(), - supertypes = listOf( - "com.intellij.platform.workspace.jps.entities.ModuleDependencyItem", - "java.io.Serializable")), - FinalClassMetadata.ClassMetadata( - fqName = "com.intellij.platform.workspace.jps.entities.LibraryDependency", - properties = listOf( - OwnPropertyMetadata( - isComputable = false, - isKey = false, isOpen = false, - name = "exported", - valueType = primitiveTypeBooleanNotNullable, - withDefault = false), - OwnPropertyMetadata( - isComputable = false, - isKey = false, isOpen = false, - name = "library", - valueType = ValueTypeMetadata.SimpleType.CustomType( - isNullable = false, - typeMetadata = FinalClassMetadata.ClassMetadata( - fqName = "com.intellij.platform.workspace.jps.entities.LibraryId", - properties = listOf( - OwnPropertyMetadata( - isComputable = false, - isKey = false, - isOpen = false, - name = "codeCache", - valueType = primitiveTypeIntNotNullable, - withDefault = false), - OwnPropertyMetadata( - isComputable = false, - isKey = false, - isOpen = false, - name = "name", - valueType = primitiveTypeStringNotNullable, - withDefault = false), - OwnPropertyMetadata( - isComputable = false, - isKey = false, - isOpen = false, - name = "presentableName", - valueType = primitiveTypeStringNotNullable, - withDefault = false), - OwnPropertyMetadata( - isComputable = false, - isKey = false, - isOpen = false, - name = "tableId", - valueType = ValueTypeMetadata.SimpleType.CustomType( - isNullable = false, - typeMetadata = ExtendableClassMetadata.AbstractClassMetadata( - fqName = "com.intellij.platform.workspace.jps.entities.LibraryTableId", - subclasses = listOf( - FinalClassMetadata.ObjectMetadata( - fqName = "com.intellij.platform.workspace.jps.entities.LibraryTableId\$ProjectLibraryTableId", - properties = listOf( - OwnPropertyMetadata( - isComputable = false, - isKey = false, - isOpen = false, - name = "level", - valueType = primitiveTypeStringNotNullable, - withDefault = false)), - supertypes = listOf( - "com.intellij.platform.workspace.jps.entities.LibraryTableId", - "java.io.Serializable")), - FinalClassMetadata.ClassMetadata( - fqName = "com.intellij.platform.workspace.jps.entities.LibraryTableId\$GlobalLibraryTableId", - properties = listOf( - OwnPropertyMetadata( - isComputable = false, - isKey = false, - isOpen = false, - name = "level", - valueType = primitiveTypeStringNotNullable, - withDefault = false)), - supertypes = listOf( - "com.intellij.platform.workspace.jps.entities.LibraryTableId", - "java.io.Serializable")), - FinalClassMetadata.ClassMetadata( - fqName = "com.intellij.platform.workspace.jps.entities.LibraryTableId\$ModuleLibraryTableId", - properties = listOf( - OwnPropertyMetadata( - isComputable = false, - isKey = false, - isOpen = false, - name = "level", - valueType = primitiveTypeStringNotNullable, - withDefault = false), - OwnPropertyMetadata( - isComputable = false, - isKey = false, - isOpen = false, - name = "moduleId", - valueType = ValueTypeMetadata.SimpleType.CustomType( - isNullable = false, - typeMetadata = FinalClassMetadata.ClassMetadata( - fqName = "com.intellij.platform.workspace.jps.entities.ModuleId", - properties = listOf( - OwnPropertyMetadata( - isComputable = false, - isKey = false, - isOpen = false, - name = "name", - valueType = primitiveTypeStringNotNullable, - withDefault = false), - OwnPropertyMetadata( - isComputable = false, - isKey = false, - isOpen = false, - name = "presentableName", - valueType = primitiveTypeStringNotNullable, - withDefault = false)), - supertypes = listOf( - "com.intellij.platform.workspace.storage.SymbolicEntityId"))), - withDefault = false)), - supertypes = listOf( - "com.intellij.platform.workspace.jps.entities.LibraryTableId", - "java.io.Serializable"))), - supertypes = listOf( - "java.io.Serializable"))), - withDefault = false)), - supertypes = listOf( - "com.intellij.platform.workspace.storage.SymbolicEntityId"))), - withDefault = false), - OwnPropertyMetadata( - isComputable = false, - isKey = false, isOpen = false, - name = "scope", - valueType = ValueTypeMetadata.SimpleType.CustomType( - isNullable = false, - typeMetadata = FinalClassMetadata.EnumClassMetadata( - fqName = "com.intellij.platform.workspace.jps.entities.DependencyScope", - properties = listOf(), - supertypes = listOf( - "java.io.Serializable", - "kotlin.Comparable", - "kotlin.Enum"), - values = listOf("COMPILE", - "PROVIDED", - "RUNTIME", - "TEST"))), - withDefault = false)), - supertypes = listOf( - "com.intellij.platform.workspace.jps.entities.ModuleDependencyItem", - "java.io.Serializable")), - FinalClassMetadata.ClassMetadata( - fqName = "com.intellij.platform.workspace.jps.entities.ModuleDependency", - properties = listOf( - OwnPropertyMetadata( - isComputable = false, - isKey = false, isOpen = false, - name = "exported", - valueType = primitiveTypeBooleanNotNullable, - withDefault = false), - OwnPropertyMetadata( - isComputable = false, - isKey = false, isOpen = false, - name = "module", - valueType = ValueTypeMetadata.SimpleType.CustomType( - isNullable = false, - typeMetadata = FinalClassMetadata.KnownClass( - fqName = "com.intellij.platform.workspace.jps.entities.ModuleId")), - withDefault = false), - OwnPropertyMetadata( - isComputable = false, - isKey = false, isOpen = false, - name = "productionOnTest", - valueType = primitiveTypeBooleanNotNullable, - withDefault = false), - OwnPropertyMetadata( - isComputable = false, - isKey = false, isOpen = false, - name = "scope", - valueType = ValueTypeMetadata.SimpleType.CustomType( - isNullable = false, - typeMetadata = FinalClassMetadata.KnownClass( - fqName = "com.intellij.platform.workspace.jps.entities.DependencyScope")), - withDefault = false)), - supertypes = listOf( - "com.intellij.platform.workspace.jps.entities.ModuleDependencyItem", - "java.io.Serializable"))), - supertypes = listOf("java.io.Serializable"))), - withDefault = false)), extProperties = listOf(), isAbstract = false) + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "configuration", + valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = true, + typeMetadata = FinalClassMetadata.ClassMetadata( + fqName = "org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptCompilationConfigurationEntity", + properties = listOf( + OwnPropertyMetadata(isComputable = false, isKey = false, + isOpen = false, name = "data", + valueType = ValueTypeMetadata.SimpleType.CustomType( + isNullable = false, + typeMetadata = FinalClassMetadata.KnownClass( + fqName = "kotlin.ByteArray")), + withDefault = false)), + supertypes = listOf())), withDefault = false), + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "sdkId", + valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = true, + typeMetadata = FinalClassMetadata.ClassMetadata( + fqName = "com.intellij.platform.workspace.jps.entities.SdkId", + properties = listOf( + OwnPropertyMetadata(isComputable = false, isKey = false, + isOpen = false, name = "name", + valueType = primitiveTypeStringNotNullable, + withDefault = false), + OwnPropertyMetadata(isComputable = false, isKey = false, + isOpen = false, + name = "presentableName", + valueType = primitiveTypeStringNotNullable, + withDefault = false), + OwnPropertyMetadata(isComputable = false, isKey = false, + isOpen = false, name = "type", + valueType = primitiveTypeStringNotNullable, + withDefault = false)), + supertypes = listOf( + "com.intellij.platform.workspace.storage.SymbolicEntityId"))), + withDefault = false), + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "reports", + valueType = ValueTypeMetadata.ParameterizedType(generics = listOf( + ValueTypeMetadata.SimpleType.CustomType(isNullable = false, typeMetadata = FinalClassMetadata.ClassMetadata( + fqName = "org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptDiagnosticData", properties = listOf( + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "code", + valueType = primitiveTypeIntNotNullable, withDefault = false), + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "exceptionMessage", + valueType = primitiveTypeStringNullable, withDefault = false), + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "location", + valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = true, + typeMetadata = FinalClassMetadata.KnownClass( + fqName = "kotlin.script.experimental.api.SourceCode\$Location")), + withDefault = false), + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "message", + valueType = primitiveTypeStringNotNullable, withDefault = false), + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "severity", + valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = false, + typeMetadata = FinalClassMetadata.KnownClass( + fqName = "kotlin.script.experimental.api.ScriptDiagnostic\$Severity")), + withDefault = false), + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "sourcePath", + valueType = primitiveTypeStringNullable, withDefault = false)), + supertypes = listOf()))), primitive = primitiveTypeListNotNullable), withDefault = true)), + extProperties = listOf(), isAbstract = false) addMetadata(typeMetadata) @@ -406,25 +229,13 @@ internal object MetadataStorageImpl : MetadataStorageBase() { } override fun initializeMetadataHash() { - addMetadataHash(typeFqn = "org.jetbrains.kotlin.idea.core.script.k2.modules.KotlinScriptEntity", metadataHash = 56160960) + addMetadataHash(typeFqn = "org.jetbrains.kotlin.idea.core.script.k2.modules.KotlinScriptEntity", metadataHash = -904523740) addMetadataHash(typeFqn = "org.jetbrains.kotlin.idea.core.script.k2.modules.KotlinScriptLibraryEntity", metadataHash = -366522520) addMetadataHash(typeFqn = "org.jetbrains.kotlin.idea.core.script.k2.modules.KotlinScriptLibraryEntityId", metadataHash = -1990443645) - addMetadataHash(typeFqn = "com.intellij.platform.workspace.jps.entities.ModuleDependencyItem", metadataHash = -907000292) - addMetadataHash(typeFqn = "com.intellij.platform.workspace.jps.entities.InheritedSdkDependency", metadataHash = -1690206127) - addMetadataHash(typeFqn = "com.intellij.platform.workspace.jps.entities.LibraryDependency", metadataHash = 494611792) - addMetadataHash(typeFqn = "com.intellij.platform.workspace.jps.entities.LibraryId", metadataHash = 1192700660) - addMetadataHash(typeFqn = "com.intellij.platform.workspace.jps.entities.LibraryTableId", metadataHash = -219154451) - addMetadataHash(typeFqn = "com.intellij.platform.workspace.jps.entities.LibraryTableId\$GlobalLibraryTableId", - metadataHash = 1911253865) - addMetadataHash(typeFqn = "com.intellij.platform.workspace.jps.entities.LibraryTableId\$ModuleLibraryTableId", metadataHash = 777479370) - addMetadataHash(typeFqn = "com.intellij.platform.workspace.jps.entities.ModuleId", metadataHash = -575206713) - addMetadataHash(typeFqn = "com.intellij.platform.workspace.jps.entities.LibraryTableId\$ProjectLibraryTableId", - metadataHash = -1574432194) - addMetadataHash(typeFqn = "com.intellij.platform.workspace.jps.entities.DependencyScope", metadataHash = 1284754485) - addMetadataHash(typeFqn = "com.intellij.platform.workspace.jps.entities.ModuleDependency", metadataHash = -409169331) - addMetadataHash(typeFqn = "com.intellij.platform.workspace.jps.entities.ModuleSourceDependency", metadataHash = -1334065142) - addMetadataHash(typeFqn = "com.intellij.platform.workspace.jps.entities.SdkDependency", metadataHash = 1386665092) + addMetadataHash(typeFqn = "org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptCompilationConfigurationEntity", + metadataHash = -1162660984) addMetadataHash(typeFqn = "com.intellij.platform.workspace.jps.entities.SdkId", metadataHash = 51502100) + addMetadataHash(typeFqn = "org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptDiagnosticData", metadataHash = -579968699) addMetadataHash(typeFqn = "com.intellij.platform.workspace.storage.EntitySource", metadataHash = -706084288) addMetadataHash( typeFqn = "org.jetbrains.kotlin.idea.core.script.k2.configurations.DefaultScriptConfigurationHandler\$DefaultScriptEntitySource", diff --git a/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptEntityApi.kt b/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptEntityApi.kt index b58a8d24cda3..768f4edc0aca 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptEntityApi.kt +++ b/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptEntityApi.kt @@ -1,10 +1,9 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.core.script.k2.modules -import com.intellij.platform.workspace.jps.entities.InheritedSdkDependency -import com.intellij.platform.workspace.jps.entities.ModuleDependencyItem -import com.intellij.platform.workspace.jps.entities.SdkDependency +import com.intellij.platform.workspace.jps.entities.SdkId import com.intellij.platform.workspace.storage.* +import com.intellij.platform.workspace.storage.annotations.Default import com.intellij.platform.workspace.storage.impl.containers.toMutableWorkspaceList import com.intellij.platform.workspace.storage.url.VirtualFileUrl @@ -13,7 +12,9 @@ interface ModifiableKotlinScriptEntity : ModifiableWorkspaceEntity - var sdk: ModuleDependencyItem + var configuration: ScriptCompilationConfigurationEntity? + var sdkId: SdkId? + var reports: MutableList } internal object KotlinScriptEntityType : EntityType() { @@ -21,14 +22,12 @@ internal object KotlinScriptEntityType : EntityType, - sdk: ModuleDependencyItem, entitySource: EntitySource, init: (ModifiableKotlinScriptEntity.() -> Unit)? = null, ): ModifiableKotlinScriptEntity { val builder = builder() builder.virtualFileUrl = virtualFileUrl builder.dependencies = dependencies.toMutableWorkspaceList() - builder.sdk = sdk builder.entitySource = entitySource init?.invoke(builder) return builder @@ -45,7 +44,6 @@ fun MutableEntityStorage.modifyKotlinScriptEntity( fun KotlinScriptEntity( virtualFileUrl: VirtualFileUrl, dependencies: List, - sdk: ModuleDependencyItem, entitySource: EntitySource, init: (ModifiableKotlinScriptEntity.() -> Unit)? = null, -): ModifiableKotlinScriptEntity = KotlinScriptEntityType(virtualFileUrl, dependencies, sdk, entitySource, init) +): ModifiableKotlinScriptEntity = KotlinScriptEntityType(virtualFileUrl, dependencies, entitySource, init) diff --git a/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptLibraryEntityApi.kt b/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptLibraryEntityApi.kt index 9583ab49d0b6..6a89f8de3b25 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptLibraryEntityApi.kt +++ b/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptLibraryEntityApi.kt @@ -2,14 +2,7 @@ package org.jetbrains.kotlin.idea.core.script.k2.modules import com.intellij.openapi.util.NlsSafe -import com.intellij.platform.workspace.storage.EntitySource -import com.intellij.platform.workspace.storage.EntityType -import com.intellij.platform.workspace.storage.GeneratedCodeApiVersion -import com.intellij.platform.workspace.storage.ModifiableWorkspaceEntity -import com.intellij.platform.workspace.storage.MutableEntityStorage -import com.intellij.platform.workspace.storage.SymbolicEntityId -import com.intellij.platform.workspace.storage.WorkspaceEntity -import com.intellij.platform.workspace.storage.WorkspaceEntityWithSymbolicId +import com.intellij.platform.workspace.storage.* import com.intellij.platform.workspace.storage.impl.containers.toMutableWorkspaceList import com.intellij.platform.workspace.storage.url.VirtualFileUrl diff --git a/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/impl/KotlinScriptEntityImpl.kt b/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/impl/KotlinScriptEntityImpl.kt index 0fb3976ae167..c8d7f281e4cc 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/impl/KotlinScriptEntityImpl.kt +++ b/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/impl/KotlinScriptEntityImpl.kt @@ -1,16 +1,9 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.core.script.k2.modules.impl -import com.intellij.platform.workspace.jps.entities.InheritedSdkDependency -import com.intellij.platform.workspace.jps.entities.LibraryDependency -import com.intellij.platform.workspace.jps.entities.LibraryId -import com.intellij.platform.workspace.jps.entities.ModuleDependency -import com.intellij.platform.workspace.jps.entities.ModuleDependencyItem -import com.intellij.platform.workspace.jps.entities.ModuleId -import com.intellij.platform.workspace.jps.entities.ModuleSourceDependency -import com.intellij.platform.workspace.jps.entities.SdkDependency import com.intellij.platform.workspace.jps.entities.SdkId import com.intellij.platform.workspace.storage.* +import com.intellij.platform.workspace.storage.annotations.Default import com.intellij.platform.workspace.storage.impl.ModifiableWorkspaceEntityBase import com.intellij.platform.workspace.storage.impl.SoftLinkable import com.intellij.platform.workspace.storage.impl.WorkspaceEntityBase @@ -25,6 +18,8 @@ import com.intellij.platform.workspace.storage.url.VirtualFileUrl import org.jetbrains.kotlin.idea.core.script.k2.modules.KotlinScriptEntity import org.jetbrains.kotlin.idea.core.script.k2.modules.KotlinScriptLibraryEntityId import org.jetbrains.kotlin.idea.core.script.k2.modules.ModifiableKotlinScriptEntity +import org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptCompilationConfigurationEntity +import org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptDiagnosticData @GeneratedCodeApiVersion(3) @GeneratedCodeImplVersion(7) @@ -52,12 +47,20 @@ internal class KotlinScriptEntityImpl(private val dataSource: KotlinScriptEntity return dataSource.dependencies } - override val sdk: ModuleDependencyItem + override val configuration: ScriptCompilationConfigurationEntity? get() { - readField("sdk") - return dataSource.sdk + readField("configuration") + return dataSource.configuration } + override val sdkId: SdkId? + get() { + readField("sdkId") + return dataSource.sdkId + } + + override var reports: List = dataSource.reports + override val entitySource: EntitySource get() { readField("entitySource") @@ -108,9 +111,6 @@ internal class KotlinScriptEntityImpl(private val dataSource: KotlinScriptEntity if (!getEntityData().isDependenciesInitialized()) { error("Field KotlinScriptEntity#dependencies should be initialized") } - if (!getEntityData().isSdkInitialized()) { - error("Field KotlinScriptEntity#sdk should be initialized") - } } override fun connectionIdList(): List { @@ -122,6 +122,10 @@ internal class KotlinScriptEntityImpl(private val dataSource: KotlinScriptEntity if (collection_dependencies is MutableWorkspaceList<*>) { collection_dependencies.cleanModificationUpdateAction() } + val collection_reports = getEntityData().reports + if (collection_reports is MutableWorkspaceList<*>) { + collection_reports.cleanModificationUpdateAction() + } } // Relabeling code, move information from dataSource to this builder @@ -130,7 +134,9 @@ internal class KotlinScriptEntityImpl(private val dataSource: KotlinScriptEntity if (this.entitySource != dataSource.entitySource) this.entitySource = dataSource.entitySource if (this.virtualFileUrl != dataSource.virtualFileUrl) this.virtualFileUrl = dataSource.virtualFileUrl if (this.dependencies != dataSource.dependencies) this.dependencies = dataSource.dependencies.toMutableList() - if (this.sdk != dataSource.sdk) this.sdk = dataSource.sdk + if (this.configuration != dataSource?.configuration) this.configuration = dataSource.configuration + if (this.sdkId != dataSource?.sdkId) this.sdkId = dataSource.sdkId + if (this.reports != dataSource.reports) this.reports = dataSource.reports.toMutableList() updateChildToParentReferences(parents) } @@ -176,15 +182,46 @@ internal class KotlinScriptEntityImpl(private val dataSource: KotlinScriptEntity dependenciesUpdater.invoke(value) } - override var sdk: ModuleDependencyItem - get() = getEntityData().sdk + override var configuration: ScriptCompilationConfigurationEntity? + get() = getEntityData().configuration set(value) { checkModificationAllowed() - getEntityData(true).sdk = value - changedProperty.add("sdk") + getEntityData(true).configuration = value + changedProperty.add("configuration") } + override var sdkId: SdkId? + get() = getEntityData().sdkId + set(value) { + checkModificationAllowed() + getEntityData(true).sdkId = value + changedProperty.add("sdkId") + + } + + private val reportsUpdater: (value: List) -> Unit = { value -> + + changedProperty.add("reports") + } + override var reports: MutableList + get() { + val collection_reports = getEntityData().reports + if (collection_reports !is MutableWorkspaceList) return collection_reports + if (diff == null || modifiable.get()) { + collection_reports.setModificationUpdateAction(reportsUpdater) + } + else { + collection_reports.cleanModificationUpdateAction() + } + return collection_reports + } + set(value) { + checkModificationAllowed() + getEntityData(true).reports = value + reportsUpdater.invoke(value) + } + override fun getEntityClass(): Class = KotlinScriptEntity::class.java } } @@ -193,32 +230,23 @@ internal class KotlinScriptEntityImpl(private val dataSource: KotlinScriptEntity internal class KotlinScriptEntityData : WorkspaceEntityData(), SoftLinkable { lateinit var virtualFileUrl: VirtualFileUrl lateinit var dependencies: MutableList - lateinit var sdk: ModuleDependencyItem + var configuration: ScriptCompilationConfigurationEntity? = null + var sdkId: SdkId? = null + var reports: MutableList = listOf().toMutableWorkspaceList() internal fun isVirtualFileUrlInitialized(): Boolean = ::virtualFileUrl.isInitialized internal fun isDependenciesInitialized(): Boolean = ::dependencies.isInitialized - internal fun isSdkInitialized(): Boolean = ::sdk.isInitialized override fun getLinks(): Set> { val result = HashSet>() for (item in dependencies) { result.add(item) } - val _sdk = sdk - when (_sdk) { - is InheritedSdkDependency -> { - } - is LibraryDependency -> { - result.add(_sdk.library) - } - is ModuleDependency -> { - result.add(_sdk.module) - } - is ModuleSourceDependency -> { - } - is SdkDependency -> { - result.add(_sdk.sdk) - } + val optionalLink_sdkId = sdkId + if (optionalLink_sdkId != null) { + result.add(optionalLink_sdkId) + } + for (item in reports) { } return result } @@ -227,21 +255,11 @@ internal class KotlinScriptEntityData : WorkspaceEntityData( for (item in dependencies) { index.index(this, item) } - val _sdk = sdk - when (_sdk) { - is InheritedSdkDependency -> { - } - is LibraryDependency -> { - index.index(this, _sdk.library) - } - is ModuleDependency -> { - index.index(this, _sdk.module) - } - is ModuleSourceDependency -> { - } - is SdkDependency -> { - index.index(this, _sdk.sdk) - } + val optionalLink_sdkId = sdkId + if (optionalLink_sdkId != null) { + index.index(this, optionalLink_sdkId) + } + for (item in reports) { } } @@ -254,31 +272,15 @@ internal class KotlinScriptEntityData : WorkspaceEntityData( index.index(this, item) } } - val _sdk = sdk - when (_sdk) { - is InheritedSdkDependency -> { - } - is LibraryDependency -> { - val removedItem__sdk_library = mutablePreviousSet.remove(_sdk.library) - if (!removedItem__sdk_library) { - index.index(this, _sdk.library) - } - } - is ModuleDependency -> { - val removedItem__sdk_module = mutablePreviousSet.remove(_sdk.module) - if (!removedItem__sdk_module) { - index.index(this, _sdk.module) - } - } - is ModuleSourceDependency -> { - } - is SdkDependency -> { - val removedItem__sdk_sdk = mutablePreviousSet.remove(_sdk.sdk) - if (!removedItem__sdk_sdk) { - index.index(this, _sdk.sdk) - } + val optionalLink_sdkId = sdkId + if (optionalLink_sdkId != null) { + val removedItem_optionalLink_sdkId = mutablePreviousSet.remove(optionalLink_sdkId) + if (!removedItem_optionalLink_sdkId) { + index.index(this, optionalLink_sdkId) } } + for (item in reports) { + } for (removed in mutablePreviousSet) { index.remove(this, removed) } @@ -304,59 +306,21 @@ internal class KotlinScriptEntityData : WorkspaceEntityData( if (dependencies_data != null) { dependencies = dependencies_data as MutableList } - val _sdk = sdk - val res_sdk = when (_sdk) { - is InheritedSdkDependency -> { - _sdk + var sdkId_data_optional = if (sdkId != null) { + val sdkId___data = if (sdkId!! == oldLink) { + changed = true + newLink as SdkId } - is LibraryDependency -> { - val _sdk_library_data = if (_sdk.library == oldLink) { - changed = true - newLink as LibraryId - } - else { - null - } - var _sdk_data = _sdk - if (_sdk_library_data != null) { - _sdk_data = _sdk_data.copy(library = _sdk_library_data) - } - _sdk_data - } - is ModuleDependency -> { - val _sdk_module_data = if (_sdk.module == oldLink) { - changed = true - newLink as ModuleId - } - else { - null - } - var _sdk_data = _sdk - if (_sdk_module_data != null) { - _sdk_data = _sdk_data.copy(module = _sdk_module_data) - } - _sdk_data - } - is ModuleSourceDependency -> { - _sdk - } - is SdkDependency -> { - val _sdk_sdk_data = if (_sdk.sdk == oldLink) { - changed = true - newLink as SdkId - } - else { - null - } - var _sdk_data = _sdk - if (_sdk_sdk_data != null) { - _sdk_data = _sdk_data.copy(sdk = _sdk_sdk_data) - } - _sdk_data + else { + null } + sdkId___data } - if (res_sdk != null) { - sdk = res_sdk + else { + null + } + if (sdkId_data_optional != null) { + sdkId = sdkId_data_optional } return changed } @@ -387,6 +351,7 @@ internal class KotlinScriptEntityData : WorkspaceEntityData( val clonedEntity = super.clone() clonedEntity as KotlinScriptEntityData clonedEntity.dependencies = clonedEntity.dependencies.toMutableWorkspaceList() + clonedEntity.reports = clonedEntity.reports.toMutableWorkspaceList() return clonedEntity } @@ -395,7 +360,10 @@ internal class KotlinScriptEntityData : WorkspaceEntityData( } override fun createDetachedEntity(parents: List>): ModifiableWorkspaceEntity<*> { - return KotlinScriptEntity(virtualFileUrl, dependencies, sdk, entitySource) { + return KotlinScriptEntity(virtualFileUrl, dependencies, entitySource) { + this.configuration = this@KotlinScriptEntityData.configuration + this.sdkId = this@KotlinScriptEntityData.sdkId + this.reports = this@KotlinScriptEntityData.reports.toMutableWorkspaceList() } } @@ -413,7 +381,9 @@ internal class KotlinScriptEntityData : WorkspaceEntityData( if (this.entitySource != other.entitySource) return false if (this.virtualFileUrl != other.virtualFileUrl) return false if (this.dependencies != other.dependencies) return false - if (this.sdk != other.sdk) return false + if (this.configuration != other.configuration) return false + if (this.sdkId != other.sdkId) return false + if (this.reports != other.reports) return false return true } @@ -425,7 +395,9 @@ internal class KotlinScriptEntityData : WorkspaceEntityData( if (this.virtualFileUrl != other.virtualFileUrl) return false if (this.dependencies != other.dependencies) return false - if (this.sdk != other.sdk) return false + if (this.configuration != other.configuration) return false + if (this.sdkId != other.sdkId) return false + if (this.reports != other.reports) return false return true } @@ -433,7 +405,9 @@ internal class KotlinScriptEntityData : WorkspaceEntityData( var result = entitySource.hashCode() result = 31 * result + virtualFileUrl.hashCode() result = 31 * result + dependencies.hashCode() - result = 31 * result + sdk.hashCode() + result = 31 * result + configuration.hashCode() + result = 31 * result + sdkId.hashCode() + result = 31 * result + reports.hashCode() return result } @@ -441,7 +415,9 @@ internal class KotlinScriptEntityData : WorkspaceEntityData( var result = javaClass.hashCode() result = 31 * result + virtualFileUrl.hashCode() result = 31 * result + dependencies.hashCode() - result = 31 * result + sdk.hashCode() + result = 31 * result + configuration.hashCode() + result = 31 * result + sdkId.hashCode() + result = 31 * result + reports.hashCode() return result } } diff --git a/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/impl/KotlinScriptLibraryEntityImpl.kt b/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/impl/KotlinScriptLibraryEntityImpl.kt index 1148518f1735..28ec8e5fa7a3 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/impl/KotlinScriptLibraryEntityImpl.kt +++ b/plugins/kotlin/base/scripting/scripting.k2/gen/org/jetbrains/kotlin/idea/core/script/k2/modules/impl/KotlinScriptLibraryEntityImpl.kt @@ -2,17 +2,7 @@ package org.jetbrains.kotlin.idea.core.script.k2.modules.impl import com.intellij.openapi.util.NlsSafe -import com.intellij.platform.workspace.storage.ConnectionId -import com.intellij.platform.workspace.storage.EntitySource -import com.intellij.platform.workspace.storage.EntityType -import com.intellij.platform.workspace.storage.GeneratedCodeApiVersion -import com.intellij.platform.workspace.storage.GeneratedCodeImplVersion -import com.intellij.platform.workspace.storage.ModifiableWorkspaceEntity -import com.intellij.platform.workspace.storage.MutableEntityStorage -import com.intellij.platform.workspace.storage.SymbolicEntityId -import com.intellij.platform.workspace.storage.WorkspaceEntity -import com.intellij.platform.workspace.storage.WorkspaceEntityInternalApi -import com.intellij.platform.workspace.storage.WorkspaceEntityWithSymbolicId +import com.intellij.platform.workspace.storage.* import com.intellij.platform.workspace.storage.impl.ModifiableWorkspaceEntityBase import com.intellij.platform.workspace.storage.impl.WorkspaceEntityBase import com.intellij.platform.workspace.storage.impl.WorkspaceEntityData diff --git a/plugins/kotlin/base/scripting/scripting.k2/resources/intellij.kotlin.base.scripting.xml b/plugins/kotlin/base/scripting/scripting.k2/resources/intellij.kotlin.base.scripting.xml index f6d392c69e73..1a3ed36260d5 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/resources/intellij.kotlin.base.scripting.xml +++ b/plugins/kotlin/base/scripting/scripting.k2/resources/intellij.kotlin.base.scripting.xml @@ -13,11 +13,6 @@ interface="org.jetbrains.kotlin.idea.core.script.k2.modules.K2IdeScriptAdditionalIdeaDependenciesProvider" dynamic="true"/> - diff --git a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/DefaultScriptConfigurationHandler.kt b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/DefaultScriptConfigurationHandler.kt index 0e876a2d9cbc..bcdd6012671d 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/DefaultScriptConfigurationHandler.kt +++ b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/DefaultScriptConfigurationHandler.kt @@ -9,8 +9,6 @@ import com.intellij.openapi.roots.ProjectRootManager import com.intellij.openapi.vfs.VirtualFile import com.intellij.platform.backend.workspace.WorkspaceModel import com.intellij.platform.backend.workspace.toVirtualFileUrl -import com.intellij.platform.workspace.jps.entities.InheritedSdkDependency -import com.intellij.platform.workspace.jps.entities.SdkDependency import com.intellij.platform.workspace.jps.entities.SdkId import com.intellij.platform.workspace.storage.EntitySource import com.intellij.platform.workspace.storage.MutableEntityStorage @@ -69,7 +67,7 @@ open class DefaultScriptConfigurationHandler( project.service().attachReports(virtualFile, result.reports) - return ScriptConfigurationWithSdk(result, sdk) + return ScriptConfigurationWithSdk(result, sdk?.let { SdkId(it.name, it.sdkType.name) }) } override suspend fun updateWorkspaceModel(configurationPerFile: Map) { @@ -105,12 +103,11 @@ open class DefaultScriptConfigurationHandler( result addEntity KotlinScriptLibraryEntity(classes, sources, DefaultScriptEntitySource) } - val sdk = configurationWithSdk.sdk?.let { SdkDependency(SdkId(it.name, it.sdkType.name)) } - result addEntity KotlinScriptEntity( - scriptUrl, libraryIds.toList(), - sdk ?: InheritedSdkDependency, DefaultScriptEntitySource - ) + scriptUrl, libraryIds.toList(), DefaultScriptEntitySource + ) { + this.sdkId = configurationWithSdk.sdkId + } } return result diff --git a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/MainKtsScriptConfigurationProvider.kt b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/MainKtsScriptConfigurationProvider.kt index ca3397103059..428168314975 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/MainKtsScriptConfigurationProvider.kt +++ b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/MainKtsScriptConfigurationProvider.kt @@ -4,12 +4,9 @@ package org.jetbrains.kotlin.idea.core.script.k2.configurations import com.google.common.collect.TreeMultimap import com.google.common.graph.Traverser import com.intellij.openapi.application.smartReadAction -import com.intellij.openapi.application.writeAction import com.intellij.openapi.components.Service import com.intellij.openapi.components.service import com.intellij.openapi.project.Project -import com.intellij.openapi.projectRoots.JavaSdk -import com.intellij.openapi.projectRoots.ProjectJdkTable import com.intellij.openapi.roots.ProjectRootManager import com.intellij.openapi.vfs.VirtualFile import com.intellij.platform.backend.workspace.WorkspaceModel @@ -18,11 +15,10 @@ import com.intellij.platform.backend.workspace.workspaceModel import com.intellij.platform.ide.progress.withBackgroundProgress import com.intellij.platform.util.progress.ProgressReporter import com.intellij.platform.util.progress.reportProgressScope -import com.intellij.platform.workspace.jps.entities.InheritedSdkDependency +import com.intellij.platform.workspace.jps.entities.SdkId import com.intellij.platform.workspace.storage.EntitySource import com.intellij.platform.workspace.storage.MutableEntityStorage import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch import org.jetbrains.kotlin.idea.core.script.k2.configurations.DefaultScriptConfigurationHandler.DefaultScriptEntitySource import org.jetbrains.kotlin.idea.core.script.k2.modules.KotlinScriptEntity import org.jetbrains.kotlin.idea.core.script.k2.modules.KotlinScriptLibraryEntity @@ -86,13 +82,6 @@ class MainKtsScriptConfigurationProvider(val project: Project, val coroutineScop private suspend fun resolveMainKtsConfiguration(mainKts: VirtualFile, definition: ScriptDefinition): ScriptConfigurationWithSdk { val scriptSource = VirtualFileScriptSource(mainKts) val sdk = ProjectRootManager.getInstance(project).projectSdk - ?: ProjectJdkTable.getInstance().findMostRecentSdkOfType(JavaSdk.getInstance())?.also { - coroutineScope.launch { - writeAction { - ProjectRootManager.getInstance(project).projectSdk = it - } - } - } val providedConfiguration = sdk?.homePath?.let { jdkHome -> definition.compilationConfiguration.with { @@ -115,7 +104,7 @@ class MainKtsScriptConfigurationProvider(val project: Project, val coroutineScop } } - return ScriptConfigurationWithSdk(result, sdk) + return ScriptConfigurationWithSdk(result, sdk?.let { SdkId(it.name, it.sdkType.name) }) } override suspend fun updateWorkspaceModel(configurationPerFile: Map) { @@ -162,8 +151,10 @@ class MainKtsScriptConfigurationProvider(val project: Project, val coroutineScop } storageToUpdate addEntity KotlinScriptEntity( - virtualFileUrl, libraryIds.toList(), InheritedSdkDependency, MainKtsKotlinScriptEntitySource - ) + virtualFileUrl, libraryIds.toList(), MainKtsKotlinScriptEntitySource + ) { + this.sdkId = configurationWithSdk.sdkId + } } return storageToUpdate diff --git a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/ScriptConfigurationWithSdk.kt b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/ScriptConfigurationWithSdk.kt index 3f5f7219d2df..f7c5a4015a7c 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/ScriptConfigurationWithSdk.kt +++ b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/ScriptConfigurationWithSdk.kt @@ -1,7 +1,7 @@ // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.core.script.k2.configurations -import com.intellij.openapi.projectRoots.Sdk +import com.intellij.platform.workspace.jps.entities.SdkId import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper import kotlin.script.experimental.api.ResultWithDiagnostics @@ -9,7 +9,7 @@ typealias ScriptConfiguration = ResultWithDiagnostics, val sources: Collection, - val sdk: Sdk?, + val sdk: SdkEntity?, ) { companion object { val EMPTY = ScriptDependencies(setOf(), setOf(), null) @@ -61,10 +61,10 @@ class ScriptConfigurationsProviderImpl(project: Project, val coroutineScope: Cor val (classes, sources) = snapshot.entities(KotlinScriptLibraryEntity::class.java).toClassesSources() val (sdkClasses, sdkSources) = - snapshot.entities(KotlinScriptEntity::class.java).mapNotNull { it.jdk } + snapshot.entities(KotlinScriptEntity::class.java).mapNotNull { entity -> entity.sdkId?.let { snapshot.resolve(it) } } .fold(mutableSetOf() to mutableSetOf()) { (accClasses, accSources), jdk -> - accClasses += jdk.rootProvider.getFiles(OrderRootType.CLASSES).toList() - accSources += jdk.rootProvider.getFiles(OrderRootType.SOURCES).toList() + accClasses += jdk.roots.filter { it.type == classesTypeId }.mapNotNull { it.url.virtualFile } + accClasses += jdk.roots.filter { it.type == sourcesTypeId }.mapNotNull { it.url.virtualFile } accClasses to accSources } @@ -82,15 +82,16 @@ class ScriptConfigurationsProviderImpl(project: Project, val coroutineScope: Cor } override fun getScriptDependenciesClassFilesScope(virtualFile: VirtualFile): GlobalSearchScope { - val (classes, _, sdk) = virtualFile.currentDependencies - val sdkClasses = sdk?.rootProvider?.getFiles(OrderRootType.CLASSES)?.toList() ?: emptyList() - return compose(classes + sdkClasses) + val sdk = virtualFile.currentDependencies.sdk + val sdkClasses = sdk?.roots?.filter { it.type == classesTypeId }?.mapNotNull { it.url.virtualFile } ?: emptyList() + return compose(virtualFile.currentDependencies.classes + sdkClasses) } override fun getScriptDependenciesClassFiles(virtualFile: VirtualFile): Collection = virtualFile.currentDependencies.classes - override fun getScriptSdk(virtualFile: VirtualFile): Sdk? = virtualFile.currentDependencies.sdk + override fun getScriptSdk(virtualFile: VirtualFile): Sdk? = + virtualFile.currentDependencies.sdk?.let { ModifiableRootModelBridge.findSdk(it.name, it.type) } private val VirtualFile.currentDependencies: ScriptDependencies get() { @@ -106,7 +107,7 @@ class ScriptConfigurationsProviderImpl(project: Project, val coroutineScope: Cor .toClassesSources() return ScriptDependencies( - classes, sources, entity.jdk + classes, sources, entity.sdkId?.let { snapshot.resolve(it) } ) } @@ -117,13 +118,6 @@ class ScriptConfigurationsProviderImpl(project: Project, val coroutineScope: Cor accClasses to accSources } - private val KotlinScriptEntity.jdk: Sdk? - get() = when (val sdkDependency = sdk) { - is SdkDependency -> ProjectJdkTable.getInstance().findJdk(sdkDependency.sdk.name, sdkDependency.sdk.type) - is InheritedSdkDependency -> ProjectRootManager.getInstance(project).projectSdk - else -> null - } - override fun getScriptConfigurationResult(file: KtFile): ScriptCompilationConfigurationResult? { val definition = file.findScriptDefinition() ?: return null return getConfigurationSupplier(definition).get(file.alwaysVirtualFile)?.scriptConfiguration @@ -135,6 +129,9 @@ class ScriptConfigurationsProviderImpl(project: Project, val coroutineScope: Cor } companion object { + private val classesTypeId = SdkRootTypeId(OrderRootType.CLASSES.customName) + private val sourcesTypeId = SdkRootTypeId(OrderRootType.SOURCES.customName) + fun getInstance(project: Project): ScriptConfigurationsProviderImpl = project.service() as ScriptConfigurationsProviderImpl } diff --git a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/scriptProjectModelUtils.kt b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/scriptProjectModelUtils.kt index a6bd02260cf8..2f5e4378b10d 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/scriptProjectModelUtils.kt +++ b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/configurations/scriptProjectModelUtils.kt @@ -11,11 +11,7 @@ import com.intellij.util.io.URLUtil import org.jetbrains.annotations.ApiStatus import org.jetbrains.kotlin.idea.core.script.k2.modules.KotlinScriptLibraryEntityId import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition -import kotlin.script.experimental.api.ScriptCompilationConfiguration -import kotlin.script.experimental.api.ScriptDependency -import kotlin.script.experimental.api.dependencies -import kotlin.script.experimental.api.dependenciesSources -import kotlin.script.experimental.api.ide +import kotlin.script.experimental.api.* import kotlin.script.experimental.jvm.JvmDependency import kotlin.script.experimental.util.PropertiesCollection @@ -85,4 +81,4 @@ private fun Iterable.toVirtualFileUrls(urlManager: VirtualFile .sorted() .map { it.toVirtualFileUrl(urlManager) } -private fun PropertiesCollection.getOrEmpty(key: PropertiesCollection.Key>): List = get(key).orEmpty() \ No newline at end of file +private fun PropertiesCollection.getOrEmpty(key: PropertiesCollection.Key>): List = get(key).orEmpty() diff --git a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/highlighting/DefaultScriptResolutionStrategy.kt b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/highlighting/DefaultScriptResolutionStrategy.kt index f307b1582179..ce3f0370713d 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/highlighting/DefaultScriptResolutionStrategy.kt +++ b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/highlighting/DefaultScriptResolutionStrategy.kt @@ -7,7 +7,6 @@ import com.intellij.openapi.application.edtWriteAction import com.intellij.openapi.application.readAction import com.intellij.openapi.components.Service import com.intellij.openapi.components.service -import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.fileEditor.FileEditor import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.project.Project @@ -18,11 +17,10 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.launch import org.jetbrains.kotlin.analysis.api.platform.modification.publishGlobalModuleStateModificationEvent import org.jetbrains.kotlin.analysis.api.platform.modification.publishGlobalScriptModuleStateModificationEvent -import org.jetbrains.kotlin.idea.core.script.k2.configurations.ScriptConfigurationsProviderImpl import org.jetbrains.kotlin.idea.core.script.k2.configurations.getConfigurationResolver import org.jetbrains.kotlin.idea.core.script.k2.configurations.getWorkspaceModelManager -import org.jetbrains.kotlin.idea.core.script.v1.alwaysVirtualFile import org.jetbrains.kotlin.idea.core.script.v1.ScriptDependenciesModificationTracker +import org.jetbrains.kotlin.idea.core.script.v1.alwaysVirtualFile import org.jetbrains.kotlin.idea.core.script.v1.scriptingDebugLog import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition @@ -52,11 +50,9 @@ class DefaultScriptResolutionStrategy(val project: Project, val coroutineScope: } fun execute(vararg ktFiles: KtFile): Job { - val definitionByFile = ktFiles - .filterNot { KotlinScripDeferredResolutionPolicy.shouldDeferResolution(project, it.virtualFile) } - .associateWith { - findScriptDefinition(project, KtFileScriptSource(it)) - } + val definitionByFile = ktFiles.associateWith { + findScriptDefinition(project, KtFileScriptSource(it)) + } scriptingDebugLog { val baseDirPath = project.basePath?.toNioPathOrNull() @@ -89,6 +85,10 @@ class DefaultScriptResolutionStrategy(val project: Project, val coroutineScope: projectModelUpdater.updateWorkspaceModel(configurationPerVirtualFile) + restartHighlighting(definitionByFile.keys) + } + + suspend fun restartHighlighting(scripts: Iterable) { edtWriteAction { project.publishGlobalModuleStateModificationEvent() project.publishGlobalScriptModuleStateModificationEvent() @@ -102,7 +102,7 @@ class DefaultScriptResolutionStrategy(val project: Project, val coroutineScope: } if (project.isOpen && !project.isDisposed) { - for (ktFile in definitionByFile.keys) { + for (ktFile in scripts) { if (ktFile.alwaysVirtualFile !in filesInEditors) continue if (project.isOpen && !project.isDisposed) { readAction { @@ -116,8 +116,5 @@ class DefaultScriptResolutionStrategy(val project: Project, val coroutineScope: companion object { @JvmStatic fun getInstance(project: Project): DefaultScriptResolutionStrategy = project.service() - - private val logger: Logger - get() = Logger.getInstance(DefaultScriptResolutionStrategy::class.java) } } \ No newline at end of file diff --git a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/highlighting/KotlinScripDeferredResolutionPolicy.kt b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/highlighting/KotlinScripDeferredResolutionPolicy.kt deleted file mode 100644 index 4c3d7e8f13d6..000000000000 --- a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/highlighting/KotlinScripDeferredResolutionPolicy.kt +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package org.jetbrains.kotlin.idea.core.script.k2.highlighting - -import com.intellij.openapi.extensions.ProjectExtensionPointName -import com.intellij.openapi.project.Project -import com.intellij.openapi.vfs.VirtualFile - -/** - * Regular scripts (.kts) do not support external dependencies, so there is no need to postpone resolving. - * However, certain plugins (e.g., Gradle) may apply their own approach to scripting analysis, which occasionally doesn't imply lazy evaluation. - */ -interface KotlinScripDeferredResolutionPolicy { - companion object { - val EP_NAME: ProjectExtensionPointName = - ProjectExtensionPointName("org.jetbrains.kotlin.kotlinScripDeferredResolutionPolicy") - - fun shouldDeferResolution(project: Project, script: VirtualFile): Boolean = - EP_NAME.getExtensions(project).any { it.shouldDeferResolution(script) } - } - - fun shouldDeferResolution(script: VirtualFile): Boolean = false -} \ No newline at end of file diff --git a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/highlighting/ScriptHighlightingExtension.kt b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/highlighting/ScriptHighlightingExtension.kt index ec9a35eba818..6718ea3a5857 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/highlighting/ScriptHighlightingExtension.kt +++ b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/highlighting/ScriptHighlightingExtension.kt @@ -5,7 +5,7 @@ import org.jetbrains.kotlin.idea.core.script.shared.AbstractKotlinScriptHighligh import org.jetbrains.kotlin.psi.KtFile class ScriptHighlightingExtension : AbstractKotlinScriptHighlightingExtension { - override fun calculateShouldHighlightScript(file: KtFile): Boolean { + override fun shouldHighlight(file: KtFile): Boolean { val strategy = DefaultScriptResolutionStrategy.getInstance(file.project) return strategy.isReadyToHighlight(file).also { isReady -> if (!isReady) strategy.execute(file) } } diff --git a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptEntity.kt b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptEntity.kt index 907261a06887..85c289797e97 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptEntity.kt +++ b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptEntity.kt @@ -1,10 +1,9 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.core.script.k2.modules -import com.intellij.platform.workspace.jps.entities.InheritedSdkDependency -import com.intellij.platform.workspace.jps.entities.ModuleDependencyItem -import com.intellij.platform.workspace.jps.entities.SdkDependency +import com.intellij.platform.workspace.jps.entities.SdkId import com.intellij.platform.workspace.storage.* +import com.intellij.platform.workspace.storage.annotations.Default import com.intellij.platform.workspace.storage.impl.containers.toMutableWorkspaceList import com.intellij.platform.workspace.storage.url.VirtualFileUrl @@ -12,5 +11,10 @@ import com.intellij.platform.workspace.storage.url.VirtualFileUrl interface KotlinScriptEntity : WorkspaceEntity { val virtualFileUrl: VirtualFileUrl val dependencies: List - val sdk: ModuleDependencyItem + val configuration: ScriptCompilationConfigurationEntity? + val sdkId: SdkId? + + @Suppress("RemoveExplicitTypeArguments") + val reports: List + @Default get() = listOf() } diff --git a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptLibraryEntity.kt b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptLibraryEntity.kt index 2be392a59a8d..db938d83a208 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptLibraryEntity.kt +++ b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/modules/KotlinScriptLibraryEntity.kt @@ -2,13 +2,7 @@ package org.jetbrains.kotlin.idea.core.script.k2.modules import com.intellij.openapi.util.NlsSafe -import com.intellij.platform.workspace.storage.EntitySource -import com.intellij.platform.workspace.storage.EntityType -import com.intellij.platform.workspace.storage.GeneratedCodeApiVersion -import com.intellij.platform.workspace.storage.MutableEntityStorage -import com.intellij.platform.workspace.storage.SymbolicEntityId -import com.intellij.platform.workspace.storage.WorkspaceEntity -import com.intellij.platform.workspace.storage.WorkspaceEntityWithSymbolicId +import com.intellij.platform.workspace.storage.* import com.intellij.platform.workspace.storage.impl.containers.toMutableWorkspaceList import com.intellij.platform.workspace.storage.url.VirtualFileUrl diff --git a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/modules/modules.kt b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/modules/modules.kt index c028f4941ff2..1e24d6ab8bd9 100644 --- a/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/modules/modules.kt +++ b/plugins/kotlin/base/scripting/scripting.k2/src/org/jetbrains/kotlin/idea/core/script/k2/modules/modules.kt @@ -11,6 +11,9 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import org.jetbrains.kotlin.idea.core.script.k2.configurations.ScriptConfigurationWithSdk import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition +import kotlin.script.experimental.api.ScriptDiagnostic +import kotlin.script.experimental.api.ScriptDiagnostic.Severity +import kotlin.script.experimental.api.SourceCode interface ScriptWorkspaceModelManager { suspend fun updateWorkspaceModel(configurationPerFile: Map) @@ -51,4 +54,60 @@ class KotlinScriptModuleManager(private val project: Project, private val corout @JvmStatic fun getInstance(project: Project): KotlinScriptModuleManager = project.service() } -} \ No newline at end of file +} + + +data class ScriptingHostConfigurationEntity(val data: ByteArray) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as ScriptingHostConfigurationEntity + + return data.contentEquals(other.data) + } + + override fun hashCode(): Int = data.contentHashCode() +} + +data class ScriptEvaluationConfigurationEntity(val data: ByteArray) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as ScriptEvaluationConfigurationEntity + + return data.contentEquals(other.data) + } + + override fun hashCode(): Int = data.contentHashCode() +} + +data class ScriptCompilationConfigurationEntity(val data: ByteArray) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as ScriptCompilationConfigurationEntity + + return data.contentEquals(other.data) + } + + override fun hashCode(): Int = data.contentHashCode() +} + +data class ScriptDiagnosticData( + val code: Int, + val message: String, + val severity: Severity = Severity.ERROR, + val sourcePath: String? = null, + val location: SourceCode.Location? = null, + val exceptionMessage: String? = null +) { + fun toScriptDiagnostic(): ScriptDiagnostic = ScriptDiagnostic( + code, message, severity, sourcePath, location, Throwable(exceptionMessage) + ) +} + +fun ScriptDiagnostic.toData(): ScriptDiagnosticData = + ScriptDiagnosticData(code, message, severity, sourcePath, location, exception?.message) diff --git a/plugins/kotlin/base/scripting/scripting.shared/src/org/jetbrains/kotlin/idea/core/script/shared/AbstractKotlinScriptHighlightingExtension.kt b/plugins/kotlin/base/scripting/scripting.shared/src/org/jetbrains/kotlin/idea/core/script/shared/AbstractKotlinScriptHighlightingExtension.kt index 75da51137f9c..94f442e1b033 100644 --- a/plugins/kotlin/base/scripting/scripting.shared/src/org/jetbrains/kotlin/idea/core/script/shared/AbstractKotlinScriptHighlightingExtension.kt +++ b/plugins/kotlin/base/scripting/scripting.shared/src/org/jetbrains/kotlin/idea/core/script/shared/AbstractKotlinScriptHighlightingExtension.kt @@ -14,26 +14,26 @@ import org.jetbrains.kotlin.psi.KtFile import kotlin.script.experimental.api.ScriptDiagnostic interface AbstractKotlinScriptHighlightingExtension : KotlinScriptHighlightingExtension { - fun calculateShouldHighlightScript(file: KtFile): Boolean + fun shouldHighlight(file: KtFile): Boolean override fun shouldHighlightScript(file: KtFile): Boolean { val project = file.project return CachedValuesManager.getManager(file.project).getCachedValue(file) { create( - file.calculateShouldHighlightScript(file), + file.calculateShouldHighlightScript(), ProjectRootModificationTracker.getInstance(project), ScriptDependenciesModificationTracker.getInstance(project) ) } } - private fun KtFile.calculateShouldHighlightScript(file: KtFile): Boolean { + private fun KtFile.calculateShouldHighlightScript(): Boolean { if (shouldDefinitelyHighlight()) return true if (KotlinPlatformUtils.isCidr) return false - if (getScriptReports(file).any { it.severity == ScriptDiagnostic.Severity.FATAL }) return false + if (getScriptReports(this).any { it.severity == ScriptDiagnostic.Severity.FATAL }) return false return RootKindFilter.projectSources.copy(includeScriptsOutsideSourceRoots = true) - .matches(this) && this@AbstractKotlinScriptHighlightingExtension.calculateShouldHighlightScript(this) + .matches(this) && shouldHighlight(this) } } \ No newline at end of file diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/BUILD.bazel b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/BUILD.bazel index bec4930a313d..727cc5278603 100644 --- a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/BUILD.bazel +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/BUILD.bazel @@ -29,7 +29,7 @@ jvm_library( name = "kotlin-gradle-scripting", module_name = "intellij.kotlin.gradle.scripting", visibility = ["//visibility:public"], - srcs = glob(["src/**/*.kt", "src/**/*.java", "src/**/*.form"], allow_empty = True), + srcs = glob(["src/**/*.kt", "src/**/*.java", "src/**/*.form", "gen/**/*.kt", "gen/**/*.java"], allow_empty = True), resources = [ ":kotlin-gradle-scripting_resources", ":kotlin-gradle-scripting_resources_1", @@ -73,6 +73,7 @@ jvm_library( "//java/openapi:java", "//platform/platform-impl:ide-impl", "//plugins/kotlin/gradle/gradle-tooling/impl", + "//plugins/kotlin/highlighting/highlighting-shared:kotlin-highlighting-shared", ] ) @@ -149,6 +150,7 @@ jvm_library( "//platform/platform-impl:ide-impl", "//plugins/kotlin/gradle/gradle-tooling/impl", "//plugins/kotlin/gradle/gradle-tooling/impl:impl_test_lib", + "//plugins/kotlin/highlighting/highlighting-shared:kotlin-highlighting-shared", ] ) ### auto-generated section `build intellij.kotlin.gradle.scripting` end diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/gen/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/GradleScriptDefinitionEntityApi.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/gen/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/GradleScriptDefinitionEntityApi.kt new file mode 100644 index 000000000000..be41f6bad995 --- /dev/null +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/gen/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/GradleScriptDefinitionEntityApi.kt @@ -0,0 +1,52 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel + +import com.intellij.openapi.util.NlsSafe +import com.intellij.platform.workspace.storage.* +import org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptCompilationConfigurationEntity +import org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptEvaluationConfigurationEntity +import org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptingHostConfigurationEntity + +@GeneratedCodeApiVersion(3) +interface ModifiableGradleScriptDefinitionEntity : ModifiableWorkspaceEntity { + override var entitySource: EntitySource + var definitionId: String + var compilationConfiguration: ScriptCompilationConfigurationEntity + var hostConfiguration: ScriptingHostConfigurationEntity + var evaluationConfiguration: ScriptEvaluationConfigurationEntity? +} + +internal object GradleScriptDefinitionEntityType : EntityType() { + override val entityClass: Class get() = GradleScriptDefinitionEntity::class.java + operator fun invoke( + definitionId: String, + compilationConfiguration: ScriptCompilationConfigurationEntity, + hostConfiguration: ScriptingHostConfigurationEntity, + entitySource: EntitySource, + init: (ModifiableGradleScriptDefinitionEntity.() -> Unit)? = null, + ): ModifiableGradleScriptDefinitionEntity { + val builder = builder() + builder.definitionId = definitionId + builder.compilationConfiguration = compilationConfiguration + builder.hostConfiguration = hostConfiguration + builder.entitySource = entitySource + init?.invoke(builder) + return builder + } +} + +fun MutableEntityStorage.modifyGradleScriptDefinitionEntity( + entity: GradleScriptDefinitionEntity, + modification: ModifiableGradleScriptDefinitionEntity.() -> Unit, +): GradleScriptDefinitionEntity = modifyEntity(ModifiableGradleScriptDefinitionEntity::class.java, entity, modification) + +@JvmOverloads +@JvmName("createGradleScriptDefinitionEntity") +fun GradleScriptDefinitionEntity( + definitionId: String, + compilationConfiguration: ScriptCompilationConfigurationEntity, + hostConfiguration: ScriptingHostConfigurationEntity, + entitySource: EntitySource, + init: (ModifiableGradleScriptDefinitionEntity.() -> Unit)? = null, +): ModifiableGradleScriptDefinitionEntity = + GradleScriptDefinitionEntityType(definitionId, compilationConfiguration, hostConfiguration, entitySource, init) diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/gen/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/impl/GradleScriptDefinitionEntityImpl.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/gen/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/impl/GradleScriptDefinitionEntityImpl.kt new file mode 100644 index 000000000000..02ef5024cb57 --- /dev/null +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/gen/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/impl/GradleScriptDefinitionEntityImpl.kt @@ -0,0 +1,270 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.impl + +import com.intellij.openapi.util.NlsSafe +import com.intellij.platform.workspace.storage.* +import com.intellij.platform.workspace.storage.impl.ModifiableWorkspaceEntityBase +import com.intellij.platform.workspace.storage.impl.WorkspaceEntityBase +import com.intellij.platform.workspace.storage.impl.WorkspaceEntityData +import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentation +import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi +import com.intellij.platform.workspace.storage.metadata.model.EntityMetadata +import org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.GradleScriptDefinitionEntity +import org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.GradleScriptDefinitionEntityId +import org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.ModifiableGradleScriptDefinitionEntity +import org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptCompilationConfigurationEntity +import org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptEvaluationConfigurationEntity +import org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptingHostConfigurationEntity + +@GeneratedCodeApiVersion(3) +@GeneratedCodeImplVersion(7) +@OptIn(WorkspaceEntityInternalApi::class) +internal class GradleScriptDefinitionEntityImpl(private val dataSource: GradleScriptDefinitionEntityData) : GradleScriptDefinitionEntity, WorkspaceEntityBase( + dataSource) { + + private companion object { + + + private val connections = listOf( + ) + + } + + override val symbolicId: GradleScriptDefinitionEntityId = super.symbolicId + + override val definitionId: String + get() { + readField("definitionId") + return dataSource.definitionId + } + + override val compilationConfiguration: ScriptCompilationConfigurationEntity + get() { + readField("compilationConfiguration") + return dataSource.compilationConfiguration + } + + override val hostConfiguration: ScriptingHostConfigurationEntity + get() { + readField("hostConfiguration") + return dataSource.hostConfiguration + } + + override val evaluationConfiguration: ScriptEvaluationConfigurationEntity? + get() { + readField("evaluationConfiguration") + return dataSource.evaluationConfiguration + } + + override val entitySource: EntitySource + get() { + readField("entitySource") + return dataSource.entitySource + } + + override fun connectionIdList(): List { + return connections + } + + + internal class Builder(result: GradleScriptDefinitionEntityData?) : ModifiableWorkspaceEntityBase( + result), ModifiableGradleScriptDefinitionEntity { + internal constructor() : this(GradleScriptDefinitionEntityData()) + + override fun applyToBuilder(builder: MutableEntityStorage) { + if (this.diff != null) { + if (existsInBuilder(builder)) { + this.diff = builder + return + } + else { + error("Entity GradleScriptDefinitionEntity is already created in a different builder") + } + } + + this.diff = builder + addToBuilder() + this.id = getEntityData().createEntityId() + // After adding entity data to the builder, we need to unbind it and move the control over entity data to builder + // Builder may switch to snapshot at any moment and lock entity data to modification + this.currentEntityData = null + + // Process linked entities that are connected without a builder + processLinkedEntities(builder) + checkInitialization() // TODO uncomment and check failed tests + } + + private fun checkInitialization() { + val _diff = diff + if (!getEntityData().isEntitySourceInitialized()) { + error("Field WorkspaceEntity#entitySource should be initialized") + } + if (!getEntityData().isDefinitionIdInitialized()) { + error("Field GradleScriptDefinitionEntity#definitionId should be initialized") + } + if (!getEntityData().isCompilationConfigurationInitialized()) { + error("Field GradleScriptDefinitionEntity#compilationConfiguration should be initialized") + } + if (!getEntityData().isHostConfigurationInitialized()) { + error("Field GradleScriptDefinitionEntity#hostConfiguration should be initialized") + } + } + + override fun connectionIdList(): List { + return connections + } + + // Relabeling code, move information from dataSource to this builder + override fun relabel(dataSource: WorkspaceEntity, parents: Set?) { + dataSource as GradleScriptDefinitionEntity + if (this.entitySource != dataSource.entitySource) this.entitySource = dataSource.entitySource + if (this.definitionId != dataSource.definitionId) this.definitionId = dataSource.definitionId + if (this.compilationConfiguration != dataSource.compilationConfiguration) this.compilationConfiguration = dataSource.compilationConfiguration + if (this.hostConfiguration != dataSource.hostConfiguration) this.hostConfiguration = dataSource.hostConfiguration + if (this.evaluationConfiguration != dataSource?.evaluationConfiguration) this.evaluationConfiguration = dataSource.evaluationConfiguration + updateChildToParentReferences(parents) + } + + + override var entitySource: EntitySource + get() = getEntityData().entitySource + set(value) { + checkModificationAllowed() + getEntityData(true).entitySource = value + changedProperty.add("entitySource") + + } + + override var definitionId: String + get() = getEntityData().definitionId + set(value) { + checkModificationAllowed() + getEntityData(true).definitionId = value + changedProperty.add("definitionId") + } + + override var compilationConfiguration: ScriptCompilationConfigurationEntity + get() = getEntityData().compilationConfiguration + set(value) { + checkModificationAllowed() + getEntityData(true).compilationConfiguration = value + changedProperty.add("compilationConfiguration") + + } + + override var hostConfiguration: ScriptingHostConfigurationEntity + get() = getEntityData().hostConfiguration + set(value) { + checkModificationAllowed() + getEntityData(true).hostConfiguration = value + changedProperty.add("hostConfiguration") + + } + + override var evaluationConfiguration: ScriptEvaluationConfigurationEntity? + get() = getEntityData().evaluationConfiguration + set(value) { + checkModificationAllowed() + getEntityData(true).evaluationConfiguration = value + changedProperty.add("evaluationConfiguration") + + } + + override fun getEntityClass(): Class = GradleScriptDefinitionEntity::class.java + } +} + +@OptIn(WorkspaceEntityInternalApi::class) +internal class GradleScriptDefinitionEntityData : WorkspaceEntityData() { + lateinit var definitionId: String + lateinit var compilationConfiguration: ScriptCompilationConfigurationEntity + lateinit var hostConfiguration: ScriptingHostConfigurationEntity + var evaluationConfiguration: ScriptEvaluationConfigurationEntity? = null + + internal fun isDefinitionIdInitialized(): Boolean = ::definitionId.isInitialized + internal fun isCompilationConfigurationInitialized(): Boolean = ::compilationConfiguration.isInitialized + internal fun isHostConfigurationInitialized(): Boolean = ::hostConfiguration.isInitialized + + override fun wrapAsModifiable(diff: MutableEntityStorage): ModifiableWorkspaceEntity { + val modifiable = GradleScriptDefinitionEntityImpl.Builder(null) + modifiable.diff = diff + modifiable.id = createEntityId() + return modifiable + } + + @OptIn(EntityStorageInstrumentationApi::class) + override fun createEntity(snapshot: EntityStorageInstrumentation): GradleScriptDefinitionEntity { + val entityId = createEntityId() + return snapshot.initializeEntity(entityId) { + val entity = GradleScriptDefinitionEntityImpl(this) + entity.snapshot = snapshot + entity.id = entityId + entity + } + } + + override fun getMetadata(): EntityMetadata { + return MetadataStorageImpl.getMetadataByTypeFqn( + "org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.GradleScriptDefinitionEntity") as EntityMetadata + } + + override fun getEntityInterface(): Class { + return GradleScriptDefinitionEntity::class.java + } + + override fun createDetachedEntity(parents: List>): ModifiableWorkspaceEntity<*> { + return GradleScriptDefinitionEntity(definitionId, compilationConfiguration, hostConfiguration, entitySource) { + this.evaluationConfiguration = this@GradleScriptDefinitionEntityData.evaluationConfiguration + } + } + + override fun getRequiredParents(): List> { + val res = mutableListOf>() + return res + } + + override fun equals(other: Any?): Boolean { + if (other == null) return false + if (this.javaClass != other.javaClass) return false + + other as GradleScriptDefinitionEntityData + + if (this.entitySource != other.entitySource) return false + if (this.definitionId != other.definitionId) return false + if (this.compilationConfiguration != other.compilationConfiguration) return false + if (this.hostConfiguration != other.hostConfiguration) return false + if (this.evaluationConfiguration != other.evaluationConfiguration) return false + return true + } + + override fun equalsIgnoringEntitySource(other: Any?): Boolean { + if (other == null) return false + if (this.javaClass != other.javaClass) return false + + other as GradleScriptDefinitionEntityData + + if (this.definitionId != other.definitionId) return false + if (this.compilationConfiguration != other.compilationConfiguration) return false + if (this.hostConfiguration != other.hostConfiguration) return false + if (this.evaluationConfiguration != other.evaluationConfiguration) return false + return true + } + + override fun hashCode(): Int { + var result = entitySource.hashCode() + result = 31 * result + definitionId.hashCode() + result = 31 * result + compilationConfiguration.hashCode() + result = 31 * result + hostConfiguration.hashCode() + result = 31 * result + evaluationConfiguration.hashCode() + return result + } + + override fun hashCodeIgnoringEntitySource(): Int { + var result = javaClass.hashCode() + result = 31 * result + definitionId.hashCode() + result = 31 * result + compilationConfiguration.hashCode() + result = 31 * result + hostConfiguration.hashCode() + result = 31 * result + evaluationConfiguration.hashCode() + return result + } +} diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/gen/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/impl/MetadataStorageImpl.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/gen/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/impl/MetadataStorageImpl.kt new file mode 100644 index 000000000000..e447f1ffc01a --- /dev/null +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/gen/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/impl/MetadataStorageImpl.kt @@ -0,0 +1,134 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.impl + +import com.intellij.platform.workspace.storage.WorkspaceEntityInternalApi +import com.intellij.platform.workspace.storage.metadata.impl.MetadataStorageBase +import com.intellij.platform.workspace.storage.metadata.model.EntityMetadata +import com.intellij.platform.workspace.storage.metadata.model.FinalClassMetadata +import com.intellij.platform.workspace.storage.metadata.model.OwnPropertyMetadata +import com.intellij.platform.workspace.storage.metadata.model.StorageTypeMetadata +import com.intellij.platform.workspace.storage.metadata.model.ValueTypeMetadata + +@OptIn(WorkspaceEntityInternalApi::class) +internal object MetadataStorageImpl : MetadataStorageBase() { + override fun initializeMetadata() { + val primitiveTypeStringNotNullable = ValueTypeMetadata.SimpleType.PrimitiveType(isNullable = false, type = "String") + + var typeMetadata: StorageTypeMetadata + + typeMetadata = FinalClassMetadata.ClassMetadata( + fqName = "org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.GradleScriptDefinitionEntityId", properties = listOf( + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "id", valueType = primitiveTypeStringNotNullable, + withDefault = false), + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "presentableName", + valueType = primitiveTypeStringNotNullable, withDefault = false)), + supertypes = listOf("com.intellij.platform.workspace.storage.SymbolicEntityId")) + + addMetadata(typeMetadata) + + typeMetadata = EntityMetadata(fqName = "org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.GradleScriptDefinitionEntity", + entityDataFqName = "org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.impl.GradleScriptDefinitionEntityData", + supertypes = listOf("com.intellij.platform.workspace.storage.WorkspaceEntity", + "com.intellij.platform.workspace.storage.WorkspaceEntityWithSymbolicId"), + properties = listOf( + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "entitySource", + valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = false, + typeMetadata = FinalClassMetadata.KnownClass( + fqName = "com.intellij.platform.workspace.storage.EntitySource")), + withDefault = false), + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "definitionId", + valueType = primitiveTypeStringNotNullable, withDefault = false), + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, + name = "compilationConfiguration", + valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = false, + typeMetadata = FinalClassMetadata.ClassMetadata( + fqName = "org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptCompilationConfigurationEntity", + properties = listOf( + OwnPropertyMetadata( + isComputable = false, + isKey = false, + isOpen = false, + name = "data", + valueType = ValueTypeMetadata.SimpleType.CustomType( + isNullable = false, + typeMetadata = FinalClassMetadata.KnownClass( + fqName = "kotlin.ByteArray")), + withDefault = false)), + supertypes = listOf())), + withDefault = false), + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "hostConfiguration", + valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = false, + typeMetadata = FinalClassMetadata.ClassMetadata( + fqName = "org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptingHostConfigurationEntity", + properties = listOf( + OwnPropertyMetadata( + isComputable = false, + isKey = false, + isOpen = false, + name = "data", + valueType = ValueTypeMetadata.SimpleType.CustomType( + isNullable = false, + typeMetadata = FinalClassMetadata.KnownClass( + fqName = "kotlin.ByteArray")), + withDefault = false)), + supertypes = listOf())), + withDefault = false), + OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, + name = "evaluationConfiguration", + valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = true, + typeMetadata = FinalClassMetadata.ClassMetadata( + fqName = "org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptEvaluationConfigurationEntity", + properties = listOf( + OwnPropertyMetadata( + isComputable = false, + isKey = false, + isOpen = false, + name = "data", + valueType = ValueTypeMetadata.SimpleType.CustomType( + isNullable = false, + typeMetadata = FinalClassMetadata.KnownClass( + fqName = "kotlin.ByteArray")), + withDefault = false)), + supertypes = listOf())), + withDefault = false), + OwnPropertyMetadata(isComputable = true, isKey = false, isOpen = false, name = "symbolicId", + valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = false, + typeMetadata = FinalClassMetadata.ClassMetadata( + fqName = "org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.GradleScriptDefinitionEntityId", + properties = listOf( + OwnPropertyMetadata( + isComputable = false, + isKey = false, + isOpen = false, + name = "id", + valueType = primitiveTypeStringNotNullable, + withDefault = false), + OwnPropertyMetadata( + isComputable = false, + isKey = false, + isOpen = false, + name = "presentableName", + valueType = primitiveTypeStringNotNullable, + withDefault = false)), + supertypes = listOf( + "com.intellij.platform.workspace.storage.SymbolicEntityId"))), + withDefault = false)), extProperties = listOf(), isAbstract = false) + + addMetadata(typeMetadata) + } + + override fun initializeMetadataHash() { + addMetadataHash(typeFqn = "org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.GradleScriptDefinitionEntity", + metadataHash = 603888767) + addMetadataHash(typeFqn = "org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptCompilationConfigurationEntity", + metadataHash = -1162660984) + addMetadataHash(typeFqn = "org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptingHostConfigurationEntity", + metadataHash = -441841951) + addMetadataHash(typeFqn = "org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptEvaluationConfigurationEntity", + metadataHash = -362496579) + addMetadataHash(typeFqn = "org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.GradleScriptDefinitionEntityId", + metadataHash = -1956757513) + addMetadataHash(typeFqn = "com.intellij.platform.workspace.storage.SymbolicEntityId", metadataHash = 1136338439) + } + +} diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/intellij.kotlin.gradle.scripting.iml b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/intellij.kotlin.gradle.scripting.iml index cb1453bff004..84937969f082 100644 --- a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/intellij.kotlin.gradle.scripting.iml +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/intellij.kotlin.gradle.scripting.iml @@ -23,6 +23,7 @@ + @@ -81,5 +82,6 @@ + \ No newline at end of file diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/resources/intellij.kotlin.gradle.scripting.xml b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/resources/intellij.kotlin.gradle.scripting.xml index 3f7b0c1ed571..18546b200bbc 100644 --- a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/resources/intellij.kotlin.gradle.scripting.xml +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/resources/intellij.kotlin.gradle.scripting.xml @@ -38,7 +38,12 @@ - - + + + + + + \ No newline at end of file diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptRefinedConfigurationProvider.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleKotlinScriptService.kt similarity index 61% rename from plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptRefinedConfigurationProvider.kt rename to plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleKotlinScriptService.kt index 6b83e4d3dfca..344ba8f2ce18 100644 --- a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptRefinedConfigurationProvider.kt +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleKotlinScriptService.kt @@ -1,6 +1,7 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.gradle.scripting.k2 +import com.intellij.openapi.application.readAction import com.intellij.openapi.components.Service import com.intellij.openapi.components.service import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil @@ -8,32 +9,46 @@ import com.intellij.openapi.options.advanced.AdvancedSettings import com.intellij.openapi.project.Project import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.vfs.VirtualFile +import com.intellij.platform.backend.observation.launchTracked +import com.intellij.platform.backend.workspace.WorkspaceModelChangeListener import com.intellij.platform.backend.workspace.toVirtualFileUrl +import com.intellij.platform.backend.workspace.virtualFile import com.intellij.platform.backend.workspace.workspaceModel -import com.intellij.platform.workspace.jps.entities.InheritedSdkDependency -import com.intellij.platform.workspace.jps.entities.SdkDependency import com.intellij.platform.workspace.jps.entities.SdkId +import com.intellij.platform.workspace.storage.EntityChange import com.intellij.platform.workspace.storage.MutableEntityStorage +import com.intellij.platform.workspace.storage.VersionedStorageChange import com.intellij.platform.workspace.storage.toBuilder import com.intellij.platform.workspace.storage.url.VirtualFileUrl -import com.intellij.util.containers.addIfNotNull +import com.intellij.psi.PsiManager import kotlinx.coroutines.CoroutineScope -import org.jetbrains.kotlin.gradle.scripting.shared.GradleScriptModel -import org.jetbrains.kotlin.gradle.scripting.shared.GradleScriptModelData +import org.jetbrains.kotlin.gradle.scripting.k2.definition.withIdeKeys +import org.jetbrains.kotlin.gradle.scripting.k2.importing.GradleScriptData +import org.jetbrains.kotlin.gradle.scripting.k2.importing.GradleScriptModel +import org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.GradleScriptDefinitionEntity +import org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.asEntity +import org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.deserialize import org.jetbrains.kotlin.gradle.scripting.shared.KotlinGradleScriptEntitySource +import org.jetbrains.kotlin.gradle.scripting.shared.definition.GradleScriptDefinition +import org.jetbrains.kotlin.gradle.scripting.shared.loadGradleDefinitions import org.jetbrains.kotlin.idea.core.script.k2.configurations.ScriptConfigurationWithSdk import org.jetbrains.kotlin.idea.core.script.k2.configurations.toVirtualFileUrl +import org.jetbrains.kotlin.idea.core.script.k2.definitions.ScriptDefinitionsModificationTracker +import org.jetbrains.kotlin.idea.core.script.k2.highlighting.DefaultScriptResolutionStrategy import org.jetbrains.kotlin.idea.core.script.k2.modules.* import org.jetbrains.kotlin.idea.core.script.v1.indexSourceRootsEagerly import org.jetbrains.kotlin.idea.core.script.v1.scriptingDebugLog import org.jetbrains.kotlin.idea.core.script.v1.scriptingWarnLog +import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition +import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource import org.jetbrains.kotlin.scripting.resolve.adjustByDefinition import org.jetbrains.kotlin.scripting.resolve.refineScriptCompilationConfiguration +import org.jetbrains.kotlin.utils.addIfNotNull import java.io.File -import java.util.concurrent.atomic.AtomicReference +import java.util.concurrent.ConcurrentHashMap import java.util.function.Predicate import kotlin.script.experimental.api.* import kotlin.script.experimental.jvm.JvmDependency @@ -41,22 +56,48 @@ import kotlin.script.experimental.jvm.jdkHome import kotlin.script.experimental.jvm.jvm @Service(Service.Level.PROJECT) -class GradleScriptRefinedConfigurationProvider( - val project: Project, val coroutineScope: CoroutineScope -) : ScriptRefinedConfigurationResolver, ScriptWorkspaceModelManager { - private val data = AtomicReference>(emptyMap()) +class GradleKotlinScriptService(val project: Project) : ScriptRefinedConfigurationResolver, ScriptWorkspaceModelManager { + private val data = ConcurrentHashMap() override suspend fun create(virtualFile: VirtualFile, definition: ScriptDefinition): ScriptConfigurationWithSdk? = null - override fun get(virtualFile: VirtualFile): ScriptConfigurationWithSdk? = data.get()[virtualFile] + override fun get(virtualFile: VirtualFile): ScriptConfigurationWithSdk? { + val url = virtualFile.toVirtualFileUrl(project.workspaceModel.getVirtualFileUrlManager()) + val result = data.computeIfAbsent(url) { url -> + val entity = project.workspaceModel.currentSnapshot.getVirtualFileUrlIndex().findEntitiesByUrl(url) + .firstOrNull { + it.entitySource is KotlinGradleScriptEntitySource && it is KotlinScriptEntity + } as? KotlinScriptEntity - suspend fun processScripts(scriptsData: GradleScriptModelData, storageToUpdate: MutableEntityStorage? = null) { - val sdk = scriptsData.javaHome.resolveSdk() + entity?.toConfigurationWithSdk() ?: ScriptConfigurationWithSdk.EMPTY + } + + return if (result == ScriptConfigurationWithSdk.EMPTY) null else result + } + + fun processScripts( + scriptData: GradleScriptData, + storageToUpdate: MutableEntityStorage + ) { + val updatedStorage = MutableEntityStorage.create() + + val definitions = loadGradleDefinitions(scriptData.definitionsParams).map { it.withIdeKeys(project) } + updatedStorage.enrichWithDefinitions(definitions) + updatedStorage.enrichWithConfigurations(scriptData, definitions) + + storageToUpdate.applyChangesFrom(updatedStorage) + } + + private fun MutableEntityStorage.enrichWithConfigurations( + scriptsData: GradleScriptData, + definitions: List + ) { + val sdk = scriptsData.definitionsParams.javaHome.resolveSdk() val javaHomePath = sdk?.homePath?.let { File(it) } val configurations = scriptsData.models.associate { gradleScript: GradleScriptModel -> val sourceCode = VirtualFileScriptSource(gradleScript.virtualFile) - val definition = findScriptDefinition(project, sourceCode) + val definition = definitions.firstOrNull { it.isScript(sourceCode) } ?: findScriptDefinition(project, sourceCode) val configuration = definition.compilationConfiguration.with { if (javaHomePath != null) { @@ -69,22 +110,10 @@ class GradleScriptRefinedConfigurationProvider( val updatedConfiguration = refineScriptCompilationConfiguration(sourceCode, definition, project, configuration) - gradleScript.virtualFile to ScriptConfigurationWithSdk(updatedConfiguration, sdk) + gradleScript.virtualFile to ScriptConfigurationWithSdk(updatedConfiguration, sdk?.let { SdkId(it.name, it.sdkType.name) }) } - val updatedStorage = MutableEntityStorage.create().apply { - enrichStorage(configurations) - } - - if (storageToUpdate == null) { - project.workspaceModel.update("updating .gradle.kts scripts") { storage -> - storage.replaceBySource({ it is KotlinGradleScriptEntitySource }, updatedStorage) - } - } else { - storageToUpdate.replaceBySource({ it is KotlinGradleScriptEntitySource }, updatedStorage) - } - - data.set(configurations) + enrichStorage(configurations) } private fun String?.resolveSdk(): Sdk? { @@ -158,9 +187,15 @@ class GradleScriptRefinedConfigurationProvider( } } - val sdk = configurationWithSdk.sdk?.let { SdkDependency(SdkId(it.name, it.sdkType.name)) } ?: InheritedSdkDependency - - this addEntity KotlinScriptEntity(scriptUrl, dependencies, sdk, KotlinGradleScriptEntitySource) + this addEntity KotlinScriptEntity( + scriptUrl, + dependencies, + KotlinGradleScriptEntitySource + ) { + this.configuration = configuration.configuration?.asEntity() + this.reports = configurationWithSdk.scriptConfiguration.reports.map { it.toData() }.toMutableList() + this.sdkId = configurationWithSdk.sdkId + } } } @@ -277,8 +312,76 @@ class GradleScriptRefinedConfigurationProvider( return removed } + private fun MutableEntityStorage.enrichWithDefinitions(definitions: List) { + definitions.forEach { + this addEntity GradleScriptDefinitionEntity( + it.definitionId, + it.compilationConfiguration.asEntity(), + it.hostConfiguration.asEntity(), + KotlinGradleScriptEntitySource + ) { + evaluationConfiguration = it.evaluationConfiguration?.asEntity() + } + } + } + + @Suppress("unused") + private class GradleWorkspaceModelListener(val project: Project, val scope: CoroutineScope) : WorkspaceModelChangeListener { + override fun changed(event: VersionedStorageChange) = scope.launchTracked { + + if (event.getChanges(GradleScriptDefinitionEntity::class.java).any()) { + ScriptDefinitionsModificationTracker.getInstance(project).incModificationCount() + } + + val updatedData = mutableMapOf() + for (entityChange in event.getChanges(KotlinScriptEntity::class.java)) { + if (entityChange is EntityChange.Removed) continue + val entity = entityChange.newEntity ?: continue + if (entity.entitySource !is KotlinGradleScriptEntitySource) continue + + val result = entity.toConfigurationWithSdk() + if (result != null) { + updatedData[entity.virtualFileUrl] = result + } + } + + if (updatedData.any()) { + val ktFiles = buildSet { + for (url in updatedData.keys) { + val virtualFile = url.virtualFile ?: continue + val ktFile = readAction { PsiManager.getInstance(project).findFile(virtualFile) } as? KtFile + addIfNotNull(ktFile) + } + } + + getInstance(project).data.clear() + if (ktFiles.any()) { + DefaultScriptResolutionStrategy.getInstance(project).restartHighlighting(ktFiles) + } + } + } + } + companion object { @JvmStatic - fun getInstance(project: Project): GradleScriptRefinedConfigurationProvider = project.service() + fun getInstance(project: Project): GradleKotlinScriptService = project.service() } -} \ No newline at end of file +} + + +fun KotlinScriptEntity.toConfigurationWithSdk(): ScriptConfigurationWithSdk? { + val virtualFile = virtualFileUrl.virtualFile ?: return null + + val result = if (configuration == null) { + ResultWithDiagnostics.Failure(listOf()) + } else { + ResultWithDiagnostics.Success( + ScriptCompilationConfigurationWrapper.FromCompilationConfiguration( + VirtualFileScriptSource(virtualFile), + configuration?.deserialize() + ), reports.map { report -> report.toScriptDiagnostic() } + ) + } + + return ScriptConfigurationWithSdk(result, sdkId) +} diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptDefinitionsSource.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptDefinitionsSource.kt deleted file mode 100644 index 8cc8ec1b363f..000000000000 --- a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptDefinitionsSource.kt +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package org.jetbrains.kotlin.gradle.scripting.k2 - -import com.intellij.openapi.components.* -import com.intellij.openapi.project.Project -import com.intellij.util.xmlb.annotations.Attribute -import org.jetbrains.kotlin.gradle.scripting.shared.GradleDefinitionsParams -import org.jetbrains.kotlin.gradle.scripting.shared.loadGradleDefinitions -import org.jetbrains.kotlin.idea.core.script.k2.configurations.configurationResolverDelegate -import org.jetbrains.kotlin.idea.core.script.k2.configurations.scriptWorkspaceModelManagerDelegate -import org.jetbrains.kotlin.idea.core.script.k2.definitions.ScriptDefinitionsModificationTracker -import org.jetbrains.kotlin.idea.core.script.v1.NewScriptFileInfo -import org.jetbrains.kotlin.idea.core.script.v1.kotlinScriptTemplateInfo -import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition -import org.jetbrains.kotlin.scripting.definitions.ScriptDefinitionsSource -import java.util.concurrent.atomic.AtomicReference -import kotlin.script.experimental.api.ide - -class GradleScriptDefinitionsSource(val project: Project) : ScriptDefinitionsSource { - override val definitions: Sequence - get() = GradleScriptDefinitionsStorage.getInstance(project).getDefinitions() -} - -@Service(Service.Level.PROJECT) -@State(name = "GradleScriptDefinitionsStorage", storages = [Storage(StoragePathMacros.WORKSPACE_FILE)]) -class GradleScriptDefinitionsStorage(val project: Project) : - SerializablePersistentStateComponent(State()) { - - private val _definitions: AtomicReference> = AtomicReference(listOf()) - private val initialized = AtomicReference(false) - - fun getDefinitions(): Sequence { - initializeIfNeeded() - return _definitions.get()?.asSequence() ?: emptySequence() - } - - private fun initializeIfNeeded() { - if (initialized.get()) return - - synchronized(this) { - if (initialized.get()) return - - val params = state.toParams() - if (params != null) { - loadDefinitions(params) - } - initialized.set(true) - } - } - - fun loadDefinitions(params: GradleDefinitionsParams) { - val definitions = loadGradleDefinitions(params).map { - it.with { - ide { - kotlinScriptTemplateInfo(NewScriptFileInfo().apply { - id = "gradle-kts" - title = ".gradle.kts" - templateName = "Kotlin Script Gradle" - }) - configurationResolverDelegate { - GradleScriptRefinedConfigurationProvider.getInstance(project) - } - scriptWorkspaceModelManagerDelegate { - GradleScriptRefinedConfigurationProvider.getInstance(project) - } - } - } - } - _definitions.set(definitions) - initialized.set(true) - updateState { - it.copyFrom(params) - } - ScriptDefinitionsModificationTracker.getInstance(project).incModificationCount() - } - - data class State( - @Attribute @JvmField val workingDir: String? = null, - @Attribute @JvmField val gradleHome: String? = null, - @Attribute @JvmField val javaHome: String? = null, - @Attribute @JvmField val gradleVersion: String? = null, - @JvmField val jvmArguments: List = emptyList(), - @JvmField val environment: Map = emptyMap(), - ) { - fun copyFrom(params: GradleDefinitionsParams): State { - return copy( - workingDir = params.workingDir, - gradleHome = params.gradleHome, - javaHome = params.javaHome, - gradleVersion = params.gradleVersion, - jvmArguments = params.jvmArguments, - environment = params.environment - ) - } - - fun toParams(): GradleDefinitionsParams? { - return GradleDefinitionsParams( - workingDir ?: return null, - gradleHome ?: return null, - javaHome ?: return null, - gradleVersion ?: return null, - jvmArguments, - environment - ) - } - } - - companion object { - fun getInstance(project: Project): GradleScriptDefinitionsStorage = project.service() - } -} diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptLazyResolveProhibitionCondition.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptHighlightingExtension.kt similarity index 52% rename from plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptLazyResolveProhibitionCondition.kt rename to plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptHighlightingExtension.kt index a165fdb75cec..c1b7d5897762 100644 --- a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptLazyResolveProhibitionCondition.kt +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptHighlightingExtension.kt @@ -2,18 +2,19 @@ package org.jetbrains.kotlin.gradle.scripting.k2 import com.intellij.openapi.project.Project -import com.intellij.openapi.vfs.VirtualFile -import org.jetbrains.kotlin.idea.core.script.k2.highlighting.KotlinScripDeferredResolutionPolicy +import org.jetbrains.kotlin.gradle.scripting.k2.definition.GradleScriptDefinitionsSource +import org.jetbrains.kotlin.idea.base.highlighting.KotlinScriptHighlightingExtension import org.jetbrains.kotlin.idea.core.script.shared.scriptDefinitionsSourceOfType import org.jetbrains.kotlin.idea.util.application.isUnitTestMode +import org.jetbrains.kotlin.psi.KtFile private const val GRADLE_KTS = ".gradle.kts" -class GradleScripDeferredResolvePolicy(val project: Project) : KotlinScripDeferredResolutionPolicy { - override fun shouldDeferResolution(script: VirtualFile): Boolean { - if (!script.name.endsWith(GRADLE_KTS) || isUnitTestMode()) return false +class GradleScriptHighlightingExtension(val project: Project) : KotlinScriptHighlightingExtension { + override fun shouldHighlightScript(file: KtFile): Boolean { + if (!file.name.endsWith(GRADLE_KTS) || isUnitTestMode()) return true // gradle definitions are empty so project import wasn't finished yet - return project.scriptDefinitionsSourceOfType()?.definitions.orEmpty().none() + return project.scriptDefinitionsSourceOfType()?.definitions.orEmpty().any() } } \ No newline at end of file diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptNotificationProvider.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptNotificationProvider.kt index b26e1d76c7b5..cb3a01e09eeb 100644 --- a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptNotificationProvider.kt +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/GradleScriptNotificationProvider.kt @@ -23,13 +23,11 @@ import org.jetbrains.kotlin.gradle.scripting.shared.roots.GradleBuildRootsLocato import org.jetbrains.kotlin.gradle.scripting.shared.roots.Imported import org.jetbrains.kotlin.gradle.scripting.shared.runPartialGradleImport import org.jetbrains.kotlin.idea.core.script.shared.KotlinBaseScriptingBundle -import org.jetbrains.kotlin.idea.core.script.k2.configurations.ScriptConfigurationsProviderImpl import org.jetbrains.kotlin.idea.util.isKotlinFileType import org.jetbrains.plugins.gradle.util.GradleConstants import java.io.File import java.util.function.Function import javax.swing.JComponent -import kotlin.script.experimental.api.valueOrNull //TODO: KTIJ-30408 internal class GradleScriptNotificationProvider : EditorNotificationProvider { @@ -160,7 +158,7 @@ internal class GradleScriptNotificationProvider : EditorNotificationProvider { } private fun isImported(virtualFile: VirtualFile, project: Project): Boolean = - GradleScriptRefinedConfigurationProvider.getInstance(project).get(virtualFile) != null + GradleKotlinScriptService.getInstance(project).get(virtualFile) != null private fun linkProject( project: Project, diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/ProjectGradleSettingsListener.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/ProjectGradleSettingsListener.kt index bd32cb9f42b9..9530cbf095e1 100644 --- a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/ProjectGradleSettingsListener.kt +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/ProjectGradleSettingsListener.kt @@ -2,22 +2,13 @@ package org.jetbrains.kotlin.gradle.scripting.k2 import com.intellij.openapi.application.edtWriteAction -import com.intellij.openapi.application.readAction import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl import com.intellij.openapi.project.Project -import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.platform.backend.observation.launchTracked -import com.intellij.psi.PsiManager import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.suspendCancellableCoroutine -import org.jetbrains.kotlin.gradle.scripting.shared.GradleScriptModel -import org.jetbrains.kotlin.gradle.scripting.shared.GradleScriptModelData import org.jetbrains.kotlin.gradle.scripting.shared.getGradleVersion -import org.jetbrains.kotlin.gradle.scripting.shared.roots.GradleBuildRootData import org.jetbrains.kotlin.gradle.scripting.shared.roots.GradleBuildRootsLocator -import org.jetbrains.kotlin.gradle.scripting.shared.roots.Imported -import org.jetbrains.kotlin.idea.core.script.k2.highlighting.DefaultScriptResolutionStrategy -import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.plugins.gradle.service.GradleInstallationManager import org.jetbrains.plugins.gradle.settings.DistributionType import org.jetbrains.plugins.gradle.settings.GradleProjectSettings @@ -49,12 +40,9 @@ class ProjectGradleSettingsListener( awaitExternalSystemInitialization() settings.forEach { val gradleVersion = getGradleVersion(project, it) - val newRoot = edtWriteAction { + edtWriteAction { buildRootsManager.loadLinkedRoot(it, gradleVersion) } - if (newRoot is Imported) { - loadScriptConfigurations(newRoot.data) - } } } } @@ -86,26 +74,4 @@ class ProjectGradleSettingsListener( val buildRootsManager = GradleBuildRootsLocator.getInstance(project) buildRootsManager.reloadBuildRoot(linkedProjectPath, null) } - - private suspend fun loadScriptConfigurations(data: GradleBuildRootData) { - if (data.models.isEmpty()) return - - val scripts = data.models.mapNotNullTo(mutableSetOf()) { - val virtualFile = VirtualFileManager.getInstance().findFileByNioPath(Path.of(it.file)) ?: return@mapNotNullTo null - GradleScriptModel( - virtualFile, - it.classPath, - it.sourcePath, - it.imports, - ) - } - - GradleScriptRefinedConfigurationProvider.getInstance(project).processScripts(GradleScriptModelData(scripts, data.javaHome)) - - val ktFiles = scripts.mapNotNull { - readAction { PsiManager.getInstance(project).findFile(it.virtualFile) as? KtFile } - }.toTypedArray() - - DefaultScriptResolutionStrategy.getInstance(project).execute(*ktFiles).join() - } } \ No newline at end of file diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/definition/GradleScriptDefinitionsSource.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/definition/GradleScriptDefinitionsSource.kt new file mode 100644 index 000000000000..d169e88fd392 --- /dev/null +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/definition/GradleScriptDefinitionsSource.kt @@ -0,0 +1,28 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.gradle.scripting.k2.definition + +import com.intellij.openapi.project.Project +import com.intellij.platform.backend.workspace.workspaceModel +import org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.GradleScriptDefinitionEntity +import org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.deserialize +import org.jetbrains.kotlin.gradle.scripting.shared.definition.ErrorGradleScriptDefinition +import org.jetbrains.kotlin.gradle.scripting.shared.definition.GradleScriptDefinition +import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition +import org.jetbrains.kotlin.scripting.definitions.ScriptDefinitionsSource + +class GradleScriptDefinitionsSource(val project: Project) : ScriptDefinitionsSource { + override val definitions: Sequence + get() = project.workspaceModel.currentSnapshot.entities(GradleScriptDefinitionEntity::class.java).map { + val compilationConfiguration = it.compilationConfiguration.deserialize() + val hostConfiguration = it.hostConfiguration.deserialize() + if (compilationConfiguration == null || hostConfiguration == null) { + ErrorGradleScriptDefinition() + } else { + GradleScriptDefinition( + compilationConfiguration, + hostConfiguration, + it.evaluationConfiguration?.deserialize(), + ).withIdeKeys(project) + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/definition/util.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/definition/util.kt new file mode 100644 index 000000000000..291f933efb81 --- /dev/null +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/definition/util.kt @@ -0,0 +1,28 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.gradle.scripting.k2.definition + +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.gradle.scripting.k2.GradleKotlinScriptService +import org.jetbrains.kotlin.gradle.scripting.shared.definition.GradleScriptDefinition +import org.jetbrains.kotlin.idea.core.script.k2.configurations.configurationResolverDelegate +import org.jetbrains.kotlin.idea.core.script.k2.configurations.scriptWorkspaceModelManagerDelegate +import org.jetbrains.kotlin.idea.core.script.v1.NewScriptFileInfo +import org.jetbrains.kotlin.idea.core.script.v1.kotlinScriptTemplateInfo +import kotlin.script.experimental.api.ide + + +fun GradleScriptDefinition.withIdeKeys(project: Project): GradleScriptDefinition = with { + ide { + kotlinScriptTemplateInfo(NewScriptFileInfo().apply { + id = "gradle-kts" + title = ".gradle.kts" + templateName = "Kotlin Script Gradle" + }) + configurationResolverDelegate { + GradleKotlinScriptService.getInstance(project) + } + scriptWorkspaceModelManagerDelegate { + GradleKotlinScriptService.getInstance(project) + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/importing/KotlinDslScriptSyncContributor.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/importing/KotlinDslScriptSyncContributor.kt index ee1076e0913a..2d26b58e7851 100644 --- a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/importing/KotlinDslScriptSyncContributor.kt +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/importing/KotlinDslScriptSyncContributor.kt @@ -1,24 +1,18 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.gradle.scripting.k2.importing -import com.intellij.openapi.application.readAction +import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.platform.workspace.storage.ImmutableEntityStorage import com.intellij.platform.workspace.storage.MutableEntityStorage import com.intellij.platform.workspace.storage.toBuilder -import com.intellij.psi.PsiManager -import org.jetbrains.kotlin.gradle.scripting.k2.GradleScriptDefinitionsStorage -import org.jetbrains.kotlin.gradle.scripting.k2.GradleScriptRefinedConfigurationProvider +import org.jetbrains.kotlin.gradle.scripting.k2.GradleKotlinScriptService import org.jetbrains.kotlin.gradle.scripting.shared.GradleDefinitionsParams -import org.jetbrains.kotlin.gradle.scripting.shared.GradleScriptModel -import org.jetbrains.kotlin.gradle.scripting.shared.GradleScriptModelData import org.jetbrains.kotlin.gradle.scripting.shared.KotlinGradleScriptEntitySource import org.jetbrains.kotlin.gradle.scripting.shared.importing.collectErrors import org.jetbrains.kotlin.gradle.scripting.shared.importing.getKotlinDslScripts import org.jetbrains.kotlin.gradle.scripting.shared.importing.kotlinDslSyncListenerInstance import org.jetbrains.kotlin.gradle.scripting.shared.importing.saveGradleBuildEnvironment -import org.jetbrains.kotlin.idea.core.script.k2.highlighting.DefaultScriptResolutionStrategy -import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.plugins.gradle.model.GradleBuildScriptClasspathModel import org.jetbrains.plugins.gradle.service.project.ProjectResolverContext import org.jetbrains.plugins.gradle.service.syncAction.GradleSyncContributor @@ -68,20 +62,11 @@ internal class KotlinDslScriptSyncContributor : GradleSyncContributor { val gradleHome = context.allBuilds.asSequence().flatMap { it.projects.asSequence() } .mapNotNull { context.getProjectModel(it, GradleBuildScriptClasspathModel::class.java) } - .mapNotNull { it.gradleHomeDir?.absolutePath }.firstOrNull() ?: context.settings.gradleHome ?: return storage + .firstNotNullOfOrNull { it.gradleHomeDir?.absolutePath } ?: context.settings.gradleHome ?: return storage val javaHome = context.buildEnvironment.java.javaHome.absolutePath - GradleScriptDefinitionsStorage.getInstance(project).loadDefinitions( - params = GradleDefinitionsParams( - context.projectPath, - gradleHome, - javaHome, - context.buildEnvironment.gradle.gradleVersion, - context.settings.jvmArguments, - context.settings.env - ) - ) + val builder = storage.toBuilder() val gradleScripts = models.mapNotNullTo(mutableSetOf()) { val virtualFile = VirtualFileManager.getInstance().findFileByNioPath(Path.of(it.file)) ?: return@mapNotNullTo null @@ -93,17 +78,32 @@ internal class KotlinDslScriptSyncContributor : GradleSyncContributor { ) } - val builder = storage.toBuilder() + val scriptData = GradleScriptData( + gradleScripts, + GradleDefinitionsParams( + context.projectPath, + gradleHome, + javaHome, + context.buildEnvironment.gradle.gradleVersion, + context.settings.jvmArguments, + context.settings.env + ) + ) - GradleScriptRefinedConfigurationProvider.getInstance(project) - .processScripts(GradleScriptModelData(gradleScripts, javaHome), builder) - - val ktFiles = gradleScripts.mapNotNull { - readAction { PsiManager.getInstance(project).findFile(it.virtualFile) as? KtFile } - }.toTypedArray() - - DefaultScriptResolutionStrategy.getInstance(project).execute(*ktFiles).join() + GradleKotlinScriptService.getInstance(project).processScripts(scriptData, builder) return builder.toSnapshot() } -} \ No newline at end of file +} + +class GradleScriptData( + val models: Collection, + val definitionsParams: GradleDefinitionsParams +) + +class GradleScriptModel( + val virtualFile: VirtualFile, + val classPath: List, + val sourcePath: List, + val imports: List, +) \ No newline at end of file diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/GradleScriptDefinitionEntity.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/GradleScriptDefinitionEntity.kt new file mode 100644 index 000000000000..6050e12d79bd --- /dev/null +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/GradleScriptDefinitionEntity.kt @@ -0,0 +1,22 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel + +import com.intellij.openapi.util.NlsSafe +import com.intellij.platform.workspace.storage.* +import org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptCompilationConfigurationEntity +import org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptEvaluationConfigurationEntity +import org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptingHostConfigurationEntity + +data class GradleScriptDefinitionEntityId(val id: String) : SymbolicEntityId { + override val presentableName: @NlsSafe String = id +} + +interface GradleScriptDefinitionEntity : WorkspaceEntityWithSymbolicId { + val definitionId: String + val compilationConfiguration: ScriptCompilationConfigurationEntity + val hostConfiguration: ScriptingHostConfigurationEntity + val evaluationConfiguration: ScriptEvaluationConfigurationEntity? + + override val symbolicId: GradleScriptDefinitionEntityId + get() = GradleScriptDefinitionEntityId(definitionId) +} diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/serialize.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/serialize.kt new file mode 100644 index 000000000000..df80ab54bd9c --- /dev/null +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/src/org/jetbrains/kotlin/gradle/scripting/k2/workspaceModel/serialize.kt @@ -0,0 +1,72 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel + +import org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptCompilationConfigurationEntity +import org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptEvaluationConfigurationEntity +import org.jetbrains.kotlin.idea.core.script.k2.modules.ScriptingHostConfigurationEntity +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.ObjectInputStream +import java.io.ObjectOutputStream +import kotlin.script.experimental.api.ScriptCompilationConfiguration +import kotlin.script.experimental.api.ScriptEvaluationConfiguration +import kotlin.script.experimental.host.ScriptingHostConfiguration +import kotlin.script.experimental.util.PropertiesCollection +import kotlin.script.experimental.util.PropertiesCollection.Key + +private fun PropertiesCollection.serialize(): ByteArray = ByteArrayOutputStream().use { bos -> + ObjectOutputStream(bos).use { oos -> + oos.writeObject(notTransientData) + } + + bos.toByteArray() +} + +fun ScriptEvaluationConfiguration.asEntity() = ScriptEvaluationConfigurationEntity(this.serialize()) + +fun ScriptEvaluationConfigurationEntity.deserialize(): ScriptEvaluationConfiguration? { + val params = ByteArrayInputStream(data).use { bis -> + ObjectInputStream(bis).use { ois -> + ois.readObject() as? LinkedHashMap, Any?> + } + } ?: return null + + return ScriptEvaluationConfiguration { + params.forEach { (key, any) -> + key.putIfNotNull(any) + } + } +} + +fun ScriptCompilationConfiguration.asEntity(): ScriptCompilationConfigurationEntity = ScriptCompilationConfigurationEntity(this.serialize()) + +fun ScriptCompilationConfigurationEntity.deserialize(): ScriptCompilationConfiguration? { + val params = ByteArrayInputStream(data).use { bis -> + ObjectInputStream(bis).use { ois -> + ois.readObject() as? LinkedHashMap, Any?> + } + } ?: return null + + return ScriptCompilationConfiguration { + params.forEach { (key, any) -> + key.putIfNotNull(any) + } + } +} + + +fun ScriptingHostConfiguration.asEntity() = ScriptingHostConfigurationEntity(this.serialize()) + +fun ScriptingHostConfigurationEntity.deserialize(): ScriptingHostConfiguration? { + val params = ByteArrayInputStream(data).use { bis -> + ObjectInputStream(bis).use { ois -> + ois.readObject() as? LinkedHashMap, Any?> + } + } ?: return null + + return ScriptingHostConfiguration { + params.forEach { (key, any) -> + key.putIfNotNull(any) + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/tests/org/jetbrains/kotlin/gradle/scripting/k2/projectStructure/KotlinGradleWorkspaceModelTest.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/tests/org/jetbrains/kotlin/gradle/scripting/k2/projectStructure/KotlinGradleWorkspaceModelTest.kt new file mode 100644 index 000000000000..36a1f805311e --- /dev/null +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.k2/tests/org/jetbrains/kotlin/gradle/scripting/k2/projectStructure/KotlinGradleWorkspaceModelTest.kt @@ -0,0 +1,95 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.gradle.scripting.k2.projectStructure + +import com.intellij.platform.backend.workspace.workspaceModel +import com.intellij.platform.testFramework.assertion.collectionAssertion.CollectionAssertions.assertEqualsUnordered +import com.intellij.platform.workspace.storage.impl.url.toVirtualFileUrl +import org.gradle.util.GradleVersion +import org.jetbrains.kotlin.gradle.scripting.k2.workspaceModel.GradleScriptDefinitionEntity +import org.jetbrains.kotlin.idea.core.script.k2.modules.KotlinScriptEntity +import org.jetbrains.kotlin.idea.test.AssertKotlinPluginMode +import org.jetbrains.kotlin.idea.test.UseK2PluginMode +import org.jetbrains.kotlin.idea.testFramework.gradle.KotlinGradleProjectTestCase +import org.jetbrains.plugins.gradle.testFramework.annotations.AllGradleVersionsSource +import org.jetbrains.plugins.gradle.testFramework.fixtures.application.GradleProjectTestApplication +import org.jetbrains.plugins.gradle.testFramework.util.assumeThatGradleIsAtLeast +import org.jetbrains.plugins.gradle.testFramework.util.assumeThatGradleIsOlderThan +import org.jetbrains.plugins.gradle.testFramework.util.assumeThatKotlinIsSupported +import org.junit.jupiter.params.ParameterizedTest +import kotlin.io.path.Path + +@UseK2PluginMode +@GradleProjectTestApplication +@AssertKotlinPluginMode +class KotlinGradleWorkspaceModelTest : KotlinGradleProjectTestCase() { + + private val currentSnapshot + get() = gradleFixture.project.workspaceModel.currentSnapshot + + private val virtualFileUrlManager + get() = gradleFixture.project.workspaceModel.getVirtualFileUrlManager() + + @ParameterizedTest + @AllGradleVersionsSource + fun `wsm should contain script definition entities after gradle sync`(gradleVersion: GradleVersion) { + assumeThatGradleIsAtLeast(gradleVersion, "6.0") { + "Script definitions were introduced in Gradle 6.0" + } + test(gradleVersion, KOTLIN_PROJECT) { + assertEqualsUnordered( + listOf( + "org.gradle.kotlin.dsl.KotlinSettingsScript", + "org.gradle.kotlin.dsl.KotlinBuildScript", + "org.gradle.kotlin.dsl.KotlinInitScript" + ), currentSnapshot.entities(GradleScriptDefinitionEntity::class.java).map { it.definitionId }.toList() + ) + } + } + + @ParameterizedTest + @AllGradleVersionsSource + fun `wsm should contain script entities after gradle sync`(gradleVersion: GradleVersion) { + assumeThatGradleIsAtLeast(gradleVersion, "6.0") { + "Script definitions were introduced in Gradle 6.0" + } + test(gradleVersion, KOTLIN_PROJECT) { + val projectPath = gradleFixture.project.basePath!! + val expected = listOf("build.gradle.kts", "settings.gradle.kts").mapNotNull { + Path(projectPath).resolve(it) + }.map { it.toVirtualFileUrl(virtualFileUrlManager) } + + assertEqualsUnordered( + expected, currentSnapshot.entities(KotlinScriptEntity::class.java).map { it.virtualFileUrl }.toList() + ) + } + } + + @ParameterizedTest + @AllGradleVersionsSource + fun `wsm should not contain script definition entities after gradle sync`(gradleVersion: GradleVersion) { + assumeThatKotlinIsSupported(gradleVersion) + assumeThatGradleIsOlderThan(gradleVersion, "6.0") { + "Script definitions were introduced in Gradle 6.0" + } + test(gradleVersion, KOTLIN_PROJECT) { + assert(currentSnapshot.entities(GradleScriptDefinitionEntity::class.java).none()) + } + } + + @ParameterizedTest + @AllGradleVersionsSource + fun `wsm should contain new script definition entities after gradle sync`(gradleVersion: GradleVersion) { + assumeThatGradleIsAtLeast(gradleVersion, "9.1.0") { + "Script definitions classes were changed in Gradle 9.1.0" + } + test(gradleVersion, KOTLIN_PROJECT) { + assertEqualsUnordered( + listOf( + "org.gradle.kotlin.dsl.KotlinGradleScriptTemplate", + "org.gradle.kotlin.dsl.KotlinProjectScriptTemplate", + "org.gradle.kotlin.dsl.KotlinSettingsScriptTemplate" + ), currentSnapshot.entities(GradleScriptDefinitionEntity::class.java).map { it.definitionId }.toList() + ) + } + } +} diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.shared/gen/org/jetbrains/kotlin/gradle/scripting/shared/definition/workspace/impl/MetadataStorageImpl.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.shared/gen/org/jetbrains/kotlin/gradle/scripting/shared/definition/workspace/impl/MetadataStorageImpl.kt new file mode 100644 index 000000000000..2f6ad136b7e1 --- /dev/null +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.shared/gen/org/jetbrains/kotlin/gradle/scripting/shared/definition/workspace/impl/MetadataStorageImpl.kt @@ -0,0 +1,9 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.gradle.scripting.shared.definition.workspace.impl + +import com.intellij.platform.workspace.storage.WorkspaceEntityInternalApi +import com.intellij.platform.workspace.storage.metadata.MetadataStorageBridge +import org.jetbrains.kotlin.gradle.scripting.shared.impl.MetadataStorageImpl + +@OptIn(WorkspaceEntityInternalApi::class) +internal object MetadataStorageImpl: MetadataStorageBridge(MetadataStorageImpl) diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.shared/src/org/jetbrains/kotlin/gradle/scripting/shared/definition/definitions.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.shared/src/org/jetbrains/kotlin/gradle/scripting/shared/definition/definitions.kt index 9ab5d278b316..875ccf0532df 100644 --- a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.shared/src/org/jetbrains/kotlin/gradle/scripting/shared/definition/definitions.kt +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.shared/src/org/jetbrains/kotlin/gradle/scripting/shared/definition/definitions.kt @@ -12,8 +12,6 @@ import kotlin.script.experimental.host.ScriptingHostConfiguration import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration import kotlin.script.templates.standard.ScriptTemplateWithArgs -const val DEFINITION_ID: String = "ideGradleScriptDefinitionId" - open class GradleScriptDefinition( compilationConfiguration: ScriptCompilationConfiguration, override val hostConfiguration: ScriptingHostConfiguration, @@ -26,9 +24,6 @@ open class GradleScriptDefinition( order = Int.MIN_VALUE } - override val definitionId: String - get() = DEFINITION_ID - override val canDefinitionBeSwitchedOff: Boolean = false override val compilationConfiguration: ScriptCompilationConfiguration by lazy { diff --git a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.shared/src/org/jetbrains/kotlin/gradle/scripting/shared/gradleScriptDefinitionsUtils.kt b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.shared/src/org/jetbrains/kotlin/gradle/scripting/shared/gradleScriptDefinitionsUtils.kt index 9b886241e0e9..a1817349b16e 100644 --- a/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.shared/src/org/jetbrains/kotlin/gradle/scripting/shared/gradleScriptDefinitionsUtils.kt +++ b/plugins/kotlin/gradle/scripting/kotlin.gradle.scripting.shared/src/org/jetbrains/kotlin/gradle/scripting/shared/gradleScriptDefinitionsUtils.kt @@ -3,7 +3,6 @@ package org.jetbrains.kotlin.gradle.scripting.shared import KotlinGradleScriptingBundle import com.intellij.gradle.toolingExtension.util.GradleVersionUtil.isGradleAtLeast -import com.intellij.openapi.vfs.VirtualFile import com.intellij.platform.workspace.storage.EntitySource import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.gradle.scripting.shared.definition.ErrorGradleScriptDefinition @@ -19,7 +18,7 @@ import java.nio.file.DirectoryStream import java.nio.file.Files import java.nio.file.Path import kotlin.io.path.* -import kotlin.script.experimental.api.* +import kotlin.script.experimental.api.ScriptCompilationConfigurationKeys import kotlin.script.experimental.host.ScriptingHostConfiguration import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration import kotlin.script.experimental.util.PropertiesCollection @@ -55,7 +54,7 @@ fun loadGradleDefinitions(params: GradleDefinitionsParams): List): List(), // There is no option in UI to set project wide gradleOptions - "gradleJvmOptions" to params.jvmArguments, - "gradleEnvironmentVariables" to params.environment + "gradleJvmOptions" to jvmArguments, + "gradleEnvironmentVariables" to environment ) } } @@ -157,15 +156,3 @@ val GradleScriptCompilationConfigurationKeys.externalProjectPath: PropertiesColl object KotlinGradleScriptEntitySource : EntitySource - -class GradleScriptModelData( - val models: Collection, - val javaHome: String? = null, -) - -class GradleScriptModel( - val virtualFile: VirtualFile, - val classPath: List, - val sourcePath: List, - val imports: List, -) \ No newline at end of file diff --git a/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinScriptHighlightingExtension.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinScriptHighlightingExtension.kt index b7626978d674..a40c97468fc2 100644 --- a/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinScriptHighlightingExtension.kt +++ b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinScriptHighlightingExtension.kt @@ -10,10 +10,14 @@ interface KotlinScriptHighlightingExtension { companion object { val EP_NAME: ProjectExtensionPointName = - ProjectExtensionPointName("org.jetbrains.kotlin.scriptHighlightingExtension") + ProjectExtensionPointName("org.jetbrains.kotlin.scriptHighlightingExtension") + /** + * Regular scripts (.kts) do not support external dependencies, so there is no need to postpone resolving. + * However, certain plugins (e.g., Gradle) may apply their own approach to scripting analysis, which occasionally doesn't imply lazy evaluation. + */ fun shouldHighlightScript(project: Project, file: KtFile): Boolean { - return EP_NAME.getExtensions(project).any { it.shouldHighlightScript(file) } + return EP_NAME.getExtensions(project).all { it.shouldHighlightScript(file) } } } } \ No newline at end of file