mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 21:11:28 +07:00
[workspace model] IJPL-847 codegen changes to move all code to generated sources
GitOrigin-RevId: 59da45aedc01bed0ad1e332277c63e49213f1464
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5985e14d11
commit
32ae5a5cb7
@@ -1,3 +1,3 @@
|
||||
codegenImplMinorVersion = 2
|
||||
codegenImplMinorVersion = 3
|
||||
codegenImplMajorVersion = 7
|
||||
codegenApiVersion = 3
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
${
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user