From 33ebfaabc04ad5cf5578fd951c2252dbc1c48c0b Mon Sep 17 00:00:00 2001 From: Kirill Bochkarev Date: Wed, 17 Dec 2025 22:50:15 +0000 Subject: [PATCH] IJPL-895 Workspace Model: codegen fixes and improvements - copyright for Metadata and Modifications.kt - fix deprecations - remove old code related to modifying sources - skip generated source roots - optimize imports in generated code - doPostponedOperationsAndUnblockDocument - dependencies for intellij.rd.ide.model.generated, intellij.android.projectSystem.gradle - IJPL-212407 Ignore NonPersistentEntitySource in generator Merge-request: IJ-MR-186285 Merged-by: Kirill Bochkarev GitOrigin-RevId: 2cb825d65b195612dbc24b614663724ed1528888 --- .../storage/generatedCodeCompatibility.kt | 2 +- .../BUILD.bazel | 1 + .../intellij.devkit.workspaceModel.iml | 1 + .../metaModel/WorkspaceMetaModelBuilder.kt | 2 +- .../metaModel/WorkspaceMetaModelBuilder.kt | 10 +- .../src/WorkspaceModelGenerator.kt | 3 +- .../src/codegen/writer/CodeWriter.kt | 282 ++++++----------- .../tests/BUILD.bazel | 1 + .../intellij.devkit.workspaceModel.tests.iml | 1 + .../addCopyrightComment/after/entity.kt | 8 - .../after/gen/SimpleEntityModifications.kt | 44 --- .../after/gen/impl/MetadataStorageImpl.kt | 26 -- .../after/gen/impl/SimpleEntityImpl.kt | 183 ----------- .../addCopyrightComment/before/entity.kt | 8 - .../compatibilityInvoke/before/entity.kt | 2 - .../codeGen/defaultProperty/after/entity.kt | 2 +- .../codeGen/finalProperty/after/entity.kt | 4 +- .../codeGen/format/after/ClassToImport.kt | 3 + .../testData/codeGen/format/after/entity.kt | 18 ++ .../after/gen/SimpleEntityModifications.kt | 10 +- .../after/gen/impl/MetadataStorageImpl.kt | 15 +- .../after/gen/impl/SimpleEntityImpl.kt | 28 +- .../codeGen/format/before/ClassToImport.kt | 3 + .../testData/codeGen/format/before/entity.kt | 18 ++ .../hierarchyOfEntities/before/entities.kt | 4 - .../testData/codeGen/imports/after/entity.kt | 32 -- .../gen/EntityWithManyImportsModifications.kt | 51 ---- .../after/gen/SimpleEntityModifications.kt | 43 --- .../gen/impl/EntityWithManyImportsImpl.kt | 284 ------------------ .../after/gen/impl/MetadataStorageImpl.kt | 39 --- .../after/gen/impl/SimpleEntityImpl.kt | 239 --------------- .../testData/codeGen/imports/before/entity.kt | 33 -- .../codeGen/propertiesOrder/after/entity.kt | 1 - .../after/gen/impl/ChildEntityImpl.kt | 1 - .../after/gen/impl/SimpleEntityImpl.kt | 1 - .../codeGen/propertiesOrder/before/entity.kt | 1 - .../refsFromAnotherModule/after/entity.kt | 2 +- .../simpleCaseWithCodestyle/after/entity.kt | 9 - .../simpleCaseWithCodestyle/before/entity.kt | 9 - .../codeGen/updateOldCode/after/entity.kt | 23 +- .../after/gen/impl/SimpleEntityImpl.kt | 1 - ...stractAllIntellijEntitiesGenerationTest.kt | 8 +- .../testSrc/AbstractEntityCodeGenTest.kt | 13 +- .../testSrc/LibrariesRequiredForWorkspace.kt | 12 +- 44 files changed, 242 insertions(+), 1239 deletions(-) delete mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/entity.kt delete mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/gen/SimpleEntityModifications.kt delete mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/gen/impl/MetadataStorageImpl.kt delete mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/gen/impl/SimpleEntityImpl.kt delete mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/before/entity.kt create mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/ClassToImport.kt create mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/entity.kt rename plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/{simpleCaseWithCodestyle => format}/after/gen/SimpleEntityModifications.kt (85%) rename plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/{simpleCaseWithCodestyle => format}/after/gen/impl/MetadataStorageImpl.kt (74%) rename plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/{simpleCaseWithCodestyle => format}/after/gen/impl/SimpleEntityImpl.kt (87%) create mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/before/ClassToImport.kt create mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/before/entity.kt delete mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/entity.kt delete mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/EntityWithManyImportsModifications.kt delete mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/SimpleEntityModifications.kt delete mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/impl/EntityWithManyImportsImpl.kt delete mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/impl/MetadataStorageImpl.kt delete mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/impl/SimpleEntityImpl.kt delete mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/before/entity.kt delete mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/after/entity.kt delete mode 100644 plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/before/entity.kt diff --git a/platform/workspace/storage/src/com/intellij/platform/workspace/storage/generatedCodeCompatibility.kt b/platform/workspace/storage/src/com/intellij/platform/workspace/storage/generatedCodeCompatibility.kt index 3ecf44402a0f..796c7746d1e6 100644 --- a/platform/workspace/storage/src/com/intellij/platform/workspace/storage/generatedCodeCompatibility.kt +++ b/platform/workspace/storage/src/com/intellij/platform/workspace/storage/generatedCodeCompatibility.kt @@ -9,7 +9,7 @@ public object CodeGeneratorVersions { /** these constants are accessed from WorkspaceImplObsoleteInspection */ private const val API_VERSION_INTERNAL = 3 private const val IMPL_MAJOR_VERSION_INTERNAL = 7 - private const val IMPL_MINOR_VERSION_INTERNAL = 8 + private const val IMPL_MINOR_VERSION_INTERNAL = 9 @set:TestOnly public var API_VERSION: Int = API_VERSION_INTERNAL diff --git a/plugins/devkit/intellij.devkit.workspaceModel/BUILD.bazel b/plugins/devkit/intellij.devkit.workspaceModel/BUILD.bazel index 543944982255..a18b02c99dab 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/BUILD.bazel +++ b/plugins/devkit/intellij.devkit.workspaceModel/BUILD.bazel @@ -67,6 +67,7 @@ jvm_library( "//platform/workspace/jps", "//java/java-impl:impl", "//plugins/kotlin/base/psi", + "//platform/code-style-impl:codeStyle-impl", ] ) ### auto-generated section `build intellij.devkit.workspaceModel` end \ No newline at end of file diff --git a/plugins/devkit/intellij.devkit.workspaceModel/intellij.devkit.workspaceModel.iml b/plugins/devkit/intellij.devkit.workspaceModel/intellij.devkit.workspaceModel.iml index 25fce83d4086..3c48a4b11f8e 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/intellij.devkit.workspaceModel.iml +++ b/plugins/devkit/intellij.devkit.workspaceModel/intellij.devkit.workspaceModel.iml @@ -64,5 +64,6 @@ + \ No newline at end of file diff --git a/plugins/devkit/intellij.devkit.workspaceModel/k1/src/metaModel/WorkspaceMetaModelBuilder.kt b/plugins/devkit/intellij.devkit.workspaceModel/k1/src/metaModel/WorkspaceMetaModelBuilder.kt index c4338592ea27..b0da35c84bd2 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/k1/src/metaModel/WorkspaceMetaModelBuilder.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/k1/src/metaModel/WorkspaceMetaModelBuilder.kt @@ -157,7 +157,7 @@ internal class WorkspaceMetaModelBuilder( val blobType = ValueType.Blob(javaClassFqn, superTypes) val inheritors = descriptor.inheritors(javaPsiFacade, allScope) - .filter { it.packageName == compiledObjModule.name } // && it.module == moduleDescriptor } + .filter { it.packageName == compiledObjModule.name && it.name.identifier != "NonPersistentEntitySource" } .map { classDescriptorToValueType(it, hashMapOf(javaClassFqn to blobType), true) } if (inheritors.isNotEmpty()) { diff --git a/plugins/devkit/intellij.devkit.workspaceModel/k2/src/metaModel/WorkspaceMetaModelBuilder.kt b/plugins/devkit/intellij.devkit.workspaceModel/k2/src/metaModel/WorkspaceMetaModelBuilder.kt index 675c0e979d32..d296e7c644f7 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/k2/src/metaModel/WorkspaceMetaModelBuilder.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/k2/src/metaModel/WorkspaceMetaModelBuilder.kt @@ -18,7 +18,6 @@ import org.jetbrains.kotlin.analysis.api.projectStructure.KaModule import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.types.KaClassType import org.jetbrains.kotlin.analysis.api.types.KaType -import org.jetbrains.kotlin.analysis.api.types.KaTypeNullability import org.jetbrains.kotlin.idea.stubindex.KotlinExactPackagesIndex import org.jetbrains.kotlin.name.StandardClassIds import java.util.concurrent.ConcurrentHashMap @@ -167,8 +166,9 @@ internal class WorkspaceMetaModelBuilder( for (inheritor in inheritorsKtClasses) { analyze(inheritor) { val inheritorSymbol = inheritor.namedClassSymbol - // FIXME: Check for module removed because of problems with kotlin.base.scripting in tests, might liead to other problems - if (inheritorSymbol != null && inheritorSymbol.packageName == compiledObjModule.name) { // && inheritorSymbol.containingModule == this@ObjModuleStub.kaModule ) { + // FIXME: Check for module (inheritorSymbol.containingModule == this@ObjModuleStub.kaModule) removed because of problems with + // kotlin.base.scripting in tests, might lead to other problems. + if (inheritorSymbol != null && inheritorSymbol.packageName == compiledObjModule.name && inheritorSymbol.name.identifier != "NonPersistentEntitySource") { val inheritorValueType = classSymbolToValueType(inheritorSymbol, hashMapOf(javaClassFqn to blobType), true) inheritors.add(inheritorValueType) } @@ -218,8 +218,8 @@ internal class WorkspaceMetaModelBuilder( hasParentAnnotation: Boolean, ): ValueType<*> { if (type !is KaClassType) error("$type is not a class in module ${compiledObjModule.name}") - if (type.nullability == KaTypeNullability.NULLABLE) { - val nonNullableType = type.withNullability(KaTypeNullability.NON_NULLABLE) + if (type.isMarkedNullable) { + val nonNullableType = type.withNullability(false) return ValueType.Optional(convertType(nonNullableType, knownTypes, hasParentAnnotation)) } diff --git a/plugins/devkit/intellij.devkit.workspaceModel/src/WorkspaceModelGenerator.kt b/plugins/devkit/intellij.devkit.workspaceModel/src/WorkspaceModelGenerator.kt index 743a9c7fcced..4fbb52942fa8 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/src/WorkspaceModelGenerator.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/src/WorkspaceModelGenerator.kt @@ -146,7 +146,8 @@ class WorkspaceModelGenerator(private val project: Project, private val coroutin const val RIDER_MODULES_PREFIX: String = "intellij.rider" val modulesWithAbstractTypes: Set = setOf( - "intellij.platform.workspace.storage.testEntities" + "intellij.platform.workspace.storage.testEntities", + "intellij.android.projectSystem.gradle" ) fun getInstance(project: Project): WorkspaceModelGenerator = project.service() diff --git a/plugins/devkit/intellij.devkit.workspaceModel/src/codegen/writer/CodeWriter.kt b/plugins/devkit/intellij.devkit.workspaceModel/src/codegen/writer/CodeWriter.kt index 4739002ac801..0c02eb113801 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/src/codegen/writer/CodeWriter.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/src/codegen/writer/CodeWriter.kt @@ -5,7 +5,7 @@ import com.intellij.devkit.workspaceModel.CodegenJarLoader import com.intellij.devkit.workspaceModel.DevKitWorkspaceModelBundle import com.intellij.devkit.workspaceModel.codegen.writer.CodeWriter.addGeneratedObjModuleFile import com.intellij.devkit.workspaceModel.metaModel.WorkspaceMetaModelProvider -import com.intellij.lang.ASTNode +import com.intellij.lang.LanguageImportStatements import com.intellij.notification.NotificationGroupManager import com.intellij.notification.NotificationType import com.intellij.openapi.application.PathManager @@ -23,27 +23,24 @@ import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.psi.PsiDirectory -import com.intellij.psi.PsiElement +import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiManager -import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.codeStyle.CodeStyleManager -import com.intellij.psi.impl.source.codeStyle.CodeEditUtil import com.intellij.util.concurrency.annotations.RequiresEdt import com.intellij.util.containers.FactoryMap -import com.intellij.util.containers.MultiMap import com.intellij.workspaceModel.codegen.deft.meta.CompiledObjModule import com.intellij.workspaceModel.codegen.engine.* import kotlinx.coroutines.delay import org.jetbrains.io.JsonReaderEx import org.jetbrains.io.JsonUtil -import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.children +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.psi.psiUtil.isPublic import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType import org.jetbrains.kotlin.resolve.ImportPath import java.io.IOException -import java.net.URL +import java.net.URI import java.nio.file.Path import java.util.* import java.util.jar.Manifest @@ -59,32 +56,27 @@ object CodeWriter { isTestSourceFolder: Boolean, isTestModule: Boolean, targetFolderGenerator: () -> VirtualFile?, existingTargetFolder: () -> VirtualFile?, - formatCode: Boolean + formatCode: Boolean, ) { val sourceFilePerObjModule = HashMap() val ktClasses = HashMap() readAction { - VfsUtilCore.processFilesRecursively(sourceFolder) { - if (it.extension == "kt") { - val ktFile = PsiManager.getInstance(project).findFile(it) as? KtFile? + VfsUtilCore.processFilesRecursively(sourceFolder) { file -> + if (file.extension == "kt") { + val ktFile = PsiManager.getInstance(project).findFile(file) as? KtFile? - ktFile?.declarations - ?.filterIsInstance() - ?.filter { it.name != null } - ?.forEach { ktClass -> - val fqName = ktClass.fqName!!.asString() - val objModuleName = fqName - .replace(ktClass.name!!, "") - .substringBeforeLast(".") + ktFile?.declarations?.filterIsInstance()?.filter { it.name != null }?.forEach { ktClass -> + val fqName = ktClass.fqName!!.asString() + val objModuleName = fqName.replace(ktClass.name!!, "").substringBeforeLast(".") - /** - * We find one virtual file for each module. - * This is necessary to find the relative path for the generated GeneratedObjModuleFile. - * See [addGeneratedObjModuleFile] method. - */ - sourceFilePerObjModule[objModuleName] = it - ktClasses[fqName] = ktClass - } + /** + * We find one virtual file for each module. + * This is necessary to find the relative path for the generated GeneratedObjModuleFile. + * See [addGeneratedObjModuleFile] method. + */ + sourceFilePerObjModule[objModuleName] = file + ktClasses[fqName] = ktClass + } } return@processFilesRecursively true } @@ -118,7 +110,7 @@ object CodeWriter { val genFolder = existingTargetFolder.invoke() if (genFolder != null) { indicator.text = DevKitWorkspaceModelBundle.message("progress.text.removing.old.code") - removeGeneratedCode(ktClasses, genFolder) + removeGeneratedCode(genFolder) } return@runWriteActionWithCancellableProgressInDispatchThread } @@ -129,14 +121,9 @@ object CodeWriter { return@runWriteActionWithCancellableProgressInDispatchThread } - // compatibility invoke in FacetEntity and KotlinSettingsEntity - val savedCompatibilityInvokeCode = mutableMapOf() - saveCompatibilityCode(ktClasses, savedCompatibilityInvokeCode) - indicator.text = DevKitWorkspaceModelBundle.message("progress.text.removing.old.code") - removeGeneratedCode(ktClasses, genFolder) + removeGeneratedCode(genFolder) - val topLevelDeclarations = MultiMap.create>>() val importsByFile = FactoryMap.create { Imports(it.packageFqName.asString()) } val generatedFiles = ArrayList() @@ -157,9 +144,7 @@ object CodeWriter { addGeneratedObjClassFile( code, generatedFiles, project, sourceFolder, genFolder, - ktClasses, importsByFile, - topLevelDeclarations, psiFactory, - savedCompatibilityInvokeCode + ktClasses, importsByFile, psiFactory, ) } } @@ -167,30 +152,20 @@ object CodeWriter { importsByFile.forEach { (file, imports) -> addImports(file, imports) } + + if (!formatCode) return@runWriteActionWithCancellableProgressInDispatchThread + val copiedEditorconfig = copyEditorConfigIfIntellij(project, genFolder) - generatedFiles.forEachIndexed { i, file -> + val kotlinImportOptimizer = generatedFiles.firstOrNull()?.let { LanguageImportStatements.INSTANCE.forFile(it) }?.firstOrNull() + for ((i, file) in generatedFiles.withIndex()) { + DumbService.getInstance(project).completeJustSubmittedTasks() indicator.fraction = 0.25 + 0.7 * i / generatedFiles.size - if (formatCode) { - CodeStyleManager.getInstance(project).reformat(file) - } - file.apiFileNameForImplFile?.let { ktClasses[it] }?.containingKtFile?.let { apiFile -> copyHeaderComment(apiFile, file) } + PsiDocumentManager.getInstance(file.project).doPostponedOperationsAndUnblockDocument(file.viewProvider.document!!) + addCopyright(file, ktClasses) + CodeStyleManager.getInstance(project).reformat(file) + kotlinImportOptimizer?.processFile(file)?.run() } copiedEditorconfig?.delete(CodeWriter) - topLevelDeclarations.entrySet().forEach { (file, placeAndDeclarations) -> - val addedElements = ArrayList() - for ((place, declarations) in placeAndDeclarations) { - var nextPlace: PsiElement = place - val newElements = ArrayList() - for (declaration in declarations) { - val added = file.addAfter(declaration, nextPlace) as KtDeclaration - newElements.add(added) - nextPlace = added - } - addGeneratedRegionStartComment(file, newElements.first()) - addGeneratedRegionEndComment(file, newElements.last()) - addedElements.addAll(newElements) - } - } } } } @@ -199,11 +174,24 @@ object CodeWriter { if (!IntelliJProjectUtil.isIntelliJPlatformProject(project)) { return null } - val editorconfigFile = VirtualFileManager.getInstance().refreshAndFindFileByNioPath(Path.of(PathManager.getHomePath(), "community", ".editorconfig"))!! + val editorconfigFile = + VirtualFileManager.getInstance().refreshAndFindFileByNioPath(Path.of(PathManager.getHomePath(), "community", ".editorconfig"))!! val copied = VfsUtil.copyFile(this, editorconfigFile, genFolder) return copied } + private fun addCopyright(file: KtFile, ktClasses: HashMap) { + if (file.name == GENERATED_METADATA_STORAGE_FILE) { + val someEntitySourceFile = ktClasses.values.firstOrNull { it.name?.contains("Entity") ?: false }?.containingKtFile + val anySourceFile = someEntitySourceFile ?: ktClasses.values.firstOrNull()?.containingKtFile ?: return + copyHeaderComment(anySourceFile, file) + return + } + val sourceClassName = getSourceClassNameForGeneratedFile(file) + val sourceFile = ktClasses[sourceClassName]?.containingKtFile ?: return + copyHeaderComment(sourceFile, file) + } + /** * Documentation for [com.intellij.openapi.project.IndexNotReadyException] says that it's enough to run completeJustSubmittedTasks only * once. However, in practice this is not enough. @@ -227,12 +215,17 @@ object CodeWriter { return true } - val message = if (apiVersionFromDownloadedJar == CodegenApiVersion.UNKNOWN_VERSION || apiVersionInDevkit > apiVersionFromDownloadedJar) { - DevKitWorkspaceModelBundle.message("notification.workspace.incompatible.codegen.api.versions.content.newer", apiVersionInDevkit, apiVersionFromDownloadedJar) - } - else { - DevKitWorkspaceModelBundle.message("notification.workspace.incompatible.codegen.api.versions.content.older", apiVersionInDevkit, apiVersionFromDownloadedJar) - } + val message = + if (apiVersionFromDownloadedJar == CodegenApiVersion.UNKNOWN_VERSION || apiVersionInDevkit > apiVersionFromDownloadedJar) { + DevKitWorkspaceModelBundle.message("notification.workspace.incompatible.codegen.api.versions.content.newer", + apiVersionInDevkit, + apiVersionFromDownloadedJar) + } + else { + DevKitWorkspaceModelBundle.message("notification.workspace.incompatible.codegen.api.versions.content.older", + apiVersionInDevkit, + apiVersionFromDownloadedJar) + } val groupId = DevKitWorkspaceModelBundle.message("notification.workspace.incompatible.codegen.api.versions") NotificationGroupManager.getInstance() @@ -245,7 +238,7 @@ object CodeWriter { private fun getApiVersionFromJSON(clazz: Class<*>): String { return getApiVersionFromJarFile(clazz, CodegenApiVersion.JSON_RELATIVE_PATH) { jsonPath -> - URL(jsonPath).openStream().reader().use { reader -> + URI(jsonPath).toURL().openStream().reader().use { reader -> val jsonReader = JsonReaderEx(reader.readText()) val objects = JsonUtil.nextObject(jsonReader) objects[CodegenApiVersion.ATTRIBUTE_NAME] as? String @@ -255,7 +248,7 @@ object CodeWriter { private fun getApiVersionFromManifest(clazz: Class<*>): String { return getApiVersionFromJarFile(clazz, CodegenApiVersion.MANIFEST_RELATIVE_PATH) { manifestPath -> - URL(manifestPath).openStream().use { + URI(manifestPath).toURL().openStream().use { val manifest = Manifest(it) val attributes = manifest.mainAttributes attributes.getValue(CodegenApiVersion.ATTRIBUTE_NAME) @@ -292,21 +285,7 @@ object CodeWriter { return entitiesImplementations + metadataStorageImplementation } - private fun saveCompatibilityCode(ktClasses: Map, savedCompatibilityInvokeCode: MutableMap) { - for (ktClass in ktClasses.values) { - val companionDeclaration = ktClass.body?.declarations?.find { it is KtObjectDeclaration && it.isCompanion() } as? KtObjectDeclaration - ?: continue - val compatibilityInvoke = companionDeclaration.declarations.find { it is KtNamedFunction && it.name == "create" && it.annotationEntries.any { it.shortName.toString() == "Deprecated" } } - ?: continue - savedCompatibilityInvokeCode[ktClass] = compatibilityInvoke.copy() - } - } - - private fun removeGeneratedCode(ktClasses: Map, genFolder: VirtualFile) { - ktClasses.values.flatMapTo(HashSet()) { listOfNotNull(it.containingFile.node, it.body?.node) }.forEach { - removeChildrenInGeneratedRegions(it) - } - + private fun removeGeneratedCode(genFolder: VirtualFile) { //remove generated files, e.g. MetadataStorageImpl.kt removeFiles(genFolder) { it.isGeneratedFile @@ -354,13 +333,9 @@ object CodeWriter { } private fun addGeneratedObjClassFile( - code: ObjClassGeneratedCode, generatedFiles: MutableList, - project: Project, sourceFolder: VirtualFile, genFolder: VirtualFile, - ktClasses: Map, importsByFile: MutableMap, - topLevelDeclarations: MultiMap>>, psiFactory: KtPsiFactory, - savedCompatibilityInvokeCode: MutableMap, + code: ObjClassGeneratedCode, generatedFiles: MutableList, project: Project, sourceFolder: VirtualFile, genFolder: VirtualFile, + ktClasses: Map, importsByFile: MutableMap, psiFactory: KtPsiFactory, ) { - if (code.target.name in SKIPPED_TYPES) return val target = code.target @@ -370,59 +345,51 @@ object CodeWriter { LOG.warn("Class $apiInterfaceName was not found") return } - val apiFile = apiClass.containingKtFile - val apiImports = importsByFile.getValue(apiFile) - addInnerDeclarations(apiClass, code, apiImports, savedCompatibilityInvokeCode) - + val apiPackageFqName = apiClass.containingKtFile.packageFqName val sourceFile = apiClass.containingFile.virtualFile val targetDirectory = getPsiDirectory(project, genFolder, sourceFolder, sourceFile) run { - val apiPackageFqnName = apiFile.packageFqName.asString() + val apiPackageFqnName = apiPackageFqName.asString() val generatedApiImports = Imports(apiPackageFqnName) apiClass.containingKtFile.importDirectives.mapNotNull { it.importPath }.forEach { import -> generatedApiImports.add(import.pathStr) } val psiFactory = KtPsiFactory(apiClass.project) - val topLevelCode = code.topLevelCode ?: return@run - val filename = "${code.target.name}Modifications" - val generatedApiFile = psiFactory.createFile("$filename.kt", generatedApiImports.findAndRemoveFqns(topLevelCode)) + val topLevelCode = code.topLevelCode ?: "" + val filename = "${code.target.name}$GENERATED_MODIFICATIONS_SUFFIX" + val generatedModificationsFile = psiFactory.createFile(filename, generatedApiImports.findAndRemoveFqns(topLevelCode)) + generatedModificationsFile.packageFqName = apiPackageFqName - val compatibilityTopLevelDeclarations = mutableListOf() - val declarations = generatedApiFile.declarations + val declarations = generatedModificationsFile.declarations for (declaration in declarations) { if (declaration.firstChild.text.contains("Deprecated")) { - compatibilityTopLevelDeclarations.add(declaration.copy() as KtDeclaration) declaration.delete() continue } } - if (compatibilityTopLevelDeclarations.isNotEmpty()) { - topLevelDeclarations.putValue(apiFile, apiClass to compatibilityTopLevelDeclarations) - } - val visibility = apiClass.visibilityModifierType().takeIf { !apiClass.isPublic } if (visibility != null) { - generatedApiFile.declarations.forEach { it.addModifier(visibility) } + generatedModificationsFile.declarations.forEach { it.addModifier(visibility) } } val apiTargetDirectory = targetDirectory.parent!! - apiTargetDirectory.findFile(generatedApiFile.name)?.delete() + apiTargetDirectory.findFile(generatedModificationsFile.name)?.delete() //todo remove other old generated files - val addedFile = apiTargetDirectory.add(generatedApiFile) as KtFile + val addedFile = apiTargetDirectory.add(generatedModificationsFile) as KtFile generatedFiles.add(addedFile) importsByFile[addedFile] = generatedApiImports } val implementationClassText = code.implementationClass if (implementationClassText != null) { - val implPackageFqnName = "${apiFile.packageFqName.asString()}.impl" + val implPackageFqnName = "${apiPackageFqName.asString()}.impl" val implImports = Imports(implPackageFqnName) - val implFile = psiFactory.createFile("${code.target.name}Impl.kt", implImports.findAndRemoveFqns(implementationClassText)) + val implFile = + psiFactory.createFile("${code.target.name}$GENERATED_IMPL_SUFFIX", implImports.findAndRemoveFqns(implementationClassText)) apiClass.containingKtFile.importDirectives.mapNotNull { it.importPath }.forEach { import -> implImports.add(import.pathStr) } - targetDirectory.findFile(implFile.name)?.delete() - //todo remove other old generated files + targetDirectory.findFile(implFile.name)?.delete() //todo remove other old generated files val addedFile = targetDirectory.add(implFile) as KtFile generatedFiles.add(addedFile) importsByFile[addedFile] = implImports @@ -437,13 +404,13 @@ object CodeWriter { } private fun copyHeaderComment(apiFile: KtFile, implFile: KtFile) { - val apiPackageDirectiveNode = apiFile.packageDirective?.node ?: return - val fileNode = implFile.node - var nodeToCopy = apiPackageDirectiveNode.treePrev - var anchorBefore = fileNode.firstChildNode + val firstNonComment = apiFile.fileAnnotationList?.node ?: apiFile.packageDirective?.node ?: return + val implFileNode = implFile.node + var nodeToCopy = firstNonComment.treePrev + var anchorBefore = implFileNode.firstChildNode while (nodeToCopy != null) { val copied = nodeToCopy.copyElement() - fileNode.addChild(copied, anchorBefore) + implFileNode.addChild(copied, anchorBefore) anchorBefore = copied nodeToCopy = nodeToCopy.treePrev } @@ -466,82 +433,21 @@ object CodeWriter { } } - private fun addInnerDeclarations(ktClass: KtClassOrObject, code: ObjClassGeneratedCode, imports: Imports, savedCompatibilityInvokeCode: MutableMap) { - if (code.builderInterface.isEmpty()) return - val psiFactory = KtPsiFactory(ktClass.project) - val builderInterface = ktClass.addDeclaration(psiFactory.createClass(imports.findAndRemoveFqns(code.builderInterface))) - val companionObject = ktClass.addDeclaration(psiFactory.createObject(imports.findAndRemoveFqns(code.companionObject))) - val body = ktClass.getOrCreateBody() - addGeneratedRegionStartComment(body, builderInterface) - addGeneratedRegionEndComment(body, companionObject) - - val compatibilityInvoke = savedCompatibilityInvokeCode.remove(ktClass) ?: return - addCompatibilityInvoke(companionObject, compatibilityInvoke, psiFactory) - } - - private fun addCompatibilityInvoke(companionObject: KtObjectDeclaration, compatibilityInvoke: PsiElement, psiFactory: KtPsiFactory) { - val companionBody = companionObject.getOrCreateBody() - companionBody.addBefore(compatibilityInvoke, companionBody.rBrace) - companionBody.addBefore(psiFactory.createNewLine(), companionBody.rBrace) - companionBody.addBefore(psiFactory.createComment(GENERATED_COMPATIBILITY_REGION_END), companionBody.rBrace) - } - - private fun addGeneratedRegionStartComment(parent: KtElement, place: KtElement) { - val psiFactory = KtPsiFactory(parent.project) - val startCommentElements = psiFactory.createFile("\n$GENERATED_REGION_START\n").children - parent.addRangeBefore(startCommentElements.first { it is PsiWhiteSpace }, startCommentElements.last(), place) - } - - private fun addGeneratedRegionEndComment(parent: KtElement, place: KtElement) { - val psiFactory = KtPsiFactory(parent.project) - val endCommentElements = psiFactory.createFile("\n$GENERATED_REGION_END\n").children - parent.addRangeAfter(endCommentElements.first { it is PsiWhiteSpace }, endCommentElements.last(), place) - } - - private fun removeChildrenInGeneratedRegions(node: ASTNode) { - for (region in findGeneratedRegions(node)) { - CodeEditUtil.removeChildren(node, region.first, region.second) + private fun getSourceClassNameForGeneratedFile(file: KtFile): String? { + val packageName = file.packageFqName.asString() + if (file.name.endsWith(GENERATED_IMPL_SUFFIX)) { + // packageName includes "impl" + return "${packageName.dropLast(4)}${file.name.dropLast(GENERATED_IMPL_SUFFIX.length)}" } + if (file.name.endsWith(GENERATED_MODIFICATIONS_SUFFIX)) { + return "$packageName.${file.name.dropLast(GENERATED_MODIFICATIONS_SUFFIX.length)}" + } + return null } - private fun findGeneratedRegions(node: ASTNode): ArrayList> { - val generatedRegions = ArrayList>() - var regionStart: ASTNode? = null - node.children().forEach { child -> - if (child.isGeneratedRegionStart) { - regionStart = if (child.treePrev?.elementType == KtTokens.WHITE_SPACE) child.treePrev else child - } - else if (child.isGeneratedRegionEnd) { - regionStart?.let { generatedRegions.add(it to child) } - } - } - return generatedRegions - } + private const val GENERATED_IMPL_SUFFIX = "Impl.kt" - private val KtFile.apiFileNameForImplFile: String? - get() { - val packageName = packageFqName.asString() - if (!packageName.endsWith(".impl") || !name.endsWith("Impl.kt")) return null - return "${packageFqName.asString().dropLast(4)}${name.dropLast(7)}" - } - - // generated region - private const val GENERATED_REGION_START = "//region generated code" - - private const val GENERATED_REGION_END = "//endregion" - - private val ASTNode.isGeneratedRegionStart: Boolean - get() = - elementType == KtTokens.EOL_COMMENT && text == GENERATED_REGION_START || firstChildNode?.isGeneratedRegionStart == true - - private val ASTNode.isGeneratedRegionEnd: Boolean - get() = - elementType == KtTokens.EOL_COMMENT && text == GENERATED_REGION_END - - // compatability region - private const val GENERATED_COMPATIBILITY_REGION_START = "//region compatibility generated code" - - private const val GENERATED_COMPATIBILITY_REGION_END = "//endregion compatibility generated code" + private const val GENERATED_MODIFICATIONS_SUFFIX = "Modifications.kt" private const val GENERATED_METADATA_STORAGE_FILE = "MetadataStorageImpl.kt" diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/BUILD.bazel b/plugins/devkit/intellij.devkit.workspaceModel/tests/BUILD.bazel index c2f7a5029c8a..a425281eee14 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/BUILD.bazel +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/BUILD.bazel @@ -52,6 +52,7 @@ jvm_library( "//plugins/editorconfig/backend", "//plugins/editorconfig/backend:backend_test_lib", "//plugins/editorconfig:editorconfig-plugin", + "@lib//:studio-platform", ], runtime_deps = ["//plugins/devkit"] ) diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/intellij.devkit.workspaceModel.tests.iml b/plugins/devkit/intellij.devkit.workspaceModel/tests/intellij.devkit.workspaceModel.tests.iml index b4b758c86416..60c54ea2fdf8 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/intellij.devkit.workspaceModel.tests.iml +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/intellij.devkit.workspaceModel.tests.iml @@ -41,5 +41,6 @@ + \ No newline at end of file diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/entity.kt deleted file mode 100644 index d716adf9ef3d..000000000000 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/entity.kt +++ /dev/null @@ -1,8 +0,0 @@ -//some copyright comment -package com.intellij.workspaceModel.test.api - -import com.intellij.platform.workspace.storage.WorkspaceEntity - -interface SimpleEntity : WorkspaceEntity { - val name: String -} diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/gen/SimpleEntityModifications.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/gen/SimpleEntityModifications.kt deleted file mode 100644 index dafdb38bb697..000000000000 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/gen/SimpleEntityModifications.kt +++ /dev/null @@ -1,44 +0,0 @@ -@file:JvmName("SimpleEntityModifications") - -package com.intellij.workspaceModel.test.api - -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.WorkspaceEntity -import com.intellij.platform.workspace.storage.WorkspaceEntityBuilder - -@GeneratedCodeApiVersion(3) -interface SimpleEntityBuilder: WorkspaceEntityBuilder{ -override var entitySource: EntitySource -var name: String -} - -internal object SimpleEntityType : EntityType(){ -override val entityClass: Class get() = SimpleEntity::class.java -operator fun invoke( -name: String, -entitySource: EntitySource, -init: (SimpleEntityBuilder.() -> Unit)? = null, -): SimpleEntityBuilder{ -val builder = builder() -builder.name = name -builder.entitySource = entitySource -init?.invoke(builder) -return builder -} -} - -fun MutableEntityStorage.modifySimpleEntity( -entity: SimpleEntity, -modification: SimpleEntityBuilder.() -> Unit, -): SimpleEntity = modifyEntity(SimpleEntityBuilder::class.java, entity, modification) - -@JvmOverloads -@JvmName("createSimpleEntity") -fun SimpleEntity( -name: String, -entitySource: EntitySource, -init: (SimpleEntityBuilder.() -> Unit)? = null, -): SimpleEntityBuilder = SimpleEntityType(name, entitySource, init) diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/gen/impl/MetadataStorageImpl.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/gen/impl/MetadataStorageImpl.kt deleted file mode 100644 index 4670d71d1f41..000000000000 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/gen/impl/MetadataStorageImpl.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.intellij.workspaceModel.test.api.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 = EntityMetadata(fqName = "com.intellij.workspaceModel.test.api.SimpleEntity", entityDataFqName = "com.intellij.workspaceModel.test.api.impl.SimpleEntityData", supertypes = listOf("com.intellij.platform.workspace.storage.WorkspaceEntity"), 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 = "name", valueType = primitiveTypeStringNotNullable, withDefault = false)), extProperties = listOf(), isAbstract = false) - -addMetadata(typeMetadata) -} - -override fun initializeMetadataHash(){ -addMetadataHash(typeFqn = "com.intellij.workspaceModel.test.api.SimpleEntity", metadataHash = -455948645) -} -} diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/gen/impl/SimpleEntityImpl.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/gen/impl/SimpleEntityImpl.kt deleted file mode 100644 index 6d795a9005f1..000000000000 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/after/gen/impl/SimpleEntityImpl.kt +++ /dev/null @@ -1,183 +0,0 @@ -//some copyright comment -package com.intellij.workspaceModel.test.api.impl - -import com.intellij.platform.workspace.storage.ConnectionId -import com.intellij.platform.workspace.storage.EntitySource -import com.intellij.platform.workspace.storage.GeneratedCodeApiVersion -import com.intellij.platform.workspace.storage.GeneratedCodeImplVersion -import com.intellij.platform.workspace.storage.MutableEntityStorage -import com.intellij.platform.workspace.storage.WorkspaceEntity -import com.intellij.platform.workspace.storage.WorkspaceEntityBuilder -import com.intellij.platform.workspace.storage.WorkspaceEntityInternalApi -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 com.intellij.workspaceModel.test.api.SimpleEntity -import com.intellij.workspaceModel.test.api.SimpleEntityBuilder - -@GeneratedCodeApiVersion(3) -@GeneratedCodeImplVersion(7) -@OptIn(WorkspaceEntityInternalApi::class) -internal class SimpleEntityImpl(private val dataSource: SimpleEntityData): SimpleEntity, WorkspaceEntityBase(dataSource) { - -private companion object { - -private val connections = listOf() - -} - -override val name: String -get() { -readField("name") -return dataSource.name -} - -override val entitySource: EntitySource -get() { -readField("entitySource") -return dataSource.entitySource -} - -override fun connectionIdList(): List { -return connections -} - - -internal class Builder(result: SimpleEntityData?): ModifiableWorkspaceEntityBase(result), SimpleEntityBuilder { -internal constructor(): this(SimpleEntityData()) - -override fun applyToBuilder(builder: MutableEntityStorage){ -if (this.diff != null){ -if (existsInBuilder(builder)){ -this.diff = builder -return -} -else{ -error("Entity SimpleEntity 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().isNameInitialized()){ -error("Field SimpleEntity#name 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 SimpleEntity -if (this.entitySource != dataSource.entitySource) this.entitySource = dataSource.entitySource -if (this.name != dataSource.name) this.name = dataSource.name -updateChildToParentReferences(parents) -} - - -override var entitySource: EntitySource -get() = getEntityData().entitySource -set(value) { -checkModificationAllowed() -getEntityData(true).entitySource = value -changedProperty.add("entitySource") - -} -override var name: String -get() = getEntityData().name -set(value) { -checkModificationAllowed() -getEntityData(true).name = value -changedProperty.add("name") -} - -override fun getEntityClass(): Class = SimpleEntity::class.java -} - -} - -@OptIn(WorkspaceEntityInternalApi::class) -internal class SimpleEntityData : WorkspaceEntityData(){ -lateinit var name: String - -internal fun isNameInitialized(): Boolean = ::name.isInitialized - -override fun wrapAsModifiable(diff: MutableEntityStorage): WorkspaceEntityBuilder{ -val modifiable = SimpleEntityImpl.Builder(null) -modifiable.diff = diff -modifiable.id = createEntityId() -return modifiable -} - -@OptIn(EntityStorageInstrumentationApi::class) -override fun createEntity(snapshot: EntityStorageInstrumentation): SimpleEntity{ -val entityId = createEntityId() -return snapshot.initializeEntity(entityId){ -val entity = SimpleEntityImpl(this) -entity.snapshot = snapshot -entity.id = entityId -entity -} -} - -override fun getMetadata(): EntityMetadata{ -return MetadataStorageImpl.getMetadataByTypeFqn("com.intellij.workspaceModel.test.api.SimpleEntity") as EntityMetadata -} - -override fun getEntityInterface(): Class{ -return SimpleEntity::class.java -} - -override fun createDetachedEntity(parents: List>): WorkspaceEntityBuilder<*>{ -return SimpleEntity(name, entitySource) -} - -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 SimpleEntityData -if (this.entitySource != other.entitySource) return false -if (this.name != other.name) return false -return true -} - -override fun equalsIgnoringEntitySource(other: Any?): Boolean{ -if (other == null) return false -if (this.javaClass != other.javaClass) return false -other as SimpleEntityData -if (this.name != other.name) return false -return true -} - -override fun hashCode(): Int{ -var result = entitySource.hashCode() -result = 31 * result + name.hashCode() -return result -} -override fun hashCodeIgnoringEntitySource(): Int{ -var result = javaClass.hashCode() -result = 31 * result + name.hashCode() -return result -} -} diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/before/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/before/entity.kt deleted file mode 100644 index d716adf9ef3d..000000000000 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/addCopyrightComment/before/entity.kt +++ /dev/null @@ -1,8 +0,0 @@ -//some copyright comment -package com.intellij.workspaceModel.test.api - -import com.intellij.platform.workspace.storage.WorkspaceEntity - -interface SimpleEntity : WorkspaceEntity { - val name: String -} diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/compatibilityInvoke/before/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/compatibilityInvoke/before/entity.kt index 916b700f574f..a78449934e14 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/compatibilityInvoke/before/entity.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/compatibilityInvoke/before/entity.kt @@ -1,7 +1,5 @@ package com.intellij.workspaceModel.test.api -import com.intellij.platform.workspace.storage.WorkspaceEntity - import com.intellij.platform.workspace.storage.EntitySource import com.intellij.platform.workspace.storage.EntityType import com.intellij.platform.workspace.storage.GeneratedCodeApiVersion diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/defaultProperty/after/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/defaultProperty/after/entity.kt index 866f3aaf5bfb..e8162d3b606e 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/defaultProperty/after/entity.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/defaultProperty/after/entity.kt @@ -1,7 +1,7 @@ package com.intellij.workspaceModel.test.api -import com.intellij.platform.workspace.storage.WorkspaceEntity import com.intellij.platform.workspace.storage.annotations.Default +import com.intellij.platform.workspace.storage.WorkspaceEntity interface DefaultFieldEntity : WorkspaceEntity { val version: Int diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/finalProperty/after/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/finalProperty/after/entity.kt index 22bad3e39d67..713ab406c071 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/finalProperty/after/entity.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/finalProperty/after/entity.kt @@ -1,9 +1,9 @@ package com.intellij.workspaceModel.test.api -import com.intellij.platform.workspace.storage.GeneratedCodeApiVersion -import com.intellij.platform.workspace.storage.MutableEntityStorage import com.intellij.platform.workspace.storage.WorkspaceEntity +import com.intellij.platform.workspace.storage.GeneratedCodeApiVersion import com.intellij.platform.workspace.storage.WorkspaceEntityBuilder +import com.intellij.platform.workspace.storage.MutableEntityStorage interface FinalFieldsEntity : WorkspaceEntity { diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/ClassToImport.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/ClassToImport.kt new file mode 100644 index 000000000000..90d23110cc06 --- /dev/null +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/ClassToImport.kt @@ -0,0 +1,3 @@ +package com.intellij.another.module + +class ClassToImport \ No newline at end of file diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/entity.kt new file mode 100644 index 000000000000..90dd7bff30e1 --- /dev/null +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/entity.kt @@ -0,0 +1,18 @@ +// 2700-2200 BCE fake copyright for test +// another line of fake copyright +package com.intellij.workspaceModel.test.api + +// imports are in wrong order purposefully +import java.nio.file.Path +import com.intellij.platform.workspace.storage.WorkspaceEntity +import java.io.File +import com.intellij.another.module.ClassToImport + +interface SimpleEntity : WorkspaceEntity { + val version: Int + val name: String + val isSimple: Boolean + val imported: ClassToImport +} + +data class UnrelatedToWsm(val name: String, val file: File, val path: Path) diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/after/gen/SimpleEntityModifications.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/gen/SimpleEntityModifications.kt similarity index 85% rename from plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/after/gen/SimpleEntityModifications.kt rename to plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/gen/SimpleEntityModifications.kt index be6f7a10e721..3e10ea380e0d 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/after/gen/SimpleEntityModifications.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/gen/SimpleEntityModifications.kt @@ -1,12 +1,14 @@ +// 2700-2200 BCE fake copyright for test +// another line of fake copyright @file:JvmName("SimpleEntityModifications") package com.intellij.workspaceModel.test.api +import com.intellij.another.module.ClassToImport 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.WorkspaceEntity import com.intellij.platform.workspace.storage.WorkspaceEntityBuilder @GeneratedCodeApiVersion(3) @@ -15,6 +17,7 @@ interface SimpleEntityBuilder : WorkspaceEntityBuilder { var version: Int var name: String var isSimple: Boolean + var imported: ClassToImport } internal object SimpleEntityType : EntityType() { @@ -23,6 +26,7 @@ internal object SimpleEntityType : EntityType version: Int, name: String, isSimple: Boolean, + imported: ClassToImport, entitySource: EntitySource, init: (SimpleEntityBuilder.() -> Unit)? = null, ): SimpleEntityBuilder { @@ -30,6 +34,7 @@ internal object SimpleEntityType : EntityType builder.version = version builder.name = name builder.isSimple = isSimple + builder.imported = imported builder.entitySource = entitySource init?.invoke(builder) return builder @@ -47,6 +52,7 @@ fun SimpleEntity( version: Int, name: String, isSimple: Boolean, + imported: ClassToImport, entitySource: EntitySource, init: (SimpleEntityBuilder.() -> Unit)? = null, -): SimpleEntityBuilder = SimpleEntityType(version, name, isSimple, entitySource, init) +): SimpleEntityBuilder = SimpleEntityType(version, name, isSimple, imported, entitySource, init) diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/after/gen/impl/MetadataStorageImpl.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/gen/impl/MetadataStorageImpl.kt similarity index 74% rename from plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/after/gen/impl/MetadataStorageImpl.kt rename to plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/gen/impl/MetadataStorageImpl.kt index e65009db0ed3..734028404a99 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/after/gen/impl/MetadataStorageImpl.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/gen/impl/MetadataStorageImpl.kt @@ -1,3 +1,5 @@ +// 2700-2200 BCE fake copyright for test +// another line of fake copyright package com.intellij.workspaceModel.test.api.impl import com.intellij.platform.workspace.storage.WorkspaceEntityInternalApi @@ -45,6 +47,16 @@ internal object MetadataStorageImpl : MetadataStorageBase() { isOpen = false, name = "isSimple", valueType = primitiveTypeBooleanNotNullable, + withDefault = false), + OwnPropertyMetadata(isComputable = false, + isKey = false, + isOpen = false, + name = "imported", + valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = false, + typeMetadata = FinalClassMetadata.ClassMetadata( + fqName = "com.intellij.another.module.ClassToImport", + properties = listOf(), + supertypes = listOf())), withDefault = false)), extProperties = listOf(), isAbstract = false) @@ -53,6 +65,7 @@ internal object MetadataStorageImpl : MetadataStorageBase() { } override fun initializeMetadataHash() { - addMetadataHash(typeFqn = "com.intellij.workspaceModel.test.api.SimpleEntity", metadataHash = 284369588) + addMetadataHash(typeFqn = "com.intellij.workspaceModel.test.api.SimpleEntity", metadataHash = 711104309) + addMetadataHash(typeFqn = "com.intellij.another.module.ClassToImport", metadataHash = -2116758707) } } diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/after/gen/impl/SimpleEntityImpl.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/gen/impl/SimpleEntityImpl.kt similarity index 87% rename from plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/after/gen/impl/SimpleEntityImpl.kt rename to plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/gen/impl/SimpleEntityImpl.kt index 08c515e83f42..f5eae13297bf 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/after/gen/impl/SimpleEntityImpl.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/after/gen/impl/SimpleEntityImpl.kt @@ -1,5 +1,8 @@ +// 2700-2200 BCE fake copyright for test +// another line of fake copyright package com.intellij.workspaceModel.test.api.impl +import com.intellij.another.module.ClassToImport import com.intellij.platform.workspace.storage.ConnectionId import com.intellij.platform.workspace.storage.EntitySource import com.intellij.platform.workspace.storage.GeneratedCodeApiVersion @@ -43,6 +46,11 @@ internal class SimpleEntityImpl(private val dataSource: SimpleEntityData) : Simp readField("isSimple") return dataSource.isSimple } + override val imported: ClassToImport + get() { + readField("imported") + return dataSource.imported + } override val entitySource: EntitySource get() { @@ -88,6 +96,9 @@ internal class SimpleEntityImpl(private val dataSource: SimpleEntityData) : Simp if (!getEntityData().isNameInitialized()) { error("Field SimpleEntity#name should be initialized") } + if (!getEntityData().isImportedInitialized()) { + error("Field SimpleEntity#imported should be initialized") + } } override fun connectionIdList(): List { @@ -101,6 +112,7 @@ internal class SimpleEntityImpl(private val dataSource: SimpleEntityData) : Simp if (this.version != dataSource.version) this.version = dataSource.version if (this.name != dataSource.name) this.name = dataSource.name if (this.isSimple != dataSource.isSimple) this.isSimple = dataSource.isSimple + if (this.imported != dataSource.imported) this.imported = dataSource.imported updateChildToParentReferences(parents) } @@ -134,6 +146,14 @@ internal class SimpleEntityImpl(private val dataSource: SimpleEntityData) : Simp getEntityData(true).isSimple = value changedProperty.add("isSimple") } + override var imported: ClassToImport + get() = getEntityData().imported + set(value) { + checkModificationAllowed() + getEntityData(true).imported = value + changedProperty.add("imported") + + } override fun getEntityClass(): Class = SimpleEntity::class.java } @@ -145,10 +165,12 @@ internal class SimpleEntityData : WorkspaceEntityData() { var version: Int = 0 lateinit var name: String var isSimple: Boolean = false + lateinit var imported: ClassToImport internal fun isNameInitialized(): Boolean = ::name.isInitialized + internal fun isImportedInitialized(): Boolean = ::imported.isInitialized override fun wrapAsModifiable(diff: MutableEntityStorage): WorkspaceEntityBuilder { val modifiable = SimpleEntityImpl.Builder(null) @@ -177,7 +199,7 @@ internal class SimpleEntityData : WorkspaceEntityData() { } override fun createDetachedEntity(parents: List>): WorkspaceEntityBuilder<*> { - return SimpleEntity(version, name, isSimple, entitySource) + return SimpleEntity(version, name, isSimple, imported, entitySource) } override fun getRequiredParents(): List> { @@ -193,6 +215,7 @@ internal class SimpleEntityData : WorkspaceEntityData() { if (this.version != other.version) return false if (this.name != other.name) return false if (this.isSimple != other.isSimple) return false + if (this.imported != other.imported) return false return true } @@ -203,6 +226,7 @@ internal class SimpleEntityData : WorkspaceEntityData() { if (this.version != other.version) return false if (this.name != other.name) return false if (this.isSimple != other.isSimple) return false + if (this.imported != other.imported) return false return true } @@ -211,6 +235,7 @@ internal class SimpleEntityData : WorkspaceEntityData() { result = 31 * result + version.hashCode() result = 31 * result + name.hashCode() result = 31 * result + isSimple.hashCode() + result = 31 * result + imported.hashCode() return result } @@ -219,6 +244,7 @@ internal class SimpleEntityData : WorkspaceEntityData() { result = 31 * result + version.hashCode() result = 31 * result + name.hashCode() result = 31 * result + isSimple.hashCode() + result = 31 * result + imported.hashCode() return result } } diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/before/ClassToImport.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/before/ClassToImport.kt new file mode 100644 index 000000000000..90d23110cc06 --- /dev/null +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/before/ClassToImport.kt @@ -0,0 +1,3 @@ +package com.intellij.another.module + +class ClassToImport \ No newline at end of file diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/before/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/before/entity.kt new file mode 100644 index 000000000000..90dd7bff30e1 --- /dev/null +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/format/before/entity.kt @@ -0,0 +1,18 @@ +// 2700-2200 BCE fake copyright for test +// another line of fake copyright +package com.intellij.workspaceModel.test.api + +// imports are in wrong order purposefully +import java.nio.file.Path +import com.intellij.platform.workspace.storage.WorkspaceEntity +import java.io.File +import com.intellij.another.module.ClassToImport + +interface SimpleEntity : WorkspaceEntity { + val version: Int + val name: String + val isSimple: Boolean + val imported: ClassToImport +} + +data class UnrelatedToWsm(val name: String, val file: File, val path: Path) diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/hierarchyOfEntities/before/entities.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/hierarchyOfEntities/before/entities.kt index 6c2d7f795759..7b6fa0d4f1ba 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/hierarchyOfEntities/before/entities.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/hierarchyOfEntities/before/entities.kt @@ -14,10 +14,6 @@ interface ParentEntity : GrandParentEntity { val data2: String } -//region generated code -fun MutableEntityStorage.modifyEntity(entity: ParentEntity, modification: ParentEntity.Builder.() -> Unit) = oldCode -//endregion - interface ChildEntity: ParentEntity { val data3: String } \ No newline at end of file diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/entity.kt deleted file mode 100644 index 4fd4fc3667c0..000000000000 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/entity.kt +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.test.api - -import com.intellij.platform.workspace.storage.* -import com.intellij.platform.workspace.storage.annotations.Parent -import com.intellij.platform.workspace.storage.url.VirtualFileUrl -import java.net.URL - -interface EntityWithManyImports : WorkspaceEntityWithSymbolicId { - val version: Int - val name: String - val files: List - val pointer: EntityPointer - - override val symbolicId: SimpleId - get() = SimpleId(name) -} - -data class SimpleId(val name: String) : SymbolicEntityId { - override val presentableName: String - get() = name -} - -interface SimpleEntity : WorkspaceEntity { - val url: VirtualFileUrl - @Parent val parent: EntityWithManyImports -} - -data class UnrelatedToEntities(val name: String, val data: EntityPointer) { - fun doSomething(src: EntitySource) { - } -} diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/EntityWithManyImportsModifications.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/EntityWithManyImportsModifications.kt deleted file mode 100644 index 4b52dbdb3216..000000000000 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/EntityWithManyImportsModifications.kt +++ /dev/null @@ -1,51 +0,0 @@ -@file:JvmName("EntityWithManyImportsModifications") - -package com.intellij.workspaceModel.test.api - -import com.intellij.platform.workspace.storage.* -import com.intellij.platform.workspace.storage.annotations.Parent -import com.intellij.platform.workspace.storage.url.VirtualFileUrl -import java.net.URL - -@GeneratedCodeApiVersion(3) -interface EntityWithManyImportsBuilder: WorkspaceEntityBuilder{ -override var entitySource: EntitySource -var version: Int -var name: String -var files: List -var pointer: EntityPointer -} - -internal object EntityWithManyImportsType : EntityType(){ -override val entityClass: Class get() = EntityWithManyImports::class.java -operator fun invoke( -version: Int, -name: String, -pointer: EntityPointer, -entitySource: EntitySource, -init: (EntityWithManyImportsBuilder.() -> Unit)? = null, -): EntityWithManyImportsBuilder{ -val builder = builder() -builder.version = version -builder.name = name -builder.pointer = pointer -builder.entitySource = entitySource -init?.invoke(builder) -return builder -} -} - -fun MutableEntityStorage.modifyEntityWithManyImports( -entity: EntityWithManyImports, -modification: EntityWithManyImportsBuilder.() -> Unit, -): EntityWithManyImports = modifyEntity(EntityWithManyImportsBuilder::class.java, entity, modification) - -@JvmOverloads -@JvmName("createEntityWithManyImports") -fun EntityWithManyImports( -version: Int, -name: String, -pointer: EntityPointer, -entitySource: EntitySource, -init: (EntityWithManyImportsBuilder.() -> Unit)? = null, -): EntityWithManyImportsBuilder = EntityWithManyImportsType(version, name, pointer, entitySource, init) diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/SimpleEntityModifications.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/SimpleEntityModifications.kt deleted file mode 100644 index 82a8c4e13b12..000000000000 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/SimpleEntityModifications.kt +++ /dev/null @@ -1,43 +0,0 @@ -@file:JvmName("SimpleEntityModifications") - -package com.intellij.workspaceModel.test.api - -import com.intellij.platform.workspace.storage.* -import com.intellij.platform.workspace.storage.annotations.Parent -import com.intellij.platform.workspace.storage.url.VirtualFileUrl -import java.net.URL - -@GeneratedCodeApiVersion(3) -interface SimpleEntityBuilder: WorkspaceEntityBuilder{ -override var entitySource: EntitySource -var url: VirtualFileUrl -var parent: EntityWithManyImportsBuilder -} - -internal object SimpleEntityType : EntityType(){ -override val entityClass: Class get() = SimpleEntity::class.java -operator fun invoke( -url: VirtualFileUrl, -entitySource: EntitySource, -init: (SimpleEntityBuilder.() -> Unit)? = null, -): SimpleEntityBuilder{ -val builder = builder() -builder.url = url -builder.entitySource = entitySource -init?.invoke(builder) -return builder -} -} - -fun MutableEntityStorage.modifySimpleEntity( -entity: SimpleEntity, -modification: SimpleEntityBuilder.() -> Unit, -): SimpleEntity = modifyEntity(SimpleEntityBuilder::class.java, entity, modification) - -@JvmOverloads -@JvmName("createSimpleEntity") -fun SimpleEntity( -url: VirtualFileUrl, -entitySource: EntitySource, -init: (SimpleEntityBuilder.() -> Unit)? = null, -): SimpleEntityBuilder = SimpleEntityType(url, entitySource, init) diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/impl/EntityWithManyImportsImpl.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/impl/EntityWithManyImportsImpl.kt deleted file mode 100644 index 330c5e7deea6..000000000000 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/impl/EntityWithManyImportsImpl.kt +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.test.api.impl - -import com.intellij.platform.workspace.storage.* -import com.intellij.platform.workspace.storage.annotations.Parent -import com.intellij.platform.workspace.storage.impl.EntityLink -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.impl.extractOneToManyChildren -import com.intellij.platform.workspace.storage.impl.updateOneToManyChildrenOfParent -import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentation -import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi -import com.intellij.platform.workspace.storage.instrumentation.MutableEntityStorageInstrumentation -import com.intellij.platform.workspace.storage.metadata.model.EntityMetadata -import com.intellij.platform.workspace.storage.url.VirtualFileUrl -import com.intellij.workspaceModel.test.api.EntityWithManyImports -import com.intellij.workspaceModel.test.api.EntityWithManyImportsBuilder -import com.intellij.workspaceModel.test.api.SimpleEntity -import com.intellij.workspaceModel.test.api.SimpleEntityBuilder -import com.intellij.workspaceModel.test.api.SimpleId -import java.net.URL - -@GeneratedCodeApiVersion(3) -@GeneratedCodeImplVersion(7) -@OptIn(WorkspaceEntityInternalApi::class) -internal class EntityWithManyImportsImpl(private val dataSource: EntityWithManyImportsData): EntityWithManyImports, WorkspaceEntityBase(dataSource) { - -private companion object { -internal val FILES_CONNECTION_ID: ConnectionId = ConnectionId.create(EntityWithManyImports::class.java, SimpleEntity::class.java, ConnectionId.ConnectionType.ONE_TO_MANY, false) -private val connections = listOf(FILES_CONNECTION_ID) - -} -override val symbolicId: SimpleId = super.symbolicId - -override val version: Int -get() { -readField("version") -return dataSource.version -} -override val name: String -get() { -readField("name") -return dataSource.name -} -override val files: List -get() = snapshot.extractOneToManyChildren(FILES_CONNECTION_ID, this)!!.toList() -override val pointer: EntityPointer -get() { -readField("pointer") -return dataSource.pointer -} - -override val entitySource: EntitySource -get() { -readField("entitySource") -return dataSource.entitySource -} - -override fun connectionIdList(): List { -return connections -} - - -internal class Builder(result: EntityWithManyImportsData?): ModifiableWorkspaceEntityBase(result), EntityWithManyImportsBuilder { -internal constructor(): this(EntityWithManyImportsData()) - -override fun applyToBuilder(builder: MutableEntityStorage){ -if (this.diff != null){ -if (existsInBuilder(builder)){ -this.diff = builder -return -} -else{ -error("Entity EntityWithManyImports 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().isNameInitialized()){ -error("Field EntityWithManyImports#name should be initialized") -} -// Check initialization for list with ref type -if (_diff != null){ -if (_diff.extractOneToManyChildren(FILES_CONNECTION_ID, this) == null){ -error("Field EntityWithManyImports#files should be initialized") -} -} -else{ -if (this.entityLinks[EntityLink(true, FILES_CONNECTION_ID)] == null){ -error("Field EntityWithManyImports#files should be initialized") -} -} -if (!getEntityData().isPointerInitialized()){ -error("Field EntityWithManyImports#pointer 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 EntityWithManyImports -if (this.entitySource != dataSource.entitySource) this.entitySource = dataSource.entitySource -if (this.version != dataSource.version) this.version = dataSource.version -if (this.name != dataSource.name) this.name = dataSource.name -if (this.pointer != dataSource.pointer) this.pointer = dataSource.pointer -updateChildToParentReferences(parents) -} - - -override var entitySource: EntitySource -get() = getEntityData().entitySource -set(value) { -checkModificationAllowed() -getEntityData(true).entitySource = value -changedProperty.add("entitySource") - -} -override var version: Int -get() = getEntityData().version -set(value) { -checkModificationAllowed() -getEntityData(true).version = value -changedProperty.add("version") -} -override var name: String -get() = getEntityData().name -set(value) { -checkModificationAllowed() -getEntityData(true).name = value -changedProperty.add("name") -} -// List of non-abstract referenced types -var _files: List? = emptyList() -override var files: List -get(){ -// Getter of the list of non-abstract referenced types -val _diff = diff -return if (_diff != null) { -@OptIn(EntityStorageInstrumentationApi::class) -((_diff as MutableEntityStorageInstrumentation).getManyChildrenBuilders(FILES_CONNECTION_ID, this)!!.toList() as List) + (this.entityLinks[EntityLink(true, FILES_CONNECTION_ID)] as? List ?: emptyList()) -} else { -this.entityLinks[EntityLink(true, FILES_CONNECTION_ID)] as? List ?: emptyList() -} -} -set(value){ -// Setter of the list of non-abstract referenced types -checkModificationAllowed() -val _diff = diff -if (_diff != null){ -for (item_value in value){ -if (item_value is ModifiableWorkspaceEntityBase<*, *> && (item_value as? ModifiableWorkspaceEntityBase<*, *>)?.diff == null){ -// Backref setup before adding to store -if (item_value is ModifiableWorkspaceEntityBase<*, *>){ -item_value.entityLinks[EntityLink(false, FILES_CONNECTION_ID)] = this -} -// else you're attaching a new entity to an existing entity that is not modifiable -_diff.addEntity(item_value as ModifiableWorkspaceEntityBase) -} -} -_diff.updateOneToManyChildrenOfParent(FILES_CONNECTION_ID, this, value) -} -else{ -for (item_value in value){ -if (item_value is ModifiableWorkspaceEntityBase<*, *>){ -item_value.entityLinks[EntityLink(false, FILES_CONNECTION_ID)] = this -} -// else you're attaching a new entity to an existing entity that is not modifiable -} -this.entityLinks[EntityLink(true, FILES_CONNECTION_ID)] = value -} -changedProperty.add("files") -} - -override var pointer: EntityPointer -get() = getEntityData().pointer -set(value) { -checkModificationAllowed() -getEntityData(true).pointer = value -changedProperty.add("pointer") - -} - -override fun getEntityClass(): Class = EntityWithManyImports::class.java -} - -} - -@OptIn(WorkspaceEntityInternalApi::class) -internal class EntityWithManyImportsData : WorkspaceEntityData(){ -var version: Int = 0 -lateinit var name: String -lateinit var pointer: EntityPointer - - -internal fun isNameInitialized(): Boolean = ::name.isInitialized -internal fun isPointerInitialized(): Boolean = ::pointer.isInitialized - -override fun wrapAsModifiable(diff: MutableEntityStorage): WorkspaceEntityBuilder{ -val modifiable = EntityWithManyImportsImpl.Builder(null) -modifiable.diff = diff -modifiable.id = createEntityId() -return modifiable -} - -@OptIn(EntityStorageInstrumentationApi::class) -override fun createEntity(snapshot: EntityStorageInstrumentation): EntityWithManyImports{ -val entityId = createEntityId() -return snapshot.initializeEntity(entityId){ -val entity = EntityWithManyImportsImpl(this) -entity.snapshot = snapshot -entity.id = entityId -entity -} -} - -override fun getMetadata(): EntityMetadata{ -return MetadataStorageImpl.getMetadataByTypeFqn("com.intellij.workspaceModel.test.api.EntityWithManyImports") as EntityMetadata -} - -override fun getEntityInterface(): Class{ -return EntityWithManyImports::class.java -} - -override fun createDetachedEntity(parents: List>): WorkspaceEntityBuilder<*>{ -return EntityWithManyImports(version, name, pointer, entitySource) -} - -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 EntityWithManyImportsData -if (this.entitySource != other.entitySource) return false -if (this.version != other.version) return false -if (this.name != other.name) return false -if (this.pointer != other.pointer) return false -return true -} - -override fun equalsIgnoringEntitySource(other: Any?): Boolean{ -if (other == null) return false -if (this.javaClass != other.javaClass) return false -other as EntityWithManyImportsData -if (this.version != other.version) return false -if (this.name != other.name) return false -if (this.pointer != other.pointer) return false -return true -} - -override fun hashCode(): Int{ -var result = entitySource.hashCode() -result = 31 * result + version.hashCode() -result = 31 * result + name.hashCode() -result = 31 * result + pointer.hashCode() -return result -} -override fun hashCodeIgnoringEntitySource(): Int{ -var result = javaClass.hashCode() -result = 31 * result + version.hashCode() -result = 31 * result + name.hashCode() -result = 31 * result + pointer.hashCode() -return result -} -} diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/impl/MetadataStorageImpl.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/impl/MetadataStorageImpl.kt deleted file mode 100644 index 2915cc4a3b1c..000000000000 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/impl/MetadataStorageImpl.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.intellij.workspaceModel.test.api.impl - -import com.intellij.platform.workspace.storage.ConnectionId -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") -val primitiveTypeIntNotNullable = ValueTypeMetadata.SimpleType.PrimitiveType(isNullable = false, type = "Int") - -var typeMetadata: StorageTypeMetadata - -typeMetadata = FinalClassMetadata.ClassMetadata(fqName = "com.intellij.workspaceModel.test.api.SimpleId", 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")) - -addMetadata(typeMetadata) - -typeMetadata = EntityMetadata(fqName = "com.intellij.workspaceModel.test.api.EntityWithManyImports", entityDataFqName = "com.intellij.workspaceModel.test.api.impl.EntityWithManyImportsData", 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 = "version", 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 = "files", valueType = ValueTypeMetadata.EntityReference(connectionType = ConnectionId.ConnectionType.ONE_TO_MANY, entityFqName = "com.intellij.workspaceModel.test.api.SimpleEntity", isChild = true, isNullable = false), withDefault = false),OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "pointer", valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = false, typeMetadata = FinalClassMetadata.KnownClass(fqName = "com.intellij.platform.workspace.storage.EntityPointer")), withDefault = false),OwnPropertyMetadata(isComputable = true, isKey = false, isOpen = false, name = "symbolicId", valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = false, typeMetadata = FinalClassMetadata.ClassMetadata(fqName = "com.intellij.workspaceModel.test.api.SimpleId", 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)), extProperties = listOf(), isAbstract = false) - -addMetadata(typeMetadata) - -typeMetadata = EntityMetadata(fqName = "com.intellij.workspaceModel.test.api.SimpleEntity", entityDataFqName = "com.intellij.workspaceModel.test.api.impl.SimpleEntityData", supertypes = listOf("com.intellij.platform.workspace.storage.WorkspaceEntity"), 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 = "url", valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = false, typeMetadata = FinalClassMetadata.KnownClass(fqName = "com.intellij.platform.workspace.storage.url.VirtualFileUrl")), withDefault = false),OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "parent", valueType = ValueTypeMetadata.EntityReference(connectionType = ConnectionId.ConnectionType.ONE_TO_MANY, entityFqName = "com.intellij.workspaceModel.test.api.EntityWithManyImports", isChild = false, isNullable = false), withDefault = false)), extProperties = listOf(), isAbstract = false) - -addMetadata(typeMetadata) -} - -override fun initializeMetadataHash(){ -addMetadataHash(typeFqn = "com.intellij.workspaceModel.test.api.EntityWithManyImports", metadataHash = -201548353) -addMetadataHash(typeFqn = "com.intellij.workspaceModel.test.api.SimpleEntity", metadataHash = -657222679) -addMetadataHash(typeFqn = "com.intellij.workspaceModel.test.api.SimpleId", metadataHash = 2085950989) -addMetadataHash(typeFqn = "com.intellij.platform.workspace.storage.SymbolicEntityId", metadataHash = 1931133873) -} -} diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/impl/SimpleEntityImpl.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/impl/SimpleEntityImpl.kt deleted file mode 100644 index 5eda2ca62fa3..000000000000 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/after/gen/impl/SimpleEntityImpl.kt +++ /dev/null @@ -1,239 +0,0 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.test.api.impl - -import com.intellij.platform.workspace.storage.* -import com.intellij.platform.workspace.storage.annotations.Parent -import com.intellij.platform.workspace.storage.impl.EntityLink -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.impl.extractOneToManyParent -import com.intellij.platform.workspace.storage.impl.updateOneToManyParentOfChild -import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentation -import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi -import com.intellij.platform.workspace.storage.instrumentation.MutableEntityStorageInstrumentation -import com.intellij.platform.workspace.storage.metadata.model.EntityMetadata -import com.intellij.platform.workspace.storage.url.VirtualFileUrl -import com.intellij.workspaceModel.test.api.EntityWithManyImports -import com.intellij.workspaceModel.test.api.EntityWithManyImportsBuilder -import com.intellij.workspaceModel.test.api.SimpleEntity -import com.intellij.workspaceModel.test.api.SimpleEntityBuilder -import java.net.URL - -@GeneratedCodeApiVersion(3) -@GeneratedCodeImplVersion(7) -@OptIn(WorkspaceEntityInternalApi::class) -internal class SimpleEntityImpl(private val dataSource: SimpleEntityData): SimpleEntity, WorkspaceEntityBase(dataSource) { - -private companion object { -internal val PARENT_CONNECTION_ID: ConnectionId = ConnectionId.create(EntityWithManyImports::class.java, SimpleEntity::class.java, ConnectionId.ConnectionType.ONE_TO_MANY, false) -private val connections = listOf(PARENT_CONNECTION_ID) - -} - -override val url: VirtualFileUrl -get() { -readField("url") -return dataSource.url -} -override val parent: EntityWithManyImports -get() = snapshot.extractOneToManyParent(PARENT_CONNECTION_ID, this)!! - -override val entitySource: EntitySource -get() { -readField("entitySource") -return dataSource.entitySource -} - -override fun connectionIdList(): List { -return connections -} - - -internal class Builder(result: SimpleEntityData?): ModifiableWorkspaceEntityBase(result), SimpleEntityBuilder { -internal constructor(): this(SimpleEntityData()) - -override fun applyToBuilder(builder: MutableEntityStorage){ -if (this.diff != null){ -if (existsInBuilder(builder)){ -this.diff = builder -return -} -else{ -error("Entity SimpleEntity 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 -index(this, "url", this.url) -// 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().isUrlInitialized()){ -error("Field SimpleEntity#url should be initialized") -} -if (_diff != null){ -if (_diff.extractOneToManyParent(PARENT_CONNECTION_ID, this) == null){ -error("Field SimpleEntity#parent should be initialized") -} -} -else{ -if (this.entityLinks[EntityLink(false, PARENT_CONNECTION_ID)] == null){ -error("Field SimpleEntity#parent 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 SimpleEntity -if (this.entitySource != dataSource.entitySource) this.entitySource = dataSource.entitySource -if (this.url != dataSource.url) this.url = dataSource.url -updateChildToParentReferences(parents) -} - - -override var entitySource: EntitySource -get() = getEntityData().entitySource -set(value) { -checkModificationAllowed() -getEntityData(true).entitySource = value -changedProperty.add("entitySource") - -} - override var url: VirtualFileUrl - get() = getEntityData().url - set(value) { - checkModificationAllowed() - getEntityData(true).url = value - changedProperty.add("url") - val _diff = diff -if (_diff != null) index(this, "url", value) - } -override var parent: EntityWithManyImportsBuilder -get(){ -val _diff = diff -return if (_diff != null) { -@OptIn(EntityStorageInstrumentationApi::class) -((_diff as MutableEntityStorageInstrumentation).getParentBuilder(PARENT_CONNECTION_ID, this) as? EntityWithManyImportsBuilder) ?: (this.entityLinks[EntityLink(false, PARENT_CONNECTION_ID)]!! as EntityWithManyImportsBuilder) -} else { -this.entityLinks[EntityLink(false, PARENT_CONNECTION_ID)]!! as EntityWithManyImportsBuilder -} -} -set(value){ -checkModificationAllowed() -val _diff = diff -if (_diff != null && value is ModifiableWorkspaceEntityBase<*, *> && value.diff == null){ -// Setting backref of the list -if (value is ModifiableWorkspaceEntityBase<*, *>){ -val data = (value.entityLinks[EntityLink(true, PARENT_CONNECTION_ID)] as? List ?: emptyList()) + this -value.entityLinks[EntityLink(true, PARENT_CONNECTION_ID)] = data -} -// else you're attaching a new entity to an existing entity that is not modifiable -_diff.addEntity(value as ModifiableWorkspaceEntityBase) -} -if (_diff != null && (value !is ModifiableWorkspaceEntityBase<*, *> || value.diff != null)){ -_diff.updateOneToManyParentOfChild(PARENT_CONNECTION_ID, this, value) -} -else{ -// Setting backref of the list -if (value is ModifiableWorkspaceEntityBase<*, *>){ -val data = (value.entityLinks[EntityLink(true, PARENT_CONNECTION_ID)] as? List ?: emptyList()) + this -value.entityLinks[EntityLink(true, PARENT_CONNECTION_ID)] = data -} -// else you're attaching a new entity to an existing entity that is not modifiable -this.entityLinks[EntityLink(false, PARENT_CONNECTION_ID)] = value -} -changedProperty.add("parent") -} - -override fun getEntityClass(): Class = SimpleEntity::class.java -} - -} - -@OptIn(WorkspaceEntityInternalApi::class) -internal class SimpleEntityData : WorkspaceEntityData(){ -lateinit var url: VirtualFileUrl - -internal fun isUrlInitialized(): Boolean = ::url.isInitialized - -override fun wrapAsModifiable(diff: MutableEntityStorage): WorkspaceEntityBuilder{ -val modifiable = SimpleEntityImpl.Builder(null) -modifiable.diff = diff -modifiable.id = createEntityId() -return modifiable -} - -@OptIn(EntityStorageInstrumentationApi::class) -override fun createEntity(snapshot: EntityStorageInstrumentation): SimpleEntity{ -val entityId = createEntityId() -return snapshot.initializeEntity(entityId){ -val entity = SimpleEntityImpl(this) -entity.snapshot = snapshot -entity.id = entityId -entity -} -} - -override fun getMetadata(): EntityMetadata{ -return MetadataStorageImpl.getMetadataByTypeFqn("com.intellij.workspaceModel.test.api.SimpleEntity") as EntityMetadata -} - -override fun getEntityInterface(): Class{ -return SimpleEntity::class.java -} - -override fun createDetachedEntity(parents: List>): WorkspaceEntityBuilder<*>{ -return SimpleEntity(url, entitySource){ -parents.filterIsInstance().singleOrNull()?.let { this.parent = it } -} -} - -override fun getRequiredParents(): List>{ -val res = mutableListOf>() -res.add(EntityWithManyImports::class.java) -return res -} - -override fun equals(other: Any?): Boolean{ -if (other == null) return false -if (this.javaClass != other.javaClass) return false -other as SimpleEntityData -if (this.entitySource != other.entitySource) return false -if (this.url != other.url) return false -return true -} - -override fun equalsIgnoringEntitySource(other: Any?): Boolean{ -if (other == null) return false -if (this.javaClass != other.javaClass) return false -other as SimpleEntityData -if (this.url != other.url) return false -return true -} - -override fun hashCode(): Int{ -var result = entitySource.hashCode() -result = 31 * result + url.hashCode() -return result -} -override fun hashCodeIgnoringEntitySource(): Int{ -var result = javaClass.hashCode() -result = 31 * result + url.hashCode() -return result -} -} diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/before/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/before/entity.kt deleted file mode 100644 index c931ce50c2c8..000000000000 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/imports/before/entity.kt +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.test.api - -import com.intellij.platform.workspace.storage.* -import com.intellij.platform.workspace.storage.WorkspaceEntityWithSymbolicId // stoopid and unnecessary -import java.net.URL // stoopid but necessary (user-added) -import com.intellij.platform.workspace.storage.annotations.Parent -import com.intellij.platform.workspace.storage.url.VirtualFileUrl - -interface EntityWithManyImports : WorkspaceEntityWithSymbolicId { - val version: Int - val name: String - val files: List - val pointer: EntityPointer - - override val symbolicId: SimpleId - get() = SimpleId(name) -} - -data class SimpleId(val name: String) : SymbolicEntityId { - override val presentableName: String - get() = name -} - -interface SimpleEntity : WorkspaceEntity { - val url: VirtualFileUrl - @Parent val parent: EntityWithManyImports -} - -data class UnrelatedToEntities(val name: String, val data: EntityPointer) { - fun doSomething(src: EntitySource) { - } -} diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/after/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/after/entity.kt index 0c51f936fd7e..014ceaaa5735 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/after/entity.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/after/entity.kt @@ -1,4 +1,3 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.workspaceModel.test.api import com.intellij.platform.workspace.storage.* diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/after/gen/impl/ChildEntityImpl.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/after/gen/impl/ChildEntityImpl.kt index c8ec2810c364..e86ec2e95de6 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/after/gen/impl/ChildEntityImpl.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/after/gen/impl/ChildEntityImpl.kt @@ -1,4 +1,3 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.workspaceModel.test.api.impl import com.intellij.platform.workspace.storage.* diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/after/gen/impl/SimpleEntityImpl.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/after/gen/impl/SimpleEntityImpl.kt index 70d8cb82fa81..bb5a208f3ddc 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/after/gen/impl/SimpleEntityImpl.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/after/gen/impl/SimpleEntityImpl.kt @@ -1,4 +1,3 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.workspaceModel.test.api.impl import com.intellij.platform.workspace.storage.* diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/before/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/before/entity.kt index 0c51f936fd7e..014ceaaa5735 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/before/entity.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/propertiesOrder/before/entity.kt @@ -1,4 +1,3 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.workspaceModel.test.api import com.intellij.platform.workspace.storage.* diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/refsFromAnotherModule/after/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/refsFromAnotherModule/after/entity.kt index 571ed66c929f..45cf1f213de9 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/refsFromAnotherModule/after/entity.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/refsFromAnotherModule/after/entity.kt @@ -1,7 +1,7 @@ package com.intellij.workspaceModel.test.api -import com.intellij.platform.workspace.jps.entities.ContentRootEntity import com.intellij.platform.workspace.storage.WorkspaceEntity +import com.intellij.platform.workspace.jps.entities.ContentRootEntity import com.intellij.platform.workspace.storage.annotations.Parent interface ReferredEntity : WorkspaceEntity { diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/after/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/after/entity.kt deleted file mode 100644 index 86b7a7b3cc1b..000000000000 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/after/entity.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.intellij.workspaceModel.test.api - -import com.intellij.platform.workspace.storage.WorkspaceEntity - -interface SimpleEntity : WorkspaceEntity { - val version: Int - val name: String - val isSimple: Boolean -} \ No newline at end of file diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/before/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/before/entity.kt deleted file mode 100644 index 86b7a7b3cc1b..000000000000 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/simpleCaseWithCodestyle/before/entity.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.intellij.workspaceModel.test.api - -import com.intellij.platform.workspace.storage.WorkspaceEntity - -interface SimpleEntity : WorkspaceEntity { - val version: Int - val name: String - val isSimple: Boolean -} \ No newline at end of file diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/updateOldCode/after/entity.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/updateOldCode/after/entity.kt index d33be5a7c6da..73d556f3f286 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/updateOldCode/after/entity.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/updateOldCode/after/entity.kt @@ -7,4 +7,25 @@ interface SimpleEntity : WorkspaceEntity { val version: Int val name: String val isSimple: Boolean -} \ No newline at end of file + + //region generated code + @GeneratedCodeApiVersion(1) + interface Builder : SimpleEntity, WorkspaceEntityBuilder { + //obsolete + } + + companion object : Type() { + operator fun invoke(version: Int, + entitySource: EntitySource, + name: String, + isSimple: Boolean, + init: (Builder.() -> Unit)? = null): SimpleEntity { + TODO("obsolete") + } + } + //endregion +} + +//region generated code +fun MutableEntityStorage.oldCode() = Unit +//endregion \ No newline at end of file diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/updateOldCode/after/gen/impl/SimpleEntityImpl.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/updateOldCode/after/gen/impl/SimpleEntityImpl.kt index 18ba6e293174..0022b77ab0cd 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/updateOldCode/after/gen/impl/SimpleEntityImpl.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testData/codeGen/updateOldCode/after/gen/impl/SimpleEntityImpl.kt @@ -1,4 +1,3 @@ -//new comment package com.intellij.workspaceModel.test.api.impl import com.intellij.platform.workspace.storage.ConnectionId diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testSrc/AbstractAllIntellijEntitiesGenerationTest.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testSrc/AbstractAllIntellijEntitiesGenerationTest.kt index a7af48bf410c..9a418b0b8ef5 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testSrc/AbstractAllIntellijEntitiesGenerationTest.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testSrc/AbstractAllIntellijEntitiesGenerationTest.kt @@ -96,7 +96,7 @@ abstract class AbstractAllIntellijEntitiesGenerationTest : CodeGenerationTestBas var storageChanged = false modulesToCheck.forEachIndexed { index, (moduleEntity, sourceRoot) -> - println("[${index + 1}/${modulesToCheck.size}] Generating workspace code for module ${moduleEntity.name}") + println("[${index + 1}/${modulesToCheck.size}] Generating workspace code for module ${moduleEntity.name} [${sourceRoot.url.presentableUrl}]") val isTestModule = sourceRoot.rootTypeId == JAVA_TEST_ROOT_ENTITY_TYPE_ID val libraries = LibrariesRequiredForWorkspace.getRelatedLibraries(moduleEntity.name) val gen = generateWorkspaceCode(moduleEntity, sourceRoot, isTestModule, libraries) @@ -233,7 +233,7 @@ abstract class AbstractAllIntellijEntitiesGenerationTest : CodeGenerationTestBas } return null } - + private fun createGenSourceRoot(storage: MutableEntityStorage, sourceRoot: SourceRootEntity): SourceRootEntity { val genFolderVirtualFile = VfsUtil.createDirectories("${sourceRoot.contentRoot.url.presentableUrl}/${WorkspaceModelGenerator.GENERATED_FOLDER_NAME}") val javaSourceRoot = sourceRoot.javaSourceRoots.first() @@ -324,9 +324,9 @@ abstract class AbstractAllIntellijEntitiesGenerationTest : CodeGenerationTestBas srcRoots@ for (sourceRoot in storage.entities()) { val moduleEntity = sourceRoot.contentRoot.module - var toCheck = false - if (moduleEntity.name in skippedModules) continue + if (sourceRoot.javaSourceRoots.none { !it.generated }) continue + var toCheck = false for (file in File(sourceRoot.url.presentableUrl).walk()) { if (file.isFile && file.extension == "kt") { diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testSrc/AbstractEntityCodeGenTest.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testSrc/AbstractEntityCodeGenTest.kt index 113710f4dbed..be46e770da81 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testSrc/AbstractEntityCodeGenTest.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testSrc/AbstractEntityCodeGenTest.kt @@ -19,7 +19,10 @@ abstract class AbstractEntityCodeGenTest : CodeGenerationTestBase() { doTest() } - fun testSimpleCaseWithCodestyle() { + /** + * Tests that code is formatted properly: codestyle, copyright is added, imports are optimized. + */ + fun testFormat() { doTest(formatCode = true) } @@ -79,14 +82,6 @@ abstract class AbstractEntityCodeGenTest : CodeGenerationTestBase() { doTest(processAbstractTypes = true) } - fun testAddCopyrightComment() { - doTest(processAbstractTypes = true) - } - - fun testImports() { - doTest() - } - fun testOpenClassProperty() { doTest(processAbstractTypes = true) } diff --git a/plugins/devkit/intellij.devkit.workspaceModel/tests/testSrc/LibrariesRequiredForWorkspace.kt b/plugins/devkit/intellij.devkit.workspaceModel/tests/testSrc/LibrariesRequiredForWorkspace.kt index 0c353cbc6346..4779527973ed 100644 --- a/plugins/devkit/intellij.devkit.workspaceModel/tests/testSrc/LibrariesRequiredForWorkspace.kt +++ b/plugins/devkit/intellij.devkit.workspaceModel/tests/testSrc/LibrariesRequiredForWorkspace.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 com.intellij.devkit.workspaceModel +import com.android.ide.common.repository.AgpVersion import com.intellij.openapi.application.ArchivedCompilationContextUtil import com.intellij.openapi.roots.ModifiableRootModel import com.intellij.openapi.roots.OrderRootType @@ -21,7 +22,8 @@ internal object LibrariesRequiredForWorkspace { private val rider = ModuleLibrary("intellij.rider") private val riderUnityPlugin = ModuleLibrary("intellij.rider.plugins.unity") - private val riderModel = ModuleLibrary("intellij.rider.model.generated") + private val riderModelGenerated = ModuleLibrary("intellij.rider.model.generated") + private val rdIdeModelGenerated = ModuleLibrary("intellij.rd.ide.model.generated") private val riderRdClient = ModuleLibrary("intellij.rider.rdclient.dotnet") private val gradle = ModuleLibrary("intellij.gradle") private val gradleToolingExtension = ModuleLibrary("intellij.gradle.toolingExtension") @@ -29,11 +31,14 @@ internal object LibrariesRequiredForWorkspace { private val pyCommon = ModuleLibrary("intellij.python.common") private val cidrProjectModel = ModuleLibrary("intellij.cidr.projectModel") private val kotlinBaseScripting = ModuleLibrary("intellij.kotlin.base.scripting") + private val androidProjectSystem = ModuleLibrary("intellij.android.projectSystem") + private val androidGradleModels = ModuleLibrary("intellij.android.projectSystem.gradle.models") private val kotlinJpsCommon = JarLibrary("kotlinc-kotlin-jps-common", KotlinModuleKind::class.java) private val kotlinScriptingCommon = JarLibrary("kotlinc-kotlin-scripting-common", SourceCode::class.java) private val rdCore = JarLibrary("rd-core", IPrintable::class.java) private val rdFramework = JarLibrary("rd-framework", RdId::class.java) + private val androidStudioPlatform = JarLibrary("studio-platform", AgpVersion::class.java) fun getRelatedLibraries(moduleEntityName: String): List = when (moduleEntityName) { @@ -47,7 +52,7 @@ internal object LibrariesRequiredForWorkspace { listOf(riderRdClient) } "intellij.rider.rdclient.dotnet" -> { - listOf(rdFramework, rdCore, riderModel, riderUnityPlugin, rider, riderRdClient) + listOf(rdFramework, rdCore, riderModelGenerated, riderUnityPlugin, rider, rdIdeModelGenerated) } "intellij.kotlin.base.facet" -> { listOf(intellijJava, kotlinJpsCommon) @@ -70,6 +75,9 @@ internal object LibrariesRequiredForWorkspace { "intellij.clion.openfolder" -> { listOf(cidrProjectModel) } + "intellij.android.projectSystem.gradle" -> { + listOf(androidProjectSystem, androidGradleModels, androidStudioPlatform) + } else -> { emptyList() }