mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
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 <kirill.bochkarev@jetbrains.com> GitOrigin-RevId: 2cb825d65b195612dbc24b614663724ed1528888
This commit is contained in:
committed by
intellij-monorepo-bot
parent
38c69cf8d3
commit
33ebfaabc0
+1
-1
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -64,5 +64,6 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.workspace.jps" />
|
||||
<orderEntry type="module" module-name="intellij.java.impl" />
|
||||
<orderEntry type="module" module-name="intellij.kotlin.base.psi" />
|
||||
<orderEntry type="module" module-name="intellij.platform.codeStyle.impl" />
|
||||
</component>
|
||||
</module>
|
||||
+1
-1
@@ -157,7 +157,7 @@ internal class WorkspaceMetaModelBuilder(
|
||||
|
||||
val blobType = ValueType.Blob<Any>(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()) {
|
||||
|
||||
+5
-5
@@ -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))
|
||||
}
|
||||
|
||||
|
||||
@@ -146,7 +146,8 @@ class WorkspaceModelGenerator(private val project: Project, private val coroutin
|
||||
const val RIDER_MODULES_PREFIX: String = "intellij.rider"
|
||||
|
||||
val modulesWithAbstractTypes: Set<String> = setOf(
|
||||
"intellij.platform.workspace.storage.testEntities"
|
||||
"intellij.platform.workspace.storage.testEntities",
|
||||
"intellij.android.projectSystem.gradle"
|
||||
)
|
||||
|
||||
fun getInstance(project: Project): WorkspaceModelGenerator = project.service()
|
||||
|
||||
@@ -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<String, VirtualFile>()
|
||||
val ktClasses = HashMap<String, KtClassOrObject>()
|
||||
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<KtClassOrObject>()
|
||||
?.filter { it.name != null }
|
||||
?.forEach { ktClass ->
|
||||
val fqName = ktClass.fqName!!.asString()
|
||||
val objModuleName = fqName
|
||||
.replace(ktClass.name!!, "")
|
||||
.substringBeforeLast(".")
|
||||
ktFile?.declarations?.filterIsInstance<KtClassOrObject>()?.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<KtClassOrObject, PsiElement>()
|
||||
saveCompatibilityCode(ktClasses, savedCompatibilityInvokeCode)
|
||||
|
||||
indicator.text = DevKitWorkspaceModelBundle.message("progress.text.removing.old.code")
|
||||
removeGeneratedCode(ktClasses, genFolder)
|
||||
removeGeneratedCode(genFolder)
|
||||
|
||||
val topLevelDeclarations = MultiMap.create<KtFile, Pair<KtClassOrObject, List<KtDeclaration>>>()
|
||||
val importsByFile = FactoryMap.create<KtFile, Imports> { Imports(it.packageFqName.asString()) }
|
||||
val generatedFiles = ArrayList<KtFile>()
|
||||
|
||||
@@ -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<KtDeclaration>()
|
||||
for ((place, declarations) in placeAndDeclarations) {
|
||||
var nextPlace: PsiElement = place
|
||||
val newElements = ArrayList<KtDeclaration>()
|
||||
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<String, KtClassOrObject>) {
|
||||
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<String, KtClassOrObject>, savedCompatibilityInvokeCode: MutableMap<KtClassOrObject, PsiElement>) {
|
||||
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<String, KtClassOrObject>, 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<KtFile>,
|
||||
project: Project, sourceFolder: VirtualFile, genFolder: VirtualFile,
|
||||
ktClasses: Map<String, KtClassOrObject>, importsByFile: MutableMap<KtFile, Imports>,
|
||||
topLevelDeclarations: MultiMap<KtFile, Pair<KtClassOrObject, List<KtDeclaration>>>, psiFactory: KtPsiFactory,
|
||||
savedCompatibilityInvokeCode: MutableMap<KtClassOrObject, PsiElement>,
|
||||
code: ObjClassGeneratedCode, generatedFiles: MutableList<KtFile>, project: Project, sourceFolder: VirtualFile, genFolder: VirtualFile,
|
||||
ktClasses: Map<String, KtClassOrObject>, importsByFile: MutableMap<KtFile, Imports>, 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<KtDeclaration>()
|
||||
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<KtClassOrObject, PsiElement>) {
|
||||
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<Pair<ASTNode, ASTNode>> {
|
||||
val generatedRegions = ArrayList<Pair<ASTNode, ASTNode>>()
|
||||
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"
|
||||
|
||||
|
||||
@@ -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"]
|
||||
)
|
||||
|
||||
+1
@@ -41,5 +41,6 @@
|
||||
<orderEntry type="library" scope="TEST" name="kotlinc.kotlin-scripting-common" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.editorconfig.backend" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.editorconfig.plugin" />
|
||||
<orderEntry type="library" scope="TEST" name="studio-platform" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
-8
@@ -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
|
||||
}
|
||||
-44
@@ -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<SimpleEntity>{
|
||||
override var entitySource: EntitySource
|
||||
var name: String
|
||||
}
|
||||
|
||||
internal object SimpleEntityType : EntityType<SimpleEntity, SimpleEntityBuilder>(){
|
||||
override val entityClass: Class<SimpleEntity> 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)
|
||||
-26
@@ -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)
|
||||
}
|
||||
}
|
||||
-183
@@ -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<ConnectionId>()
|
||||
|
||||
}
|
||||
|
||||
override val name: String
|
||||
get() {
|
||||
readField("name")
|
||||
return dataSource.name
|
||||
}
|
||||
|
||||
override val entitySource: EntitySource
|
||||
get() {
|
||||
readField("entitySource")
|
||||
return dataSource.entitySource
|
||||
}
|
||||
|
||||
override fun connectionIdList(): List<ConnectionId> {
|
||||
return connections
|
||||
}
|
||||
|
||||
|
||||
internal class Builder(result: SimpleEntityData?): ModifiableWorkspaceEntityBase<SimpleEntity, SimpleEntityData>(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<ConnectionId>{
|
||||
return connections
|
||||
}
|
||||
// Relabeling code, move information from dataSource to this builder
|
||||
override fun relabel(dataSource: WorkspaceEntity, parents: Set<WorkspaceEntity>?){
|
||||
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> = SimpleEntity::class.java
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OptIn(WorkspaceEntityInternalApi::class)
|
||||
internal class SimpleEntityData : WorkspaceEntityData<SimpleEntity>(){
|
||||
lateinit var name: String
|
||||
|
||||
internal fun isNameInitialized(): Boolean = ::name.isInitialized
|
||||
|
||||
override fun wrapAsModifiable(diff: MutableEntityStorage): WorkspaceEntityBuilder<SimpleEntity>{
|
||||
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<out WorkspaceEntity>{
|
||||
return SimpleEntity::class.java
|
||||
}
|
||||
|
||||
override fun createDetachedEntity(parents: List<WorkspaceEntityBuilder<*>>): WorkspaceEntityBuilder<*>{
|
||||
return SimpleEntity(name, entitySource)
|
||||
}
|
||||
|
||||
override fun getRequiredParents(): List<Class<out WorkspaceEntity>>{
|
||||
val res = mutableListOf<Class<out WorkspaceEntity>>()
|
||||
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
|
||||
}
|
||||
}
|
||||
-8
@@ -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
|
||||
}
|
||||
-2
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+2
-2
@@ -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 {
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package com.intellij.another.module
|
||||
|
||||
class ClassToImport
|
||||
+18
@@ -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)
|
||||
+8
-2
@@ -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<SimpleEntity> {
|
||||
var version: Int
|
||||
var name: String
|
||||
var isSimple: Boolean
|
||||
var imported: ClassToImport
|
||||
}
|
||||
|
||||
internal object SimpleEntityType : EntityType<SimpleEntity, SimpleEntityBuilder>() {
|
||||
@@ -23,6 +26,7 @@ internal object SimpleEntityType : EntityType<SimpleEntity, SimpleEntityBuilder>
|
||||
version: Int,
|
||||
name: String,
|
||||
isSimple: Boolean,
|
||||
imported: ClassToImport,
|
||||
entitySource: EntitySource,
|
||||
init: (SimpleEntityBuilder.() -> Unit)? = null,
|
||||
): SimpleEntityBuilder {
|
||||
@@ -30,6 +34,7 @@ internal object SimpleEntityType : EntityType<SimpleEntity, SimpleEntityBuilder>
|
||||
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)
|
||||
+14
-1
@@ -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)
|
||||
}
|
||||
}
|
||||
+27
-1
@@ -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<ConnectionId> {
|
||||
@@ -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> = SimpleEntity::class.java
|
||||
}
|
||||
@@ -145,10 +165,12 @@ internal class SimpleEntityData : WorkspaceEntityData<SimpleEntity>() {
|
||||
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<SimpleEntity> {
|
||||
val modifiable = SimpleEntityImpl.Builder(null)
|
||||
@@ -177,7 +199,7 @@ internal class SimpleEntityData : WorkspaceEntityData<SimpleEntity>() {
|
||||
}
|
||||
|
||||
override fun createDetachedEntity(parents: List<WorkspaceEntityBuilder<*>>): WorkspaceEntityBuilder<*> {
|
||||
return SimpleEntity(version, name, isSimple, entitySource)
|
||||
return SimpleEntity(version, name, isSimple, imported, entitySource)
|
||||
}
|
||||
|
||||
override fun getRequiredParents(): List<Class<out WorkspaceEntity>> {
|
||||
@@ -193,6 +215,7 @@ internal class SimpleEntityData : WorkspaceEntityData<SimpleEntity>() {
|
||||
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<SimpleEntity>() {
|
||||
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<SimpleEntity>() {
|
||||
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<SimpleEntity>() {
|
||||
result = 31 * result + version.hashCode()
|
||||
result = 31 * result + name.hashCode()
|
||||
result = 31 * result + isSimple.hashCode()
|
||||
result = 31 * result + imported.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package com.intellij.another.module
|
||||
|
||||
class ClassToImport
|
||||
+18
@@ -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)
|
||||
-4
@@ -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
|
||||
}
|
||||
-32
@@ -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<SimpleEntity>
|
||||
val pointer: EntityPointer<SimpleEntity>
|
||||
|
||||
override val symbolicId: SimpleId
|
||||
get() = SimpleId(name)
|
||||
}
|
||||
|
||||
data class SimpleId(val name: String) : SymbolicEntityId<EntityWithManyImports> {
|
||||
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<SimpleEntity>) {
|
||||
fun doSomething(src: EntitySource) {
|
||||
}
|
||||
}
|
||||
-51
@@ -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<EntityWithManyImports>{
|
||||
override var entitySource: EntitySource
|
||||
var version: Int
|
||||
var name: String
|
||||
var files: List<SimpleEntityBuilder>
|
||||
var pointer: EntityPointer
|
||||
}
|
||||
|
||||
internal object EntityWithManyImportsType : EntityType<EntityWithManyImports, EntityWithManyImportsBuilder>(){
|
||||
override val entityClass: Class<EntityWithManyImports> 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)
|
||||
-43
@@ -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<SimpleEntity>{
|
||||
override var entitySource: EntitySource
|
||||
var url: VirtualFileUrl
|
||||
var parent: EntityWithManyImportsBuilder
|
||||
}
|
||||
|
||||
internal object SimpleEntityType : EntityType<SimpleEntity, SimpleEntityBuilder>(){
|
||||
override val entityClass: Class<SimpleEntity> 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)
|
||||
-284
@@ -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<ConnectionId>(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<SimpleEntity>
|
||||
get() = snapshot.extractOneToManyChildren<SimpleEntity>(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<ConnectionId> {
|
||||
return connections
|
||||
}
|
||||
|
||||
|
||||
internal class Builder(result: EntityWithManyImportsData?): ModifiableWorkspaceEntityBase<EntityWithManyImports, EntityWithManyImportsData>(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<WorkspaceEntityBase>(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<ConnectionId>{
|
||||
return connections
|
||||
}
|
||||
// Relabeling code, move information from dataSource to this builder
|
||||
override fun relabel(dataSource: WorkspaceEntity, parents: Set<WorkspaceEntity>?){
|
||||
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<SimpleEntity>? = emptyList()
|
||||
override var files: List<SimpleEntityBuilder>
|
||||
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<SimpleEntityBuilder>) + (this.entityLinks[EntityLink(true, FILES_CONNECTION_ID)] as? List<SimpleEntityBuilder> ?: emptyList())
|
||||
} else {
|
||||
this.entityLinks[EntityLink(true, FILES_CONNECTION_ID)] as? List<SimpleEntityBuilder> ?: 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<WorkspaceEntity, *>)
|
||||
}
|
||||
}
|
||||
_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> = EntityWithManyImports::class.java
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OptIn(WorkspaceEntityInternalApi::class)
|
||||
internal class EntityWithManyImportsData : WorkspaceEntityData<EntityWithManyImports>(){
|
||||
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<EntityWithManyImports>{
|
||||
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<out WorkspaceEntity>{
|
||||
return EntityWithManyImports::class.java
|
||||
}
|
||||
|
||||
override fun createDetachedEntity(parents: List<WorkspaceEntityBuilder<*>>): WorkspaceEntityBuilder<*>{
|
||||
return EntityWithManyImports(version, name, pointer, entitySource)
|
||||
}
|
||||
|
||||
override fun getRequiredParents(): List<Class<out WorkspaceEntity>>{
|
||||
val res = mutableListOf<Class<out WorkspaceEntity>>()
|
||||
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
|
||||
}
|
||||
}
|
||||
-39
@@ -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)
|
||||
}
|
||||
}
|
||||
-239
@@ -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<ConnectionId>(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<ConnectionId> {
|
||||
return connections
|
||||
}
|
||||
|
||||
|
||||
internal class Builder(result: SimpleEntityData?): ModifiableWorkspaceEntityBase<SimpleEntity, SimpleEntityData>(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<WorkspaceEntityBase>(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<ConnectionId>{
|
||||
return connections
|
||||
}
|
||||
// Relabeling code, move information from dataSource to this builder
|
||||
override fun relabel(dataSource: WorkspaceEntity, parents: Set<WorkspaceEntity>?){
|
||||
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<Any> ?: 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<WorkspaceEntity, *>)
|
||||
}
|
||||
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<Any> ?: 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> = SimpleEntity::class.java
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OptIn(WorkspaceEntityInternalApi::class)
|
||||
internal class SimpleEntityData : WorkspaceEntityData<SimpleEntity>(){
|
||||
lateinit var url: VirtualFileUrl
|
||||
|
||||
internal fun isUrlInitialized(): Boolean = ::url.isInitialized
|
||||
|
||||
override fun wrapAsModifiable(diff: MutableEntityStorage): WorkspaceEntityBuilder<SimpleEntity>{
|
||||
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<out WorkspaceEntity>{
|
||||
return SimpleEntity::class.java
|
||||
}
|
||||
|
||||
override fun createDetachedEntity(parents: List<WorkspaceEntityBuilder<*>>): WorkspaceEntityBuilder<*>{
|
||||
return SimpleEntity(url, entitySource){
|
||||
parents.filterIsInstance<EntityWithManyImportsBuilder>().singleOrNull()?.let { this.parent = it }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getRequiredParents(): List<Class<out WorkspaceEntity>>{
|
||||
val res = mutableListOf<Class<out WorkspaceEntity>>()
|
||||
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
|
||||
}
|
||||
}
|
||||
-33
@@ -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<SimpleEntity>
|
||||
val pointer: EntityPointer<SimpleEntity>
|
||||
|
||||
override val symbolicId: SimpleId
|
||||
get() = SimpleId(name)
|
||||
}
|
||||
|
||||
data class SimpleId(val name: String) : SymbolicEntityId<EntityWithManyImports> {
|
||||
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<SimpleEntity>) {
|
||||
fun doSomething(src: EntitySource) {
|
||||
}
|
||||
}
|
||||
-1
@@ -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.*
|
||||
|
||||
-1
@@ -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.*
|
||||
|
||||
-1
@@ -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.*
|
||||
|
||||
-1
@@ -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.*
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
-9
@@ -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
|
||||
}
|
||||
-9
@@ -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
|
||||
}
|
||||
+22
-1
@@ -7,4 +7,25 @@ interface SimpleEntity : WorkspaceEntity {
|
||||
val version: Int
|
||||
val name: String
|
||||
val isSimple: Boolean
|
||||
}
|
||||
|
||||
//region generated code
|
||||
@GeneratedCodeApiVersion(1)
|
||||
interface Builder : SimpleEntity, WorkspaceEntityBuilder<SimpleEntity> {
|
||||
//obsolete
|
||||
}
|
||||
|
||||
companion object : Type<SimpleEntity, Builder>() {
|
||||
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
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
//new comment
|
||||
package com.intellij.workspaceModel.test.api.impl
|
||||
|
||||
import com.intellij.platform.workspace.storage.ConnectionId
|
||||
|
||||
+4
-4
@@ -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<SourceRootEntity>()) {
|
||||
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") {
|
||||
|
||||
+4
-9
@@ -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)
|
||||
}
|
||||
|
||||
+10
-2
@@ -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<RelatedLibrary> =
|
||||
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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user