diff --git a/examples/README.md b/examples/README.md index 55f75e587dc..85b7003168c 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,10 +1,10 @@ # Samples -| Sample | Description | Platforms | -| ------------------------------------ | -------------------------------------------------------------------------------------------- | --------------------- | -| [Imageviewer](imageviewer) | Image Viewer application | Android, iOS, Desktop | -| [Codeviewer](codeviewer) | File browser and code viewer application | Android, iOS, Desktop | -| [Chat](chat) | A simple chat | Android, iOS, Desktop | -| [Graphics2D](graphics-2d) | 2D Games and graphics examples | Android, iOS, Desktop | -| [Nav Cupcake](nav_cupcake) | Multiscreen app to demonstrate the use of Compose Navigation | Android, iOS, Desktop | -| [Issues tracker](issues) | GitHub issue tracker with an adaptive UI and ktor-client | Android, Desktop | -| [HTML based samples](html/README.md) | Examples written with Compose HTML Library | +| Sample | Description | Platforms | +| -------------------------------------- |:---------------------------------------------------------| -------------------------- | +| [Imageviewer](imageviewer) | Image Viewer | Android, iOS, Desktop, Web | +| [Codeviewer](codeviewer) | File browser and code viewer | Android, iOS, Desktop, Web | +| [Chat](chat) | A simple chat | Android, iOS, Desktop, Web | +| [Graphics2D](graphics-2d) | 2D Games and graphics examples | Android, iOS, Desktop, Web | +| [Nav Cupcake](nav_cupcake) | Multiscreen app using Compose Navigation 2 | Android, iOS, Desktop, Web | +| [Issues tracker](issues) | GitHub issue tracker with an adaptive UI and ktor-client | Android, Desktop | +| [Compose HTML samples](html/README.md) | Examples written with Compose HTML Library | Web | diff --git a/examples/buildWithKotlinToolchain.sh b/examples/buildWithKotlinToolchain.sh new file mode 100755 index 00000000000..d1b34eae5b3 --- /dev/null +++ b/examples/buildWithKotlinToolchain.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +# Script to build an example with the Kotlin Toolchain, optionally with the given Compose and Kotlin versions. +# The Kotlin Toolchain can't override versions from the command line, so in that case the example is copied +# to a temporary directory, and every module there applies a template with the versions and the dev maven repo. + +set -euo pipefail + +if [ "$#" -lt 2 ] || [ "$#" -gt 4 ]; then + echo "Specify the example, the platform and optionally Compose and Kotlin versions. For example: ./buildWithKotlinToolchain.sh codeviewer jvm 1.13.0-alpha03 2.3.20" + exit 1 +fi + +example="$1" +platform="$2" +compose_version="${3:-}" +kotlin_version="${4:-}" +build_dir="$example" + +if [ -n "$compose_version" ]; then + temp_dir="$(mktemp -d)" + # Keep the copy if the build fails, so that its logs can be inspected + trap 'if [ "$?" -eq 0 ]; then rm -rf "$temp_dir"; else echo "Failed $example, its copy is kept in $temp_dir"; fi' EXIT + + tar -C "$example" --exclude=./build -cf - . | tar -C "$temp_dir" -xf - + echo "Building a copy of $example in $temp_dir with Compose $compose_version${kotlin_version:+ and Kotlin $kotlin_version}" + + template="validation-versions.module-template.yaml" + { + echo "repositories:" + echo " - https://packages.jetbrains.team/maven/p/cmp/dev" + echo + echo "settings:" + echo " compose:" + echo " version: $compose_version" + if [ -n "$kotlin_version" ]; then + echo " kotlin:" + echo " version: $kotlin_version" + fi + } > "$temp_dir/$template" + + find "$temp_dir" -name module.yaml | while read -r module; do + { printf 'apply:\n - //%s\n\n' "$template"; cat "$module"; } > "$module.tmp" + mv "$module.tmp" "$module" + done + + if [ -f "$temp_dir/libs.versions.toml" ]; then + sed -E "s/^(compose-multiplatform[[:space:]]*=[[:space:]]*).*/\1\"$compose_version\"/" "$temp_dir/libs.versions.toml" > "$temp_dir/libs.versions.toml.tmp" + mv "$temp_dir/libs.versions.toml.tmp" "$temp_dir/libs.versions.toml" + fi + + build_dir="$temp_dir" +fi + +cd "$build_dir" +./kotlin build -p "$platform" diff --git a/examples/codeviewer/.gitattributes b/examples/codeviewer/.gitattributes new file mode 100644 index 00000000000..f539da4fa1d --- /dev/null +++ b/examples/codeviewer/.gitattributes @@ -0,0 +1,4 @@ +*.bat text eol=crlf + +# Kotlin CLI wrapper without extension +kotlin text eol=lf diff --git a/examples/codeviewer/.gitignore b/examples/codeviewer/.gitignore index 6e5f30477c5..7c1a2b3a43b 100644 --- a/examples/codeviewer/.gitignore +++ b/examples/codeviewer/.gitignore @@ -1,15 +1,11 @@ +build/ +.kotlin/ +.idea/ *.iml -.gradle -/local.properties -/.idea .DS_Store -build/ -/captures -.externalNativeBuild -.cxx -iosApp/Podfile.lock -iosApp/Pods/* -iosApp/iosApp.xcworkspace/* -iosApp/iosApp.xcodeproj/* -!iosApp/iosApp.xcodeproj/project.pbxproj -shared/shared.podspec +**/module.xcodeproj/* +!**/module.xcodeproj/project.pbxproj +!**/module.xcodeproj/xcshareddata/ +!**/module.xcodeproj/project.xcworkspace/ +**/xcshareddata/WorkspaceSettings.xcsettings +xcuserdata diff --git a/examples/codeviewer/.run/desktopApp.run.xml b/examples/codeviewer/.run/desktopApp.run.xml deleted file mode 100644 index 2d56d7f072a..00000000000 --- a/examples/codeviewer/.run/desktopApp.run.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - true - true - false - - - \ No newline at end of file diff --git a/examples/codeviewer/README.md b/examples/codeviewer/README.md index 2c680764cfe..f58ff7f4444 100644 --- a/examples/codeviewer/README.md +++ b/examples/codeviewer/README.md @@ -1,24 +1,33 @@ # Code Viewer -Code Viewer example for Desktop, Android and iOS written in Compose Multiplatform. +Code Viewer example for Desktop, Android, iOS, and Web written in Compose Multiplatform. + +The project is built with the [Kotlin Toolchain](https://github.com/JetBrains/kotlin-toolchain). ## Setting up your development environment -To setup the environment, please consult these [instructions](https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-multiplatform-setup.html). +To set up the environment, please consult these [instructions](https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-multiplatform-setup.html). + +Open the project in IntelliJ IDEA with the Kotlin Toolchain plugin and use the run gutter icons or run configurations +to launch the app on the target of your choice. + +## Run desktop app + +`./kotlin run -m desktopApp` + +## Run Android app + +`./kotlin run -m androidApp` -## How to run +## Run iOS app -Choose a run configuration for an appropriate target in Android Studio and run it. +`./kotlin run -m iosApp` -![run-configurations.png](run-configurations.png) +or open `iosApp/module.xcodeproj` in Xcode. -## Run desktop via Gradle +## Run web app -`./gradlew desktopApp:run` +`./kotlin run -m webApp` -### Building native desktop distribution -``` -./gradlew :desktop:packageDistributionForCurrentOS -# outputs are written to desktop/build/compose/binaries -``` +and open the printed URL in a browser that supports [Wasm GC](https://kotl.in/wasm-help). -![Desktop](screenshots/codeviewer.png) \ No newline at end of file +![Desktop](screenshots/codeviewer.png) diff --git a/examples/codeviewer/androidApp/src/main/assets/data/EditorView.kt b/examples/codeviewer/androidApp/assets/data/EditorView.kt similarity index 100% rename from examples/codeviewer/androidApp/src/main/assets/data/EditorView.kt rename to examples/codeviewer/androidApp/assets/data/EditorView.kt diff --git a/examples/codeviewer/androidApp/build.gradle.kts b/examples/codeviewer/androidApp/build.gradle.kts deleted file mode 100644 index c02e2e322d4..00000000000 --- a/examples/codeviewer/androidApp/build.gradle.kts +++ /dev/null @@ -1,35 +0,0 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - alias(libs.plugins.androidApplication) - alias(libs.plugins.composeCompiler) - alias(libs.plugins.composeMultiplatform) -} - -kotlin { - compilerOptions { - jvmTarget = JvmTarget.JVM_17 - } -} -dependencies { - implementation(project(":shared")) - implementation(libs.androidx.activity.compose) -} - -android { - compileSdk { - version = release(37) { minorApiLevel = 1 } - } - namespace = "org.jetbrains.codeviewer" - defaultConfig { - applicationId = "org.jetbrains.Codeviewer" - minSdk = 26 - targetSdk = 37 - versionCode = 1 - versionName = "1.0" - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 - } -} diff --git a/examples/codeviewer/androidApp/module.yaml b/examples/codeviewer/androidApp/module.yaml new file mode 100644 index 00000000000..621d4e0e660 --- /dev/null +++ b/examples/codeviewer/androidApp/module.yaml @@ -0,0 +1,17 @@ +product: android/app + +dependencies: + - //shared + - $libs.androidx.activity.compose + +settings: + compose: enabled + android: + namespace: org.jetbrains.codeviewer + applicationId: org.jetbrains.Codeviewer + minSdk: 26 + compileSdk: + apiLevel: 37 + minorApiLevel: 1 + versionCode: 1 + versionName: "1.0" diff --git a/examples/codeviewer/androidApp/src/main/res/drawable/ic_launcher_foreground.xml b/examples/codeviewer/androidApp/res/drawable/ic_launcher_foreground.xml similarity index 100% rename from examples/codeviewer/androidApp/src/main/res/drawable/ic_launcher_foreground.xml rename to examples/codeviewer/androidApp/res/drawable/ic_launcher_foreground.xml diff --git a/examples/codeviewer/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/examples/codeviewer/androidApp/res/mipmap-anydpi-v26/ic_launcher.xml similarity index 100% rename from examples/codeviewer/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml rename to examples/codeviewer/androidApp/res/mipmap-anydpi-v26/ic_launcher.xml diff --git a/examples/codeviewer/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/examples/codeviewer/androidApp/res/mipmap-anydpi-v26/ic_launcher_round.xml similarity index 100% rename from examples/codeviewer/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to examples/codeviewer/androidApp/res/mipmap-anydpi-v26/ic_launcher_round.xml diff --git a/examples/codeviewer/androidApp/src/main/res/values-night/styles.xml b/examples/codeviewer/androidApp/res/values-night/styles.xml similarity index 100% rename from examples/codeviewer/androidApp/src/main/res/values-night/styles.xml rename to examples/codeviewer/androidApp/res/values-night/styles.xml diff --git a/examples/codeviewer/androidApp/src/main/res/values/ic_launcher_background.xml b/examples/codeviewer/androidApp/res/values/ic_launcher_background.xml similarity index 100% rename from examples/codeviewer/androidApp/src/main/res/values/ic_launcher_background.xml rename to examples/codeviewer/androidApp/res/values/ic_launcher_background.xml diff --git a/examples/codeviewer/androidApp/src/main/res/values/strings.xml b/examples/codeviewer/androidApp/res/values/strings.xml similarity index 100% rename from examples/codeviewer/androidApp/src/main/res/values/strings.xml rename to examples/codeviewer/androidApp/res/values/strings.xml diff --git a/examples/codeviewer/androidApp/src/main/res/values/styles.xml b/examples/codeviewer/androidApp/res/values/styles.xml similarity index 100% rename from examples/codeviewer/androidApp/src/main/res/values/styles.xml rename to examples/codeviewer/androidApp/res/values/styles.xml diff --git a/examples/codeviewer/androidApp/src/main/AndroidManifest.xml b/examples/codeviewer/androidApp/src/AndroidManifest.xml similarity index 92% rename from examples/codeviewer/androidApp/src/main/AndroidManifest.xml rename to examples/codeviewer/androidApp/src/AndroidManifest.xml index f91ba3788ad..42016792c17 100644 --- a/examples/codeviewer/androidApp/src/main/AndroidManifest.xml +++ b/examples/codeviewer/androidApp/src/AndroidManifest.xml @@ -10,7 +10,7 @@ android:theme="@style/Theme.Application"> diff --git a/examples/codeviewer/androidApp/src/main/kotlin/org/jetbrains/codeviewer/MainActivity.kt b/examples/codeviewer/androidApp/src/org/jetbrains/codeviewer/MainActivity.kt similarity index 100% rename from examples/codeviewer/androidApp/src/main/kotlin/org/jetbrains/codeviewer/MainActivity.kt rename to examples/codeviewer/androidApp/src/org/jetbrains/codeviewer/MainActivity.kt diff --git a/examples/codeviewer/build.gradle.kts b/examples/codeviewer/build.gradle.kts deleted file mode 100644 index 50aea4ca8b4..00000000000 --- a/examples/codeviewer/build.gradle.kts +++ /dev/null @@ -1,10 +0,0 @@ -plugins { - // this is necessary to avoid the plugins to be loaded multiple times - // in each subproject's classloader - alias(libs.plugins.androidApplication) apply false - alias(libs.plugins.androidMultiplatformLibrary) apply false - alias(libs.plugins.composeMultiplatform) apply false - alias(libs.plugins.composeCompiler) apply false - alias(libs.plugins.kotlinJvm) apply false - alias(libs.plugins.kotlinMultiplatform) apply false -} diff --git a/examples/codeviewer/desktopApp/build.gradle.kts b/examples/codeviewer/desktopApp/build.gradle.kts deleted file mode 100644 index ccef649b265..00000000000 --- a/examples/codeviewer/desktopApp/build.gradle.kts +++ /dev/null @@ -1,41 +0,0 @@ -import org.jetbrains.compose.desktop.application.dsl.TargetFormat - -plugins { - alias(libs.plugins.kotlinMultiplatform) - alias(libs.plugins.composeCompiler) - alias(libs.plugins.composeMultiplatform) -} - -kotlin { - jvm {} - - sourceSets { - jvmMain.dependencies { - implementation(compose.desktop.currentOs) - implementation(project(":shared")) - } - } -} - -compose.desktop { - application { - mainClass = "org.jetbrains.codeviewer.MainKt" - - nativeDistributions { - targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) - packageName = "ComposeCodeViewer" - packageVersion = "1.0.0" - - windows { - menu = true - // see https://wixtoolset.org/documentation/manual/v3/howtos/general/generate_guids.html - upgradeUuid = "AF792DA6-2EA3-495A-95E5-C3C6CBCB9948" - } - - macOS { - // Use -Pcompose.desktop.mac.sign=true to sign and notarize. - bundleID = "com.jetbrains.compose.codeviewer" - } - } - } -} diff --git a/examples/codeviewer/desktopApp/module.yaml b/examples/codeviewer/desktopApp/module.yaml new file mode 100644 index 00000000000..11ab5ac5b56 --- /dev/null +++ b/examples/codeviewer/desktopApp/module.yaml @@ -0,0 +1,11 @@ +product: jvm/app + +dependencies: + - //shared + - $libs.compose.runtime + - $libs.compose.ui + +settings: + compose: enabled + jvm: + mainClass: org.jetbrains.codeviewer.MainKt diff --git a/examples/codeviewer/desktopApp/src/jvmMain/resources/ic_launcher.png b/examples/codeviewer/desktopApp/resources/ic_launcher.png similarity index 100% rename from examples/codeviewer/desktopApp/src/jvmMain/resources/ic_launcher.png rename to examples/codeviewer/desktopApp/resources/ic_launcher.png diff --git a/examples/codeviewer/desktopApp/src/jvmMain/kotlin/org/jetbrains/codeviewer/main.kt b/examples/codeviewer/desktopApp/src/org/jetbrains/codeviewer/main.kt similarity index 100% rename from examples/codeviewer/desktopApp/src/jvmMain/kotlin/org/jetbrains/codeviewer/main.kt rename to examples/codeviewer/desktopApp/src/org/jetbrains/codeviewer/main.kt diff --git a/examples/codeviewer/gradle.properties b/examples/codeviewer/gradle.properties deleted file mode 100644 index a5a909b489e..00000000000 --- a/examples/codeviewer/gradle.properties +++ /dev/null @@ -1,10 +0,0 @@ -kotlin.code.style=official -xcodeproj=./iosApp -android.useAndroidX=true -org.gradle.jvmargs=-Xmx8g -org.gradle.configuration-cache=true -org.gradle.caching=true -org.jetbrains.compose.experimental.macos.enabled=true -kotlin.version=2.4.20 -agp.version=9.2.1 -compose.version=1.12.0 diff --git a/examples/codeviewer/gradle/libs.versions.toml b/examples/codeviewer/gradle/libs.versions.toml deleted file mode 100644 index c3f71366f22..00000000000 --- a/examples/codeviewer/gradle/libs.versions.toml +++ /dev/null @@ -1,27 +0,0 @@ -[versions] -kotlin = "2.3.20" # overriden via gradle.properties -compose = "1.10.1" # overriden via gradle.properties -agp = "9.2.1" # overriden via gradle.properties -androidx-activity = "1.13.0" -androidx-appcompat = "1.7.1" -androidx-core = "1.18.0" - -[libraries] -androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" } -androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" } -androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core" } -compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "compose" } -compose-ui-tooling-preview = { module = "org.jetbrains.compose.ui:ui-tooling-preview", version.ref = "compose" } -material-icons-extended = { module = "org.jetbrains.compose.material:material-icons-extended", version = "1.7.3" } -compose-runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "compose" } -compose-foundation = { module = "org.jetbrains.compose.foundation:foundation", version.ref = "compose" } -compose-material = { module = "org.jetbrains.compose.material:material", version.ref = "compose" } -components-resources = { module = "org.jetbrains.compose.components:components-resources", version.ref = "compose"} - -[plugins] -androidApplication = { id = "com.android.application", version.ref = "agp" } -androidMultiplatformLibrary = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" } -composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose" } -composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } -kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } -kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } diff --git a/examples/codeviewer/gradle/wrapper/gradle-wrapper.jar b/examples/codeviewer/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f09..00000000000 Binary files a/examples/codeviewer/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/examples/codeviewer/gradle/wrapper/gradle-wrapper.properties b/examples/codeviewer/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 2b7a686b445..00000000000 --- a/examples/codeviewer/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,8 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionSha256Sum=553c78f50dafcd54d65b9a444649057857469edf836431389695608536d6b746 -distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/examples/codeviewer/gradlew b/examples/codeviewer/gradlew deleted file mode 100755 index a69d9cb6c20..00000000000 --- a/examples/codeviewer/gradlew +++ /dev/null @@ -1,240 +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 \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# 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/examples/codeviewer/gradlew.bat b/examples/codeviewer/gradlew.bat deleted file mode 100644 index f127cfd49d4..00000000000 --- a/examples/codeviewer/gradlew.bat +++ /dev/null @@ -1,91 +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% equ 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% equ 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! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/examples/codeviewer/iosApp/Configuration/Config.xcconfig b/examples/codeviewer/iosApp/Configuration/Config.xcconfig deleted file mode 100644 index 1393dc4f0b7..00000000000 --- a/examples/codeviewer/iosApp/Configuration/Config.xcconfig +++ /dev/null @@ -1,3 +0,0 @@ -TEAM_ID= -BUNDLE_ID=org.jetbrains.Codeviewer -APP_NAME=Codeviewer diff --git a/examples/codeviewer/iosApp/iosApp.xcodeproj/project.pbxproj b/examples/codeviewer/iosApp/iosApp.xcodeproj/project.pbxproj deleted file mode 100644 index b2916a6c394..00000000000 --- a/examples/codeviewer/iosApp/iosApp.xcodeproj/project.pbxproj +++ /dev/null @@ -1,382 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 50; - objects = { - -/* Begin PBXBuildFile section */ - 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; }; - 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; }; - 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; }; - 3251B1382AA8CF70001521C0 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3251B1372AA8CF70001521C0 /* ContentView.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 2152FB032600AC8F00CF470E /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = ""; }; - 3251B1372AA8CF70001521C0 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; - 7555FF7B242A565900829871 /* Codeviewer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Codeviewer.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - AB3632DC29227652001CCB65 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - F85CB1118929364A9C6EFABC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 058557D7273AAEEB004C7B11 /* Preview Content */ = { - isa = PBXGroup; - children = ( - 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; - 7555FF72242A565900829871 = { - isa = PBXGroup; - children = ( - AB1DB47929225F7C00F7AF9C /* Configuration */, - 7555FF7D242A565900829871 /* iosApp */, - 7555FF7C242A565900829871 /* Products */, - ); - sourceTree = ""; - }; - 7555FF7C242A565900829871 /* Products */ = { - isa = PBXGroup; - children = ( - 7555FF7B242A565900829871 /* Codeviewer.app */, - ); - name = Products; - sourceTree = ""; - }; - 7555FF7D242A565900829871 /* iosApp */ = { - isa = PBXGroup; - children = ( - 058557BA273AAA24004C7B11 /* Assets.xcassets */, - 7555FF8C242A565B00829871 /* Info.plist */, - 2152FB032600AC8F00CF470E /* iOSApp.swift */, - 058557D7273AAEEB004C7B11 /* Preview Content */, - 3251B1372AA8CF70001521C0 /* ContentView.swift */, - ); - path = iosApp; - sourceTree = ""; - }; - AB1DB47929225F7C00F7AF9C /* Configuration */ = { - isa = PBXGroup; - children = ( - AB3632DC29227652001CCB65 /* Config.xcconfig */, - ); - path = Configuration; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 7555FF7A242A565900829871 /* iosApp */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */; - buildPhases = ( - 05E104072A8AA90A00D11C3D /* Compile Kotlin */, - 7555FF77242A565900829871 /* Sources */, - 7555FF79242A565900829871 /* Resources */, - F85CB1118929364A9C6EFABC /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = iosApp; - productName = iosApp; - productReference = 7555FF7B242A565900829871 /* Codeviewer.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 7555FF73242A565900829871 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 1130; - LastUpgradeCheck = 1130; - ORGANIZATIONNAME = orgName; - TargetAttributes = { - 7555FF7A242A565900829871 = { - CreatedOnToolsVersion = 11.3.1; - }; - }; - }; - buildConfigurationList = 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 7555FF72242A565900829871; - productRefGroup = 7555FF7C242A565900829871 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 7555FF7A242A565900829871 /* iosApp */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 7555FF79242A565900829871 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */, - 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 05E104072A8AA90A00D11C3D /* Compile Kotlin */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Compile Kotlin"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "cd \"$SRCROOT/..\"\n./gradlew :shared:embedAndSignAppleFrameworkForXcode\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 7555FF77242A565900829871 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3251B1382AA8CF70001521C0 /* ContentView.swift in Sources */, - 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 7555FFA3242A565B00829871 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 7555FFA4242A565B00829871 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 7555FFA6242A565B00829871 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; - DEVELOPMENT_TEAM = "${TEAM_ID}"; - ENABLE_PREVIEWS = YES; - FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n"; - INFOPLIST_FILE = iosApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - OTHER_LDFLAGS = ( - "$(inherited)", - "-framework", - "shared\n", - ); - PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; - PRODUCT_NAME = "${APP_NAME}"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 7555FFA7242A565B00829871 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; - DEVELOPMENT_TEAM = "${TEAM_ID}"; - ENABLE_PREVIEWS = YES; - FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n"; - INFOPLIST_FILE = iosApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - OTHER_LDFLAGS = ( - "$(inherited)", - "-framework", - "shared\n", - ); - PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; - PRODUCT_NAME = "${APP_NAME}"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7555FFA3242A565B00829871 /* Debug */, - 7555FFA4242A565B00829871 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7555FFA6242A565B00829871 /* Debug */, - 7555FFA7242A565B00829871 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 7555FF73242A565900829871 /* Project object */; -} diff --git a/examples/codeviewer/iosApp/iosApp/Info.plist b/examples/codeviewer/iosApp/iosApp/Info.plist deleted file mode 100644 index 412e3781280..00000000000 --- a/examples/codeviewer/iosApp/iosApp/Info.plist +++ /dev/null @@ -1,50 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - LSRequiresIPhoneOS - - CADisableMinimumFrameDurationOnPhone - - UIApplicationSceneManifest - - UIApplicationSupportsMultipleScenes - - - UILaunchScreen - - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/examples/codeviewer/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json b/examples/codeviewer/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json deleted file mode 100644 index 4aa7c5350bf..00000000000 --- a/examples/codeviewer/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} \ No newline at end of file diff --git a/examples/codeviewer/iosApp/module.xcodeproj/project.pbxproj b/examples/codeviewer/iosApp/module.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..1bbc11aa054 --- /dev/null +++ b/examples/codeviewer/iosApp/module.xcodeproj/project.pbxproj @@ -0,0 +1,221 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXFileReference section */ + 61953054E79C679999285760 /* Codeviewer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Codeviewer.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 61953F84EDE8841FF4EB58FD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.info; name = Info.plist; path = src/Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + 619536EC3227DE902FA82C88 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = 61953448E778222CB0131C83 /* app */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 6195343827A0FB09880F5E89 /* src */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + 619536EC3227DE902FA82C88 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, + ); + path = src; + sourceTree = SOURCE_ROOT; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 61953852C94087CBE26CE7E2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 61953869EC51EBC6C13E7A72 = { + isa = PBXGroup; + children = ( + 61953F4FE2725B94BB5DE016 /* Products */, + 61953F84EDE8841FF4EB58FD /* Info.plist */, + 6195343827A0FB09880F5E89 /* src */, + ); + sourceTree = ""; + }; + 61953F4FE2725B94BB5DE016 /* Products */ = { + isa = PBXGroup; + children = ( + 61953054E79C679999285760 /* Codeviewer.app */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 61953448E778222CB0131C83 /* app */ = { + isa = PBXNativeTarget; + buildConfigurationList = 619537AD847CA000C1640B8B /* Build configuration list for PBXNativeTarget "app" */; + buildPhases = ( + 61953AB277B46DCD95A720D6 /* Build Kotlin */, + 61953E99CB2418540738CD58 /* Sources */, + 61953852C94087CBE26CE7E2 /* Frameworks */, + 61953807DDCA3237E8120E0C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 6195343827A0FB09880F5E89 /* src */, + ); + name = app; + productName = app; + productReference = 61953054E79C679999285760 /* Codeviewer.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 61953894F26186C70B8C203C /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 61953A94F0B4D42348B90F07 /* Build configuration list for PBXProject "module" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 61953869EC51EBC6C13E7A72; + productRefGroup = 61953F4FE2725B94BB5DE016 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 61953448E778222CB0131C83 /* app */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 61953807DDCA3237E8120E0C /* Resources */ = { + isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 61953AB277B46DCD95A720D6 /* Build Kotlin */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + inputPaths = ( + ); + name = "Build Kotlin"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# !KOTLIN INTEGRATION STEP!\n# This script is managed by the Kotlin Toolchain, do not edit manually!\n\"${KOTLIN_CLI_WRAPPER_PATH}\" tool xcode-integration\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 61953E99CB2418540738CD58 /* Sources */ = { + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 619532473E3B85FD35EA73E8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_OPTIMIZATION_LEVEL = 0; + INFOPLIST_FILE = src/Info.plist; + KOTLIN_CLI_WRAPPER_PATH = ../kotlin; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = org.jetbrains.Codeviewer; + PRODUCT_MODULE_NAME = app; + PRODUCT_NAME = Codeviewer; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = ( + 1, + 2, + ); + }; + name = Debug; + }; + 619534C7499BFCC9FFF5D8EC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Debug; + }; + 619536FEC92F1AEADBE2167D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + INFOPLIST_FILE = src/Info.plist; + KOTLIN_CLI_WRAPPER_PATH = ../kotlin; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = org.jetbrains.Codeviewer; + PRODUCT_MODULE_NAME = app; + PRODUCT_NAME = Codeviewer; + SDKROOT = iphoneos; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = ( + 1, + 2, + ); + }; + name = Release; + }; + 61953F9B26C121FF0F32B955 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 619537AD847CA000C1640B8B /* Build configuration list for PBXNativeTarget "app" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 619532473E3B85FD35EA73E8 /* Debug */, + 619536FEC92F1AEADBE2167D /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; + 61953A94F0B4D42348B90F07 /* Build configuration list for PBXProject "module" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 619534C7499BFCC9FFF5D8EC /* Debug */, + 61953F9B26C121FF0F32B955 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 61953894F26186C70B8C203C /* Project object */; +} diff --git a/examples/codeviewer/iosApp/module.xcodeproj/xcshareddata/xcschemes/Module iosApp.xcscheme b/examples/codeviewer/iosApp/module.xcodeproj/xcshareddata/xcschemes/Module iosApp.xcscheme new file mode 100644 index 00000000000..4910983be59 --- /dev/null +++ b/examples/codeviewer/iosApp/module.xcodeproj/xcshareddata/xcschemes/Module iosApp.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/codeviewer/iosApp/module.yaml b/examples/codeviewer/iosApp/module.yaml new file mode 100644 index 00000000000..392eaa5f782 --- /dev/null +++ b/examples/codeviewer/iosApp/module.yaml @@ -0,0 +1,8 @@ +product: ios/app + +dependencies: + - //shared + - $libs.compose.ui + +settings: + compose: enabled diff --git a/examples/codeviewer/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json b/examples/codeviewer/iosApp/src/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from examples/codeviewer/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json rename to examples/codeviewer/iosApp/src/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/examples/codeviewer/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/codeviewer/iosApp/src/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from examples/codeviewer/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json rename to examples/codeviewer/iosApp/src/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/examples/codeviewer/iosApp/iosApp/Assets.xcassets/Contents.json b/examples/codeviewer/iosApp/src/Assets.xcassets/Contents.json similarity index 100% rename from examples/codeviewer/iosApp/iosApp/Assets.xcassets/Contents.json rename to examples/codeviewer/iosApp/src/Assets.xcassets/Contents.json diff --git a/examples/codeviewer/iosApp/iosApp/ContentView.swift b/examples/codeviewer/iosApp/src/ContentView.swift similarity index 95% rename from examples/codeviewer/iosApp/iosApp/ContentView.swift rename to examples/codeviewer/iosApp/src/ContentView.swift index ddb2dd9b6eb..f5de0ba0a83 100644 --- a/examples/codeviewer/iosApp/iosApp/ContentView.swift +++ b/examples/codeviewer/iosApp/src/ContentView.swift @@ -1,6 +1,6 @@ import UIKit import SwiftUI -import shared +import KotlinModules struct ContentView: View { var body: some View { diff --git a/examples/codeviewer/iosApp/src/Info.plist b/examples/codeviewer/iosApp/src/Info.plist new file mode 100644 index 00000000000..80d2cac7d55 --- /dev/null +++ b/examples/codeviewer/iosApp/src/Info.plist @@ -0,0 +1,41 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + UILaunchScreen + + UIApplicationSupportsIndirectInputEvents + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + CADisableMinimumFrameDurationOnPhone + + + diff --git a/examples/codeviewer/iosApp/iosApp/iOSApp.swift b/examples/codeviewer/iosApp/src/iOSApp.swift similarity index 100% rename from examples/codeviewer/iosApp/iosApp/iOSApp.swift rename to examples/codeviewer/iosApp/src/iOSApp.swift diff --git a/examples/codeviewer/shared/src/iosMain/kotlin/main.ios.kt b/examples/codeviewer/iosApp/src/main.ios.kt similarity index 100% rename from examples/codeviewer/shared/src/iosMain/kotlin/main.ios.kt rename to examples/codeviewer/iosApp/src/main.ios.kt diff --git a/examples/codeviewer/kotlin b/examples/codeviewer/kotlin new file mode 100755 index 00000000000..5ef1dee4f32 --- /dev/null +++ b/examples/codeviewer/kotlin @@ -0,0 +1,292 @@ +#!/bin/sh + +# +# Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +# + +# Possible environment variables: +# KOTLIN_CLI_DOWNLOAD_ROOT Maven repository to download the Kotlin CLI dist from. +# default: https://packages.jetbrains.team/maven/p/amper/amper +# KOTLIN_CLI_JRE_DOWNLOAD_ROOT Url prefix to download the JRE to run the Kotlin CLI +# default: https:/ +# KOTLIN_CLI_BOOTSTRAP_CACHE_DIR Cache directory to store the extracted JRE and Kotlin CLI distribution +# KOTLIN_CLI_JAVA_HOME JRE to run the Kotlin CLI itself (optional, does not affect compilation) +# KOTLIN_CLI_JAVA_OPTIONS JVM options to pass to the JVM running the Kotlin CLI (does not affect the user's application) +# KOTLIN_CLI_NO_WELCOME_BANNER Disables the first-run welcome message if set to a non-empty value + +set -e -u + +# The version of the Kotlin Toolchain (and CLI) distribution to provision and use +kotlin_cli_version=0.13.0 +# Establish chain of trust from here by specifying exact checksum of Kotlin Toolchain (and CLI) distribution to be run +kotlin_cli_sha256=fa82b9872dcfa04d26c8f800f33d597c99fbffd747a0e9bbce3a9e4424b3a588 + +KOTLIN_CLI_DOWNLOAD_ROOT="${KOTLIN_CLI_DOWNLOAD_ROOT:-https://packages.jetbrains.team/maven/p/amper/amper}" + +die() { + echo >&2 + echo "$@" >&2 + echo >&2 + exit 1 +} + +# usage: check_sha SOURCE_MONIKER FILE SHA_CHECKSUM SHA_SIZE +# $1 SOURCE_MONIKER (e.g. url) +# $2 FILE +# $3 SHA hex string +# $4 SHA size in bits (256, 512, ...) +check_sha() { + sha_size=$4 + if command -v shasum >/dev/null 2>&1; then + echo "$3 *$2" | shasum -a "$sha_size" --status -c || { + die "ERROR: Checksum mismatch for $2 (downloaded from $1): expected checksum $3 but got $(shasum --binary -a "$sha_size" "$2" | awk '{print $1}')" + } + return 0 + fi + + shaNsumCommand="sha${sha_size}sum" + if command -v "$shaNsumCommand" >/dev/null 2>&1; then + # discard the output as sha*sum may print redundant warnings in some versions + echo "$3 *$2" | $shaNsumCommand -w -c >/dev/null 2>&1 || { + die "ERROR: Checksum mismatch for $2 (downloaded from $1): expected checksum $3 but got $($shaNsumCommand "$2" | awk '{print $1}')" + } + return 0 + fi + + echo "Both 'shasum' and 'sha${sha_size}sum' utilities are missing. Please install one of them" + return 1 +} + + +download_and_extract() { + moniker="$1" + file_url="$2" + file_sha="$3" + sha_size="$4" + cache_dir="$5" + extract_dir="$6" + show_banner_on_cache_miss="$7" + + if [ -e "$extract_dir/.flag" ] && [ "$(cat "$extract_dir/.flag")" = "${file_sha}" ]; then + # Everything is up-to-date in $extract_dir, do nothing + return 0; + fi + + mkdir -p "$cache_dir" + + # Take a lock for the download of this file + short_sha=$(echo "$file_sha" | cut -c1-32) # cannot use the ${short_sha:0:32} syntax in regular /bin/sh + download_lock_file="$cache_dir/download-${short_sha}.lock" + process_lock_file="$cache_dir/download-${short_sha}.$$.lock" + temp_file="$cache_dir/download-${short_sha}.$$.bin" + echo $$ >"$process_lock_file" + while ! ln "$process_lock_file" "$download_lock_file" 2>/dev/null; do + lock_owner=$(cat "$download_lock_file" 2>/dev/null || true) + # We use `kill -0` instead of `ps -p` as the first one is more portable + if [ -n "$lock_owner" ] && kill -0 "$lock_owner" >/dev/null; then + echo "Another Kotlin CLI instance (pid $lock_owner) is downloading $moniker. Awaiting the result..." + sleep 1 + elif [ -n "$lock_owner" ] && [ "$(cat "$download_lock_file" 2>/dev/null)" = "$lock_owner" ]; then + rm -f "$download_lock_file" + # We don't want to simply loop again here, because multiple concurrent processes may face this at the same time, + # which means the 'rm' command above from another script could delete our new valid lock file. Instead, we just + # ask the user to try again. This doesn't 100% eliminate the race, but the probability of issues is drastically + # reduced because it would involve 4 processes with perfect timing. We can revisit this later. + die "Another Kotlin CLI instance (pid $lock_owner) locked the download of $moniker, but is no longer running. The lock file is now removed, please try again." + fi + done + + + # An extraction left half-done must never keep the .flag file, which marks $extract_dir as complete: subsequent runs + # would skip the extraction and use the broken directory. + cleanup_incomplete_provisioning() { + rm -f "$download_lock_file" "$temp_file" + rm -rf "$extract_dir" + } + trap cleanup_incomplete_provisioning EXIT + rm -f "$process_lock_file" + + unlock_and_cleanup() { + rm -f "$download_lock_file" + trap - EXIT + return 0 + } + + if [ -e "$extract_dir/.flag" ] && [ "$(cat "$extract_dir/.flag")" = "${file_sha}" ]; then + # Everything is up-to-date in $extract_dir, just release the lock + unlock_and_cleanup + return 0; + fi + + if [ "$show_banner_on_cache_miss" = "true" ] && [ -z "${KOTLIN_CLI_NO_WELCOME_BANNER:-}" ]; then + echo + cat </dev/null 2>&1; then + if [ -t 1 ]; then CURL_PROGRESS="--progress-bar"; else CURL_PROGRESS="--silent --show-error"; fi + # shellcheck disable=SC2086 + curl $CURL_PROGRESS -L --fail --retry 5 --connect-timeout 30 --output "${temp_file}" "$file_url" + elif command -v wget >/dev/null 2>&1; then + if [ -t 1 ]; then WGET_PROGRESS=""; else WGET_PROGRESS="-nv"; fi + wget $WGET_PROGRESS --tries=5 --connect-timeout=30 --read-timeout=120 -O "${temp_file}" "$file_url" + else + die "ERROR: Please install 'wget' or 'curl', as one of them is required to download $moniker" + fi + + check_sha "$file_url" "$temp_file" "$file_sha" "$sha_size" + + rm -rf "$extract_dir" + mkdir -p "$extract_dir" + + case "$file_url" in + *".zip") + if command -v unzip >/dev/null 2>&1; then + unzip -q "$temp_file" -d "$extract_dir" + else + die "ERROR: Please install 'unzip', which is required to extract $moniker" + fi ;; + *) + if command -v tar >/dev/null 2>&1; then + tar -x -f "$temp_file" -C "$extract_dir" + else + die "ERROR: Please install 'tar', which is required to extract $moniker" + fi ;; + esac + + rm -f "$temp_file" + + echo "$file_sha" >"$extract_dir/.flag" + + # Unlock and cleanup the lock file + unlock_and_cleanup + + echo "Download complete." + echo +} + + +# ********** Project-local version detection ********** + +# 1. Search upwards for an executable `amper` file and/or `project.yaml` +# Sets wrapper_script to the found wrapper path, or empty string if not found. +find_project_context() { + wrapper_script="" + this_script="$(realpath "$0")" + project_dir=$(pwd) + while [ "$project_dir" != "/" ] && [ -n "$project_dir" ]; do + wrapper_candidate="$project_dir/kotlin" + if [ "$this_script" = "$wrapper_candidate" ]; then + # Found itself (local wrapper case), no need to update any version or search further. + return 1 + fi + + if [ -f "$wrapper_candidate" ] && [ -x "$wrapper_candidate" ]; then + # Found the wrapper — check that a project context exists alongside it + if [ -f "$project_dir/project.yaml" ] || [ -f "$project_dir/module.yaml" ]; then + wrapper_script="$wrapper_candidate" + return 0 + else + echo "WARNING: Found wrapper script '$wrapper_candidate', but no project.yaml or module.yaml near it. Skipping." >&2 + # Continue the search + fi + elif [ -f "$project_dir/project.yaml" ]; then + # Found project.yaml but no executable wrapper alongside it + echo "WARNING: Found a project.yaml in '$project_dir', but the wrapper script is missing; using Kotlin Toolchain v$kotlin_cli_version." >&2 + return 1 + fi + + project_dir=$(dirname "$project_dir") + done + # Do not check root '/' - it's an unlikely candidate for a project + + return 1 +} + +parse_project_context() { + # Parse kotlin_cli_version and kotlin_cli_sha256 from "$wrapper_script" without executing it. + parsed_kotlin_cli_version=$( + sed -n 's/^kotlin_cli_version=\([A-Za-z0-9._+-]\{1,\}\)[[:space:]]*$/\1/p' "$wrapper_script" \ + | head -n 1 + ) + parsed_kotlin_cli_sha256=$( + sed -n 's/^kotlin_cli_sha256=\([0-9a-fA-F]\{64\}\)[[:space:]]*$/\1/p' "$wrapper_script" \ + | head -n 1 + ) + + if [ -z "$parsed_kotlin_cli_version" ]; then + echo "ERROR: Suspicious local wrapper script: failed to detect the distribution version in '$wrapper_script'" >&2 + return 1 + fi + if [ -z "$parsed_kotlin_cli_sha256" ]; then + echo "ERROR: Suspicious local wrapper script: failed to detect the distribution checksum in '$wrapper_script'" >&2 + return 1 + fi + + # overwrite builtin values and proceed + kotlin_cli_version=$parsed_kotlin_cli_version + kotlin_cli_sha256=$parsed_kotlin_cli_sha256 + return 0 +} + +if [ -z "${KOTLIN_CLI_WRAPPER_ALWAYS_USE_INTRINSIC_VERSION:-}" ]; then + find_project_context && parse_project_context +fi + +# ********** System detection ********** + +kernelName=$(uname -s) +case "$kernelName" in + Darwin* ) + default_kotlin_cli_cache_dir="$HOME/Library/Caches/JetBrains/Kotlin/cli" + ;; + Linux* ) + default_kotlin_cli_cache_dir="$HOME/.cache/JetBrains/Kotlin/cli" + ;; + CYGWIN* | MSYS* | MINGW* ) + if command -v cygpath >/dev/null 2>&1; then + default_kotlin_cli_cache_dir=$(cygpath -u "$LOCALAPPDATA\JetBrains\Kotlin\cli") + else + die "The 'cypath' command is not available, but the Kotlin CLI needs it. Use kotlin.bat instead, or try a Cygwin or MSYS environment." + fi + ;; + *) + die "Unsupported platform $kernelName" + ;; +esac + +kotlin_cli_cache_dir="${KOTLIN_CLI_BOOTSTRAP_CACHE_DIR:-$default_kotlin_cli_cache_dir}" + +# ********** Provision the Kotlin Toolchain distribution ********** + +kotlin_cli_url="$KOTLIN_CLI_DOWNLOAD_ROOT/org/jetbrains/kotlin/kotlin-cli/$kotlin_cli_version/kotlin-cli-$kotlin_cli_version-dist.tgz" +kotlin_cli_target_dir="$kotlin_cli_cache_dir/kotlin-cli-$kotlin_cli_version" +download_and_extract "Kotlin Toolchain distribution v$kotlin_cli_version" "$kotlin_cli_url" "$kotlin_cli_sha256" 256 "$kotlin_cli_cache_dir" "$kotlin_cli_target_dir" "true" + +# ********** Launch the Kotlin CLI ********** + +launcher_script="$kotlin_cli_target_dir/bin/launcher.sh" + +KOTLIN_CLI_WRAPPER_PATH="$(realpath "$0")" \ +exec /bin/sh "$launcher_script" "$@" diff --git a/examples/codeviewer/kotlin.bat b/examples/codeviewer/kotlin.bat new file mode 100755 index 00000000000..f295d64bf00 --- /dev/null +++ b/examples/codeviewer/kotlin.bat @@ -0,0 +1,280 @@ +@echo off + +@rem +@rem Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +@rem + +@rem Possible environment variables: +@rem KOTLIN_CLI_DOWNLOAD_ROOT Maven repository to download the Kotlin CLI dist from +@rem default: https://packages.jetbrains.team/maven/p/amper/amper +@rem KOTLIN_CLI_JRE_DOWNLOAD_ROOT Url prefix to download the Kotlin CLI JRE from. +@rem default: https:/ +@rem KOTLIN_CLI_BOOTSTRAP_CACHE_DIR Cache directory to store the extracted JRE and Kotlin CLI distribution +@rem KOTLIN_CLI_JAVA_HOME JRE to run the Kotlin CLI itself (optional, does not affect compilation) +@rem KOTLIN_CLI_JAVA_OPTIONS JVM options to pass to the JVM running the Kotlin CLI (does not affect the user's application) +@rem KOTLIN_CLI_NO_WELCOME_BANNER Disables the first-run welcome message if set to a non-empty value + +setlocal + +@rem The version of the Kotlin Toolchain distribution to provision and use +set kotlin_cli_version=0.13.0 +@rem Establish chain of trust from here by specifying the exact checksum of the Kotlin Toolchain distribution to be run +set kotlin_cli_sha256=fa82b9872dcfa04d26c8f800f33d597c99fbffd747a0e9bbce3a9e4424b3a588 + +if not defined KOTLIN_CLI_DOWNLOAD_ROOT set KOTLIN_CLI_DOWNLOAD_ROOT=https://packages.jetbrains.team/maven/p/amper/amper +if not defined KOTLIN_CLI_BOOTSTRAP_CACHE_DIR set KOTLIN_CLI_BOOTSTRAP_CACHE_DIR=%LOCALAPPDATA%\JetBrains\Kotlin\cli +@rem remove trailing \ if present +if [%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR:~-1%] EQU [\] set KOTLIN_CLI_BOOTSTRAP_CACHE_DIR=%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR:~0,-1% + +goto :after_function_declarations + +REM ********** Download and extract any zip or .tar.gz archive ********** + +:download_and_extract +setlocal + +set moniker=%~1 +set url=%~2 +set target_dir=%~3 +set sha=%~4 +set sha_size=%~5 +set show_banner_on_cache_miss=%~6 + +setlocal enableDelayedExpansion + +set flag_file=%target_dir%\.flag +if exist "%flag_file%" ( + set /p current_flag=<"%flag_file%" + if "!current_flag!" == "%sha%" exit /b +) + +set NL=^ + + +@rem two empty lines required above for the NL character + +@rem We have to build the welcome banner here as an env var because we +@rem can't pass a multiline string through the single line powershell +set welcome_banner=!NL! ^ +Welcome to !NL! ^ + !NL! ^ +@@@ @@@@ @@@ @@@ !NL! ^ +@@@ @@@@ @@@ @@@ @@@ !NL! ^ +@@@ #@@@^" ,@@@ @@@ !NL! ^ +@@@ ,@@@%% ,@@@@@@@, @@@@@@@@@@ @@@ @@@ @@@ ,@@@@@, !NL! ^ +@@@ @@@@ @@@@@%%^"%%@@@@@ @@@@@@@@@@ @@@ @@@ @@@@@@%%%%@@@@@ !NL! ^ +@@@@@@%% @@@%% %%@@@ @@@ @@@ @@@ @@@@ %%@@%% !NL! ^ +@@@ @@@@= #@@@ @@@# @@@ @@@ @@@ @@@ @@@ !NL! ^ +@@@ @@@@ #@@@ @@@# @@@ @@@ @@@ @@@ @@@ !NL! ^ +@@@ *@@@%% @@@@ @@@@ @@@ @@@ @@@ @@@ @@@ !NL! ^ +@@@ %%@@@= %%@@@@*,*@@@@%% @@@@### @@@ @@@ @@@ @@@ !NL! ^ +@@@ @@@@ ^"@@@@@@@^" %%@@@@@ @@@ @@@ @@@ @@@ !NL! + +@rem This multiline string is actually passed as a single line to powershell, meaning #-comments are not possible. +@rem So here are a few comments about the code below: +@rem - we need to support both .zip and .tar.gz archives (for the Kotlin Toolchain distribution and the JRE) +@rem - tar should be present in all Windows machines since 2018 (and usable from both cmd and powershell) +@rem - tar requires the destination dir to exist +@rem - native commands like tar don't raise PowerShell errors on failure, so we have to check $LASTEXITCODE. +@rem The extraction must never be left half-done with the .flag file in place, because the .flag file marks the +@rem target dir as complete, and subsequent runs would then skip the extraction and use the broken directory. +@rem - We use (New-Object Net.WebClient).DownloadFile instead of Invoke-WebRequest for performance. See the issue +@rem https://github.com/PowerShell/PowerShell/issues/16914, which is still not fixed in Windows PowerShell 5.1 +@rem - DownloadFile requires the directories in the destination file's path to exist +set download_and_extract_ps1= ^ +Set-StrictMode -Version 3.0; ^ +$ErrorActionPreference = 'Stop'; ^ + ^ +$temp_file = $null; ^ +$createdNew = $false; ^ +$lock = New-Object System.Threading.Mutex($true, ('Global\kotlin-cli-bootstrap.' + '%target_dir%'.GetHashCode().ToString()), [ref]$createdNew); ^ +if (-not $createdNew) { ^ + Write-Host 'Another Kotlin CLI instance is bootstrapping. Waiting for our turn...'; ^ + [void]$lock.WaitOne(); ^ +} ^ + ^ +try { ^ + if ((Get-Content '%flag_file%' -ErrorAction Ignore) -ne '%sha%') { ^ + if (('%show_banner_on_cache_miss%' -eq 'true') -and [string]::IsNullOrEmpty('%KOTLIN_CLI_NO_WELCOME_BANNER%')) { ^ + Write-Host \"$env:welcome_banner\"; ^ + Write-Host ''; ^ + Write-Host 'This is the first run of the Kotlin CLI v%kotlin_cli_version%, so we need to download the Kotlin Toolchain.'; ^ + Write-Host 'Please give us a few seconds now, subsequent runs will be faster.'; ^ + Write-Host ''; ^ + } ^ + $temp_file = '%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR%\' + [System.IO.Path]::GetRandomFileName(); ^ + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; ^ + Write-Host 'Downloading %moniker%...'; ^ + [void](New-Item '%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR%' -ItemType Directory -Force); ^ + if (Get-Command curl.exe -errorAction SilentlyContinue) { ^ + curl.exe -L --silent --show-error --fail --output $temp_file '%url%'; ^ + } else { ^ + (New-Object Net.WebClient).DownloadFile('%url%', $temp_file); ^ + } ^ + ^ + $actualSha = (Get-FileHash -Algorithm SHA%sha_size% -Path $temp_file).Hash.ToString(); ^ + if ($actualSha -ne '%sha%') { ^ + $writeErr = if ($Host.Name -eq 'ConsoleHost') { [Console]::Error.WriteLine } else { $host.ui.WriteErrorLine } ^ + $writeErr.Invoke(\"ERROR: Checksum mismatch for $temp_file (downloaded from %url%): expected checksum %sha% but got $actualSha\"); ^ + exit 1; ^ + } ^ + ^ + if (Test-Path '%target_dir%') { ^ + Remove-Item '%target_dir%' -Recurse; ^ + } ^ + try { ^ + if ($temp_file -like '*.zip') { ^ + Add-Type -A 'System.IO.Compression.FileSystem'; ^ + [IO.Compression.ZipFile]::ExtractToDirectory($temp_file, '%target_dir%'); ^ + } else { ^ + [void](New-Item '%target_dir%' -ItemType Directory -Force); ^ + tar -xzf $temp_file -C '%target_dir%'; ^ + if ($LASTEXITCODE -ne 0) { ^ + throw \"tar failed to extract %moniker% (exit code $LASTEXITCODE)\"; ^ + } ^ + } ^ + } catch { ^ + Remove-Item '%flag_file%' -Force -ErrorAction Ignore; ^ + Remove-Item '%target_dir%' -Recurse -Force -ErrorAction Ignore; ^ + throw; ^ + } ^ + ^ + Set-Content '%flag_file%' -Value '%sha%'; ^ + Write-Host 'Download complete.'; ^ + Write-Host ''; ^ + } ^ +} ^ +finally { ^ + if ($temp_file) { ^ + Remove-Item $temp_file -Force -ErrorAction Ignore; ^ + } ^ + $lock.ReleaseMutex(); ^ +} + +rem We reset the PSModulePath in case this batch script was called from PowerShell Core +rem See https://github.com/PowerShell/PowerShell/issues/18108#issuecomment-2269703022 +set PSModulePath= +set powershell=%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe +"%powershell%" -NonInteractive -NoProfile -NoLogo -Command %download_and_extract_ps1% +if errorlevel 1 exit /b 1 +exit /b 0 + +:find_project_context +@rem Search upwards for a kotlin.bat wrapper file and/or project.yaml +@rem Sets wrapper_script to the found wrapper path, or empty string if not found. +@rem Returns errorlevel 0 if a valid wrapper (that is not this script itself) was found, 1 otherwise. +set wrapper_script= +set this_script=%~f0 +set project_dir=%CD% + +:find_loop +set wrapper_candidate=%project_dir%\kotlin.bat +if "%this_script%"=="%wrapper_candidate%" ( + @rem Found itself (local wrapper case), no need to update any version or search further. + exit /b 1 +) + +if exist "%wrapper_candidate%" ( + @rem Found a wrapper — check that a project context exists alongside it + if exist "%project_dir%\project.yaml" ( + set wrapper_script=%wrapper_candidate% + exit /b 0 + ) + if exist "%project_dir%\module.yaml" ( + set wrapper_script=%wrapper_candidate% + exit /b 0 + ) + echo WARNING: Found wrapper script '%wrapper_candidate%', but no project.yaml or module.yaml near it. Skipping. >&2 + @rem Continue the search + goto :find_next_parent +) + +if exist "%project_dir%\project.yaml" ( + @rem Found project.yaml but no wrapper alongside it + echo WARNING: Found a project.yaml in '%project_dir%', but the wrapper script is missing; using Kotlin Toolchain v%kotlin_cli_version%. >&2 + exit /b 1 +) + +:find_next_parent +@rem Move to parent directory +for %%P in ("%project_dir%\..") do set parent_dir=%%~fP +if "%parent_dir%"=="%project_dir%" ( + @rem Reached the root, stop searching + exit /b 1 +) +set project_dir=%parent_dir% +goto :find_loop + +:parse_project_context +@rem Parse kotlin_cli_version and kotlin_cli_sha256 from the found wrapper_script without executing it. +set parsed_kotlin_cli_version= +set parsed_kotlin_cli_sha256= + +for /f "tokens=2 delims==" %%A in ('findstr /r /c:"^set kotlin_cli_version=[A-Za-z0-9._+-]*$" "%wrapper_script%"') do ( + if not defined parsed_kotlin_cli_version set parsed_kotlin_cli_version=%%A +) +for /f "tokens=2 delims==" %%A in ('findstr /r /c:"^set kotlin_cli_sha256=[0-9a-fA-F]*$" "%wrapper_script%"') do ( + if not defined parsed_kotlin_cli_sha256 set parsed_kotlin_cli_sha256=%%A +) + +if not defined parsed_kotlin_cli_version ( + echo ERROR: Suspicious local wrapper script: failed to detect the distribution version in '%wrapper_script%' >&2 + exit /b 1 +) +if not defined parsed_kotlin_cli_sha256 ( + echo ERROR: Suspicious local wrapper script: failed to detect the distribution checksum in '%wrapper_script%' >&2 + exit /b 1 +) + +@rem Overwrite builtin values and proceed +set kotlin_cli_version=%parsed_kotlin_cli_version% +set kotlin_cli_sha256=%parsed_kotlin_cli_sha256% +exit /b 0 + +:fail +echo ERROR: Kotlin CLI bootstrap failed, see errors above +exit /b 1 + +:after_function_declarations + +REM ********** Project-local version detection ********** + +if defined KOTLIN_CLI_WRAPPER_ALWAYS_USE_INTRINSIC_VERSION goto :after_local_version_detection + +call :find_project_context +if errorlevel 1 goto :after_local_version_detection +call :parse_project_context +if errorlevel 1 goto fail +:after_local_version_detection + +REM ********** Provision the Kotlin Toolchain distribution ********** + +set kotlin_cli_url=%KOTLIN_CLI_DOWNLOAD_ROOT%/org/jetbrains/kotlin/kotlin-cli/%kotlin_cli_version%/kotlin-cli-%kotlin_cli_version%-dist.tgz +set kotlin_cli_target_dir=%KOTLIN_CLI_BOOTSTRAP_CACHE_DIR%\kotlin-cli-%kotlin_cli_version% +call :download_and_extract "Kotlin Toolchain distribution v%kotlin_cli_version%" "%kotlin_cli_url%" "%kotlin_cli_target_dir%" "%kotlin_cli_sha256%" "256" "true" +if errorlevel 1 goto fail + +REM ********** Launch the Kotlin CLI ********** + +rem Determine the correct busybox binary based on architecture +if "%PROCESSOR_ARCHITECTURE%"=="ARM64" ( + set busybox_exe=%kotlin_cli_target_dir%\bin\busybox64a.exe +) else if "%PROCESSOR_ARCHITECTURE%"=="AMD64" ( + set busybox_exe=%kotlin_cli_target_dir%\bin\busybox64u.exe +) else ( + echo Unsupported architecture %PROCESSOR_ARCHITECTURE% >&2 + goto fail +) + +rem We use busybox here because it doesn't reinterpret the user-passed command-line arguments (that we pass via %*). +rem Also this way we can use the unified launcher script (.sh) +set KOTLIN_CLI_WRAPPER_PATH=%~f0 + +rem The '& call' after the app run is to avoid the "Terminate batch job (Y/N)?" prompt +"%busybox_exe%" sh "%kotlin_cli_target_dir%\bin\launcher.sh" %* & call :exitWithErrorLevel + +:exitWithErrorLevel +@rem We use "%COMSPEC%" /d /c exit so that and/or operators work properly when calling kotlin.bat directly from a script +@rem without the `call` command. With a plain `exit /B %ERRORLEVEL%`, using `kotlin.bat && echo success` would print +@rem 'success' even in case of failure. Consumers would have to use `call kotlin.bat && echo success` for it to work.` +"%COMSPEC%" /d /c exit %ERRORLEVEL% diff --git a/examples/codeviewer/libs.versions.toml b/examples/codeviewer/libs.versions.toml new file mode 100644 index 00000000000..331ceb6ec8e --- /dev/null +++ b/examples/codeviewer/libs.versions.toml @@ -0,0 +1,17 @@ +[versions] +androidx-activity = "1.13.0" +androidx-appcompat = "1.7.1" +androidx-core = "1.18.0" +compose-multiplatform = "1.12.1" +material-icons-extended = "1.7.3" + +[libraries] +androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" } +androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" } +androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core" } +compose-components-resources = { module = "org.jetbrains.compose.components:components-resources", version.ref = "compose-multiplatform" } +compose-foundation = { module = "org.jetbrains.compose.foundation:foundation", version.ref = "compose-multiplatform" } +compose-material = { module = "org.jetbrains.compose.material:material", version.ref = "compose-multiplatform" } +compose-runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "compose-multiplatform" } +compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "compose-multiplatform" } +material-icons-extended = { module = "org.jetbrains.compose.material:material-icons-extended", version.ref = "material-icons-extended" } diff --git a/examples/codeviewer/project.yaml b/examples/codeviewer/project.yaml new file mode 100644 index 00000000000..e056ef58ed4 --- /dev/null +++ b/examples/codeviewer/project.yaml @@ -0,0 +1,6 @@ +modules: + - androidApp + - desktopApp + - iosApp + - shared + - webApp diff --git a/examples/codeviewer/run-configurations.png b/examples/codeviewer/run-configurations.png deleted file mode 100644 index d859ff0870f..00000000000 Binary files a/examples/codeviewer/run-configurations.png and /dev/null differ diff --git a/examples/codeviewer/settings.gradle.kts b/examples/codeviewer/settings.gradle.kts deleted file mode 100644 index ca43bf2d371..00000000000 --- a/examples/codeviewer/settings.gradle.kts +++ /dev/null @@ -1,33 +0,0 @@ -pluginManagement { - repositories { - gradlePluginPortal() - maven("https://packages.jetbrains.team/maven/p/cmp/dev") - google() - } -} - -dependencyResolutionManagement { - repositories { - google() - mavenCentral() - maven("https://packages.jetbrains.team/maven/p/cmp/dev") - } - - versionCatalogs { - create("libs") { - version("kotlin", extra["kotlin.version"].toString()) - version("compose", extra["compose.version"].toString()) - version("agp", extra["agp.version"].toString()) - } - } -} - -plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version("1.0.0") -} - -rootProject.name = "codeviewer" - -include(":androidApp") -include(":shared") -include(":desktopApp") diff --git a/examples/codeviewer/shared/build.gradle.kts b/examples/codeviewer/shared/build.gradle.kts deleted file mode 100644 index a509d3b44ce..00000000000 --- a/examples/codeviewer/shared/build.gradle.kts +++ /dev/null @@ -1,63 +0,0 @@ -@file:Suppress("OPT_IN_IS_NOT_ENABLED") - -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - alias(libs.plugins.kotlinMultiplatform) - alias(libs.plugins.composeCompiler) - alias(libs.plugins.androidMultiplatformLibrary) - alias(libs.plugins.composeMultiplatform) -} - -version = "1.0-SNAPSHOT" - -kotlin { - jvm("desktop") - - listOf( - iosArm64(), - iosSimulatorArm64() - ).forEach { iosTarget -> - iosTarget.binaries.framework { - baseName = "shared" - isStatic = true - } - } - - android { - compileSdk { - version = release(37) { minorApiLevel = 1 } - } - namespace = "org.jetbrains.codeviewer.common" - minSdk = 26 - - compilerOptions { - jvmTarget = JvmTarget.JVM_17 - } - } - - sourceSets { - commonMain.dependencies { - implementation(libs.compose.runtime) - implementation(libs.compose.foundation) - implementation(libs.compose.material) - implementation(libs.material.icons.extended) - implementation(libs.components.resources) - } - androidMain { - kotlin { - srcDirs("src/jvmMain/kotlin") - } - dependencies { - api(libs.androidx.activity.compose) - api(libs.androidx.appcompat) - api(libs.androidx.core.ktx) - } - } - val desktopMain by getting { - kotlin { - srcDirs("src/jvmMain/kotlin") - } - } - } -} diff --git a/examples/codeviewer/shared/composeResources/files/EditorView.kt b/examples/codeviewer/shared/composeResources/files/EditorView.kt new file mode 100644 index 00000000000..8917e4c6035 --- /dev/null +++ b/examples/codeviewer/shared/composeResources/files/EditorView.kt @@ -0,0 +1,183 @@ +/** + * This file is an example (we can open it in iOS application) + */ + +package org.jetbrains.codeviewer.ui.editor + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.text.selection.DisableSelection +import androidx.compose.material.AmbientContentColor +import androidx.compose.material.CircularProgressIndicator +import androidx.compose.material.Surface +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.key +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.text.* +import androidx.compose.ui.unit.dp +import org.jetbrains.codeviewer.platform.SelectionContainer +import org.jetbrains.codeviewer.ui.common.AppTheme +import org.jetbrains.codeviewer.ui.common.Fonts +import org.jetbrains.codeviewer.ui.common.Settings +import org.jetbrains.codeviewer.util.loadableScoped +import org.jetbrains.codeviewer.util.withoutWidthConstraints +import kotlin.text.Regex.Companion.fromLiteral + +@Composable +fun EditorView(model: Editor, settings: Settings) = key(model) { + with (LocalDensity.current) { + SelectionContainer { + Surface( + Modifier.fillMaxSize(), + color = AppTheme.colors.backgroundDark, + ) { + val lines by loadableScoped(model.lines) + + if (lines != null) { + Box { + Lines(lines!!, settings) + Box( + Modifier + .offset( + x = settings.fontSize.toDp() * 0.5f * settings.maxLineSymbols + ) + .width(1.dp) + .fillMaxHeight() + .background(AppTheme.colors.codeGuide) + ) + } + } else { + CircularProgressIndicator( + modifier = Modifier + .size(36.dp) + .padding(4.dp) + ) + } + } + } + } +} + +@Composable +private fun Lines(lines: Editor.Lines, settings: Settings) = with(DensityAmbient.current) { + val maxNumber = remember(lines.lineNumberDigitCount) { + (1..lines.lineNumberDigitCount).joinToString(separator = "") { "9" } + } + + Box(Modifier.fillMaxSize()) { + val scrollState = rememberLazyListState() + val lineHeight = settings.fontSize.toDp() * 1.6f + + LazyColumnFor( + lines.size, + modifier = Modifier.fillMaxSize(), + state = scrollState, + itemContent = { index -> + val line: Editor.Line? by loadable { lines.get(index) } + Box(Modifier.height(lineHeight)) { + if (line != null) { + Line(Modifier.align(Alignment.CenterStart), maxNumber, line!!, settings) + } + } + } + ) + + VerticalScrollbar( + Modifier.align(Alignment.CenterEnd), + scrollState, + lines.size, + lineHeight + ) + } +} + +// Поддержка русского языка +// دعم اللغة العربية +// 中文支持 +@Composable +private fun Line(modifier: Modifier, maxNumber: String, line: Editor.Line, settings: Settings) { + Row(modifier = modifier) { + DisableSelection { + Box { + LineNumber(maxNumber, Modifier.alpha(0f), settings) + LineNumber(line.number.toString(), Modifier.align(Alignment.CenterEnd), settings) + } + } + LineContent( + line.content, + modifier = Modifier + .weight(1f) + .withoutWidthConstraints() + .padding(start = 28.dp, end = 12.dp), + settings = settings + ) + } +} + +@Composable +private fun LineNumber(number: String, modifier: Modifier, settings: Settings) = Text( + text = number, + fontSize = settings.fontSize, + fontFamily = Fonts.jetbrainsMono(), + color = AmbientContentColor.current.copy(alpha = 0.30f), + modifier = modifier.padding(start = 12.dp) +) + +@Composable +private fun LineContent(content: Editor.Content, modifier: Modifier, settings: Settings) = Text( + text = if (content.isCode) { + codeString(content.value.value) + } else { + AnnotatedString(content.value.value) + }, + fontSize = settings.fontSize, + fontFamily = Fonts.jetbrainsMono(), + modifier = modifier, + softWrap = false +) + +private fun codeString(str: String) = buildAnnotatedString { + withStyle(AppTheme.code.simple) { + append(str.replace("\t", " ")) + addStyle(AppTheme.code.punctuation, ":") + addStyle(AppTheme.code.punctuation, "=") + addStyle(AppTheme.code.punctuation, "\"") + addStyle(AppTheme.code.punctuation, "[") + addStyle(AppTheme.code.punctuation, "]") + addStyle(AppTheme.code.punctuation, "{") + addStyle(AppTheme.code.punctuation, "}") + addStyle(AppTheme.code.punctuation, "(") + addStyle(AppTheme.code.punctuation, ")") + addStyle(AppTheme.code.punctuation, ",") + addStyle(AppTheme.code.keyword, "fun ") + addStyle(AppTheme.code.keyword, "val ") + addStyle(AppTheme.code.keyword, "var ") + addStyle(AppTheme.code.keyword, "private ") + addStyle(AppTheme.code.keyword, "internal ") + addStyle(AppTheme.code.keyword, "for ") + addStyle(AppTheme.code.keyword, "expect ") + addStyle(AppTheme.code.keyword, "actual ") + addStyle(AppTheme.code.keyword, "import ") + addStyle(AppTheme.code.keyword, "package ") + addStyle(AppTheme.code.value, "true") + addStyle(AppTheme.code.value, "false") + addStyle(AppTheme.code.value, Regex("[0-9]*")) + addStyle(AppTheme.code.annotation, Regex("^@[a-zA-Z_]*")) + addStyle(AppTheme.code.comment, Regex("^\\s*//.*")) + } +} + +private fun AnnotatedString.Builder.addStyle(style: SpanStyle, regexp: String) { + addStyle(style, fromLiteral(regexp)) +} + +private fun AnnotatedString.Builder.addStyle(style: SpanStyle, regexp: Regex) { + for (result in regexp.findAll(toString())) { + addStyle(style, result.range.first, result.range.last + 1) + } +} \ No newline at end of file diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_bold.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_bold.ttf similarity index 100% rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_bold.ttf rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_bold.ttf diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_bold_italic.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_bold_italic.ttf similarity index 100% rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_bold_italic.ttf rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_bold_italic.ttf diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_extrabold.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_extrabold.ttf similarity index 100% rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_extrabold.ttf rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_extrabold.ttf diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_extrabold_italic.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_extrabold_italic.ttf similarity index 100% rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_extrabold_italic.ttf rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_extrabold_italic.ttf diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_italic.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_italic.ttf similarity index 100% rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_italic.ttf rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_italic.ttf diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_medium.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_medium.ttf similarity index 100% rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_medium.ttf rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_medium.ttf diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_medium_italic.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_medium_italic.ttf similarity index 100% rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_medium_italic.ttf rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_medium_italic.ttf diff --git a/examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_regular.ttf b/examples/codeviewer/shared/composeResources/font/jetbrainsmono_regular.ttf similarity index 100% rename from examples/codeviewer/shared/src/commonMain/composeResources/font/jetbrainsmono_regular.ttf rename to examples/codeviewer/shared/composeResources/font/jetbrainsmono_regular.ttf diff --git a/examples/codeviewer/shared/module.yaml b/examples/codeviewer/shared/module.yaml new file mode 100644 index 00000000000..f5701d43cc3 --- /dev/null +++ b/examples/codeviewer/shared/module.yaml @@ -0,0 +1,28 @@ +product: + type: kmp/lib + platforms: [android, iosArm64, iosSimulatorArm64, jvm, wasmJs] + +aliases: + - jvmAndAndroid: [jvm, android] + +dependencies: + - $libs.compose.runtime + - $libs.compose.foundation + - $libs.compose.material + - $libs.compose.components.resources + - $libs.material.icons.extended + +dependencies@android: + - $libs.androidx.activity.compose: exported + - $libs.androidx.appcompat: exported + - $libs.androidx.core.ktx: exported + +settings: + compose: + enabled: true + resources: + packageName: codeviewer.shared.generated.resources + android: + namespace: org.jetbrains.codeviewer.common + minSdk: 26 + diff --git a/examples/codeviewer/shared/src/androidMain/AndroidManifest.xml b/examples/codeviewer/shared/src/androidMain/AndroidManifest.xml deleted file mode 100644 index 568741e54f2..00000000000 --- a/examples/codeviewer/shared/src/androidMain/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/File.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/platform/File.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/File.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/platform/File.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/platform/Mouse.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/platform/Mouse.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/platform/Scrollbar.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/platform/Scrollbar.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/CodeViewer.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/CodeViewer.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/CodeViewer.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/CodeViewer.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/CodeViewerView.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/CodeViewerView.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/CodeViewerView.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/CodeViewerView.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/MainView.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/MainView.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/MainView.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/MainView.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/common/Fonts.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/common/Fonts.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/common/Fonts.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/common/Fonts.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/common/Settings.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/common/Settings.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/common/Settings.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/common/Settings.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/common/Theme.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/common/Theme.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/common/Theme.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/common/Theme.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/Editor.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/Editor.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/Editor.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/Editor.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorEmptyView.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/EditorEmptyView.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorEmptyView.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/EditorEmptyView.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorTabsView.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/EditorTabsView.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorTabsView.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/EditorTabsView.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorView.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/EditorView.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorView.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/EditorView.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/Editors.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/Editors.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/Editors.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/editor/Editors.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/filetree/FileTree.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/filetree/FileTree.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/filetree/FileTree.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/filetree/FileTree.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/filetree/FileTreeView.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/filetree/FileTreeView.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/filetree/FileTreeView.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/filetree/FileTreeView.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/statusbar/StatusBar.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/statusbar/StatusBar.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/statusbar/StatusBar.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/ui/statusbar/StatusBar.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/LayoutModifiers.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/LayoutModifiers.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/LayoutModifiers.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/LayoutModifiers.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/Loadable.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/Loadable.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/Loadable.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/Loadable.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/SingleSelection.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/SingleSelection.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/SingleSelection.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/SingleSelection.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/TextLines.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/TextLines.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/TextLines.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/TextLines.kt diff --git a/examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/VerticalSplittable.kt b/examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/VerticalSplittable.kt similarity index 100% rename from examples/codeviewer/shared/src/commonMain/kotlin/org/jetbrains/codeviewer/util/VerticalSplittable.kt rename to examples/codeviewer/shared/src/org/jetbrains/codeviewer/util/VerticalSplittable.kt diff --git a/examples/codeviewer/shared/src/androidMain/kotlin/main.android.kt b/examples/codeviewer/shared/src@android/main.android.kt similarity index 100% rename from examples/codeviewer/shared/src/androidMain/kotlin/main.android.kt rename to examples/codeviewer/shared/src@android/main.android.kt diff --git a/examples/codeviewer/shared/src/androidMain/kotlin/org/jetbrains/codeviewer/platform/File.kt b/examples/codeviewer/shared/src@android/org/jetbrains/codeviewer/platform/File.kt similarity index 100% rename from examples/codeviewer/shared/src/androidMain/kotlin/org/jetbrains/codeviewer/platform/File.kt rename to examples/codeviewer/shared/src@android/org/jetbrains/codeviewer/platform/File.kt diff --git a/examples/codeviewer/shared/src/androidMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt b/examples/codeviewer/shared/src@android/org/jetbrains/codeviewer/platform/Mouse.kt similarity index 100% rename from examples/codeviewer/shared/src/androidMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt rename to examples/codeviewer/shared/src@android/org/jetbrains/codeviewer/platform/Mouse.kt diff --git a/examples/codeviewer/shared/src/androidMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt b/examples/codeviewer/shared/src@android/org/jetbrains/codeviewer/platform/Scrollbar.kt similarity index 100% rename from examples/codeviewer/shared/src/androidMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt rename to examples/codeviewer/shared/src@android/org/jetbrains/codeviewer/platform/Scrollbar.kt diff --git a/examples/codeviewer/shared/src/iosMain/kotlin/org/jetbrains/codeviewer/platform/File.kt b/examples/codeviewer/shared/src@ios/org/jetbrains/codeviewer/platform/File.kt similarity index 95% rename from examples/codeviewer/shared/src/iosMain/kotlin/org/jetbrains/codeviewer/platform/File.kt rename to examples/codeviewer/shared/src@ios/org/jetbrains/codeviewer/platform/File.kt index 2a1dee9218d..a45227e3145 100644 --- a/examples/codeviewer/shared/src/iosMain/kotlin/org/jetbrains/codeviewer/platform/File.kt +++ b/examples/codeviewer/shared/src@ios/org/jetbrains/codeviewer/platform/File.kt @@ -34,7 +34,7 @@ actual val HomeFolder: File get() = VirtualFile("files", VirtualFile("EditorView.kt", isDirectory = false, textLines = runBlocking { - Res.readBytes("EditorView.kt") + Res.readBytes("files/EditorView.kt") }.toTextLines() ) ) diff --git a/examples/codeviewer/shared/src/iosMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt b/examples/codeviewer/shared/src@ios/org/jetbrains/codeviewer/platform/Mouse.kt similarity index 100% rename from examples/codeviewer/shared/src/iosMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt rename to examples/codeviewer/shared/src@ios/org/jetbrains/codeviewer/platform/Mouse.kt diff --git a/examples/codeviewer/shared/src/iosMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt b/examples/codeviewer/shared/src@ios/org/jetbrains/codeviewer/platform/Scrollbar.kt similarity index 100% rename from examples/codeviewer/shared/src/iosMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt rename to examples/codeviewer/shared/src@ios/org/jetbrains/codeviewer/platform/Scrollbar.kt diff --git a/examples/codeviewer/shared/src/desktopMain/kotlin/main.desktop.kt b/examples/codeviewer/shared/src@jvm/main.desktop.kt similarity index 100% rename from examples/codeviewer/shared/src/desktopMain/kotlin/main.desktop.kt rename to examples/codeviewer/shared/src@jvm/main.desktop.kt diff --git a/examples/codeviewer/shared/src/desktopMain/kotlin/org/jetbrains/codeviewer/platform/File.kt b/examples/codeviewer/shared/src@jvm/org/jetbrains/codeviewer/platform/File.kt similarity index 100% rename from examples/codeviewer/shared/src/desktopMain/kotlin/org/jetbrains/codeviewer/platform/File.kt rename to examples/codeviewer/shared/src@jvm/org/jetbrains/codeviewer/platform/File.kt diff --git a/examples/codeviewer/shared/src/desktopMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt b/examples/codeviewer/shared/src@jvm/org/jetbrains/codeviewer/platform/Mouse.kt similarity index 100% rename from examples/codeviewer/shared/src/desktopMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt rename to examples/codeviewer/shared/src@jvm/org/jetbrains/codeviewer/platform/Mouse.kt diff --git a/examples/codeviewer/shared/src/desktopMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt b/examples/codeviewer/shared/src@jvm/org/jetbrains/codeviewer/platform/Scrollbar.kt similarity index 100% rename from examples/codeviewer/shared/src/desktopMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt rename to examples/codeviewer/shared/src@jvm/org/jetbrains/codeviewer/platform/Scrollbar.kt diff --git a/examples/codeviewer/shared/src/jvmMain/kotlin/org/jetbrains/codeviewer/platform/JvmFile.kt b/examples/codeviewer/shared/src@jvmAndAndroid/org/jetbrains/codeviewer/platform/JvmFile.kt similarity index 100% rename from examples/codeviewer/shared/src/jvmMain/kotlin/org/jetbrains/codeviewer/platform/JvmFile.kt rename to examples/codeviewer/shared/src@jvmAndAndroid/org/jetbrains/codeviewer/platform/JvmFile.kt diff --git a/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/File.kt b/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/File.kt new file mode 100644 index 00000000000..595b847a9a8 --- /dev/null +++ b/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/File.kt @@ -0,0 +1,52 @@ +package org.jetbrains.codeviewer.platform + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import codeviewer.shared.generated.resources.Res +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import org.jetbrains.codeviewer.util.EmptyTextLines +import org.jetbrains.codeviewer.util.TextLines + +class VirtualFolder(override val name: String, override val children: List) : File { + override val isDirectory: Boolean + get() = true + + override val hasChildren: Boolean + get() = children.isNotEmpty() + + override fun readLines(scope: CoroutineScope): TextLines = EmptyTextLines +} + +class ResourceFile(override val name: String, private val path: String) : File { + override val isDirectory: Boolean + get() = false + + override val children: List + get() = emptyList() + + override val hasChildren: Boolean + get() = false + + // Resources are fetched over the network on the web, so lines are loaded in background + override fun readLines(scope: CoroutineScope): TextLines { + var lines by mutableStateOf(emptyList()) + + scope.launch { + lines = Res.readBytes(path).decodeToString().split("\n") + } + + return object : TextLines { + override val size get() = lines.size + + override fun get(index: Int): String = lines[index] + } + } +} + +actual val HomeFolder: File get() = VirtualFolder("files", + children = listOf( + ResourceFile("EditorView.kt", "files/EditorView.kt") + ) +) diff --git a/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/Mouse.kt b/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/Mouse.kt new file mode 100644 index 00000000000..3a8174f63cf --- /dev/null +++ b/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/Mouse.kt @@ -0,0 +1,5 @@ +package org.jetbrains.codeviewer.platform + +import androidx.compose.ui.Modifier + +actual fun Modifier.cursorForHorizontalResize(): Modifier = this diff --git a/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/Scrollbar.kt b/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/Scrollbar.kt new file mode 100644 index 00000000000..c8af7f095c3 --- /dev/null +++ b/examples/codeviewer/shared/src@wasmJs/org/jetbrains/codeviewer/platform/Scrollbar.kt @@ -0,0 +1,25 @@ +package org.jetbrains.codeviewer.platform + +import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.rememberScrollbarAdapter +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +@Composable +actual fun VerticalScrollbar( + modifier: Modifier, + scrollState: ScrollState +) = androidx.compose.foundation.VerticalScrollbar( + rememberScrollbarAdapter(scrollState), + modifier +) + +@Composable +actual fun VerticalScrollbar( + modifier: Modifier, + scrollState: LazyListState +) = androidx.compose.foundation.VerticalScrollbar( + rememberScrollbarAdapter(scrollState), + modifier +) \ No newline at end of file diff --git a/examples/codeviewer/webApp/module.yaml b/examples/codeviewer/webApp/module.yaml new file mode 100644 index 00000000000..f6bb0a65c3f --- /dev/null +++ b/examples/codeviewer/webApp/module.yaml @@ -0,0 +1,8 @@ +product: wasm-js/app + +dependencies: + - //shared + - $libs.compose.ui + +settings: + compose: enabled diff --git a/examples/codeviewer/webApp/resources/index.html b/examples/codeviewer/webApp/resources/index.html new file mode 100644 index 00000000000..de4f11d9af2 --- /dev/null +++ b/examples/codeviewer/webApp/resources/index.html @@ -0,0 +1,20 @@ + + + + + + Code Viewer + + + +{{kotlin.scripts}} + + diff --git a/examples/codeviewer/webApp/src/org/jetbrains/codeviewer/main.kt b/examples/codeviewer/webApp/src/org/jetbrains/codeviewer/main.kt new file mode 100644 index 00000000000..587b61b408b --- /dev/null +++ b/examples/codeviewer/webApp/src/org/jetbrains/codeviewer/main.kt @@ -0,0 +1,10 @@ +package org.jetbrains.codeviewer + +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.window.ComposeViewport +import org.jetbrains.codeviewer.ui.MainView + +@OptIn(ExperimentalComposeUiApi::class) +fun main() = ComposeViewport { + MainView() +} diff --git a/examples/html/compose-in-js/build.gradle.kts b/examples/html/compose-in-js/build.gradle.kts index a49d05e325a..4baf71022ca 100644 --- a/examples/html/compose-in-js/build.gradle.kts +++ b/examples/html/compose-in-js/build.gradle.kts @@ -30,7 +30,7 @@ kotlin { sourceSets { val jsMain by getting { dependencies { - implementation(compose.web.core) + implementation(compose.html.core) implementation(compose.runtime) } } diff --git a/examples/validateExamples.sh b/examples/validateExamples.sh index e398a58cb88..09fe752335c 100755 --- a/examples/validateExamples.sh +++ b/examples/validateExamples.sh @@ -19,6 +19,8 @@ if [ "$#" -eq 2 ]; then version_args=("-Pcompose.version=$1" "-Pkotlin.version=$2") fi +compose_version="${1:-}" +kotlin_version="${2:-}" runGradle() { local example="$1" @@ -32,8 +34,14 @@ runGradle() { popd } +runKotlin() { + local example="$1" + local platform="$2" + ./buildWithKotlinToolchain.sh "$example" "$platform" "$compose_version" "$kotlin_version" +} + runGradle chat packageDistributionForCurrentOS -runGradle codeviewer packageDistributionForCurrentOS +runKotlin codeviewer jvm runGradle imageviewer packageDistributionForCurrentOS runGradle issues packageDistributionForCurrentOS runGradle graphics-2d packageDistributionForCurrentOS diff --git a/examples/validateExamplesAndroid.sh b/examples/validateExamplesAndroid.sh index aeab9104b7d..46f6c5732e1 100755 --- a/examples/validateExamplesAndroid.sh +++ b/examples/validateExamplesAndroid.sh @@ -19,6 +19,8 @@ if [ "$#" -eq 2 ]; then version_args=("-Pcompose.version=$1" "-Pkotlin.version=$2") fi +compose_version="${1:-}" +kotlin_version="${2:-}" runGradle() { local example="$1" @@ -32,8 +34,14 @@ runGradle() { popd } +runKotlin() { + local example="$1" + local platform="$2" + ./buildWithKotlinToolchain.sh "$example" "$platform" "$compose_version" "$kotlin_version" +} + runGradle chat assembleDebug -runGradle codeviewer assembleDebug +runKotlin codeviewer android runGradle imageviewer assembleDebug runGradle issues assembleDebug runGradle graphics-2d assembleDebug diff --git a/examples/validateExamplesIos.sh b/examples/validateExamplesIos.sh index 5fd23b337d6..7d19d54720b 100755 --- a/examples/validateExamplesIos.sh +++ b/examples/validateExamplesIos.sh @@ -19,6 +19,8 @@ if [ "$#" -eq 2 ]; then version_args=("-Pcompose.version=$1" "-Pkotlin.version=$2") fi +compose_version="${1:-}" +kotlin_version="${2:-}" runGradle() { local example="$1" @@ -32,7 +34,13 @@ runGradle() { popd } +runKotlin() { + local example="$1" + local platform="$2" + ./buildWithKotlinToolchain.sh "$example" "$platform" "$compose_version" "$kotlin_version" +} + runGradle chat -runGradle codeviewer +runKotlin codeviewer iosSimulatorArm64 runGradle imageviewer runGradle graphics-2d diff --git a/examples/validateExamplesWithJs.sh b/examples/validateExamplesWithJs.sh index 5636a251556..af9e12910f9 100755 --- a/examples/validateExamplesWithJs.sh +++ b/examples/validateExamplesWithJs.sh @@ -19,6 +19,8 @@ if [ "$#" -eq 2 ]; then version_args=("-Pcompose.version=$1" "-Pkotlin.version=$2") fi +compose_version="${1:-}" +kotlin_version="${2:-}" runGradle() { local example="$1" @@ -32,7 +34,18 @@ runGradle() { popd } +runKotlin() { + local example="$1" + local platform="$2" + ./buildWithKotlinToolchain.sh "$example" "$platform" "$compose_version" "$kotlin_version" +} + runGradle html/compose-bird build +runGradle html/compose-in-js build runGradle html/landing build runGradle html/with-react build +runGradle chat :jsApp:jsBrowserDistribution +runGradle graphics-2d :jsApp:jsBrowserDistribution runGradle imageviewer :webApp:wasmJsBrowserDistribution +runGradle nav_cupcake :webApp:wasmJsBrowserDistribution +runKotlin codeviewer wasmJs