diff --git a/platform/workspaceModel/codegen-api-one/.gitignore b/platform/workspaceModel/codegen-api-one/.gitignore deleted file mode 100644 index b63da4551b2e..000000000000 --- a/platform/workspaceModel/codegen-api-one/.gitignore +++ /dev/null @@ -1,42 +0,0 @@ -.gradle -build/ -!gradle/wrapper/gradle-wrapper.jar -!**/src/main/**/build/ -!**/src/test/**/build/ - -### IntelliJ IDEA ### -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ -*.iws -*.iml -*.ipr -out/ -!**/src/main/**/out/ -!**/src/test/**/out/ - -### Eclipse ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache -bin/ -!**/src/main/**/bin/ -!**/src/test/**/bin/ - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ - -### VS Code ### -.vscode/ - -### Mac OS ### -.DS_Store \ No newline at end of file diff --git a/platform/workspaceModel/codegen-api-one/build.gradle.kts b/platform/workspaceModel/codegen-api-one/build.gradle.kts deleted file mode 100644 index d817f2c5c71a..000000000000 --- a/platform/workspaceModel/codegen-api-one/build.gradle.kts +++ /dev/null @@ -1,42 +0,0 @@ -plugins { - id("maven-publish") - // Java support - id("java") - // Kotlin support - id("org.jetbrains.kotlin.jvm") version "1.8.0" -} - -group = "com.jetbrains.intellij.platform" -version = "0.0.4" - -repositories { - mavenCentral() - maven { - url = uri("https://www.jetbrains.com/intellij-repository/releases") - } - maven { - url = uri("https://packages.jetbrains.team/maven/p/ij/intellij-dependencies") - } -} - -publishing { - repositories { - maven { - url = uri("https://packages.jetbrains.team/maven/p/ide-accessibility-assistant/codegen-test") - credentials { - username = System.getProperty("intellij.workspace.codegen.repository.user") - password = System.getProperty("intellij.workspace.codegen.repository.password") - } - } - } - publications { - register("mavenJava", MavenPublication::class) { - from(components["java"]) - } - } -} - -dependencies { - implementation("org.jetbrains:annotations:24.0.0") - implementation("com.jetbrains.intellij.platform:workspace-model-storage:223.8836.34") -} \ No newline at end of file diff --git a/platform/workspaceModel/codegen-api-one/gradle/wrapper/gradle-wrapper.jar b/platform/workspaceModel/codegen-api-one/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f090..000000000000 Binary files a/platform/workspaceModel/codegen-api-one/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/platform/workspaceModel/codegen-api-one/gradle/wrapper/gradle-wrapper.properties b/platform/workspaceModel/codegen-api-one/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 3bb0ebd3dc95..000000000000 --- a/platform/workspaceModel/codegen-api-one/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Mar 10 15:23:48 AMT 2023 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/platform/workspaceModel/codegen-api-one/gradlew b/platform/workspaceModel/codegen-api-one/gradlew deleted file mode 100755 index 1b6c787337ff..000000000000 --- a/platform/workspaceModel/codegen-api-one/gradlew +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/platform/workspaceModel/codegen-api-one/gradlew.bat b/platform/workspaceModel/codegen-api-one/gradlew.bat deleted file mode 100644 index 107acd32c4e6..000000000000 --- a/platform/workspaceModel/codegen-api-one/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/platform/workspaceModel/codegen-api-one/settings.gradle.kts b/platform/workspaceModel/codegen-api-one/settings.gradle.kts deleted file mode 100644 index f60a1cf62881..000000000000 --- a/platform/workspaceModel/codegen-api-one/settings.gradle.kts +++ /dev/null @@ -1,2 +0,0 @@ -rootProject.name = "workspace-model-codegen" - diff --git a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/annotations/Cached.kt b/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/annotations/Cached.kt deleted file mode 100644 index 756776ead917..000000000000 --- a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/annotations/Cached.kt +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.deft.annotations - -@Target( - AnnotationTarget.PROPERTY_GETTER, - AnnotationTarget.FUNCTION -) -annotation class Cached \ No newline at end of file diff --git a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/annotations/Name.kt b/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/annotations/Name.kt deleted file mode 100644 index 4a036a9b133b..000000000000 --- a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/annotations/Name.kt +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.deft.annotations - -/** - * Name property values acts as implicit field of parent object. - * - * By setting name of some object, you are actually declare implicit field - * of parent object with same name and this object as value. - */ -@Target(AnnotationTarget.PROPERTY) -annotation class Name diff --git a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/annotations/Parent.kt b/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/annotations/Parent.kt deleted file mode 100644 index 4467a10fb219..000000000000 --- a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/annotations/Parent.kt +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.deft.annotations - -annotation class Parent \ No newline at end of file diff --git a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/CompiledObjClass.kt b/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/CompiledObjClass.kt deleted file mode 100644 index 49f14561044b..000000000000 --- a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/CompiledObjClass.kt +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.deft.meta - -interface CompiledObjModule : ObjModule { - fun objClass(typeId: Int): ObjClass<*> - fun extField(receiver: ObjClass<*>, name: String, default: T.() -> V): ExtProperty -} \ No newline at end of file diff --git a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/Obj.kt b/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/Obj.kt deleted file mode 100644 index 3d4aac076410..000000000000 --- a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/Obj.kt +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.deft.meta - -interface Obj { - val objType: ObjType<*> -} - -/** - * Mutable, possibly not fully initialized [Obj]. - * - * Implementation of that interface is generated by the Deft compiler, - * inside each [Obj]. It will contain `var`s for all final fields. - * - * [ObjBuilder] inherits all corresponding builders of [Obj] supertypes. - * - * Doesn't have `var`s for open field, as open setters contravariance - * contradicts open getter invariance. [ObjFinalBuilder] contains rest fields, - * but **not** inherits supertypes Builders. - */ -interface ObjBuilder : Obj { - val isInitialized: Boolean - - fun isInitialized(field: OwnProperty): Boolean - fun isInitialized(field: ExtProperty): Boolean - - fun setValue(field: OwnProperty, value: V) - fun setValue(field: ExtProperty, value: V) - fun setValue(type: ObjClass, value: V) - - fun remove(field: ExtProperty): Boolean - fun remove(type: ObjClass<*>): Boolean - - fun build(): T -} - -/** - * See [ObjBuilder]. - * - * Contains rest open fields, and not inherits supertypes Builders - * (as open setters contravariance contradicts open getter invariance). - */ -interface ObjFinalBuilder : ObjBuilder - diff --git a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/ObjModule.kt b/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/ObjModule.kt deleted file mode 100644 index 389dfce0e80a..000000000000 --- a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/ObjModule.kt +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.deft.meta - -import com.intellij.workspaceModel.codegen.deft.annotations.Name -import org.jetbrains.deft.annotations.Child - -interface ObjModule : Obj { - @Name - val name: String - - val moduleId: Id - get() = Id(name) - - val dependencies: List - - val types: List<@Child ObjClass<*>> - - val extensions: List<@Child ExtProperty<*, *>> - - /** - * Example: `org.jetbrains.deft.obj.intellijWs` - * will be parsed as: - * - `org.jetbrains.deft.obj.intellijWs` package - * - `org.jetbrains.deft.obj.intellijWs.IntellijWs` object name - **/ - @JvmInline - value class Id(private val notation: String) { - private val javaPackage: String - get() = notation - - private val objName: String - get() = notation.substringAfterLast(".") - .replaceFirstChar { it.titlecaseChar() } - - val objFqn: String - get() = "$javaPackage.$objName" - - fun check() { - check(objName.first().isUpperCase()) { - "`$notation` should be an id notation like `org.jetbrains.deft.obj.IntellijWs`.\n" + - "Will be parsed as:\n" + - "- `org.jetbrains.deft.obj.intellijWs` package\n" + - "- `IntellijWs` object name" - } - } - - override fun toString(): String = "ObjModule.Id($notation)" - } -} \ No newline at end of file diff --git a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/ObjProperty.kt b/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/ObjProperty.kt deleted file mode 100644 index 14482c35dc09..000000000000 --- a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/ObjProperty.kt +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.deft.meta - -import com.intellij.workspaceModel.codegen.deft.annotations.Name -import com.intellij.workspaceModel.codegen.deft.annotations.Parent - -/** - * Same as [kotlin.reflect.KProperty] - */ -interface ObjProperty : Obj { - val suspend: Boolean - - val open: Boolean - - val mutable: Boolean - - val receiver: ObjClass - - @Name - val name: String - - val valueType: ValueType - - val valueKind: ValueKind - - sealed interface ValueKind { - object Plain : ValueKind - class Computable(val expression: String) : ValueKind - class WithDefault(val value: String) : ValueKind - } - - ////// Kotlin DSL - - val content: Boolean -} - -/** - * Same as [kotlin.reflect.KProperty1] - */ -interface OwnProperty : ObjProperty { - @Parent - override val receiver: ObjClass - - val constructorParameter: Boolean - - val classLocalId: Int - - val isKey: Boolean -} - -/** - * Same as [kotlin.reflect.KProperty1] - */ -interface ExtProperty : ObjProperty { - @Parent - val module: ObjModule - - override val receiver: ObjClass - - val moduleLocalId: Int -} \ No newline at end of file diff --git a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/ObjType.kt b/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/ObjType.kt deleted file mode 100644 index b2a0aef31ec9..000000000000 --- a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/ObjType.kt +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.deft.meta - -import com.intellij.workspaceModel.codegen.deft.annotations.Cached -import com.intellij.workspaceModel.codegen.deft.annotations.Parent -import org.jetbrains.deft.annotations.Child - -interface ObjType : Obj { - val classifier: ObjType - - val arguments: List> -} - -/** - * Describes parameterized type of [Objects][Obj]. - * - * Read first: "Values, References and Objects" in [Obj] docs. - * - * For implementation simplicity, [ObjClass] is used to define both [ObjClass] - * itself and [asStructure], even when you need [asStructure] only. - * - * Objects can have [own][OwnProperty] and [extension][ExtProperty] fields. - */ -interface ObjClass : ObjType { - val typeParameters: List<@Child TypeParameter> - - val superTypes: List> - - @Parent - val module: ObjModule - - val name: String - - val openness: Openness - - enum class Openness( - val instantiatable: Boolean = false, - val extendable: Boolean = false, - val openHierarchy: Boolean = extendable - ) { - /** Single instance */ - `const`, - - /** Can't be extended */ - `final`(instantiatable = true), - - /** Should be extended (can't be instantiated directly) */ - `abstract`(extendable = true), - - /** Should be extended with sealed hierarchy */ - `enum`(extendable = true, openHierarchy = false), - - /** Can be extended and can be instantiated */ - `open`(instantiatable = true, extendable = true) - } - - val fields: List<@Child OwnProperty> - - val parentField: OwnProperty? - - val nameField: OwnProperty? - - val fieldsByName: Map> - @Cached get() = fields.associateBy { it.name } - - val fieldsByLocalId: Map> - @Cached get() = fields.associateBy { it.classLocalId } - - val asStructure: ValueType.Structure - @Cached get() = ValueType.Structure(fields.mapTo(mutableListOf()) { it.valueType }) - - companion object -} - -interface TypeParameter : Obj { - val name: String - val lowerBound: ObjType<*> -} diff --git a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/ValueType.kt b/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/ValueType.kt deleted file mode 100644 index 27fbd7fae4c9..000000000000 --- a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/ValueType.kt +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.deft.meta - -/** - * [ValueType] is used to describe the set of suitable values. - */ -sealed class ValueType { - sealed class Primitive : ValueType() - - /** - * `true` or `false`. Actually, the shorthand for `OneOf(Const(true), Const(false))`. - * - * Same as Kotlin [kotlin.Boolean] and Java primitive `boolean` ([java.lang.Boolean]) - */ - object Boolean : Primitive() - - /** - * 8-bit signed integer with the least significant bit. - * - * Same as Kotlin [kotlin.Byte] and Java primitive `byte`([java.lang.Byte]). - */ - object Byte : Primitive() - - /** - * 16-bit signed, big endian integer with the least significant bit. - * - * Same as Kotlin [kotlin.Short] and Java primitive `short`([java.lang.Short]). - */ - object Short : Primitive() - - /** - * 32-bit signed, big endian integer with the least significant bit. - * - * Same as Kotlin [kotlin.Int] and Java primitive `int`([java.lang.Integer]) - */ - object Int : Primitive() - - /** - * 64-bit signed, big endian integer with the least significant bit. - * - * Same as Kotlin [kotlin.Long] and Java primitive `long`([java.lang.Long]) - */ - object Long : Primitive() - - /** - * Represents a double-precision 32-bit [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754) floating point number. - * - * Same as Kotlin [kotlin.Float] and Java primitive `float`([java.lang.Float]) - */ - object Float : Primitive() - - /** - * Represents a double-precision 64-bit [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754) floating point number. - * - * Same as Kotlin [kotlin.Double] and Java primitive `double`([java.lang.Double]) - */ - object Double : Primitive() - - /** - * 8-bit unsigned integer. - * - * Same as Kotlin [UByte]. Not available in Java. - */ - object UByte : Primitive() - - /** - * 16-bit unsigned, big endian integer. - * - * Same as Kotlin [UShort]. Not available in Java. - */ - object UShort : Primitive() - - /** - * 32-bit unsigned, big endian integer. - * - * Same as Kotlin [UInt]. Not available in Java. - */ - object UInt : Primitive() - - /** - * 64-bit unsigned, big endian integer. - * - * Same as Kotlin [ULong]. Not available in Java. - */ - object ULong : Primitive() - - /** - * 16-bit Unicode character encoded by [UShort]. - * - * Same as Kotlin [kotlin.Char] and Java [java.lang.Character] - */ - object Char : Primitive() - - /** - * Behaves as [List] of [Char]. - * - * Unlike all other [ValueType]s, requires decoding on read and encoding on write, - * thus should be cached on client side. The actual binary representation is - * implementation detail. - * - * Translated to [kotlin.String] and Java [java.lang.String]. - */ - object String : Primitive() - - /** - * Polymorphic reference to [Obj] of [target] [ObjClass]. - **/ - data class ObjRef( - val child: kotlin.Boolean, - val target: ObjClass - ) : ValueType() - - sealed class JvmClass( - val javaClassName: kotlin.String, - val javaSuperClasses: kotlin.collections.List, - ) : ValueType() - - class DataClass( - javaClassName: kotlin.String, - javaSuperClasses: kotlin.collections.List, - val properties: kotlin.collections.List - ) : JvmClass(javaClassName, javaSuperClasses) - - data class DataClassProperty(val name: kotlin.String, val type: ValueType<*>) - - class SealedClass( - javaClassName: kotlin.String, - javaSuperClasses: kotlin.collections.List, - val subclasses: kotlin.collections.List> - ) : JvmClass(javaClassName, javaSuperClasses) - - class Blob( - javaClassName: kotlin.String, - javaSuperClasses: kotlin.collections.List, - ) : JvmClass(javaClassName, javaSuperClasses) - - class Enum( - javaClassName: kotlin.String, - ) : JvmClass(javaClassName, emptyList()) - - class Object( - javaClassName: kotlin.String, - javaSuperClasses: kotlin.collections.List, - ) : JvmClass(javaClassName, javaSuperClasses) - - /** - * Tuple of fields with fixed [ValueType]s. - * - * [Structure] is [ValueType] itself, thus can be nested (but without recursion) - * and compared by value. - * - * Use [ObjClass] to define your own structure. - * - * Read "Values, References and Objects" in [Obj] to understand differences - * between [ValueType] (which [Structure] is) and [ObjClass]. - * - * Unlike [ObjProperty], [Structure] fields are not nominal. - * Thus, two structures with same set of field types considered equal. - */ - data class Structure(val fields: kotlin.collections.List>) : ValueType() - - sealed class Collection> : ValueType() { - abstract val elementType: ValueType - } - - data class List(override val elementType: ValueType) : Collection>() - data class Set(override val elementType: ValueType) : Collection>() - - data class Map( - val keyType: ValueType, - val valueType: ValueType - ) : ValueType>() - - data class Optional(val type: ValueType) : ValueType() - - /** - * Any possible value. - * Valid inside [ValueRef] only. - * - * Logical representation: [AnyOf]`(...all value kinds)`. - */ - object Any : ValueType() - - /** - * Nothing has no possible values. - * Used to denote [Optional] values. - * - * Logical representation: [Both]`(...all value kinds, except Any)`. - */ - object Nothing : ValueType() -} diff --git a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/package-info.java b/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/package-info.java deleted file mode 100644 index 8ea6b2702376..000000000000 --- a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/deft/meta/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -/** - * Contains interfaces which describe structure of {@link com.intellij.workspaceModel.storage.WorkspaceEntity workspace entities}. - */ -@ApiStatus.Experimental -package com.intellij.workspaceModel.codegen.deft.meta; - -import org.jetbrains.annotations.ApiStatus; \ No newline at end of file diff --git a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/engine/CodeGenerator.kt b/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/engine/CodeGenerator.kt deleted file mode 100644 index a05f95508d67..000000000000 --- a/platform/workspaceModel/codegen-api-one/src/main/kotlin/com/intellij/workspaceModel/codegen/engine/CodeGenerator.kt +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.engine - -import com.intellij.workspaceModel.codegen.deft.meta.* -import com.intellij.workspaceModel.storage.WorkspaceEntity -import com.intellij.workspaceModel.storage.WorkspaceEntityWithSymbolicId - -val SKIPPED_TYPES: Set = setOfNotNull(WorkspaceEntity::class.simpleName, - WorkspaceEntity.Builder::class.simpleName, - WorkspaceEntityWithSymbolicId::class.simpleName) -interface CodeGenerator { - fun generate(module: CompiledObjModule): GenerationResult -} - -class GenerationResult(val generatedCode: List, val problems: List) - -class GenerationProblem( - val message: String, - val level: Level, - val location: ProblemLocation -) { - enum class Level { ERROR, WARNING } -} - -sealed interface ProblemLocation { - val objModule: ObjModule - - class Class(val objClass: ObjClass<*>) : ProblemLocation { - override val objModule: ObjModule - get() = objClass.module - - override fun toString(): String = objClass.name - } - class Property(val property: ObjProperty<*, *>) : ProblemLocation { - override val objModule: ObjModule - get() = when (property) { - is ExtProperty<*, *> -> property.module - else -> property.receiver.module - } - - override fun toString(): String = property.toString() - } -} - -class GeneratedCode( - val target: ObjClass<*>, - val builderInterface: String, - val companionObject: String, - val topLevelCode: String?, - val implementationClass: String? -) diff --git a/platform/workspaceModel/codegen-impl-one/.gitignore b/platform/workspaceModel/codegen-impl-one/.gitignore deleted file mode 100644 index b63da4551b2e..000000000000 --- a/platform/workspaceModel/codegen-impl-one/.gitignore +++ /dev/null @@ -1,42 +0,0 @@ -.gradle -build/ -!gradle/wrapper/gradle-wrapper.jar -!**/src/main/**/build/ -!**/src/test/**/build/ - -### IntelliJ IDEA ### -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ -*.iws -*.iml -*.ipr -out/ -!**/src/main/**/out/ -!**/src/test/**/out/ - -### Eclipse ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache -bin/ -!**/src/main/**/bin/ -!**/src/test/**/bin/ - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ - -### VS Code ### -.vscode/ - -### Mac OS ### -.DS_Store \ No newline at end of file diff --git a/platform/workspaceModel/codegen-impl-one/build.gradle.kts b/platform/workspaceModel/codegen-impl-one/build.gradle.kts deleted file mode 100644 index 68ae3ec572d5..000000000000 --- a/platform/workspaceModel/codegen-impl-one/build.gradle.kts +++ /dev/null @@ -1,43 +0,0 @@ -plugins { - id("maven-publish") - // Java support - id("java") - // Kotlin support - id("org.jetbrains.kotlin.jvm") version "1.8.0" -} - -group = "com.jetbrains.intellij.platform" -version = "0.0.6" - -repositories { - mavenCentral() - maven { - url = uri("https://www.jetbrains.com/intellij-repository/releases") - } - maven { - url = uri("https://www.jetbrains.com/intellij-repository/nightly") - } -} - -publishing { - repositories { - maven { - url = uri("https://packages.jetbrains.team/maven/p/ide-accessibility-assistant/codegen-test") - credentials { - username = System.getProperty("intellij.workspace.codegen.repository.user") - password = System.getProperty("intellij.workspace.codegen.repository.password") - } - } - } - publications { - register("mavenJava", MavenPublication::class) { - from(components["java"]) - } - } -} - -dependencies { - implementation("org.jetbrains.kotlin:kotlin-reflect") - implementation("com.jetbrains.intellij.platform:workspace-model-codegen:LATEST-TRUNK-SNAPSHOT") - implementation("com.jetbrains.intellij.platform:workspace-model-storage:223.8836.34") -} \ No newline at end of file diff --git a/platform/workspaceModel/codegen-impl-one/gradle/wrapper/gradle-wrapper.jar b/platform/workspaceModel/codegen-impl-one/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f090..000000000000 Binary files a/platform/workspaceModel/codegen-impl-one/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/platform/workspaceModel/codegen-impl-one/gradle/wrapper/gradle-wrapper.properties b/platform/workspaceModel/codegen-impl-one/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index e04458538d3b..000000000000 --- a/platform/workspaceModel/codegen-impl-one/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Mar 10 15:27:35 AMT 2023 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/platform/workspaceModel/codegen-impl-one/gradlew b/platform/workspaceModel/codegen-impl-one/gradlew deleted file mode 100755 index 1b6c787337ff..000000000000 --- a/platform/workspaceModel/codegen-impl-one/gradlew +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/platform/workspaceModel/codegen-impl-one/gradlew.bat b/platform/workspaceModel/codegen-impl-one/gradlew.bat deleted file mode 100644 index 107acd32c4e6..000000000000 --- a/platform/workspaceModel/codegen-impl-one/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/platform/workspaceModel/codegen-impl-one/settings.gradle.kts b/platform/workspaceModel/codegen-impl-one/settings.gradle.kts deleted file mode 100644 index f81783e06f9b..000000000000 --- a/platform/workspaceModel/codegen-impl-one/settings.gradle.kts +++ /dev/null @@ -1,2 +0,0 @@ -rootProject.name = "workspace-model-codegen-impl" - diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/InterfaceTraverser.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/InterfaceTraverser.kt deleted file mode 100644 index 9ab94aeb08d6..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/InterfaceTraverser.kt +++ /dev/null @@ -1,343 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen - -import com.intellij.workspaceModel.codegen.deft.meta.ObjClass -import com.intellij.workspaceModel.codegen.deft.meta.OwnProperty -import com.intellij.workspaceModel.codegen.deft.meta.ValueType -import com.intellij.workspaceModel.codegen.writer.fields.javaType -import com.intellij.workspaceModel.codegen.writer.LinesBuilder -import com.intellij.workspaceModel.codegen.writer.isRefType - -class InterfaceTraverser { - fun traverse(myInterface: ObjClass<*>, visitor: InterfaceVisitor): Boolean { - for (field in myInterface.fields) { - val res = traverseField(field, visitor, field.name) - if (!res) return false - } - return true - } - - private fun traverseField(field: OwnProperty<*, *>, visitor: InterfaceVisitor, varName: String): Boolean { - return traverseType(field.valueType, visitor, varName) - } - - private fun traverseType(type: ValueType<*>, visitor: InterfaceVisitor, varName: String): Boolean { - when (type) { - is ValueType.Boolean -> return visitor.visitBoolean(varName) - is ValueType.Int -> return visitor.visitInt(varName) - is ValueType.String -> return visitor.visitString(varName) - is ValueType.Collection<*, *> -> { - val itemVarName = "_$varName" - val shouldProcessList = visitor.visitListStart(varName, itemVarName, type.elementType) - if (!shouldProcessList) return false - val traversingResult = traverseType(type.elementType, visitor, itemVarName) - return visitor.visitListEnd(varName, itemVarName, traversingResult, type.elementType) - } - - is ValueType.Map<*, *> -> { - val keyVarName = "key_$varName" - val valueVarName = "value_$varName" - val shouldProcessMap = visitor.visitMapStart(varName, keyVarName, valueVarName, type.keyType, type.valueType) - if (!shouldProcessMap) return false - - val keyTraverseResult = traverseType(type.keyType, visitor, keyVarName) - val valueTraverseResult = traverseType(type.valueType, visitor, valueVarName) - - return visitor.visitMapEnd(varName, keyVarName, valueVarName, type.keyType, type.valueType, - keyTraverseResult && valueTraverseResult) - } - is ValueType.Optional<*> -> { - val notNullVarName = "_$varName" - var continueProcess = visitor.visitOptionalStart(varName, notNullVarName, type.type) - if (!continueProcess) return false - - continueProcess = traverseType(type.type, visitor, notNullVarName) - return visitor.visitOptionalEnd(varName, notNullVarName, type.type, continueProcess) - } - is ValueType.Blob<*> -> { - return visitor.visitUnknownBlob(varName, type.javaClassName) - /* - - - var process = visitor.visitKnownBlobStart(varName, type.javaSimpleName) - if (!process) return false - - process = traverse(foundType, visitor) - return visitor.visitKnownBlobFinish(varName, type.javaSimpleName, process) - */ - } - is ValueType.DataClass<*> -> { - var process = visitor.visitDataClassStart(varName, type) - if (!process) return false - - //process = traverse(type, visitor) - return visitor.visitDataClassEnd(varName, type, process) - } - else -> {} - } - return true - } -} - -class DeserializationVisitor(linesBuilder: LinesBuilder) : InterfaceVisitor { - private val builders: ArrayDeque = ArrayDeque().also { it.add(linesBuilder) } - private val builder: LinesBuilder - get() = builders.last() - - private var countersCounter = 0 - - override fun visitBoolean(varName: String): Boolean { - builder.line("$varName = de.readBoolean()") - return true - } - - override fun visitInt(varName: String): Boolean { - builder.line("$varName = de.readInt()") - return true - } - - override fun visitString(varName: String): Boolean { - builder.line("$varName = de.readString()") - return true - } - - override fun visitListStart(varName: String, itemVarName: String, listArgumentType: ValueType<*>): Boolean { - if (listArgumentType.isRefType()) return true - - val sub = LinesBuilder(StringBuilder(), builder.indentLevel + 1) - builders.add(sub) - return true - } - - override fun visitListEnd(varName: String, itemVarName: String, traverseResult: Boolean, listArgumentType: ValueType<*>): Boolean { - if (listArgumentType.isRefType()) return true - - val myInListBuilder = builders.removeLast() - if (myInListBuilder.result.isNotBlank()) { - val varCounter = "counter" + counter() - val varCollector = "collector" + counter() - builder.line("val $varCounter = de.readInt()") - builder.line("val $varCollector = ArrayList<${listArgumentType.javaType}>()") - builder.line("var $itemVarName: ${listArgumentType.javaType}") - builder.line("repeat($varCounter) {") - myInListBuilder.line("$varCollector.add($itemVarName)") - builder.result.append(myInListBuilder.result) - builder.line("}") - builder.line("$varName = $varCollector") - } - return true - } - - override fun visitMapStart(varName: String, - keyVarName: String, - valueVarName: String, - keyType: ValueType<*>, - valueType: ValueType<*>): Boolean { - return false - } - - override fun visitMapEnd(varName: String, - keyVarName: String, - valueVarName: String, - keyType: ValueType<*>, - valueType: ValueType<*>, - traverseResult: Boolean): Boolean { - return false - } - - override fun visitOptionalStart(varName: String, notNullVarName: String, type: ValueType<*>): Boolean { - if (type.isRefType()) return true - - val sub = LinesBuilder(StringBuilder(), builder.indentLevel + 1) - builders.add(sub) - return true - } - - override fun visitOptionalEnd(varName: String, notNullVarName: String, type: ValueType<*>, traverseResult: Boolean): Boolean { - if (type.isRefType()) return true - - val popLast = builders.removeLast() - builder.section("if (de.acceptNull())") { - line("$varName = null") - } - builder.section("else") { - if (popLast.result.isNotBlank()) { - line("val $notNullVarName: ${type.javaType}") - result.append(popLast.result) - line("$varName = $notNullVarName") - } - } - return true - } - - override fun visitUnknownBlob(varName: String, javaSimpleName: String): Boolean { - return false - } - - override fun visitKnownBlobStart(varName: String, javaSimpleName: String): Boolean { - return false - } - - override fun visitKnownBlobFinish(varName: String, javaSimpleName: String, traverseResult: Boolean): Boolean { - return false - } - - override fun visitDataClassStart(varName: String, dataClass: ValueType.DataClass<*>): Boolean { - TODO("Not yet implemented") - } - - override fun visitDataClassEnd(varName: String, dataClass: ValueType.DataClass<*>, traverseResult: Boolean): Boolean { - TODO("Not yet implemented") - } - - private fun counter(): Int { - return countersCounter++ - } -} - -class SerializatorVisitor private constructor(private val linesBuilder: ArrayDeque) : InterfaceVisitor { - - constructor(linesBuilder: LinesBuilder) : this(ArrayDeque().also { it.add(linesBuilder) }) - - val builder: LinesBuilder - get() = linesBuilder.last() - - override fun visitBoolean(varName: String): Boolean { - builder.line("ser.saveBoolean($varName)") - return true - } - - override fun visitInt(varName: String): Boolean { - builder.line("ser.saveInt($varName)") - return true - } - - override fun visitString(varName: String): Boolean { - builder.line("ser.saveString($varName)") - return true - } - - override fun visitListStart(varName: String, itemVarName: String, listArgumentType: ValueType<*>): Boolean { - if (listArgumentType.isRefType()) return true - - val sub = LinesBuilder(StringBuilder(), builder.indentLevel + 1) - linesBuilder.add(sub) - return true - } - - override fun visitListEnd(varName: String, itemVarName: String, traverseResult: Boolean, listArgumentType: ValueType<*>): Boolean { - if (listArgumentType.isRefType()) return true - - val myInListBuilder = linesBuilder.removeLast() - if (myInListBuilder.result.isNotBlank()) { - builder.line("ser.saveInt($varName.size)") - builder.line("for ($itemVarName in $varName) {") - builder.result.append(myInListBuilder.result) - builder.line("}") - } - return true - } - - override fun visitMapStart(varName: String, - keyVarName: String, - valueVarName: String, - keyType: ValueType<*>, - valueType: ValueType<*>): Boolean { - if (keyType.isRefType() || valueType.isRefType()) return true - - val sub = LinesBuilder(StringBuilder(), builder.indentLevel + 1) - linesBuilder.add(sub) - return true - } - - override fun visitMapEnd(varName: String, - keyVarName: String, - valueVarName: String, - keyType: ValueType<*>, - valueType: ValueType<*>, - traverseResult: Boolean): Boolean { - if (keyType.isRefType() || valueType.isRefType()) return true - - val inMapBuilder = linesBuilder.removeLast() - if (inMapBuilder.result.isNotBlank()) { - builder.line("ser.saveInt($varName.size)") - builder.line("for (($keyVarName, $valueVarName) in $varName) {") - builder.result.append(inMapBuilder.result) - builder.line("}") - } - return true - } - - override fun visitOptionalStart(varName: String, notNullVarName: String, type: ValueType<*>): Boolean { - if (type.isRefType()) return true - - val sub = LinesBuilder(StringBuilder(), builder.indentLevel + 1) - linesBuilder.add(sub) - return true - } - - override fun visitOptionalEnd(varName: String, notNullVarName: String, type: ValueType<*>, traverseResult: Boolean): Boolean { - if (type.isRefType()) return true - - val inMapBuilder = linesBuilder.removeLast() - if (inMapBuilder.result.isNotBlank()) { - builder.line("val $notNullVarName = $varName") - builder.line("if ($notNullVarName != null) {") - builder.result.append(inMapBuilder.result) - builder.line("} else {") - builder.line(" ser.saveNull()") - builder.line("}") - } - return true - } - - override fun visitUnknownBlob(varName: String, javaSimpleName: String): Boolean { - if (javaSimpleName == "EntitySource") return true - builder.line("ser.saveBlob($varName, \"$javaSimpleName\")") - return true - } - - override fun visitKnownBlobStart(varName: String, javaSimpleName: String): Boolean { - return true - } - - override fun visitKnownBlobFinish(varName: String, javaSimpleName: String, traverseResult: Boolean): Boolean { - return true - } - - override fun visitDataClassStart(varName: String, dataClass: ValueType.DataClass<*>): Boolean { - TODO("Not yet implemented") - } - - override fun visitDataClassEnd(varName: String, dataClass: ValueType.DataClass<*>, traverseResult: Boolean): Boolean { - TODO("Not yet implemented") - } -} - -interface InterfaceVisitor { - fun visitBoolean(varName: String): Boolean - fun visitInt(varName: String): Boolean - fun visitString(varName: String): Boolean - - fun visitListStart(varName: String, itemVarName: String, listArgumentType: ValueType<*>): Boolean - fun visitListEnd(varName: String, itemVarName: String, traverseResult: Boolean, listArgumentType: ValueType<*>): Boolean - - fun visitMapStart(varName: String, keyVarName: String, valueVarName: String, keyType: ValueType<*>, valueType: ValueType<*>): Boolean - fun visitMapEnd(varName: String, - keyVarName: String, - valueVarName: String, - keyType: ValueType<*>, - valueType: ValueType<*>, - traverseResult: Boolean): Boolean - - fun visitOptionalStart(varName: String, notNullVarName: String, type: ValueType<*>): Boolean - fun visitOptionalEnd(varName: String, notNullVarName: String, type: ValueType<*>, traverseResult: Boolean): Boolean - - fun visitUnknownBlob(varName: String, javaSimpleName: String): Boolean - fun visitKnownBlobStart(varName: String, javaSimpleName: String): Boolean - fun visitKnownBlobFinish(varName: String, javaSimpleName: String, traverseResult: Boolean): Boolean - - fun visitDataClassStart(varName: String, dataClass: ValueType.DataClass<*>): Boolean - fun visitDataClassEnd(varName: String, dataClass: ValueType.DataClass<*>, traverseResult: Boolean): Boolean -} - diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/engine/impl/CodeGeneratorImpl.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/engine/impl/CodeGeneratorImpl.kt deleted file mode 100644 index 840b4d4be84a..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/engine/impl/CodeGeneratorImpl.kt +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.engine.impl - -import com.intellij.workspaceModel.codegen.deft.meta.CompiledObjModule -import com.intellij.workspaceModel.codegen.engine.CodeGenerator -import com.intellij.workspaceModel.codegen.engine.GeneratedCode -import com.intellij.workspaceModel.codegen.engine.GenerationProblem -import com.intellij.workspaceModel.codegen.engine.GenerationResult -import com.intellij.workspaceModel.codegen.writer.generateBuilderCode -import com.intellij.workspaceModel.codegen.writer.generateCompanionObject -import com.intellij.workspaceModel.codegen.writer.generateExtensionCode -import com.intellij.workspaceModel.codegen.writer.implWsCode - -class CodeGeneratorImpl : CodeGenerator { - override fun generate(module: CompiledObjModule): GenerationResult { - val problems = ArrayList() - val reporter = ProblemReporter { problems.add(it) } - val objClassToBuilderInterface = module.types.associateWith { - val builderInterface = it.generateBuilderCode(reporter) - builderInterface - } - // If there is at least one error, report them and stop any further calculations and - if (problems.any { it.level == GenerationProblem.Level.ERROR }) { - return GenerationResult(emptyList(), problems) - } - - val code = objClassToBuilderInterface.map { (objClass, builderInterface) -> - GeneratedCode( - target = objClass, - builderInterface = builderInterface, - companionObject = objClass.generateCompanionObject(), - topLevelCode = objClass.generateExtensionCode(), - implementationClass = objClass.implWsCode() - ) - } - return GenerationResult(code, problems) - } -} - -fun interface ProblemReporter { - fun reportProblem(problem: GenerationProblem) -} \ No newline at end of file diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/LinesBuilder.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/LinesBuilder.kt deleted file mode 100644 index c3bf1306cac2..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/LinesBuilder.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.intellij.workspaceModel.codegen.writer - -class LinesBuilder( - val result: StringBuilder, - val indentLevel: Int, - val indentSize: Int = 4 -) { - var first = true - - fun line(str: String = "") { - lineNoNl(str) - result.append('\n') - } - - fun lineNoNl(str: String) { - if (first) { - first = false - } - - result.append(" ".repeat(indentLevel * indentSize)) - result.append(str) - } - - fun list(c: Collection, f: T.() -> String = { "$this" }) { - c.forEach { - line(it.f()) - } - } - - fun section(s: LinesBuilder.() -> Unit) { - LinesBuilder(result, indentLevel + 1, indentSize).s() - } - - fun section(head: String, s: LinesBuilder.() -> Unit) { - lineNoNl(head) - val sub = LinesBuilder(result, indentLevel+1, indentSize) - sub.result.append(" {\n") - sub.s() - line("}") - } - - fun sectionNoBrackets(head: String, s: LinesBuilder.() -> Unit) { - lineNoNl(head) - val sub = LinesBuilder(result, indentLevel+1, indentSize) - sub.result.append("\n") - sub.s() - } -} - -inline fun lines(level: Int = 0, lines: LinesBuilder.() -> Unit): String { - val result = StringBuilder() - LinesBuilder(result, level).lines() - return result.toString() -} \ No newline at end of file diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/QualifiedName.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/QualifiedName.kt deleted file mode 100644 index b3a0d18c67dc..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/QualifiedName.kt +++ /dev/null @@ -1,79 +0,0 @@ -package com.intellij.workspaceModel.codegen.writer - -import com.intellij.workspaceModel.storage.EntityStorage -import com.intellij.workspaceModel.storage.MutableEntityStorage -import com.intellij.workspaceModel.storage.WorkspaceEntity -import com.intellij.workspaceModel.storage.impl.ConnectionId -import com.intellij.workspaceModel.storage.impl.ModifiableWorkspaceEntityBase -import kotlin.reflect.* -import kotlin.reflect.jvm.javaMethod - -private const val fqnEscape = "#uC03o#" - -fun fqn(function: KProperty1, Collection>): QualifiedName = function.fqn -fun fqn1(function: KFunction3): QualifiedName = function.fqn -fun fqn2(function: KFunction3>): QualifiedName = function.fqn -fun fqn3(function: KFunction4): QualifiedName = function.fqn -fun fqn4(function: KFunction4, Unit>): QualifiedName = function.fqn -fun fqn5(function: KFunction4, Unit>): QualifiedName = function.fqn -fun fqn6(function: KFunction2, MutableEntityStorage, Unit>): QualifiedName = function.fqn -fun fqn7(function: KFunction1, Collection<*>>): QualifiedName = function.fqn - -private val KProperty<*>.fqn: QualifiedName - get() { - val declaringClass = this.getter.javaMethod?.declaringClass ?: return "".toQualifiedName() - return fqn(declaringClass.packageName, this.name) - } - -private val KFunction<*>.fqn: QualifiedName - get() { - val declaringClass = this.javaMethod?.declaringClass ?: return "".toQualifiedName() - return fqn(declaringClass.packageName, this.name) - } - -@JvmInline -value class QualifiedName(val encodedString: String) { - override fun toString(): String { - return encodedString - } - - val decoded: String - get() = encodedString.removePrefix(fqnEscape).substringBefore("#").replace("@@", ".") - fun appendInner(innerClassPath: String): QualifiedName = QualifiedName("$encodedString.$innerClassPath") - fun appendSuffix(suffix: String): QualifiedName = QualifiedName("$encodedString$suffix") -} - -/** - * Temporary string for adding to imports - */ -fun fqn(packageName: String?, name: String): QualifiedName { - if (packageName.isNullOrEmpty()) return QualifiedName(name) - - val outerClassName = name.substringBefore(".") - return QualifiedName("$fqnEscape$packageName@@$outerClassName#$name") -} - -fun String.toQualifiedName(): QualifiedName { - val classNameMatch = Regex("\\.[A-Z]").find(this) ?: return QualifiedName(this) - return fqn(substring(0, classNameMatch.range.first), substring(classNameMatch.range.last)) -} - -val KClass<*>.fqn: QualifiedName - get() = java.fqn - -val Class<*>.fqn: QualifiedName - get() { - val name = name - val packageName = name.substringBeforeLast(".") - val className = name.substringAfterLast(".") - .replace('$', '.') - - if (className.contains(".")) { - val outerClassName = className.substringBefore(".") - val innerClassPath = className.substringAfter(".") - return fqn(packageName, outerClassName).appendInner(innerClassPath) - } - else { - return fqn(packageName, className) - } - } diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/Type.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/Type.kt deleted file mode 100644 index 7aa968019a7f..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/Type.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.intellij.workspaceModel.codegen.writer - -import com.intellij.workspaceModel.codegen.deft.meta.ObjClass - -val ObjClass<*>.javaFullName: QualifiedName - get() = fqn(module.name, name) - -val ObjClass<*>.javaBuilderName: String - get() = "$name.Builder" - -val ObjClass<*>.javaImplName: String - get() = "${name.replace(".", "")}Impl" - -val ObjClass<*>.javaImplBuilderName - get() = "${javaImplName}.Builder" diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/apiCode.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/apiCode.kt deleted file mode 100644 index edce6c369612..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/apiCode.kt +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.writer - -import com.intellij.workspaceModel.codegen.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.engine.impl.ProblemReporter -import com.intellij.workspaceModel.codegen.writer.fields.javaMutableType -import com.intellij.workspaceModel.codegen.writer.fields.javaType -import com.intellij.workspaceModel.codegen.writer.fields.wsCode -import com.intellij.workspaceModel.codegen.writer.fqn -import com.intellij.workspaceModel.codegen.writer.fqn7 -import com.intellij.workspaceModel.codegen.writer.lines -import com.intellij.workspaceModel.codegen.writer.* -import com.intellij.workspaceModel.storage.* -import com.intellij.workspaceModel.storage.impl.containers.toMutableWorkspaceList -import com.intellij.workspaceModel.storage.impl.containers.toMutableWorkspaceSet -import com.intellij.workspaceModel.storage.url.VirtualFileUrl -import org.jetbrains.deft.ObjBuilder -import org.jetbrains.deft.Type - -fun ObjClass<*>.generateBuilderCode(reporter: ProblemReporter): String = lines { - checkSuperTypes(this@generateBuilderCode, reporter) - checkSymbolicId(this@generateBuilderCode, reporter) - line("@${GeneratedCodeApiVersion::class.fqn}(${CodeGeneratorVersions.API_VERSION})") - val (typeParameter, typeDeclaration) = - if (openness.extendable) "T" to "" else javaFullName to "" - val superBuilders = superTypes.filterIsInstance>().filter { !it.isStandardInterface }.joinToString { - ", ${it.name}.Builder<$typeParameter>" - } - val header = "interface Builder$typeDeclaration: $javaFullName$superBuilders, ${WorkspaceEntity.Builder::class.fqn}<$typeParameter>, ${ObjBuilder::class.fqn}<$typeParameter>" - - section(header) { - list(allFields.noSymbolicId()) { - checkProperty(this, reporter) - wsBuilderApi - } - } -} - -fun checkSuperTypes(objClass: ObjClass<*>, reporter: ProblemReporter) { - objClass.superTypes.filterIsInstance>().forEach {superClass -> - if (!superClass.openness.extendable) { - 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))) - } - } -} - -private fun checkSymbolicId(objClass: ObjClass<*>, reporter: ProblemReporter) { - if (!objClass.isEntityWithSymbolicId) return - if (objClass.openness == ObjClass.Openness.abstract) return - if (objClass.fields.none { it.name == "symbolicId" }) { - reporter.reportProblem(GenerationProblem("Class extends '${WorkspaceEntityWithSymbolicId::class.simpleName}' but " + - "doesn't override 'WorkspaceEntityWithSymbolicId.getSymbolicId' property", - GenerationProblem.Level.ERROR, ProblemLocation.Class(objClass))) - } -} - -private fun checkProperty(objProperty: ObjProperty<*, *>, reporter: ProblemReporter) { - checkInheritance(objProperty, reporter) - checkAllImmutable(objProperty, reporter) - checkPropertyType(objProperty, reporter) -} - -fun checkInheritance(objProperty: ObjProperty<*, *>, reporter: ProblemReporter) { - objProperty.receiver.allSuperClasses.mapNotNull { it.fieldsByName[objProperty.name] }.forEach { overriddenField -> - if (!overriddenField.open) { - reporter.reportProblem( - GenerationProblem("Property '${overriddenField.receiver.name}::${overriddenField.name}' cannot be overridden", - GenerationProblem.Level.ERROR, ProblemLocation.Property(objProperty))) - } - } -} - -private fun checkPropertyType(objProperty: ObjProperty<*, *>, reporter: ProblemReporter) { - val errorMessage = when (val type = objProperty.valueType) { - is ValueType.ObjRef<*> -> { - if (type.child) "Child references should always be nullable" - else null - } - else -> checkType(type) - } - if (errorMessage != null) { - reporter.reportProblem(GenerationProblem(errorMessage, GenerationProblem.Level.ERROR, ProblemLocation.Property(objProperty))) - } -} - -fun checkAllImmutable(objProperty: ObjProperty<*, *>, reporter: ProblemReporter) { - if (objProperty.mutable) { - reporter.reportProblem(GenerationProblem("An immutable interface can't contain mutable properties", GenerationProblem.Level.ERROR, ProblemLocation.Property(objProperty))) - } -} - -private fun checkType(type: ValueType<*>): String? = when (type) { - is ValueType.Optional -> when (type.type) { - is ValueType.List<*> -> "Optional lists aren't supported" - 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) - } - is ValueType.Blob<*> -> { - if (!keepUnknownFields && type.javaClassName !in knownInterfaces) { - "Unsupported type '${type.javaClassName}'" - } - else null - } - else -> null -} - -private val keepUnknownFields: Boolean - get() = java.lang.Boolean.getBoolean("workspace.model.generator.keep.unknown.fields") - -private val knownInterfaces = setOf( - VirtualFileUrl::class.qualifiedName!!, - EntitySource::class.qualifiedName!!, - SymbolicEntityId::class.qualifiedName!!, -) - -fun ObjClass<*>.generateCompanionObject(): String = lines { - val builderGeneric = if (openness.extendable) "<$javaFullName>" else "" - val companionObjectHeader = buildString { - append("companion object: ${Type::class.fqn}<$javaFullName, Builder$builderGeneric>(") - val base = superTypes.filterIsInstance>().firstOrNull() - if (base != null && base.name !in SKIPPED_TYPES) - append(base.javaFullName) - append(")") - } - val mandatoryFields = allFields.mandatoryFields() - if (mandatoryFields.isNotEmpty()) { - val fields = mandatoryFields.joinToString { "${it.name}: ${it.valueType.javaType}" } - section(companionObjectHeader) { - line("@${JvmOverloads::class.fqn}") - line("@${JvmStatic::class.fqn}") - line("@${JvmName::class.fqn}(\"create\")") - section("operator fun invoke($fields, init: (Builder$builderGeneric.() -> Unit)? = null): $javaFullName") { - line("val builder = builder()") - list(mandatoryFields) { - if (this.valueType is ValueType.Set<*> && !this.valueType.isRefType()) { - "builder.$name = $name.${fqn7(Collection<*>::toMutableWorkspaceSet)}()" - } else if (this.valueType is ValueType.List<*> && !this.valueType.isRefType()) { - "builder.$name = $name.${fqn7(Collection<*>::toMutableWorkspaceList)}()" - } else { - "builder.$name = $name" - } - } - line("init?.invoke(builder)") - line("return builder") - } - } - } - else { - section(companionObjectHeader) { - line("@${JvmOverloads::class.fqn}") - line("@${JvmStatic::class.fqn}") - line("@${JvmName::class.fqn}(\"create\")") - section("operator fun invoke(init: (Builder$builderGeneric.() -> Unit)? = null): $javaFullName") { - line("val builder = builder()") - line("init?.invoke(builder)") - line("return builder") - } - } - } -} - -fun List>.mandatoryFields(): List> { - var fields = this.noRefs().noOptional().noSymbolicId().noDefaultValue() - if (fields.isNotEmpty()) { - fields = fields.noEntitySource() + fields.single { it.name == "entitySource" } - } - return fields -} - -fun ObjClass<*>.generateExtensionCode(): String? { - val fields = module.extensions.filter { it.receiver == this || it.receiver.module != module && it.valueType.isRefType() && it.valueType.getRefType().target == this } - if (openness.extendable && fields.isEmpty()) return null - - return lines { - if (!openness.extendable) { - line("fun ${MutableEntityStorage::class.fqn}.modifyEntity(entity: $name, modification: $name.Builder.() -> Unit) = modifyEntity($name.Builder::class.java, entity, modification)") - } - fields.sortedWith(compareBy({ it.receiver.name }, { it.name })).forEach { line(it.wsCode) } - } -} - -val ObjProperty<*, *>.wsBuilderApi: String - get() { - val returnType = if (valueType is ValueType.Collection<*, *> && !valueType.isRefType()) valueType.javaMutableType else valueType.javaType - return "override var $javaName: $returnType" - } - diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/SoftLinksCode.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/SoftLinksCode.kt deleted file mode 100644 index ec8b25578a17..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/SoftLinksCode.kt +++ /dev/null @@ -1,316 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.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.ValueType -import com.intellij.workspaceModel.codegen.writer.fields.javaMutableType -import com.intellij.workspaceModel.codegen.writer.isRefType -import com.intellij.workspaceModel.codegen.writer.LinesBuilder -import com.intellij.workspaceModel.codegen.writer.fqn -import com.intellij.workspaceModel.codegen.writer.lines -import com.intellij.workspaceModel.codegen.writer.toQualifiedName -import com.intellij.workspaceModel.codegen.writer.allFields -import com.intellij.workspaceModel.storage.SymbolicEntityId -import com.intellij.workspaceModel.storage.impl.indices.WorkspaceMutableIndex - -internal fun ObjClass<*>.softLinksCode(context: LinesBuilder, hasSoftLinks: Boolean) { - context.conditionalLine({ hasSoftLinks }, "override fun getLinks(): Set<${SymbolicEntityId::class.fqn}<*>>") { - line("val result = HashSet<${SymbolicEntityId::class.fqn}<*>>()") - operate(this) { line("result.add($it)") } - line("return result") - } - - context.conditionalLine( - { hasSoftLinks }, - "override fun index(index: ${WorkspaceMutableIndex::class.fqn}<${SymbolicEntityId::class.fqn}<*>>)" - ) { - operate(this) { line("index.index(this, $it)") } - } - - context.conditionalLine( - { hasSoftLinks }, - "override fun updateLinksIndex(prev: Set<${SymbolicEntityId::class.fqn}<*>>, index: ${WorkspaceMutableIndex::class.fqn}<${SymbolicEntityId::class.fqn}<*>>)" - ) { - line("// TODO verify logic") - line("val mutablePreviousSet = HashSet(prev)") - operate(this) { - line("val removedItem_${it.clean()} = mutablePreviousSet.remove($it)") - section("if (!removedItem_${it.clean()})") { - line("index.index(this, $it)") - } - } - section("for (removed in mutablePreviousSet)") { - line("index.remove(this, removed)") - } - } - - context.conditionalLine( - { hasSoftLinks }, - "override fun updateLink(oldLink: ${SymbolicEntityId::class.fqn}<*>, newLink: ${SymbolicEntityId::class.fqn}<*>): Boolean" - ) { - line("var changed = false") - operateUpdateLink(this) - line("return changed") - } -} - -internal fun ObjClass<*>.hasSoftLinks(): Boolean { - return fields.noSymbolicId().noRefs().any { field -> - field.hasSoftLinks() - } -} - -internal fun ObjProperty<*, *>.hasSoftLinks(): Boolean { - if (name == "symbolicId") return false - return valueType.hasSoftLinks() -} - -internal fun ValueType<*>.hasSoftLinks(): Boolean = when (this) { - is ValueType.Blob -> isSymbolicId - is ValueType.Collection<*, *> -> elementType.hasSoftLinks() - is ValueType.Optional<*> -> type.hasSoftLinks() - is ValueType.SealedClass<*> -> isSymbolicId || subclasses.any { it.hasSoftLinks() } - is ValueType.DataClass<*> -> isSymbolicId || properties.any { it.type.hasSoftLinks() } - else -> false -} - -val ValueType.JvmClass<*>.isSymbolicId: Boolean - get() = SymbolicEntityId::class.java.name in javaSuperClasses - -private fun ObjClass<*>.operate( - context: LinesBuilder, - operation: LinesBuilder.(String) -> Unit -) { - allFields.noSymbolicId().noRefs().forEach { field -> - field.valueType.operate(field.name, context, operation) - } -} - -private fun ValueType<*>.operate( - varName: String, - context: LinesBuilder, - operation: LinesBuilder.(String) -> Unit, - generateNewName: Boolean = true, -) { - when (this) { - is ValueType.JvmClass -> { - when { - isSymbolicId -> context.operation(varName) - this is ValueType.SealedClass<*> -> processSealedClass(this, varName, context, operation, generateNewName) - this is ValueType.DataClass<*> -> processDataClassProperties(varName, context, properties, operation) - } - } - is ValueType.Collection<*, *> -> { - val elementType = elementType - - context.section("for (item in ${varName})") { - elementType.operate("item", this@section, operation, false) - } - } - is ValueType.Optional<*> -> { - if (type is ValueType.JvmClass && (type as ValueType.JvmClass<*>).isSymbolicId) { - context.line("val optionalLink_${varName.clean()} = $varName") - context.`if`("optionalLink_${varName.clean()} != null") label@{ - type.operate("optionalLink_${varName.clean()}", this@label, operation) - } - } - } - else -> Unit - } -} - -private fun processDataClassProperties(varName: String, - context: LinesBuilder, - dataClassProperties: List, - operation: LinesBuilder.(String) -> Unit) { - for (property in dataClassProperties) { - property.type.operate("$varName.${property.name}", context, operation) - } -} - -private fun processSealedClass(thisClass: ValueType.SealedClass<*>, - varName: String, - context: LinesBuilder, - operation: LinesBuilder.(String) -> Unit, - generateNewName: Boolean = true) { - val newVarName = if (generateNewName) "_${varName.clean()}" else varName - if (generateNewName) context.line("val $newVarName = $varName") - context.section("when ($newVarName)") { - listBuilder(thisClass.subclasses) { item -> - val linesBuilder = LinesBuilder(StringBuilder(), context.indentLevel+1, context.indentSize).wrapper() - if (item is ValueType.SealedClass) { - processSealedClass(item, newVarName, linesBuilder, operation, generateNewName) - } - else if (item is ValueType.DataClass) { - processDataClassProperties(newVarName, linesBuilder, item.properties, operation) - } - section("is ${item.javaClassName.toQualifiedName()} -> ") { - result.append(linesBuilder.result) - } - } - } -} - - -private fun ObjClass<*>.operateUpdateLink(context: LinesBuilder) { - allFields.noSymbolicId().noRefs().forEach { field -> - val retType = field.valueType.processType(context, field.name) - if (retType != null) { - context.`if`("$retType != null") { - if (field.valueType is ValueType.Set<*> && !field.valueType.isRefType()) { - line("${field.name} = $retType as ${field.valueType.javaMutableType}") - } else if (field.valueType is ValueType.List<*> && !field.valueType.isRefType()) { - line("${field.name} = $retType as ${field.valueType.javaMutableType}") - } else { - line("${field.name} = $retType") - } - } - } - } -} - -private fun ValueType<*>.processType( - context: LinesBuilder, - varName: String, -): String? { - return when (this) { - is ValueType.JvmClass -> { - when { - isSymbolicId -> { - val name = "${varName.clean()}_data" - context.lineNoNl("val $name = ") - context.ifElse("$varName == oldLink", { - line("changed = true") - line("newLink as ${javaClassName.toQualifiedName()}") - }) { line("null") } - name - } - this is ValueType.SealedClass<*> -> { - processSealedClass(this, varName, context) - } - this is ValueType.DataClass<*> -> { - val updates = properties.mapNotNull label@{ - val retVar = it.type.processType( - context, - "$varName.${it.name}" - ) - if (retVar != null) it.name to retVar else null - } - if (updates.isEmpty()) { - null - } - else { - val name = "${varName.clean()}_data" - context.line("var $name = $varName") - updates.forEach { (fieldName, update) -> - context.`if`("$update != null") { - line("$name = $name.copy($fieldName = $update)") - } - } - name - } - } - else -> null - } - } - is ValueType.Collection<*, *> -> { - var name: String? = "${varName.clean()}_data" - val builder = lines(context.indentLevel) { - section("val $name = $varName.map") label@{ - val returnVar = elementType.processType( - this@label, - "it" - ) - if (returnVar != null) { - ifElse("$returnVar != null", { - line(returnVar) - }) { line("it") } - } - else { - name = null - } - } - } - if (name != null) { - context.result.append(builder) - } - name - } - is ValueType.Optional<*> -> { - var name: String? = "${varName.clean()}_data_optional" - val builder = lines(context.indentLevel) { - lineNoNl("var $name = ") - ifElse("$varName != null", labelIf@{ - val returnVar = type.processType( - this@labelIf, - "$varName!!" - ) - if (returnVar != null) { - line(returnVar) - } - else { - name = null - } - }) { line("null") } - } - if (name != null) { - context.result.append(builder) - } - name - } - else -> return null - } -} - -private fun processSealedClass(thisClass: ValueType.SealedClass<*>, - varName: String, - context: LinesBuilder): String { - val newVarName = "_${varName.clean()}" - val resVarName = "res_${varName.clean()}" - context.line("val $newVarName = $varName") - context.lineNoNl("val $resVarName = ") - context.section("when ($newVarName)") { - listBuilder(thisClass.subclasses) { item -> - section("is ${item.javaClassName.toQualifiedName()} -> ") label@{ - var sectionVarName = newVarName - val properties: List - if (item is ValueType.SealedClass) { - sectionVarName = processSealedClass(item, sectionVarName, this) - properties = emptyList() - } - else if (item is ValueType.DataClass) { - properties = item.properties - } - else { - properties = emptyList() - } - val updates = properties.mapNotNull { - val retVar = it.type.processType( - this@label, - "$sectionVarName.${it.name}" - ) - if (retVar != null) it.name to retVar else null - } - if (updates.isEmpty()) { - line(sectionVarName) - } - else { - val name = "${sectionVarName.clean()}_data" - line("var $name = $sectionVarName") - updates.forEach { (fieldName, update) -> - `if`("$update != null") { - line("$name = $name.copy($fieldName = $update)") - } - } - line(name) - } - } - } - } - return resVarName -} - -private fun String.clean(): String { - return this.replace(".", "_").replace('!', '_') -} \ No newline at end of file diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/implWsDataClassCode.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/implWsDataClassCode.kt deleted file mode 100644 index 29e44bdaf093..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/implWsDataClassCode.kt +++ /dev/null @@ -1,335 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.writer.classes - -import com.intellij.workspaceModel.codegen.* -import com.intellij.workspaceModel.codegen.deft.meta.ObjClass -import com.intellij.workspaceModel.codegen.deft.meta.ObjProperty -import com.intellij.workspaceModel.codegen.deft.meta.ValueType -import com.intellij.workspaceModel.codegen.writer.fields.implWsDataFieldCode -import com.intellij.workspaceModel.codegen.writer.fields.implWsDataFieldInitializedCode -import com.intellij.workspaceModel.codegen.writer.fields.javaType -import com.intellij.workspaceModel.codegen.writer.* -import com.intellij.workspaceModel.codegen.writer.allFields -import com.intellij.workspaceModel.storage.* -import com.intellij.workspaceModel.storage.impl.SoftLinkable -import com.intellij.workspaceModel.storage.impl.UsedClassesCollector -import com.intellij.workspaceModel.storage.impl.WorkspaceEntityData -import com.intellij.workspaceModel.storage.impl.containers.toMutableWorkspaceList -import com.intellij.workspaceModel.storage.impl.containers.toMutableWorkspaceSet -import com.intellij.workspaceModel.storage.url.VirtualFileUrl - -/** - * - Soft links - * - with SymbolicId - */ - -val ObjClass<*>.javaDataName - get() = "${name.replace(".", "")}Data" - -val ObjClass<*>.isEntityWithSymbolicId: Boolean - get() = superTypes.any { - it is ObjClass<*> && (it.javaFullName.decoded == WorkspaceEntityWithSymbolicId::class.java.name || it.isEntityWithSymbolicId) - } - -fun ObjClass<*>.implWsDataClassCode(): String { - val entityDataBaseClass = if (isEntityWithSymbolicId) { - "${WorkspaceEntityData::class.fqn}.WithCalculableSymbolicId<$javaFullName>()" - } - else { - "${WorkspaceEntityData::class.fqn}<$javaFullName>()" - } - val hasSoftLinks = hasSoftLinks() - val softLinkable = if (hasSoftLinks) SoftLinkable::class.fqn else null - return lines { - section("class $javaDataName : ${sups(entityDataBaseClass, softLinkable?.encodedString)}") label@{ - listNl(allFields.noRefs().noEntitySource().noSymbolicId()) { implWsDataFieldCode } - - listNl(allFields.noRefs().noEntitySource().noSymbolicId().noOptional().noDefaultValue()) { implWsDataFieldInitializedCode } - - this@implWsDataClassCode.softLinksCode(this, hasSoftLinks) - - sectionNl( - "override fun wrapAsModifiable(diff: ${MutableEntityStorage::class.fqn}): ${WorkspaceEntity.Builder::class.fqn}<$javaFullName>") { - line("val modifiable = $javaImplBuilderName(null)") - line("modifiable.diff = diff") - line("modifiable.snapshot = diff") - line("modifiable.id = createEntityId()") - line("return modifiable") - } - - // --- createEntity - sectionNl("override fun createEntity(snapshot: ${EntityStorage::class.fqn}): $javaFullName") { - section("return getCached(snapshot)") { - line("val entity = $javaImplName(this)") - line("entity.snapshot = snapshot") - line("entity.id = createEntityId()") - line("entity") - } - } - - val collectionFields = allFields.noRefs().filter { it.valueType is ValueType.Collection<*, *> } - if (collectionFields.isNotEmpty()) { - sectionNl("override fun clone(): $javaDataName") { - val fieldName = "clonedEntity" - line("val $fieldName = super.clone()") - line("$fieldName as $javaDataName") - collectionFields.forEach { field -> - if (field.valueType is ValueType.Set<*>) { - line("$fieldName.${field.name} = $fieldName.${field.name}.${fqn7(Collection<*>::toMutableWorkspaceSet)}()") - } else { - line("$fieldName.${field.name} = $fieldName.${field.name}.${fqn7(Collection<*>::toMutableWorkspaceList)}()") - } - } - line("return $fieldName") - } - } - - if (isEntityWithSymbolicId) { - val symbolicIdField = fields.first { it.name == "symbolicId" } - val valueKind = symbolicIdField.valueKind - val methodBody = (valueKind as ObjProperty.ValueKind.Computable).expression - if (methodBody.contains("return")) { - if (methodBody.startsWith("{")) { - line("override fun symbolicId(): ${SymbolicEntityId::class.fqn}<*> $methodBody \n") - } else { - sectionNl("override fun symbolicId(): ${SymbolicEntityId::class.fqn}<*>") { - line(methodBody) - } - } - } else { - sectionNl("override fun symbolicId(): ${SymbolicEntityId::class.fqn}<*>") { - if (methodBody.startsWith("=")) { - line("return ${methodBody.substring(2)}") - } - else { - line("return $methodBody") - } - } - } - } - - // --- getEntityInterface method - sectionNl("override fun getEntityInterface(): Class") { - line("return $name::class.java") - } - - sectionNl("override fun serialize(ser: ${EntityInformation.Serializer::class.fqn})") { - //InterfaceTraverser(simpleTypes).traverse(this@implWsDataClassCode, SerializatorVisitor(this@sectionNl)) - } - - sectionNl("override fun deserialize(de: ${EntityInformation.Deserializer::class.fqn})") { - //InterfaceTraverser(simpleTypes).traverse(this@implWsDataClassCode, DeserializationVisitor(this@sectionNl)) - } - - sectionNl("override fun createDetachedEntity(parents: List<${WorkspaceEntity::class.fqn}>): ${WorkspaceEntity::class.fqn}") { - val noRefs = allFields.noRefs().noSymbolicId() - val mandatoryFields = allFields.mandatoryFields() - val constructor = mandatoryFields.joinToString(", ") { it.name }.let { if (it.isNotBlank()) "($it)" else "" } - val optionalFields = noRefs.filterNot { it in mandatoryFields } - - section("return $javaFullName$constructor") { - optionalFields.forEach { - line("this.${it.name} = this@$javaDataName.${it.name}") - } - allRefsFields.filterNot { it.valueType.getRefType().child }.forEach { - val parentType = it.valueType - if (parentType is ValueType.Optional) { - line("this.${it.name} = parents.filterIsInstance<${parentType.type.javaType}>().singleOrNull()") - } else { - line("parents.filterIsInstance<${parentType.javaType}>().singleOrNull()?.let { this.${it.name} = it }") - } - } - } - } - - sectionNl("override fun getRequiredParents(): List>") { - line("val res = mutableListOf>()") - allRefsFields.filterNot { it.valueType.getRefType().child }.forEach { - val parentType = it.valueType - if (parentType !is ValueType.Optional) { - line("res.add(${parentType.javaType}::class.java)") - } - } - line("return res") - } - - // --- equals - val keyFields = allFields.filter { it.isKey } - sectionNl("override fun equals(other: Any?): Boolean") { - line("if (other == null) return false") - line("if (this.javaClass != other.javaClass) return false") - - lineWrapped("other as $javaDataName") - - list(allFields.noRefs().noSymbolicId()) { - "if (this.$name != other.$name) return false" - } - - line("return true") - } - - // --- equalsIgnoringEntitySource - sectionNl("override fun equalsIgnoringEntitySource(other: Any?): Boolean") { - line("if (other == null) return false") - line("if (this.javaClass != other.javaClass) return false") - - lineWrapped("other as $javaDataName") - - list(allFields.noRefs().noEntitySource().noSymbolicId()) { - "if (this.$name != other.$name) return false" - } - - line("return true") - } - - // --- hashCode - section("override fun hashCode(): Int") { - line("var result = entitySource.hashCode()") - list(allFields.noRefs().noEntitySource().noSymbolicId()) { - "result = 31 * result + $name.hashCode()" - } - line("return result") - } - - // --- hashCodeIgnoringEntitySource - section("override fun hashCodeIgnoringEntitySource(): Int") { - line("var result = javaClass.hashCode()") - list(allFields.noRefs().noEntitySource().noSymbolicId()) { - "result = 31 * result + $name.hashCode()" - } - line("return result") - } - - if (keyFields.isNotEmpty()) { - line() - section("override fun equalsByKey(other: Any?): Boolean") { - line("if (other == null) return false") - line("if (this.javaClass != other.javaClass) return false") - - lineWrapped("other as $javaDataName") - - list(keyFields) { - "if (this.$name != other.$name) return false" - } - - line("return true") - } - line() - section("override fun hashCodeByKey(): Int") { - line("var result = javaClass.hashCode()") - list(keyFields) { - "result = 31 * result + $name.hashCode()" - } - line("return result") - } - } - - cacheCollector(this@lines) - } - } -} - -fun List>.noRefs(): List> = this.filterNot { it.valueType.isRefType() } -fun List>.noEntitySource() = this.filter { it.name != "entitySource" } -fun List>.noSymbolicId() = this.filter { it.name != "symbolicId" } -fun List>.noOptional() = this.filter { it.valueType !is ValueType.Optional<*> } -fun List>.noDefaultValue() = this.filter { it.valueKind == ObjProperty.ValueKind.Plain } - -private fun ObjClass<*>.cacheCollector(linesBuilder: LinesBuilder) { - val clazzes = HashSet() - val accessors = HashSet() - val objects = HashSet() - val res = allFields.map { - it.valueType.getClasses(it.name, clazzes, accessors, objects) - }.all{ it } - linesBuilder.section("override fun collectClassUsagesData(collector: ${UsedClassesCollector::class.fqn})") { - clazzes.forEach { - line("collector.add(${it.toQualifiedName()}::class.java)") - } - objects.forEach { - line("collector.addObject(${it.toQualifiedName()}::class.java)") - } - accessors.forEach { - line(it) - } - line("collector.sameForAllEntities = $res") - } -} - -private fun ValueType<*>.getClasses(fieldName: String, clazzes: HashSet, accessors: HashSet, objects: HashSet): Boolean { - var res = true - when (this) { - is ValueType.List<*> -> { - if (!this.isRefType()) { - accessors.add("this.$fieldName?.let { collector.add(it::class.java) }") - res = false - } - this.elementType.getClasses(fieldName, clazzes, accessors, objects) - return res - } - is ValueType.Set<*> -> { - if (!this.isRefType()) { - accessors.add("this.$fieldName?.let { collector.add(it::class.java) }") - res = false - } - this.elementType.getClasses(fieldName, clazzes, accessors, objects) - return res - } - is ValueType.Blob -> { - val className = this.javaClassName - if (className !in setOf(VirtualFileUrl::class.java.name, EntitySource::class.java.name, SymbolicEntityId::class.java.name)) { - accessors.add("this.$fieldName?.let { collector.addDataToInspect(it) }") - return res - } - if (className == VirtualFileUrl::class.java.name) { - accessors.add("this.$fieldName?.let { collector.add(it::class.java) }") - return false - } - return true - } - is ValueType.Enum -> { - val className = this.javaClassName - clazzes.add(className) - return res - } - is ValueType.DataClass -> { - // Here we might filter SymbolicIds and get them from the index, but in this case we would need to inspect their fields on the fly - // Here we have all the information about the symbolic ids and it's fields, so let's keep them here (at least for a while). - clazzes.add(javaClassName) - properties.forEach { property -> - property.type.getClasses(fieldName, clazzes, accessors, objects) - } - return true - } - is ValueType.SealedClass -> { - clazzes.add(javaClassName) - this.subclasses.forEach { subclass -> - subclass.getClasses(fieldName, clazzes, accessors, objects) - } - return true - } - is ValueType.Map<*, *> -> { - if (!this.isRefType()) { - accessors.add("this.$fieldName?.let { collector.add(it::class.java) }") - res = false - } - this.keyType.getClasses(fieldName, clazzes, accessors, objects) - this.valueType.getClasses(fieldName, clazzes, accessors, objects) - return res - } - is ValueType.Optional -> { - return this.type.getClasses(fieldName, clazzes, accessors, objects) - } - is ValueType.Structure -> { - this.fields.forEach { - it.getClasses(fieldName, clazzes, accessors, objects) - } - return true - } - is ValueType.Object<*> -> { - objects.add(javaClassName) - return true - } - else -> return true - } -} diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/implWsEntityBuilderClassCode.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/implWsEntityBuilderClassCode.kt deleted file mode 100644 index 0d2fb1479759..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/implWsEntityBuilderClassCode.kt +++ /dev/null @@ -1,132 +0,0 @@ -package com.intellij.workspaceModel.codegen.writer.classes - -import com.intellij.workspaceModel.codegen.deft.meta.ObjClass -import com.intellij.workspaceModel.codegen.deft.meta.ValueType -import com.intellij.workspaceModel.codegen.writer.* -import com.intellij.workspaceModel.codegen.writer.fields.implWsBuilderFieldCode -import com.intellij.workspaceModel.codegen.writer.fields.implWsBuilderIsInitializedCode -import com.intellij.workspaceModel.storage.MutableEntityStorage -import com.intellij.workspaceModel.storage.WorkspaceEntity -import com.intellij.workspaceModel.storage.bridgeEntities.LibraryEntity -import com.intellij.workspaceModel.storage.impl.ConnectionId -import com.intellij.workspaceModel.storage.impl.ModifiableWorkspaceEntityBase -import com.intellij.workspaceModel.storage.impl.containers.MutableWorkspaceList -import com.intellij.workspaceModel.storage.impl.containers.MutableWorkspaceSet - -fun ObjClass<*>.implWsEntityBuilderCode(): String { - return """ - class Builder(result: $javaDataName?): ${ModifiableWorkspaceEntityBase::class.fqn}<$javaFullName, $javaDataName>(result), $javaBuilderName { - constructor(): this($javaDataName()) - -${ - lines(2) { - section("override fun applyToBuilder(builder: ${MutableEntityStorage::class.fqn})") { - `if`("this.diff != null") { - ifElse("existsInBuilder(builder)", { - line("this.diff = builder") - line("return") - }) { - line("error(\"Entity $name is already created in a different builder\")") - } - } - line() - line("this.diff = builder") - line("this.snapshot = builder") - line("addToBuilder()") - line("this.id = getEntityData().createEntityId()") - lineComment("After adding entity data to the builder, we need to unbind it and move the control over entity data to builder") - lineComment("Builder may switch to snapshot at any moment and lock entity data to modification") - line("this.currentEntityData = null") - line() - list(vfuFields) { - "index(this, \"$name\", this.$name)" - } - if (name == LibraryEntity::class.simpleName) { - line("indexLibraryRoots(${LibraryEntity::roots.name})") - } - lineComment("Process linked entities that are connected without a builder") - line("processLinkedEntities(builder)") - - //------------ - - line("checkInitialization() // TODO uncomment and check failed tests") - } - result.append("\n") - - section("fun checkInitialization()") { - line("val _diff = diff") - list(allFields.noSymbolicId().noOptional().noDefaultValue()) { lineBuilder, field -> - lineBuilder.implWsBuilderIsInitializedCode(field) - } - } - - line() - section("override fun connectionIdList(): List<${ConnectionId::class.fqn}>") { - line("return connections") - } - line() - - val collectionFields = allFields.noRefs().filter { it.valueType is ValueType.Collection<*,*> } - if (collectionFields.isNotEmpty()) { - section("override fun afterModification()") { - collectionFields.forEach { field -> - line("val collection_${field.javaName} = getEntityData().${field.javaName}") - if (field.valueType is ValueType.List<*>) { - `if`("collection_${field.javaName} is ${MutableWorkspaceList::class.fqn}<*>") { - line("collection_${field.javaName}.cleanModificationUpdateAction()") - } - } - if (field.valueType is ValueType.Set<*>) { - `if`("collection_${field.javaName} is ${MutableWorkspaceSet::class.fqn}<*>") { - line("collection_${field.javaName}.cleanModificationUpdateAction()") - } - } - } - } - line() - } - - lineComment("Relabeling code, move information from dataSource to this builder") - section("override fun relabel(dataSource: ${WorkspaceEntity::class.fqn}, parents: Set?)") { - line("dataSource as $javaFullName") - list(allFields.noSymbolicId().noRefs()) { lineBuilder, field -> - var type = field.valueType - var qm = "" - if (type is ValueType.Optional<*>) { - qm = "?" - type = type.type - } - when (type) { - is ValueType.List<*> -> lineBuilder.line("if (this.${field.name} != dataSource${qm}.${field.name}) this.${field.name} = dataSource${qm}.${field.name}${qm}.toMutableList()") - is ValueType.Set<*> -> lineBuilder.line("if (this.${field.name} != dataSource${qm}.${field.name}) this.${field.name} = dataSource${qm}.${field.name}${qm}.toMutableSet()") - is ValueType.Map<*, *> -> lineBuilder.line("if (this.${field.name} != dataSource${qm}.${field.name}) this.${field.name} = dataSource${qm}.${field.name}${qm}.toMutableMap()") - else -> lineBuilder.line("if (this.${field.name} != dataSource${qm}.${field.name}) this.${field.name} = dataSource.${field.name}") - } - } - - line("updateChildToParentReferences(parents)") - } - - if (name == LibraryEntity::class.simpleName) { - section("private fun indexLibraryRoots(libraryRoots: List)") { - line("val jarDirectories = mutableSetOf()") - line("val libraryRootList = libraryRoots.map {") - line(" if (it.inclusionOptions != LibraryRoot.InclusionOptions.ROOT_ITSELF) {") - line(" jarDirectories.add(it.url)") - line(" }") - line(" it.url") - line("}.toHashSet()") - line("index(this, \"roots\", libraryRootList)") - line("indexJarDirectories(this, jarDirectories)") - } - } - } - } - - ${allFields.filter { it.name != "symbolicId" }.lines(" ") { implWsBuilderFieldCode }.trimEnd()} - - override fun getEntityClass(): Class<$javaFullName> = $javaFullName::class.java - } - """.trimIndent() -} - diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/implWsEntityClassCode.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/implWsEntityClassCode.kt deleted file mode 100644 index 9ebc3ca278b6..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/implWsEntityClassCode.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.intellij.workspaceModel.codegen.writer.classes - -import com.intellij.workspaceModel.codegen.deft.meta.ObjClass -import com.intellij.workspaceModel.codegen.writer.* -import com.intellij.workspaceModel.codegen.writer.fields.implWsEntityFieldCode -import com.intellij.workspaceModel.codegen.writer.fields.refsConnectionId -import com.intellij.workspaceModel.codegen.writer.fields.refsConnectionIdCode -import com.intellij.workspaceModel.storage.CodeGeneratorVersions -import com.intellij.workspaceModel.storage.GeneratedCodeApiVersion -import com.intellij.workspaceModel.storage.GeneratedCodeImplVersion -import com.intellij.workspaceModel.storage.impl.ConnectionId -import com.intellij.workspaceModel.storage.impl.WorkspaceEntityBase - -fun ObjClass<*>.implWsEntityCode(): String { - return """ -package ${module.name} - -@${GeneratedCodeApiVersion::class.fqn}(${CodeGeneratorVersions.API_VERSION}) -@${GeneratedCodeImplVersion::class.fqn}(${CodeGeneratorVersions.IMPL_VERSION}) -${if (openness.instantiatable) "open" else "abstract"} class $javaImplName(val dataSource: $javaDataName): $javaFullName, ${WorkspaceEntityBase::class.fqn}() { - ${ - """ - companion object { - ${allRefsFields.lines(" ") { refsConnectionIdCode }.trimEnd()} - -${getLinksOfConnectionIds(this)} - }""" - } - - ${allFields.filter { it.name !in listOf("entitySource", "symbolicId") }.lines(" ") { implWsEntityFieldCode }.trimEnd()} - - override val entitySource: EntitySource - get() = dataSource.entitySource - - override fun connectionIdList(): List<${ConnectionId::class.fqn}> { - return connections - } - - ${implWsEntityBuilderCode().indentRestOnly(" ")} -} - """.trimIndent() -} - -private fun getLinksOfConnectionIds(type: ObjClass<*>): String { - return lines(2) { - line("val connections = listOf<${ConnectionId::class.fqn}>(") - type.allRefsFields.forEach { - line(" " + it.refsConnectionId + ",") - } - line(")") - } -} diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/lineBuilderExtensions.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/lineBuilderExtensions.kt deleted file mode 100644 index fba76532d853..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/classes/lineBuilderExtensions.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.intellij.workspaceModel.codegen.writer.classes - -import com.intellij.workspaceModel.codegen.writer.LinesBuilder - -internal fun LinesBuilder.lineWrapped(str: String) { - line() - line(str) - line() -} - -internal fun LinesBuilder.sectionNl(head: String, s: LinesBuilder.() -> Unit) { - section(head, s) - result.append("\n") -} - -internal fun LinesBuilder.conditionalLine(predicate: () -> Boolean, head: String, s: LinesBuilder.() -> Unit) { - if (predicate.invoke()) { - section(head, s) - result.append("\n") - } -} - -internal fun LinesBuilder.listNl(c: Collection, f: T.() -> String = { "$this" }) { - list(c, f) - result.append("\n") -} - -internal fun LinesBuilder.list(c: Collection, func: (LinesBuilder, T) -> Unit) { - c.forEach { - func(this, it) - } -} - -internal fun LinesBuilder.`if`(condition: String, s: LinesBuilder.() -> Unit) { - section("if ($condition)", s) -} - -internal fun LinesBuilder.lineComment(text: String) { - line("// $text") -} - -internal fun LinesBuilder.`for`(condition: String, s: LinesBuilder.() -> Unit) { - section("for ($condition)", s) -} - -internal fun LinesBuilder.`else`(s: LinesBuilder.() -> Unit) { - section("else", s) -} - -internal fun LinesBuilder.ifElse(condition: String, s: LinesBuilder.() -> Unit, `else`: (LinesBuilder.() -> Unit)) { - section("if ($condition)", s) - section("else", `else`) -} - -internal fun LinesBuilder.listBuilder(c: Collection, f: LinesBuilder.(item: T) -> Unit) { - c.forEach { - this.f(it) - } -} - -internal fun LinesBuilder.wrapper(): LinesBuilder { - return LinesBuilder(result, indentLevel+1, indentSize) -} \ No newline at end of file diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/defCode.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/defCode.kt deleted file mode 100644 index f5b07eb13494..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/defCode.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.intellij.workspaceModel.codegen.writer.fields - -import com.intellij.workspaceModel.codegen.writer.javaFullName -import com.intellij.workspaceModel.codegen.deft.meta.ValueType -import com.intellij.workspaceModel.codegen.writer.QualifiedName -import com.intellij.workspaceModel.codegen.writer.toQualifiedName - -val ValueType<*>.javaType: QualifiedName - get() = when (this) { - ValueType.Boolean -> "Boolean".toQualifiedName() - ValueType.Int -> "Int".toQualifiedName() - ValueType.String -> "String".toQualifiedName() - is ValueType.List<*> -> "List".toQualifiedName().appendSuffix("<${elementType.javaType}>") - is ValueType.Set<*> -> "Set".toQualifiedName().appendSuffix("<${elementType.javaType}>") - is ValueType.Map<*, *> -> "Map".toQualifiedName().appendSuffix("<${keyType.javaType}, ${valueType.javaType}>") - is ValueType.ObjRef -> target.javaFullName - is ValueType.Optional<*> -> type.javaType.appendSuffix("?") - is ValueType.JvmClass -> javaClassName.toQualifiedName() - else -> throw UnsupportedOperationException("$this type isn't supported") - } - -val ValueType<*>.javaMutableType: QualifiedName - get() = when (this) { - is ValueType.List<*> -> "MutableList".toQualifiedName().appendSuffix("<${elementType.javaType}>") - is ValueType.Set<*> -> "MutableSet".toQualifiedName().appendSuffix("<${elementType.javaType}>") - is ValueType.Map<*, *> -> "MutableMap".toQualifiedName().appendSuffix("<${keyType.javaType}, ${valueType.javaType}>") - is ValueType.Optional<*> -> type.javaMutableType.appendSuffix("?") - else -> javaType - } - - -fun ValueType<*>.unsupportedTypeError(): Nothing = error("Unsupported field type: $this") \ No newline at end of file diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsConnectionCode.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsConnectionCode.kt deleted file mode 100644 index 51f13fba81fc..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsConnectionCode.kt +++ /dev/null @@ -1,103 +0,0 @@ -package com.intellij.workspaceModel.codegen.writer.fields - -import com.intellij.workspaceModel.storage.EntityStorage -import com.intellij.workspaceModel.storage.impl.* -import com.intellij.workspaceModel.codegen.writer.getRefType -import com.intellij.workspaceModel.codegen.writer.refsFields -import com.intellij.workspaceModel.codegen.writer.* -import com.intellij.workspaceModel.codegen.deft.meta.ObjProperty -import com.intellij.workspaceModel.codegen.deft.meta.ValueType - -val ObjProperty<*, *>.refsConnectionId: String - get() = if (name == "parent") { - val originalField = receiver.refsFields.first { it.valueType.javaType == valueType.javaType } - "${originalField.name.uppercase()}_CONNECTION_ID" - } - else "${name.uppercase()}_CONNECTION_ID" - -val ObjProperty<*, *>.refsConnectionIdCode: String - get() = buildString { - val ref = valueType.getRefType() - val isListType = valueType is ValueType.List<*> || ((valueType as? ValueType.Optional<*>)?.type is ValueType.List<*>) - - append("internal val $refsConnectionId: ${ConnectionId::class.fqn} = ConnectionId.create(") - if (ref.child) { - append("${receiver.name}::class.java, ${ref.javaType}::class.java,") - } - else { - append("${ref.javaType}::class.java, ${receiver.name}::class.java,") - } - val isParentNullable = if (ref.child) { - if (isListType) { - if (ref.target.openness.extendable) { - append(" ConnectionId.ConnectionType.ONE_TO_ABSTRACT_MANY,") - } - else { - append(" ConnectionId.ConnectionType.ONE_TO_MANY,") - } - } - else { - if (ref.target.openness.extendable) { - append(" ConnectionId.ConnectionType.ABSTRACT_ONE_TO_ONE,") - } - else { - append(" ConnectionId.ConnectionType.ONE_TO_ONE,") - } - } - referencedField.valueType is ValueType.Optional<*> - } - else { - val declaredReferenceFromParent = referencedField - var valueType = declaredReferenceFromParent.valueType - if (valueType is ValueType.Optional<*>) { - valueType = valueType.type - } - if (valueType is ValueType.List<*>) { - if (receiver.openness.extendable) { - append(" ConnectionId.ConnectionType.ONE_TO_ABSTRACT_MANY,") - } - else { - append(" ConnectionId.ConnectionType.ONE_TO_MANY,") - } - } - else if (valueType is ValueType.ObjRef<*>) { - if (receiver.openness.extendable) { - append(" ConnectionId.ConnectionType.ABSTRACT_ONE_TO_ONE,") - } - else { - append(" ConnectionId.ConnectionType.ONE_TO_ONE,") - } - } - this@refsConnectionIdCode.valueType is ValueType.Optional<*> - } - append(" $isParentNullable)") - } - -fun ObjProperty<*, *>.refsConnectionMethodCode(genericType: String = ""): String { - val ref = valueType.getRefType() - val connectionName = name.uppercase() + "_CONNECTION_ID" - val getterName = if (ref.child) { - if (ref.target.openness.extendable) - "${fqn1(EntityStorage::extractOneToAbstractOneChild)}$genericType" - else - "${fqn1(EntityStorage::extractOneToOneChild)}$genericType" - } - else { - var valueType = referencedField.valueType - if (valueType is ValueType.Optional<*>) { - valueType = valueType.type - } - when (valueType) { - is ValueType.List<*> -> if (receiver.openness.extendable) - "${fqn1(EntityStorage::extractOneToAbstractManyParent)}$genericType" - else - "${fqn1(EntityStorage::extractOneToManyParent)}$genericType" - is ValueType.ObjRef<*> -> if (receiver.openness.extendable) - "${fqn1(EntityStorage::extractOneToAbstractOneParent)}$genericType" - else - "${fqn1(EntityStorage::extractOneToOneParent)}$genericType" - else -> error("Unsupported reference type") - } - } - return "$getterName($connectionName, this)" -} \ No newline at end of file diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsDataClassFiledCode.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsDataClassFiledCode.kt deleted file mode 100644 index 0bd040bbe101..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsDataClassFiledCode.kt +++ /dev/null @@ -1,79 +0,0 @@ -package com.intellij.workspaceModel.codegen.writer.fields - -import com.intellij.workspaceModel.codegen.deft.meta.ObjProperty -import com.intellij.workspaceModel.codegen.deft.meta.ValueType -import com.intellij.workspaceModel.codegen.writer.isRefType -import com.intellij.workspaceModel.codegen.writer.hasSetter -import com.intellij.workspaceModel.codegen.writer.isOverride -import com.intellij.workspaceModel.codegen.writer.javaName - -val ObjProperty<*, *>.implWsDataFieldCode: String - get() = buildString { - if (hasSetter) { - if (isOverride && name !in listOf("name", "entitySource")) append(implWsBlockingCodeOverride) - else append(implWsDataBlockingCode) - } - else { - val expression = when (val kind = valueKind) { - is ObjProperty.ValueKind.Computable -> kind.expression - is ObjProperty.ValueKind.WithDefault -> kind.value - else -> error(kind) - } - if (expression.startsWith("=")) { - append("var $javaName: ${valueType.javaType} $expression") - } else { - append("var $javaName: ${valueType.javaType} = $expression") - } - } - } -private val ObjProperty<*, *>.implWsDataBlockingCode: String - get() = implWsDataBlockCode(valueType, name) - -private fun ObjProperty<*, *>.implWsDataBlockCode(fieldType: ValueType<*>, name: String, isOptional: Boolean = false): String { - return when (fieldType) { - ValueType.Int -> "var $javaName: ${fieldType.javaType} = 0" - ValueType.Boolean -> "var $javaName: ${fieldType.javaType} = false" - ValueType.String -> "lateinit var $javaName: String" - is ValueType.ObjRef<*> -> error("Reference type at EntityData not supported") - is ValueType.Collection<*, *> -> { - if (fieldType.isRefType()) error("Reference type at EntityData not supported") - if (!isOptional) { - "lateinit var $javaName: ${fieldType.javaMutableType}" - } - else { - "var $javaName: ${fieldType.javaMutableType}? = null" - } - } - is ValueType.Map<*, *> -> { - if (!isOptional) { - "lateinit var $javaName: ${fieldType.javaType}" - } - else { - "var $javaName: ${fieldType.javaType}? = null" - } - } - is ValueType.Optional<*> -> when (fieldType.type) { - ValueType.Int, ValueType.Boolean, ValueType.String -> "var $javaName: ${fieldType.javaType} = null" - else -> implWsDataBlockCode(fieldType.type, name, true) - } - is ValueType.JvmClass -> { - if (!isOptional) { - "lateinit var $javaName: ${fieldType.javaType}" - } - else { - "var $javaName: ${fieldType.javaType}? = null" - } - } - else -> error("Unsupported field type: $this") - } -} - -val ObjProperty<*, *>.implWsDataFieldInitializedCode: String - get() = when (valueType) { - is ValueType.Int, is ValueType.Boolean -> "" - is ValueType.String, is ValueType.JvmClass, is ValueType.Collection<*, *>, is ValueType.Map<*, *> -> { - val capitalizedFieldName = javaName.replaceFirstChar { it.titlecaseChar() } - "fun is${capitalizedFieldName}Initialized(): Boolean = ::${javaName}.isInitialized" - } - else -> error("Unsupported field type: $this") - } diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsEntityBuilderFieldCode.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsEntityBuilderFieldCode.kt deleted file mode 100644 index 4751c7157041..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsEntityBuilderFieldCode.kt +++ /dev/null @@ -1,354 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.writer.fields - -import com.intellij.workspaceModel.codegen.writer.classes.* -import com.intellij.workspaceModel.codegen.deft.meta.ObjProperty -import com.intellij.workspaceModel.codegen.deft.meta.ValueType -import com.intellij.workspaceModel.codegen.writer.getRefType -import com.intellij.workspaceModel.codegen.writer.isRefType -import com.intellij.workspaceModel.codegen.writer.* -import com.intellij.workspaceModel.codegen.writer.javaName -import com.intellij.workspaceModel.storage.EntityStorage -import com.intellij.workspaceModel.storage.bridgeEntities.LibraryRoot -import com.intellij.workspaceModel.storage.impl.* -import com.intellij.workspaceModel.storage.impl.containers.MutableWorkspaceList -import com.intellij.workspaceModel.storage.impl.containers.MutableWorkspaceSet -import com.intellij.workspaceModel.storage.url.VirtualFileUrl - -val ObjProperty<*, *>.implWsBuilderFieldCode: String - get() = valueType.implWsBuilderBlockingCode(this) - -private fun ValueType<*>.implWsBuilderBlockingCode(field: ObjProperty<*, *>, optionalSuffix: String = ""): String = when (this) { - ValueType.Boolean, ValueType.Int -> """ - override var ${field.javaName}: ${field.valueType.javaMutableType}$optionalSuffix - get() = getEntityData().${field.javaName} - set(value) { - checkModificationAllowed() - getEntityData(true).${field.javaName} = value - changedProperty.add("${field.javaName}") - } - - """.trimIndent() - ValueType.String -> """ - override var ${field.javaName}: ${field.valueType.javaMutableType} - get() = getEntityData().${field.javaName} - set(value) { - checkModificationAllowed() - getEntityData(true).${field.javaName} = value - changedProperty.add("${field.javaName}") - } - - """.trimIndent() - is ValueType.ObjRef -> { - val connectionName = field.refsConnectionId - val getterSetterNames = field.refNames() - - // Opposite field may be either one-to-one or one-to-many - - val notNullAssertion = if (optionalSuffix.isBlank()) "!!" else "" - lines { - sectionNoBrackets("override var ${field.javaName}: $javaType$optionalSuffix") { - section("get()") { - line("val _diff = diff") - line("return if (_diff != null) {") - line(" _diff.${getterSetterNames.getter}($connectionName, this) ?: this.entityLinks[${EntityLink::class.fqn}(${field.valueType.getRefType().child}, ${field.refsConnectionId})]$notNullAssertion as$optionalSuffix $javaType") - line("} else {") - line(" this.entityLinks[${EntityLink::class.fqn}(${field.valueType.getRefType().child}, ${field.refsConnectionId})]$notNullAssertion as$optionalSuffix $javaType") - line("}") - } - section("set(value)") { - line("checkModificationAllowed()") - line("val _diff = diff") - `if`("_diff != null && value is ${ModifiableWorkspaceEntityBase::class.fqn}<*, *> && value.diff == null") { - backrefSetup(field) - line("_diff.addEntity(value)") - } - section("if (_diff != null && (value !is ${ModifiableWorkspaceEntityBase::class.fqn}<*, *> || value.diff != null))") { - line("_diff.${getterSetterNames.setter}($connectionName, this, value)") - } - section("else") { - backrefSetup(field) - line() - line("this.entityLinks[${EntityLink::class.fqn}(${field.valueType.getRefType().child}, ${field.refsConnectionId})] = value") - } - line("changedProperty.add(\"${field.javaName}\")") - } - } - } - } - is ValueType.List<*> -> { - val elementType = this.elementType - if (this.isRefType()) { - val connectionName = field.refsConnectionId - val notNullAssertion = if (optionalSuffix.isBlank()) "!!" else error("It's prohibited to have nullable reference list") - if ((elementType as ValueType.ObjRef<*>).target.openness.extendable) { - lines(level = 1) { - sectionNoBrackets("override var ${field.javaName}: $javaType$optionalSuffix") { - section("get()") { - line("val _diff = diff") - line("return if (_diff != null) {") - line(" _diff.${fqn2(EntityStorage::extractOneToAbstractManyChildren)}<${elementType.javaType}>($connectionName, this)$notNullAssertion.toList() + (this.entityLinks[${EntityLink::class.fqn}(${field.valueType.getRefType().child}, ${field.refsConnectionId})] as? $javaType ?: emptyList())") - line("} else {") - line(" this.entityLinks[${EntityLink::class.fqn}(${field.valueType.getRefType().child}, ${field.refsConnectionId})] as $javaType ${if (notNullAssertion.isNotBlank()) "?: emptyList()" else ""}") - line("}") - } - section("set(value)") { - lineComment("Set list of ref types for abstract entities") - line("checkModificationAllowed()") - line("val _diff = diff") - `if`("_diff != null") { - `for`("item_value in value") { - `if`("item_value is ${ModifiableWorkspaceEntityBase::class.fqn}<*, *> && (item_value as? ${ - ModifiableWorkspaceEntityBase::class.fqn - }<*, *>)?.diff == null") { - lineComment("Backref setup before adding to store an abstract entity") - backrefSetup(field, "item_value") - line("_diff.addEntity(item_value)") - } - } - line("_diff.${fqn5(EntityStorage::updateOneToAbstractManyChildrenOfParent)}($connectionName, this, value.asSequence())") - } - `else` { - backrefListSetup(field) - line() - line("this.entityLinks[${EntityLink::class.fqn}(${field.valueType.getRefType().child}, ${field.refsConnectionId})] = value") - } - line("changedProperty.add(\"${field.javaName}\")") - } - } - } - } - else { - lines { - lineComment("List of non-abstract referenced types") - line("var _${field.javaName}: $javaType? = emptyList()") - sectionNoBrackets("override var ${field.javaName}: $javaType$optionalSuffix") { - section("get()") { - lineComment("Getter of the list of non-abstract referenced types") - line("val _diff = diff") - line("return if (_diff != null) {") - line(" _diff.${fqn2(EntityStorage::extractOneToManyChildren)}<${elementType.javaType}>($connectionName, this)$notNullAssertion.toList() + (this.entityLinks[${EntityLink::class.fqn}(${field.valueType.getRefType().child}, ${field.refsConnectionId})] as? $javaType ?: emptyList())") - line("} else {") - line( - " this.entityLinks[${EntityLink::class.fqn}(${field.valueType.getRefType().child}, ${field.refsConnectionId})] as? $javaType ${if (notNullAssertion.isNotBlank()) "?: emptyList()" else ""}") - line("}") - } - section("set(value)") { - lineComment("Setter of the list of non-abstract referenced types") - line("checkModificationAllowed()") - line("val _diff = diff") - `if`("_diff != null") { - `for`("item_value in value") { - `if`("item_value is ${ModifiableWorkspaceEntityBase::class.fqn}<*, *> && (item_value as? ${ModifiableWorkspaceEntityBase::class.fqn}<*, *>)?.diff == null") { - lineComment("Backref setup before adding to store") - backrefSetup(field, "item_value") - line() - line("_diff.addEntity(item_value)") - } - } - line("_diff.${fqn4(EntityStorage::updateOneToManyChildrenOfParent)}($connectionName, this, value)") - } - `else` { - backrefListSetup(field) - line() - line("this.entityLinks[${EntityLink::class.fqn}(${field.valueType.getRefType().child}, ${field.refsConnectionId})] = value") - } - line("changedProperty.add(\"${field.javaName}\")") - } - } - } - } - } - else { - """ - private val ${field.javaName}Updater: (value: List<${elementType.javaType}>) -> Unit = { value -> - ${elementType.addVirtualFileIndex(field)} - changedProperty.add("${field.javaName}") - } - override var ${field.javaName}: MutableList<${elementType.javaType}> - get() { - val collection_${field.javaName} = getEntityData().${field.javaName} - if (collection_${field.javaName} !is ${MutableWorkspaceList::class.fqn}) return collection_${field.javaName} - if (diff == null || modifiable.get()) { - collection_${field.javaName}.setModificationUpdateAction(${field.javaName}Updater) - } else { - collection_${field.javaName}.cleanModificationUpdateAction() - } - return collection_${field.javaName} - } - set(value) { - checkModificationAllowed() - getEntityData(true).${field.javaName} = value - ${field.javaName}Updater.invoke(value) - } - - """.trimIndent() - } - } - is ValueType.Set<*> -> { - val elementType = this.elementType - if (this.isRefType()) { - error("Set of references is not supported") - } else { - """ - private val ${field.javaName}Updater: (value: Set<${elementType.javaType}>) -> Unit = { value -> - ${elementType.addVirtualFileIndex(field)} - changedProperty.add("${field.javaName}") - } - override var ${field.javaName}: MutableSet<${elementType.javaType}> - get() { - val collection_${field.javaName} = getEntityData().${field.javaName} - if (collection_${field.javaName} !is ${MutableWorkspaceSet::class.fqn}) return collection_${field.javaName} - if (diff == null || modifiable.get()) { - collection_${field.javaName}.setModificationUpdateAction(${field.javaName}Updater) - } else { - collection_${field.javaName}.cleanModificationUpdateAction() - } - return collection_${field.javaName} - } - set(value) { - checkModificationAllowed() - getEntityData(true).${field.javaName} = value - ${field.javaName}Updater.invoke(value) - } - - """.trimIndent() - } - } - is ValueType.Map<*, *> -> """ - override var ${field.javaName}: $javaType - get() = getEntityData().${field.javaName} - set(value) { - checkModificationAllowed() - getEntityData(true).${field.javaName} = value - changedProperty.add("${field.javaName}") - } - - """.trimIndent() - is ValueType.Optional<*> -> type.implWsBuilderBlockingCode(field, "?") - is ValueType.Structure<*> -> "//TODO: ${field.javaName}" - is ValueType.JvmClass -> """ - override var ${field.javaName}: ${javaType.appendSuffix(optionalSuffix)} - get() = getEntityData().${field.javaName} - set(value) { - checkModificationAllowed() - getEntityData(true).${field.javaName} = value - changedProperty.add("${field.javaName}") - ${ - if (javaType.decoded == VirtualFileUrl::class.java.name) - """val _diff = diff - | if (_diff != null) index(this, "${field.javaName}", value) - """.trimMargin() - else "" - } - } - - """.trimIndent() - else -> unsupportedTypeError() -} - -private fun LinesBuilder.backrefSetup( - field: ObjProperty<*, *>, - varName: String = "value", -) { - val referencedField = field.referencedField - val type = referencedField.valueType - val isChild = type.getRefType().child - when (type) { - is ValueType.List<*> -> { - lineComment("Setting backref of the list") - `if`("$varName is ${ModifiableWorkspaceEntityBase::class.fqn}<*, *>") { - line("val data = ($varName.entityLinks[${EntityLink::class.fqn}($isChild, ${field.refsConnectionId})] as? List ?: emptyList()) + this") - line("$varName.entityLinks[${EntityLink::class.fqn}($isChild, ${field.refsConnectionId})] = data") - } - line("// else you're attaching a new entity to an existing entity that is not modifiable") - } - is ValueType.Set<*> -> { - lineComment("Setting backref of the set") - `if`("$varName is ${ModifiableWorkspaceEntityBase::class.fqn}<*, *>") { - line("val data = ($varName.entityLinks[${EntityLink::class.fqn}($isChild, ${field.refsConnectionId})] as? Set ?: emptySet()) + this") - line("$varName.entityLinks[${EntityLink::class.fqn}($isChild, ${field.refsConnectionId})] = data") - } - line("// else you're attaching a new entity to an existing entity that is not modifiable") - } - is ValueType.Optional<*> -> { - `if`("$varName is ${ModifiableWorkspaceEntityBase::class.fqn}<*, *>") { - line("$varName.entityLinks[${EntityLink::class.fqn}($isChild, ${field.refsConnectionId})] = this") - } - line("// else you're attaching a new entity to an existing entity that is not modifiable") - } - is ValueType.ObjRef<*> -> { - `if`("$varName is ${ModifiableWorkspaceEntityBase::class.fqn}<*, *>") { - line("$varName.entityLinks[${EntityLink::class.fqn}($isChild, ${field.refsConnectionId})] = this") - } - line("// else you're attaching a new entity to an existing entity that is not modifiable") - } - else -> error("Unexpected") - } -} - -private fun LinesBuilder.backrefListSetup( - field: ObjProperty<*, *>, - varName: String = "value", -) { - val itemName = "item_$varName" - `for`("$itemName in $varName") { - backrefSetup(field, itemName) - } -} - -fun LinesBuilder.implWsBuilderIsInitializedCode(field: ObjProperty<*, *>) { - val javaName = field.javaName - when (field.valueType) { - is ValueType.List<*> -> if (field.valueType.isRefType()) { - lineComment("Check initialization for list with ref type") - ifElse("_diff != null", { - `if`("_diff.${fqn2(EntityStorage::extractOneToManyChildren)}<${WorkspaceEntityBase::class.fqn}>(${field.refsConnectionId}, this) == null") { - line("error(\"Field ${field.receiver.name}#$javaName should be initialized\")") - } - }) { - isInitializedBaseCode(field, "this.entityLinks[${EntityLink::class.fqn}(${field.valueType.getRefType().child}, ${field.refsConnectionId})] == null") - } - } - else { - val capitalizedFieldName = javaName.replaceFirstChar { it.titlecaseChar() } - isInitializedBaseCode(field, "!getEntityData().is${capitalizedFieldName}Initialized()") - } - is ValueType.ObjRef<*> -> { - ifElse("_diff != null", { - `if`("_diff.${field.refsConnectionMethodCode("<${WorkspaceEntityBase::class.fqn}>")} == null") { - line("error(\"Field ${field.receiver.name}#$javaName should be initialized\")") - } - }) { - isInitializedBaseCode(field, "this.entityLinks[${EntityLink::class.fqn}(${field.valueType.getRefType().child}, ${field.refsConnectionId})] == null") - }.toString() - } - is ValueType.Int, is ValueType.Boolean -> return - else -> { - val capitalizedFieldName = javaName.replaceFirstChar { it.titlecaseChar() } - isInitializedBaseCode(field, "!getEntityData().is${capitalizedFieldName}Initialized()") - } - } -} - -private fun LinesBuilder.isInitializedBaseCode(field: ObjProperty<*, *>, expression: String) { - section("if ($expression)") { - line("error(\"Field ${field.receiver.name}#${field.javaName} should be initialized\")") - } -} - -private fun ValueType<*>.addVirtualFileIndex(field: ObjProperty<*, *>): String { - return when { - this is ValueType.Blob && javaClassName == VirtualFileUrl::class.java.name -> - """val _diff = diff -| if (_diff != null) index(this, "${field.javaName}", value) - """.trimMargin() - this is ValueType.JvmClass && javaClassName == LibraryRoot::class.java.name -> """ - val _diff = diff - if (_diff != null) { - indexLibraryRoots(value) - } - """ - else -> "" - } -} \ No newline at end of file diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsEntityBuilderRefsUpdateMethods.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsEntityBuilderRefsUpdateMethods.kt deleted file mode 100644 index cbe12205949c..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsEntityBuilderRefsUpdateMethods.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.intellij.workspaceModel.codegen.writer.fields - -import com.intellij.workspaceModel.storage.EntityStorage -import com.intellij.workspaceModel.storage.impl.* -import com.intellij.workspaceModel.codegen.writer.isRefType -import com.intellij.workspaceModel.codegen.deft.meta.ObjProperty -import com.intellij.workspaceModel.codegen.deft.meta.ValueType -import com.intellij.workspaceModel.codegen.writer.* - -data class RefMethods(val getter: QualifiedName, val setter: QualifiedName) - -infix fun QualifiedName.getterWithSetter(setter: QualifiedName): RefMethods = RefMethods(this, setter) - -fun ObjProperty<*, *>.refNames(): RefMethods { - if (!valueType.isRefType()) error("Call this on ref field") - return when (valueType) { - is ValueType.ObjRef -> constructCode(valueType) - is ValueType.Optional -> constructCode((this.valueType as ValueType.Optional<*>).type) - is ValueType.List<*> -> fqn2(EntityStorage::extractOneToManyChildren) getterWithSetter fqn4(EntityStorage::updateOneToManyChildrenOfParent) - else -> error("Call this on ref field") - } -} - -private fun ObjProperty<*, *>.constructCode(type: ValueType<*>): RefMethods { - type as ValueType.ObjRef<*> - - return if (type.child) { - if (type.target.openness.extendable) { - fqn1(EntityStorage::extractOneToAbstractOneChild) getterWithSetter fqn3(EntityStorage::updateOneToAbstractOneChildOfParent) - } - else { - fqn1(EntityStorage::extractOneToOneChild) getterWithSetter fqn3(EntityStorage::updateOneToOneChildOfParent) - } - } - else { - var valueType = referencedField.valueType - if (valueType is ValueType.Optional<*>) { - valueType = valueType.type - } - when (valueType) { - is ValueType.List<*> -> { - if (receiver.openness.extendable) { - fqn1(EntityStorage::extractOneToAbstractManyParent) getterWithSetter fqn3(EntityStorage::updateOneToAbstractManyParentOfChild) - } - else { - fqn1(EntityStorage::extractOneToManyParent) getterWithSetter fqn3(EntityStorage::updateOneToManyParentOfChild) - } - } - is ValueType.ObjRef<*> -> { - if (receiver.openness.extendable) { - fqn1(EntityStorage::extractOneToAbstractOneParent) getterWithSetter fqn3(EntityStorage::updateOneToAbstractOneParentOfChild) - } - else { - fqn1(EntityStorage::extractOneToOneParent) getterWithSetter fqn3(EntityStorage::updateOneToOneParentOfChild) - } - } - else -> error("Unsupported reference type") - } - } -} diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsEntityFiledCode.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsEntityFiledCode.kt deleted file mode 100644 index 0defa3ad98f7..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/implWsEntityFiledCode.kt +++ /dev/null @@ -1,159 +0,0 @@ -package com.intellij.workspaceModel.codegen.writer.fields - -import com.intellij.workspaceModel.codegen.deft.meta.ObjProperty -import com.intellij.workspaceModel.codegen.deft.meta.ValueType -import com.intellij.workspaceModel.codegen.writer.getRefType -import com.intellij.workspaceModel.codegen.writer.isRefType -import com.intellij.workspaceModel.codegen.writer.refsFields -import com.intellij.workspaceModel.codegen.writer.fqn1 -import com.intellij.workspaceModel.codegen.writer.fqn2 -import com.intellij.workspaceModel.codegen.writer.toQualifiedName -import com.intellij.workspaceModel.codegen.writer.hasSetter -import com.intellij.workspaceModel.codegen.writer.isOverride -import com.intellij.workspaceModel.codegen.writer.javaName -import com.intellij.workspaceModel.storage.EntityStorage -import com.intellij.workspaceModel.storage.impl.* - -val ObjProperty<*, *>.implWsEntityFieldCode: String - get() = buildString { - if (hasSetter) { - if (isOverride && name !in listOf("name", "entitySource")) { - append(implWsBlockingCodeOverride) - } - else append(implWsBlockingCode) - } else { - append("override var $javaName: ${valueType.javaType} = dataSource.$javaName\n") - } - } - -private val ObjProperty<*, *>.implWsBlockingCode: String - get() = implWsBlockCode(valueType, name, "") - -internal fun ObjProperty<*, *>.implWsBlockCode(fieldType: ValueType<*>, name: String, optionalSuffix: String = ""): String { - return when (fieldType) { - ValueType.Int -> "override val $name: ${fieldType.javaType} get() = dataSource.$name" - ValueType.Boolean -> "override val $name: ${fieldType.javaType} get() = dataSource.$name" - ValueType.String -> """ - override val $name: ${fieldType.javaType}${optionalSuffix} - get() = dataSource.$name - - """.trimIndent() - is ValueType.ObjRef -> { - val notNullAssertion = if (optionalSuffix.isBlank()) "!!" else "" - """ - override val $name: ${fieldType.javaType}$optionalSuffix - get() = snapshot.${refsConnectionMethodCode()}$notNullAssertion - - """.trimIndent() - } - is ValueType.List<*> -> { - if (fieldType.isRefType()) { - val connectionName = name.uppercase() + "_CONNECTION_ID" - val notNullAssertion = if (optionalSuffix.isBlank()) "!!" else "" - if ((fieldType.elementType as ValueType.ObjRef<*>).target.openness.extendable) { - """ - override val $name: ${fieldType.javaType}$optionalSuffix - get() = snapshot.${fqn2(EntityStorage::extractOneToAbstractManyChildren)}<${fieldType.elementType.javaType}>($connectionName, this)$notNullAssertion.toList() - - """.trimIndent() - } - else { - """ - override val $name: ${fieldType.javaType}$optionalSuffix - get() = snapshot.${fqn2(EntityStorage::extractOneToManyChildren)}<${fieldType.elementType.javaType}>($connectionName, this)$notNullAssertion.toList() - - """.trimIndent() - } - } - else { - """ - override val $name: ${fieldType.javaType}$optionalSuffix - get() = dataSource.$name - - """.trimIndent() - } - } - is ValueType.Set<*> -> { - if (fieldType.isRefType()) { - error("Set of references is not supported") - } - else { - """ - override val $javaName: ${fieldType.javaType}$optionalSuffix - get() = dataSource.$name - - """.trimIndent() - } - } - is ValueType.Map<*, *> -> """ - override val $name: ${fieldType.javaType}$optionalSuffix - get() = dataSource.$name - """.trimIndent() - is ValueType.Optional<*> -> when (fieldType.type) { - ValueType.Int, ValueType.Boolean -> "override val $name: ${fieldType.javaType} get() = dataSource.$name" - else -> implWsBlockCode(fieldType.type, name, "?") - } - is ValueType.JvmClass -> """ - override val $name: ${fieldType.javaClassName.toQualifiedName()}$optionalSuffix - get() = dataSource.$name - - """.trimIndent() - else -> error("Unsupported field type: $this") - } -} - -internal val ObjProperty<*, *>.implWsBlockingCodeOverride: String - get() { - val originalField = receiver.refsFields.first { it.valueType.javaType == valueType.javaType } - val connectionName = originalField.name.uppercase() + "_CONNECTION_ID" - var valueType = referencedField.valueType - val notNullAssertion = if (valueType is ValueType.Optional<*>) "" else "!!" - if (valueType is ValueType.Optional<*>) { - valueType = valueType.type - } - val getterName = when (valueType) { - is ValueType.List<*> -> if (receiver.openness.extendable) - fqn1(EntityStorage::extractOneToAbstractManyParent) - else - fqn1(EntityStorage::extractOneToManyParent) - is ValueType.ObjRef<*> -> if (receiver.openness.extendable) - fqn1(EntityStorage::extractOneToAbstractOneParent) - else - fqn1(EntityStorage::extractOneToOneParent) - else -> error("Unsupported reference type") - } - return """ - override val $name: ${this.valueType.javaType} - get() = snapshot.$getterName($connectionName, this)$notNullAssertion - - """.trimIndent() - } - -internal val ObjProperty<*, *>.referencedField: ObjProperty<*, *> - get() { - val ref = valueType.getRefType() - val declaredReferenceFromChild = - ref.target.refsFields.filter { it.valueType.getRefType().target == receiver && it != this } + - setOf(ref.target.module, - receiver.module).flatMap { it.extensions }.filter { it.valueType.getRefType().target == receiver && it.receiver == ref.target && it != this } - if (declaredReferenceFromChild.isEmpty()) { - error("Reference should be declared at both entities. It exist at ${receiver.name}#$name but absent at ${ref.target.name}") - } - if (declaredReferenceFromChild.size > 1) { - error(""" - |More then one reference to ${receiver.name} declared at ${declaredReferenceFromChild[0].receiver.name}#${declaredReferenceFromChild[0].name}, - |${declaredReferenceFromChild[1].receiver.name}#${declaredReferenceFromChild[1].name} - |""".trimMargin()) - } - val referencedField = declaredReferenceFromChild[0] - if (this.valueType.getRefType().child == referencedField.valueType.getRefType().child) { - val (childStr, fix) = if (this.valueType.getRefType().child) { - "child" to "Have you @Child annotation on both sides?" - } - else { - "parent" to "Did you forget to add @Child annotation?" - } - error("Both fields ${receiver.name}#$name and ${ref.target.name}#${referencedField.name} are marked as $childStr. $fix") - } - return referencedField - } \ No newline at end of file diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/wsExtFields.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/wsExtFields.kt deleted file mode 100644 index 0922d0f98fb8..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/fields/wsExtFields.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.intellij.workspaceModel.codegen.writer.fields - -import com.intellij.workspaceModel.codegen.deft.meta.ExtProperty -import com.intellij.workspaceModel.codegen.writer.getRefType -import com.intellij.workspaceModel.codegen.writer.javaBuilderName -import com.intellij.workspaceModel.codegen.writer.fqn -import com.intellij.workspaceModel.codegen.writer.lines -import org.jetbrains.deft.annotations.Child - -val ExtProperty<*, *>.wsCode: String - get() = lines { - val isChild = valueType.getRefType().child - val annotation = if (isChild) "@${Child::class.fqn} " else "" - sectionNoBrackets("var ${receiver.javaBuilderName}.$name: $annotation${valueType.javaType}") { - line("by WorkspaceEntity.extension()") - } - } diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/objTypeExtensions.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/objTypeExtensions.kt deleted file mode 100644 index 7c0fd38be34a..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/objTypeExtensions.kt +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.writer - -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.storage.WorkspaceEntity -import com.intellij.workspaceModel.storage.WorkspaceEntityWithSymbolicId - -val ObjClass<*>.isStandardInterface: Boolean - get() = name in setOf(WorkspaceEntity::class.java.simpleName, WorkspaceEntityWithSymbolicId::class.java.simpleName) - -val ObjClass<*>.allSuperClasses: List> - get() = superTypes.filterIsInstance>().flatMapTo(LinkedHashSet()) { it.allSuperClasses + listOf(it) }.toList() - -val ObjClass<*>.allFields: List> - get() { - val fieldsByName = LinkedHashMap>() - collectFields(this, fieldsByName) - return fieldsByName.values.toList() - } - -private fun collectFields(objClass: ObjClass<*>, fieldsByName: MutableMap>) { - for (superType in objClass.superTypes) { - if (superType is ObjClass<*>) { - collectFields(superType, fieldsByName) - } - } - for (field in objClass.fields) { - if (field.valueKind !is ObjProperty.ValueKind.Computable) { - fieldsByName.remove(field.name) - fieldsByName[field.name] = field - } - } -} - -val ObjProperty<*, *>.hasSetter: Boolean - get() = open || valueKind == ObjProperty.ValueKind.Plain - -val ObjProperty<*, *>.javaName: String - get() = name - -val ObjProperty<*, *>.isOverride: Boolean - get() = receiver.allSuperClasses.any { name in it.fieldsByName } \ No newline at end of file diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/refsUtilExtensions.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/refsUtilExtensions.kt deleted file mode 100644 index b34136ce76d3..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/refsUtilExtensions.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.intellij.workspaceModel.codegen.writer - -import com.intellij.workspaceModel.codegen.deft.meta.ObjClass -import com.intellij.workspaceModel.codegen.deft.meta.OwnProperty -import com.intellij.workspaceModel.codegen.deft.meta.ValueType -import com.intellij.workspaceModel.storage.url.VirtualFileUrl - -val ObjClass<*>.refsFields: List> - get() = fields.filter { !it.isOverride && it.valueType.isRefType() } - -val ObjClass<*>.allRefsFields: List> - get() = allFields.filter { it.valueType.isRefType() } - -val ObjClass<*>.vfuFields: List> - get() = fields.filter { !it.isOverride && it.valueType.isVfuType() } - -fun ValueType<*>.getRefType(): ValueType.ObjRef<*> = when (this) { - is ValueType.ObjRef<*> -> this - is ValueType.Optional<*> -> type.getRefType() - is ValueType.Collection<*, *> -> elementType.getRefType() - else -> error("Unsupported type of requester, should be called only if `isRefType` is true") -} - -fun ValueType<*>.isRefType(): Boolean = when (this) { - is ValueType.ObjRef<*> -> true - is ValueType.Optional<*> -> type.isRefType() - is ValueType.Collection<*, *> -> elementType.isRefType() - else -> false -} - -fun ValueType<*>.isVfuType(): Boolean = when (this) { - is ValueType.Blob -> javaClassName == VirtualFileUrl::class.java.name - is ValueType.Optional<*> -> type.isVfuType() - is ValueType.Collection<*, *> -> elementType.isVfuType() - else -> false -} - -fun sups(vararg extensions: String?): String = extensions.filterNotNull().joinToString(separator = ", ") diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/utils.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/utils.kt deleted file mode 100644 index 8a69d59b1785..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/utils.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.intellij.workspaceModel.codegen.writer - -fun Collection.lines(f: T.() -> String = { "$this" }): String = - mapNotNull { f(it).takeIf { item -> item.isNotBlank() } }.joinToString("\n") - -fun Collection.lines(indent: String, f: T.() -> String = { "$this" }): String = - mapNotNull { f(it).takeIf { item -> item.isNotBlank() } }.indent(indent) - -fun Collection.indent(indent: String): String = when { - size > 1 -> first().indentRestOnly(indent) + "\n" + - drop(1).joinToString("\n") { it.indentAll(indent) } - size == 1 -> single().indentRestOnly(indent) - else -> joinToString("\n") { it.indentAll(indent) } -} - -fun String.indentRestOnly(indent: String): String { - val lines = lines() - return when { - lines.size > 1 -> lines.first() + "\n" + lines.drop(1).joinToString("\n") { "$indent$it" } - lines.size == 1 -> lines.first() - else -> "" - } -} - -private fun String.indentAll(indent: String): String { - return lines().joinToString("\n") { "$indent$it" } -} - diff --git a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/wsEntityGenCode.kt b/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/wsEntityGenCode.kt deleted file mode 100644 index f46832fc3046..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/kotlin/com/intellij/workspaceModel/codegen/writer/wsEntityGenCode.kt +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.workspaceModel.codegen.writer - -import com.intellij.workspaceModel.codegen.writer.classes.implWsDataClassCode -import com.intellij.workspaceModel.codegen.writer.classes.implWsEntityCode -import com.intellij.workspaceModel.codegen.deft.meta.ObjClass - -/** - * TODO: - * - Abstract Class do - * - This about mutable lists (custom implementation?) - * - This about mutable lists for properties - * - This about mutable lists for references - * - Facet: 2 parents, how to implement? - * Поправить генерилку, чтоб все было чисто без лишних строк (почистил в applyToBuilder) - * factory: ObjType - * hasNewValue -- Будем обсуждать с Сережей после НГ - * setValue -- Будем обсуждать с Сережей после НГ - * builder(): ObjBuilder<*> - * Привести билдер в порядок: поля идут первыми, потом applyBuilder, потом все утильные методы.. - * - * Done: - * createReference проверить нужны ли они в ентити (не нужны, грохнул) - * hasEqualProperties (забахали на всяк случай) // Там всего одно использование, посовещавшись мы решили хрохнуть его - * Поправить импорты - * Метод проверки, что все поля заиничены - * - * --------------------------- - * Перенести тесты идеи к нам или наоборрот <-- - */ - -fun ObjClass<*>.implWsCode(): String? { - if (!openness.instantiatable) return null - return """ -${implWsEntityCode()} - -${implWsDataClassCode()} - """.trimIndent() -} \ No newline at end of file diff --git a/platform/workspaceModel/codegen-impl-one/src/main/resources/services/com.intellij.workspaceModel.codegen.engine.CodeGenerator b/platform/workspaceModel/codegen-impl-one/src/main/resources/services/com.intellij.workspaceModel.codegen.engine.CodeGenerator deleted file mode 100644 index 807eb6643890..000000000000 --- a/platform/workspaceModel/codegen-impl-one/src/main/resources/services/com.intellij.workspaceModel.codegen.engine.CodeGenerator +++ /dev/null @@ -1 +0,0 @@ -com.intellij.workspaceModel.codegen.engine.impl.CodeGeneratorImpl \ No newline at end of file