[workspace model] IJPL-847 codegen changes to move all code to generated sources

GitOrigin-RevId: 59da45aedc01bed0ad1e332277c63e49213f1464
This commit is contained in:
Kirill Bochkarev
2025-10-14 02:30:26 +02:00
committed by intellij-monorepo-bot
parent 5985e14d11
commit 32ae5a5cb7
9 changed files with 287 additions and 71 deletions

View File

@@ -1,3 +1,3 @@
codegenImplMinorVersion = 2
codegenImplMinorVersion = 3
codegenImplMajorVersion = 7
codegenApiVersion = 3

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// 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.workspaceModel.codegen.impl.engine
import com.intellij.workspaceModel.codegen.deft.meta.CompiledObjModule
@@ -21,9 +21,9 @@ class CodeGeneratorImpl : CodeGenerator {
return failedGenerationResult(reporter)
}
val objClassToBuilderInterface = module.types.associateWith {
val builderInterface = it.generateBuilderCode(reporter)
builderInterface
val objClassToTopLevelCode = module.types.associateWith {
val topLevelCode = it.generateTopLevelCode(reporter)
topLevelCode
}
if (reporter.hasErrors()) {
@@ -31,12 +31,12 @@ class CodeGeneratorImpl : CodeGenerator {
}
val generatedCode = objClassToBuilderInterface.map { (objClass, builderInterface) ->
val generatedCode = objClassToTopLevelCode.map { (objClass, topLevelCode) ->
ObjClassGeneratedCode(
target = objClass,
builderInterface = builderInterface,
companionObject = objClass.generateCompanionObject(),
topLevelCode = objClass.generateExtensionCode(),
builderInterface = objClass.generateCompatabilityBuilder(),
companionObject = objClass.generateCompatibilityCompanion(),
topLevelCode = topLevelCode,
implementationClass = objClass.implWsCode()
)
}

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// 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.workspaceModel.codegen.impl.writer
private const val workspaceBasePackageName = "com.intellij.platform.workspace"
@@ -64,7 +64,7 @@ internal object WorkspaceEntity {
private val fqn = fqn(packageName, className)
val simpleName = fqn.simpleName
val Builder = fqn(packageName, "$className.Builder")
val Builder = fqn(packageName, "Modifiable$className")
override fun toString(): String {
return fqn.toString()
}

View File

@@ -1,46 +1,44 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// 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.workspaceModel.codegen.impl.writer
import com.intellij.workspaceModel.codegen.impl.writer.classes.*
import com.intellij.workspaceModel.codegen.deft.meta.ObjClass
import com.intellij.workspaceModel.codegen.deft.meta.ObjProperty
import com.intellij.workspaceModel.codegen.deft.meta.OwnProperty
import com.intellij.workspaceModel.codegen.deft.meta.ValueType
import com.intellij.workspaceModel.codegen.engine.GenerationProblem
import com.intellij.workspaceModel.codegen.engine.ProblemLocation
import com.intellij.workspaceModel.codegen.engine.SKIPPED_TYPES
import com.intellij.workspaceModel.codegen.deft.meta.*
import com.intellij.workspaceModel.codegen.engine.*
import com.intellij.workspaceModel.codegen.impl.CodeGeneratorVersionCalculator
import com.intellij.workspaceModel.codegen.impl.engine.ProblemReporter
import com.intellij.workspaceModel.codegen.impl.writer.classes.*
import com.intellij.workspaceModel.codegen.impl.writer.extensions.*
import com.intellij.workspaceModel.codegen.impl.writer.fields.*
fun ObjClass<*>.generateBuilderCode(reporter: ProblemReporter): String = lines {
checkSuperTypes(this@generateBuilderCode, reporter)
checkSymbolicId(this@generateBuilderCode, reporter)
fun ObjClass<*>.generateMutableCode(reporter: ProblemReporter): String = lines {
checkSuperTypes(this@generateMutableCode, reporter)
checkSymbolicId(this@generateMutableCode, reporter)
if (additionalAnnotations.isNotEmpty()) {
line(additionalAnnotations)
}
line("@${GeneratedCodeApiVersion}(${CodeGeneratorVersionCalculator.apiVersion})")
val (typeParameter, typeDeclaration) = if (builderWithTypeParameter) "T" to "<T: $javaFullName>" else javaFullName to ""
val superBuilders = superTypes.filterIsInstance<ObjClass<*>>().filter { !it.isStandardInterface }.joinToString {
", ${it.name}.Builder<$typeParameter>"
", ${it.javaBuilderName}<$typeParameter>"
}
val header = "$generatedCodeVisibilityModifier interface Builder$typeDeclaration: ${WorkspaceEntity.Builder}<$typeParameter>$superBuilders"
val header = "$generatedCodeVisibilityModifier interface $defaultJavaBuilderName$typeDeclaration: ${WorkspaceEntity.Builder}<$typeParameter>$superBuilders"
section(header) {
list(allFields.noSymbolicId()) {
checkProperty(this, reporter)
getWsBuilderApi(this@generateBuilderCode)
getWsBuilderApi(this@generateMutableCode)
}
}
}
fun checkSuperTypes(objClass: ObjClass<*>, reporter: ProblemReporter) {
objClass.superTypes.filterIsInstance<ObjClass<*>>().forEach {superClass ->
objClass.superTypes.filterIsInstance<ObjClass<*>>().forEach { superClass ->
if (!superClass.openness.extendable) {
reporter.reportProblem(GenerationProblem("Class '${superClass.name}' cannot be extended", GenerationProblem.Level.ERROR,
ProblemLocation.Class(objClass)))
reporter.reportProblem(GenerationProblem("Class '${superClass.name}' cannot be extended", GenerationProblem.Level.ERROR,
ProblemLocation.Class(objClass)))
}
else if (!superClass.openness.openHierarchy && superClass.module != objClass.module) {
reporter.reportProblem(GenerationProblem("Class '${superClass.name}' cannot be extended from other modules",
GenerationProblem.Level.ERROR, ProblemLocation.Class(objClass)))
reporter.reportProblem(GenerationProblem("Class '${superClass.name}' cannot be extended from other modules",
GenerationProblem.Level.ERROR, ProblemLocation.Class(objClass)))
}
}
}
@@ -50,8 +48,8 @@ private fun checkSymbolicId(objClass: ObjClass<*>, reporter: ProblemReporter) {
if (objClass.openness == ObjClass.Openness.abstract) return
if (objClass.fields.none { it.name == "symbolicId" }) {
reporter.reportProblem(GenerationProblem("Class extends '${WorkspaceEntityWithSymbolicId.simpleName}' but " +
"doesn't override 'WorkspaceEntityWithSymbolicId.getSymbolicId' property",
GenerationProblem.Level.ERROR, ProblemLocation.Class(objClass)))
"doesn't override 'WorkspaceEntityWithSymbolicId.getSymbolicId' property",
GenerationProblem.Level.ERROR, ProblemLocation.Class(objClass)))
}
}
@@ -66,7 +64,7 @@ fun checkInheritance(objProperty: ObjProperty<*, *>, reporter: ProblemReporter)
if (!overriddenField.open) {
reporter.reportProblem(
GenerationProblem("Property '${overriddenField.receiver.name}::${overriddenField.name}' cannot be overridden",
GenerationProblem.Level.ERROR, ProblemLocation.Property(objProperty)))
GenerationProblem.Level.ERROR, ProblemLocation.Property(objProperty)))
}
}
}
@@ -77,6 +75,7 @@ private fun checkPropertyType(objProperty: ObjProperty<*, *>, reporter: ProblemR
if (type.child) "Child references should always be nullable"
else null
}
else -> checkType(type)
}
if (errorMessage != null) {
@@ -96,48 +95,44 @@ private fun checkType(type: ValueType<*>): String? = when (type) {
is ValueType.Set<*> -> "Optional sets aren't supported"
else -> checkType(type.type)
}
is ValueType.Set<*> -> {
if (type.elementType.isRefType()) {
"Set of references isn't supported"
}
else checkType(type.elementType)
}
is ValueType.Map<*, *> -> {
checkType(type.keyType) ?: checkType(type.valueType)
}
else -> null
}
private val knownInterfaces = setOf(VirtualFileUrl.decoded, EntitySource.decoded, SymbolicEntityId.decoded)
fun ObjClass<*>.generateCompanionObject(): String = lines {
fun ObjClass<*>.generateEntityTypeObject(): String = lines {
val builderGeneric = if (openness.extendable) "<$javaFullName>" else ""
val companionObjectHeader = buildString {
append("$generatedCodeVisibilityModifier companion object: ${EntityType}<$javaFullName, Builder$builderGeneric>(")
val base = superTypes.filterIsInstance<ObjClass<*>>().firstOrNull()
if (base != null && base.name !in SKIPPED_TYPES)
append(base.javaFullName)
append(")")
}
val mandatoryFields = allFields.mandatoryFields()
if (mandatoryFields.isNotEmpty()) {
section(companionObjectHeader) {
line("@${JvmOverloads::class.fqn}")
line("@${JvmStatic::class.fqn}")
line("@${JvmName::class.fqn}(\"create\")")
line("$generatedCodeVisibilityModifier operator fun invoke(")
section("internal object ${javaFullName}Type : ${EntityType}<$javaFullName, $defaultJavaBuilderName$builderGeneric>()") {
line("override val entityClass: Class<$javaFullName> get() = $javaFullName::class.java")
if (mandatoryFields.isNotEmpty()) {
line("operator fun invoke(")
mandatoryFields.forEach { field ->
line(" ".repeat(this.indentSize) + "${field.name}: ${field.valueType.javaType},")
}
line(" ".repeat(this.indentSize) + "init: (Builder$builderGeneric.() -> Unit)? = null,")
section("): Builder$builderGeneric") {
line(" ".repeat(this.indentSize) + "init: ($defaultJavaBuilderName$builderGeneric.() -> Unit)? = null,")
section("): $defaultJavaBuilderName$builderGeneric") {
line("val builder = builder()")
list(mandatoryFields) {
if (this.valueType is ValueType.Set<*> && !this.valueType.isRefType()) {
"builder.$name = $name.${StorageCollection.toMutableWorkspaceSet}()"
} else if (this.valueType is ValueType.List<*> && !this.valueType.isRefType()) {
}
else if (this.valueType is ValueType.List<*> && !this.valueType.isRefType()) {
"builder.$name = $name.${StorageCollection.toMutableWorkspaceList}()"
} else {
}
else {
"builder.$name = $name"
}
}
@@ -145,18 +140,16 @@ fun ObjClass<*>.generateCompanionObject(): String = lines {
line("return builder")
}
}
}
else {
section(companionObjectHeader) {
line("@${JvmOverloads::class.fqn}")
line("@${JvmStatic::class.fqn}")
line("@${JvmName::class.fqn}(\"create\")")
section("$generatedCodeVisibilityModifier operator fun invoke(init: (Builder$builderGeneric.() -> Unit)? = null): Builder$builderGeneric") {
else {
section("$generatedCodeVisibilityModifier operator fun invoke(init: ($defaultJavaBuilderName$builderGeneric.() -> Unit)? = null): $defaultJavaBuilderName$builderGeneric") {
line("val builder = builder()")
line("init?.invoke(builder)")
line("return builder")
}
}
if (requiresCompatibility) {
compatibilityInvoke(mandatoryFields, javaFullName, builderGeneric)
}
}
}
@@ -168,6 +161,46 @@ fun List<OwnProperty<*, *>>.mandatoryFields(): List<ObjProperty<*, *>> {
return fields
}
fun ObjClass<*>.generateTopLevelCode(reporter: ProblemReporter): String {
var result = generateMutableCode(reporter)
val companion = generateEntityTypeObject()
result = "$result\n$companion"
val extensions = generateExtensionCode()
if (extensions != null) {
result = "$result\n$extensions"
}
val constructor = generateConstructorCode()
if (constructor != null) {
result = "$result\n$constructor"
}
return result
}
fun ObjClass<*>.generateConstructorCode(): String? {
if (openness == ObjClass.Openness.abstract) return null
val mandatoryFields = allFields.mandatoryFields()
val builderGeneric = if (openness.extendable) "<$javaFullName>" else ""
return lines {
if (additionalAnnotations.isNotEmpty()) {
line(additionalAnnotations)
}
line("@${JvmOverloads::class.fqn}")
line("@${JvmName::class.fqn}(\"create$name\")")
if (mandatoryFields.isNotEmpty()) {
line("$generatedCodeVisibilityModifier fun $name(")
mandatoryFields.forEach { field ->
line(" ".repeat(this.indentSize) + "${field.name}: ${field.valueType.javaType},")
}
line(" ".repeat(this.indentSize) + "init: ($defaultJavaBuilderName$builderGeneric.() -> Unit)? = null,")
line(" ".repeat(this.indentSize) + "): $defaultJavaBuilderName = ${name}Type(${mandatoryFields.joinToString(", ") { it.name }}, init)")
}
else {
line("$generatedCodeVisibilityModifier fun $name(init: ($defaultJavaBuilderName$builderGeneric.() -> Unit)? = null): $defaultJavaBuilderName = ${name}Companion(init)")
}
}
}
fun ObjClass<*>.generateExtensionCode(): String? {
val fields = allExtensions
if (openness.extendable && fields.isEmpty()) return null
@@ -179,10 +212,17 @@ fun ObjClass<*>.generateExtensionCode(): String? {
}
line("$generatedCodeVisibilityModifier fun ${MutableEntityStorage}.modify$name(")
line(" entity: $name,")
line(" modification: $name.Builder.() -> Unit,")
line("): $name = modifyEntity($name.Builder::class.java, entity, modification)")
line(" modification: $defaultJavaBuilderName.() -> Unit,")
line("): $name = modifyEntity($defaultJavaBuilderName::class.java, entity, modification)")
if (requiresCompatibility) {
compatibilityModifyCode(this@lines)
}
}
fields.sortedWith(compareBy({ it.receiver.name }, { it.name })).forEach { line(it.wsCode) }
if (requiresCompatibility) {
fields.sortedWith(compareBy({ it.receiver.name }, { it.name })).forEach { it.compatibilityExtensionWsCode(this@lines) }
}
}
}
@@ -194,4 +234,3 @@ fun ObjProperty<*, *>.getWsBuilderApi(objClass: ObjClass<*>): String {
}
return "$override var $javaName: $returnType"
}

View File

@@ -1,3 +1,4 @@
// 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.workspaceModel.codegen.impl.writer.classes
import com.intellij.workspaceModel.codegen.deft.meta.ObjClass
@@ -9,7 +10,7 @@ import com.intellij.workspaceModel.codegen.impl.writer.fields.implWsBuilderIsIni
fun ObjClass<*>.implWsEntityBuilderCode(): String {
return """
internal class Builder(result: $javaDataName?): ${ModifiableWorkspaceEntityBase}<$javaFullName, $javaDataName>(result), $javaBuilderName {
internal class Builder(result: $javaDataName?): ${ModifiableWorkspaceEntityBase}<$javaFullName, $javaDataName>(result), $compatibleJavaBuilderName {
internal constructor(): this($javaDataName())
${

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// 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.workspaceModel.codegen.impl.writer.classes
import com.intellij.workspaceModel.codegen.deft.meta.ObjClass
@@ -18,7 +18,9 @@ fun ObjClass<*>.implWsEntityCode(): String {
}
return """
package ${module.implPackage}
package ${module.implPackage}
import $module.${defaultJavaBuilderName}
${implWsEntityAnnotations}
@OptIn($WorkspaceEntityInternalApi::class)

View File

@@ -0,0 +1,157 @@
// 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.workspaceModel.codegen.impl.writer
import com.intellij.workspaceModel.codegen.deft.meta.*
import com.intellij.workspaceModel.codegen.impl.CodeGeneratorVersionCalculator
import com.intellij.workspaceModel.codegen.impl.writer.extensions.*
import com.intellij.workspaceModel.codegen.impl.writer.fields.additionalAnnotations
import com.intellij.workspaceModel.codegen.impl.writer.fields.javaType
import java.util.Locale.getDefault
private val DEPRECATION = "@${Deprecated::class.fqn}(message = \"Use new API instead\")"
private fun String.capitalizeFirstChar(): String = replaceFirstChar { if (it.isLowerCase()) it.titlecase(getDefault()) else it.toString() }
fun ObjClass<*>.generateCompatabilityBuilder(): String =
lines {
if (!requiresCompatibility) {
return@lines
}
val (typeParameter, typeDeclaration) = if (builderWithTypeParameter) "<T>" to "<T: $javaFullName>" else "" to ""
val message = "Use $defaultJavaBuilderName instead"
line("@${Deprecated::class.fqn}(message = \"$message\")")
val superFields = allSuperClasses.flatMap { it.allFields.map { it.name } }.toSet()
val refsFields = allRefsFields.filter { it.name !in superFields && it.valueType !is ValueType.Collection<*, *>}
if (refsFields.isNotEmpty()) {
section("interface Builder$typeDeclaration : $defaultJavaBuilderName$typeParameter") {
refsFields
.forEach { field ->
line(DEPRECATION)
line("fun get${field.name.capitalizeFirstChar()}():${field.valueType.compatibilityJavaBuilderTypeWithGeneric} = ${field.name} as ${field.valueType.compatibilityJavaBuilderTypeWithGeneric}")
line(DEPRECATION)
line("fun set${field.name.capitalizeFirstChar()}(value: ${field.valueType.compatibilityJavaBuilderTypeWithGeneric}) { ${field.name} = value }")
}
}
}
else {
line("interface Builder$typeDeclaration : $defaultJavaBuilderName$typeParameter")
}
}
fun ObjClass<*>.generateCompatibilityCompanion(): String =
lines {
if (!requiresCompatibility) {
return@lines
}
val builderGeneric = if (openness.extendable) "<$javaFullName>" else ""
section("companion object : ${EntityType}<$javaFullName, Builder$builderGeneric>()") {
val mandatoryFields = allFields.mandatoryFields()
line(DEPRECATION)
line("@${JvmOverloads::class.fqn}")
line("@${JvmStatic::class.fqn}")
line("@${JvmName::class.fqn}(\"create\")")
if (mandatoryFields.isNotEmpty()) {
line("operator fun invoke(")
mandatoryFields.forEach { field ->
line(" ".repeat(this.indentSize) + "${field.name}: ${field.valueType.javaType},")
}
line(" ".repeat(this.indentSize) + "init: (Builder$builderGeneric.() -> Unit)? = null,")
line("): Builder$builderGeneric = ${javaFullName}Type.compatibilityInvoke(${mandatoryFields.joinToString(", ") { it.name }}, init)")
}
else {
line("$generatedCodeVisibilityModifier operator fun invoke(init: (Builder$builderGeneric.() -> Unit)? = null): Builder$builderGeneric = = ${javaFullName}Type.compatibilityInvoke(init)")
}
}
}
fun LinesBuilder.compatibilityInvoke(
mandatoryFields: List<ObjProperty<*, *>>,
javaFullName: QualifiedName,
builderGeneric: String,
) {
val builderSymbol = "$javaFullName.Builder$builderGeneric"
line(DEPRECATION)
if (mandatoryFields.isNotEmpty()) {
line("fun compatibilityInvoke(")
mandatoryFields.forEach { field ->
line(" ".repeat(this.indentSize) + "${field.name}: ${field.valueType.javaType},")
}
line(" ".repeat(this.indentSize) + "init: ($builderSymbol.() -> Unit)? = null,")
section("): $builderSymbol") {
line("val builder = builder() as $builderSymbol")
list(mandatoryFields) {
if (this.valueType is ValueType.Set<*> && !this.valueType.isRefType()) {
"builder.$name = $name.${StorageCollection.toMutableWorkspaceSet}()"
}
else if (this.valueType is ValueType.List<*> && !this.valueType.isRefType()) {
"builder.$name = $name.${StorageCollection.toMutableWorkspaceList}()"
}
else {
"builder.$name = $name"
}
}
line("init?.invoke(builder)")
line("return builder")
}
}
else {
section("$generatedCodeVisibilityModifier fun compatibilityInvoke(init: ($builderSymbol.() -> Unit)? = null): $builderSymbol") {
line("val builder = builder() as $builderSymbol")
line("init?.invoke(builder)")
line("return builder")
}
}
}
fun ObjClass<*>.compatibilityModifyCode(linesBuilder: LinesBuilder) {
with(linesBuilder) {
line(DEPRECATION)
if (additionalAnnotations.isNotEmpty()) {
line(additionalAnnotations)
}
line("$generatedCodeVisibilityModifier fun ${MutableEntityStorage}.modify$name(")
line(" entity: $name,")
line(" modification: $compatibleJavaBuilderName.() -> Unit,")
line("): $name {")
line(" return modifyEntity($compatibleJavaBuilderName::class.java, entity, modification)")
line("}")
}
}
fun ExtProperty<*, *>.compatibilityExtensionWsCode(linesBuilder: LinesBuilder) {
val isChild = valueType.getRefType().child
val parentAnnotation = if (!isChild) "@${Parent}\n" else ""
val generic = if (receiver.builderWithTypeParameter) "<out ${receiver.javaFullName}>" else ""
if (additionalAnnotations.isNotEmpty()) {
linesBuilder.line(additionalAnnotations)
}
linesBuilder.line(DEPRECATION)
val propertyType = valueType.compatibilityJavaBuilderTypeWithGeneric
linesBuilder.sectionNoBrackets("$parentAnnotation$generatedCodeVisibilityModifier var ${receiver.compatibleJavaBuilderName}$generic.$name: $propertyType") {
line("get() = (this as ${receiver.defaultJavaBuilderName}$generic).$name as $propertyType")
section("set(value)") {
line("(this as ${receiver.defaultJavaBuilderName}$generic).$name = value")
}
}
}
private val ObjClass<*>.compatibilityJavaBuilderFqnName: QualifiedName
get() = fqn(module.name, "$name.Builder")
private val ValueType<*>.compatibilityJavaBuilderTypeWithGeneric: QualifiedName
get() = when (this) {
ValueType.Boolean -> "Boolean".toQualifiedName()
ValueType.Int -> "Int".toQualifiedName()
ValueType.String -> "String".toQualifiedName()
is ValueType.List<*> -> "List".toQualifiedName().appendSuffix("<${elementType.compatibilityJavaBuilderTypeWithGeneric}>")
is ValueType.Set<*> -> "Set".toQualifiedName().appendSuffix("<${elementType.compatibilityJavaBuilderTypeWithGeneric}>")
is ValueType.Map<*, *> -> "Map".toQualifiedName().appendSuffix("<${keyType.compatibilityJavaBuilderTypeWithGeneric}, ${valueType.compatibilityJavaBuilderTypeWithGeneric}>")
is ValueType.ObjRef -> {
val out = if (target.openness == ObjClass.Openness.abstract) "out " else ""
target.compatibilityJavaBuilderFqnName.appendSuffix(if (target.builderWithTypeParameter) "<$out${this.javaType}>" else "")
}
is ValueType.Optional<*> -> type.compatibilityJavaBuilderTypeWithGeneric.appendSuffix("?")
is ValueType.JvmClass -> kotlinClassName.toQualifiedName()
else -> throw UnsupportedOperationException("$this type isn't supported")
}

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// 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.workspaceModel.codegen.impl.writer.extensions
import com.intellij.workspaceModel.codegen.deft.meta.*
@@ -6,14 +6,31 @@ import com.intellij.workspaceModel.codegen.impl.writer.*
import com.intellij.workspaceModel.codegen.impl.writer.WorkspaceEntity
import com.intellij.workspaceModel.codegen.impl.writer.WorkspaceEntityWithSymbolicId
private val compatibilityModules = setOf(
"com.intellij.platform.workspace.jps.entities",
"com.intellij.java.workspace.entities",
"com.intellij.openapi.externalSystem.settings.workspaceModel",
"com.goide.vgo.project.workspaceModel.entities",
"org.jetbrains.kotlin.idea.workspaceModel"
)
internal val ObjClass<*>.requiresCompatibility: Boolean
get() = module.name in compatibilityModules
internal val ObjClass<*>.javaFullName: QualifiedName
get() = fqn(module.name, name)
internal val ObjClass<*>.compatibleJavaBuilderName: String
get() = if (requiresCompatibility) "$name.Builder" else defaultJavaBuilderName
internal val ObjClass<*>.defaultJavaBuilderName: String
get() = "Modifiable$name"
internal val ObjClass<*>.javaBuilderName: String
get() = "$name.Builder"
get() = if (requiresCompatibility) compatibleJavaBuilderName else defaultJavaBuilderName
internal val ObjClass<*>.javaBuilderFqnName: QualifiedName
get() = fqn(module.name, "$name.Builder")
get() = fqn(module.name, defaultJavaBuilderName)
internal val ObjClass<*>.javaImplName: String
get() = "${name.replace(".", "")}Impl"

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// 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.workspaceModel.codegen.impl.writer.fields
import com.intellij.workspaceModel.codegen.deft.meta.ExtProperty
@@ -13,12 +13,12 @@ val ExtProperty<*, *>.wsCode: String
if (additionalAnnotations.isNotEmpty()) {
line(additionalAnnotations)
}
sectionNoBrackets("$parentAnnotation$generatedCodeVisibilityModifier var ${receiver.javaBuilderName}$generic.$name: ${valueType.javaBuilderTypeWithGeneric}") {
sectionNoBrackets("$parentAnnotation$generatedCodeVisibilityModifier var ${receiver.defaultJavaBuilderName}$generic.$name: ${valueType.javaBuilderTypeWithGeneric}") {
line("by WorkspaceEntity.extensionBuilder(${valueType.entityType}::class.java)")
}
}
private val ExtProperty<*, *>.additionalAnnotations: String
val ExtProperty<*, *>.additionalAnnotations: String
get() {
val hasInternalAnnotation = annotations.any {
it.fqName == Internal.decoded