Showing preview only (490K chars total). Download the full file or copy to clipboard to get everything.
Repository: JyAether/Aether
Branch: main
Commit: 067addb978aa
Files: 112
Total size: 442.6 KB
Directory structure:
gitextract_t7d67c2l/
├── .fleet/
│ └── receipt.json
├── .gitignore
├── README.md
├── annotations/
│ ├── build.gradle.kts
│ └── src/
│ └── main/
│ └── java/
│ └── com/
│ └── aether/
│ └── annotations/
│ ├── ComposeMirror.kt
│ └── Reflectable.kt
├── build.gradle.kts
├── composeApp/
│ ├── build.gradle.kts
│ └── src/
│ ├── androidMain/
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin/
│ │ │ ├── Myapplicaton.kt
│ │ │ └── org/
│ │ │ └── example/
│ │ │ └── project/
│ │ │ ├── MainActivity.kt
│ │ │ └── Platform.android.kt
│ │ └── res/
│ │ ├── drawable/
│ │ │ └── ic_launcher_background.xml
│ │ ├── drawable-v24/
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── mipmap-anydpi-v26/
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ └── values/
│ │ └── strings.xml
│ ├── commonMain/
│ │ ├── composeResources/
│ │ │ └── drawable/
│ │ │ └── compose-multiplatform.xml
│ │ └── kotlin/
│ │ └── org/
│ │ └── example/
│ │ └── project/
│ │ ├── App.kt
│ │ ├── Greeting.kt
│ │ └── Platform.kt
│ ├── iosMain/
│ │ └── kotlin/
│ │ └── org/
│ │ └── example/
│ │ └── project/
│ │ ├── MainViewController.kt
│ │ └── Platform.ios.kt
│ └── main/
│ ├── AndroidManifest.xml
│ └── java/
│ └── com/
│ └── aether/
│ └── composeapp/
│ └── example/
│ └── ReflectableExample.kt
├── core/
│ ├── .gitignore
│ ├── build.gradle.kts
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── aether/
│ │ └── core/
│ │ └── runtime/
│ │ └── ExampleInstrumentedTest.kt
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── assets/
│ │ │ ├── test0_compose.json
│ │ │ └── test1_compose.json
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── aether/
│ │ │ └── core/
│ │ │ └── runtime/
│ │ │ ├── AppContextManager.kt
│ │ │ ├── AstRuntime.kt
│ │ │ ├── ClassMirror.kt
│ │ │ ├── KtAstVisitor.kt
│ │ │ ├── Node.kt
│ │ │ ├── ProgramStack.kt
│ │ │ ├── ProjectHelper.kt
│ │ │ ├── Structs.kt
│ │ │ ├── StructsImpl.kt
│ │ │ ├── context.kt
│ │ │ ├── deliver/
│ │ │ │ ├── TemplateProvider.kt
│ │ │ │ └── binding.kt
│ │ │ ├── entity/
│ │ │ │ └── SimpleMember.kt
│ │ │ ├── mirror/
│ │ │ │ └── MirrorHelper.kt
│ │ │ ├── proxy/
│ │ │ │ └── ProxyBinding.kt
│ │ │ ├── reflectable/
│ │ │ │ ├── ClassMirror.kt
│ │ │ │ ├── ClassMirrorBase.kt
│ │ │ │ ├── ComposeComponentDescriptor.kt
│ │ │ │ ├── ComposeComponentRegistry.kt
│ │ │ │ ├── ComposeMirror.kt
│ │ │ │ ├── ComposeMirrorRuntime.kt
│ │ │ │ ├── ComposeReflectRuntime.kt
│ │ │ │ ├── DeclarationMirror.kt
│ │ │ │ ├── MethodMirrorImpl.kt
│ │ │ │ ├── Mirror.kt
│ │ │ │ ├── ParamInfo.kt
│ │ │ │ └── widgets/
│ │ │ │ ├── ColumnMirror.kt
│ │ │ │ ├── MaterialThemeMirror.kt
│ │ │ │ ├── TextMirror.kt
│ │ │ │ ├── TextStyleMirror.kt
│ │ │ │ └── TypographyMirror.kt
│ │ │ └── utils/
│ │ │ └── JsonReader.kt
│ │ └── res/
│ │ ├── drawable/
│ │ │ ├── ic_launcher_background.xml
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── mipmap-anydpi/
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── themes.xml
│ │ └── values-night/
│ │ └── themes.xml
│ └── test/
│ └── java/
│ └── com/
│ └── aether/
│ └── core/
│ ├── ExampleUnitTest.kt
│ ├── compose/
│ │ ├── ColumArgsComposeExpressText.kt
│ │ ├── ColumComposeNameExpressText.kt
│ │ ├── DemoCompose.kt
│ │ ├── DemoComposeColor.kt
│ │ └── NameExpressComposeNameExpressText.kt
│ ├── express/
│ │ ├── ArgsComposeTest.kt
│ │ ├── ColumArgsExpressComposeTest.kt
│ │ ├── ColumExpressComposeTest.kt
│ │ ├── DemoEmptyFunctionExpress.kt
│ │ ├── DemoFunctionExpress.kt
│ │ ├── DemoTest.kt
│ │ ├── InstanceComposeTest.kt
│ │ ├── InstanceCreationExpressionTest.kt
│ │ ├── InstanceJsonEmptyCreationExpressionTest.kt
│ │ ├── InstanceTest.kt
│ │ └── NameExpressComposeTest.kt
│ └── runtime/
│ └── ExampleUnitTest.kt
├── gradle/
│ ├── libs.versions.toml
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── iosApp/
│ ├── Configuration/
│ │ └── Config.xcconfig
│ ├── iosApp/
│ │ ├── Assets.xcassets/
│ │ │ ├── AccentColor.colorset/
│ │ │ │ └── Contents.json
│ │ │ ├── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── ContentView.swift
│ │ ├── Info.plist
│ │ ├── Preview Content/
│ │ │ └── Preview Assets.xcassets/
│ │ │ └── Contents.json
│ │ └── iOSApp.swift
│ └── iosApp.xcodeproj/
│ └── project.pbxproj
├── processor/
│ ├── build.gradle.kts
│ └── src/
│ └── main/
│ ├── java/
│ │ └── com/
│ │ └── aether/
│ │ └── processor/
│ │ ├── ComposeMirrorProcessor.kt
│ │ ├── ComposeMirrorProcessor2.kt
│ │ ├── ComposeReflectProcessor.kt
│ │ └── ReflectableProcessor.kt
│ └── resources/
│ └── META-INF/
│ └── services/
│ └── com.google.devtools.ksp.processing.SymbolProcessorProvider
└── settings.gradle.kts
================================================
FILE CONTENTS
================================================
================================================
FILE: .fleet/receipt.json
================================================
// Project generated by Kotlin Multiplatform Wizard
{
"spec": {
"template_id": "kmt",
"targets": {
"android": {
"ui": [
"compose"
]
},
"ios": {
"ui": [
"compose"
]
}
}
},
"timestamp": "2025-04-06T08:25:58.346564588Z"
}
================================================
FILE: .gitignore
================================================
*.iml
.kotlin
.gradle
**/build/
xcuserdata
!src/**/build/
local.properties
.idea
.DS_Store
captures
.externalNativeBuild
.cxx
*.xcodeproj/*
!*.xcodeproj/project.pbxproj
!*.xcodeproj/xcshareddata/
!*.xcodeproj/project.xcworkspace/
!*.xcworkspace/contents.xcworkspacedata
**/xcshareddata/WorkspaceSettings.xcsettings
================================================
FILE: README.md
================================================
**一、介绍**
* **Aether**:业内首次创新性基于 AST + Runtime 构建 KMP + CMP 的动态化方案,实现逻辑页面动态下发。
* 全流程覆盖开发至运维。提升发版效率与热修复能力,有效缓解 KMP 缺失的动态化,可大范围推动 Android KMP 的生态发展。
* 但因为个人精力有限,还有很多工程化的能力需要建设,期待社区一起未来后续将强化复杂语法支持与生态建设,降低开发成本、优化体验并扩大业务覆盖;推进大前端融合,实现跨终端一致性体验。
* 目前实现最小的实验原型,后续依赖于社区一起建设。
---
**二、项目结构**
* `/composeApp` 是用于在 Compose Multiplatform 应用程序之间共享代码的部分。
它包含以下几个子文件夹:
- `commonMain` 用于所有目标平台通用的代码。
- 其他文件夹是针对特定平台编译的 Kotlin 代码。例如,如果你想在 iOS 部分使用 Apple 的 CoreCrypto,
则应该在 `iosMain` 文件夹中编写相关调用。
* `/iosApp` 包含 iOS 应用程序。即使你通过 Compose Multiplatform 共享 UI,
你仍然需要这个入口点来启动你的 iOS 应用。这也是你添加 SwiftUI 代码的地方。
* `/core` 模块是 Aether 的核心模块。
git
---
**三、挑战**
* 工作量巨大,需要保持耐心,笔者在业余时间进行探索,几乎已经投入全部时间。
* 项目较为复杂,核心链路虽然跑通了,但是一些复杂的语法还未支持,需要保持一定耐心去兼容。之所以开源出来也是希望依赖于社区同学一起投入进来。
* 因为牵扯到 AST 和 DSL 的转换和解析执行虚拟机的加载,对于排查问题有一定的门槛,边界异常逻辑处理需要后继者更为注意。
---
================================================
FILE: annotations/build.gradle.kts
================================================
plugins {
kotlin("jvm")
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlin {
jvmToolchain(17)
}
dependencies {
implementation(kotlin("stdlib"))
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions {
jvmTarget = "17"
}
}
================================================
FILE: annotations/src/main/java/com/aether/annotations/ComposeMirror.kt
================================================
package com.aether.annotations
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.SOURCE)
annotation class ComposeMirror
================================================
FILE: annotations/src/main/java/com/aether/annotations/Reflectable.kt
================================================
package com.aether.annotations
/**
* 用于标记可反射的Compose组件类
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.SOURCE)
annotation class Reflectable(
val name: String = "",
val description: String = ""
)
/**
* 用于标记可反射的Compose函数
*/
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.SOURCE)
annotation class ReflectableFunction(
val name: String = "",
val description: String = ""
)
// 标记要生成反射元数据的注解
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
annotation class GenerateMirror
================================================
FILE: build.gradle.kts
================================================
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.androidLibrary) apply false
alias(libs.plugins.composeMultiplatform) apply false
alias(libs.plugins.kotlinMultiplatform) apply false
alias(libs.plugins.kotlinAndroid) apply false
}
================================================
FILE: composeApp/build.gradle.kts
================================================
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
import org.jetbrains.compose.ExperimentalComposeLibrary
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidApplication)
alias(libs.plugins.composeMultiplatform)
}
configurations.implementation {
exclude(group = "org.jetbrains", module = "annotations")
}
kotlin {
android {
compilations.all {
kotlinOptions {
jvmTarget = "17"
}
}
}
sourceSets {
val androidMain by getting {
dependencies {
implementation(compose.preview)
implementation(libs.androidx.activity.compose)
}
}
@OptIn(ExperimentalComposeLibrary::class)
val commonMain by getting {
dependencies {
implementation(project(":core"))
implementation(project(":annotations"))
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(compose.preview)
implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.lifecycle.runtime.compose)
}
}
}
}
android {
namespace = "org.example.project"
compileSdk = 34
defaultConfig {
applicationId = "org.example.project"
minSdk = libs.versions.android.minSdk.get().toInt()
targetSdk = 34
versionCode = 1
versionName = "1.0"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
packagingOptions {
resources.excludes.add("kotlin/reflect/reflect.kotlin_builtins")
resources.excludes.add("kotlin/internal/internal.kotlin_builtins")
resources.excludes.add("kotlin/kotlin.kotlin_builtins")
resources.excludes.add("kotlin/coroutines/coroutines.kotlin_builtins")
resources.excludes.add("kotlin/ranges/ranges.kotlin_builtins")
resources.excludes.add("kotlin/collections/collections.kotlin_builtins")
resources.excludes.add("kotlin/annotation/annotation.kotlin_builtins")
excludes.addAll(listOf(
"META-INF/DEPENDENCIES",
"META-INF/LICENSE",
"META-INF/LICENSE.txt",
"META-INF/NOTICE",
"META-INF/NOTICE.txt",
"META-INF/ASL2.0"
))
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
buildToolsVersion = "34.0.0"
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.8.22")
debugImplementation(compose.uiTooling)
implementation(compose.ui)
implementation(compose.preview)
implementation(project(":annotations"))
implementation(project(":core"))
}
================================================
FILE: composeApp/src/androidMain/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name="MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher_test"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_test"
android:supportsRtl="true"
tools:replace="android:theme"
android:theme="@android:style/Theme.Material.Light.NoActionBar">
<activity
android:exported="true"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|mnc|colorMode|density|fontScale|fontWeightAdjustment|keyboard|layoutDirection|locale|mcc|navigation|smallestScreenSize|touchscreen|uiMode"
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: composeApp/src/androidMain/kotlin/Myapplicaton.kt
================================================
package org.example.project
import android.app.Application
import com.aether.core.runtime.reflectable.ComposeComponentFactory.initializeComposeMirrors
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// 初始化 Compose 镜像反射系统
initializeComposeMirrors()
// 其他初始化代码...
}
}
================================================
FILE: composeApp/src/androidMain/kotlin/org/example/project/MainActivity.kt
================================================
package org.example.project
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import com.aether.core.runtime.deliver.ExampleUsage
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
// App()
ExampleUsage()
}
}
}
@Preview
@Composable
fun AppAndroidPreview() {
App()
}
================================================
FILE: composeApp/src/androidMain/kotlin/org/example/project/Platform.android.kt
================================================
package org.example.project
import android.os.Build
class AndroidPlatform : Platform {
override val name: String = "Android ${Build.VERSION.SDK_INT}"
}
actual fun getPlatform(): Platform = AndroidPlatform()
================================================
FILE: composeApp/src/androidMain/res/drawable/ic_launcher_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>
================================================
FILE: composeApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
================================================
FILE: composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
================================================
FILE: composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
================================================
FILE: composeApp/src/androidMain/res/values/strings.xml
================================================
<resources>
<string name="app_name">KotlinProject</string>
</resources>
================================================
FILE: composeApp/src/commonMain/composeResources/drawable/compose-multiplatform.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="600dp"
android:height="600dp"
android:viewportWidth="600"
android:viewportHeight="600">
<path
android:pathData="M301.21,418.53C300.97,418.54 300.73,418.56 300.49,418.56C297.09,418.59 293.74,417.72 290.79,416.05L222.6,377.54C220.63,376.43 219,374.82 217.85,372.88C216.7,370.94 216.09,368.73 216.07,366.47L216.07,288.16C216.06,287.32 216.09,286.49 216.17,285.67C216.38,283.54 216.91,281.5 217.71,279.6L199.29,268.27L177.74,256.19C175.72,260.43 174.73,265.23 174.78,270.22L174.79,387.05C174.85,393.89 178.57,400.2 184.53,403.56L286.26,461.02C290.67,463.51 295.66,464.8 300.73,464.76C300.91,464.76 301.09,464.74 301.27,464.74C301.24,449.84 301.22,439.23 301.22,439.23L301.21,418.53Z"
android:fillColor="#041619"
android:fillType="nonZero"/>
<path
android:pathData="M409.45,242.91L312.64,188.23C303.64,183.15 292.58,183.26 283.68,188.51L187.92,245C183.31,247.73 179.93,251.62 177.75,256.17L177.74,256.19L199.29,268.27L217.71,279.6C217.83,279.32 217.92,279.02 218.05,278.74C218.24,278.36 218.43,277.98 218.64,277.62C219.06,276.88 219.52,276.18 220.04,275.51C221.37,273.8 223.01,272.35 224.87,271.25L289.06,233.39C290.42,232.59 291.87,231.96 293.39,231.51C295.53,230.87 297.77,230.6 300,230.72C302.98,230.88 305.88,231.73 308.47,233.2L373.37,269.85C375.54,271.08 377.49,272.68 379.13,274.57C379.68,275.19 380.18,275.85 380.65,276.53C380.86,276.84 381.05,277.15 381.24,277.47L397.79,266.39L420.34,252.93L420.31,252.88C417.55,248.8 413.77,245.35 409.45,242.91Z"
android:fillColor="#37BF6E"
android:fillType="nonZero"/>
<path
android:pathData="M381.24,277.47C381.51,277.92 381.77,278.38 382.01,278.84C382.21,279.24 382.39,279.65 382.57,280.06C382.91,280.88 383.19,281.73 383.41,282.59C383.74,283.88 383.92,285.21 383.93,286.57L383.93,361.1C383.96,363.95 383.35,366.77 382.16,369.36C381.93,369.86 381.69,370.35 381.42,370.83C379.75,373.79 377.32,376.27 374.39,378L310.2,415.87C307.47,417.48 304.38,418.39 301.21,418.53L301.22,439.23C301.22,439.23 301.24,449.84 301.27,464.74C306.1,464.61 310.91,463.3 315.21,460.75L410.98,404.25C419.88,399 425.31,389.37 425.22,379.03L425.22,267.85C425.17,262.48 423.34,257.34 420.34,252.93L397.79,266.39L381.24,277.47Z"
android:fillColor="#3870B2"
android:fillType="nonZero"/>
<path
android:pathData="M177.75,256.17C179.93,251.62 183.31,247.73 187.92,245L283.68,188.51C292.58,183.26 303.64,183.15 312.64,188.23L409.45,242.91C413.77,245.35 417.55,248.8 420.31,252.88L420.34,252.93L498.59,206.19C494.03,199.46 487.79,193.78 480.67,189.75L320.86,99.49C306.01,91.1 287.75,91.27 273.07,99.95L114.99,193.2C107.39,197.69 101.81,204.11 98.21,211.63L177.74,256.19L177.75,256.17ZM301.27,464.74C301.09,464.74 300.91,464.76 300.73,464.76C295.66,464.8 290.67,463.51 286.26,461.02L184.53,403.56C178.57,400.2 174.85,393.89 174.79,387.05L174.78,270.22C174.73,265.23 175.72,260.43 177.74,256.19L98.21,211.63C94.86,218.63 93.23,226.58 93.31,234.82L93.31,427.67C93.42,438.97 99.54,449.37 109.4,454.92L277.31,549.77C284.6,553.88 292.84,556.01 301.2,555.94L301.2,555.8C301.39,543.78 301.33,495.26 301.27,464.74Z"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#083042"
android:fillType="nonZero"/>
<path
android:pathData="M498.59,206.19L420.34,252.93C423.34,257.34 425.17,262.48 425.22,267.85L425.22,379.03C425.31,389.37 419.88,399 410.98,404.25L315.21,460.75C310.91,463.3 306.1,464.61 301.27,464.74C301.33,495.26 301.39,543.78 301.2,555.8L301.2,555.94C309.48,555.87 317.74,553.68 325.11,549.32L483.18,456.06C497.87,447.39 506.85,431.49 506.69,414.43L506.69,230.91C506.6,222.02 503.57,213.5 498.59,206.19Z"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#083042"
android:fillType="nonZero"/>
<path
android:pathData="M301.2,555.94C292.84,556.01 284.6,553.88 277.31,549.76L109.4,454.92C99.54,449.37 93.42,438.97 93.31,427.67L93.31,234.82C93.23,226.58 94.86,218.63 98.21,211.63C101.81,204.11 107.39,197.69 114.99,193.2L273.07,99.95C287.75,91.27 306.01,91.1 320.86,99.49L480.67,189.75C487.79,193.78 494.03,199.46 498.59,206.19C503.57,213.5 506.6,222.02 506.69,230.91L506.69,414.43C506.85,431.49 497.87,447.39 483.18,456.06L325.11,549.32C317.74,553.68 309.48,555.87 301.2,555.94Z"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#083042"
android:fillType="nonZero"/>
</vector>
================================================
FILE: composeApp/src/commonMain/kotlin/org/example/project/App.kt
================================================
package org.example.project
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.painterResource
import kotlinproject.composeapp.generated.resources.Res
import kotlinproject.composeapp.generated.resources.compose_multiplatform
@Composable
fun App() {
MaterialTheme {
var showContent by remember { mutableStateOf(false) }
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
Button(onClick = { showContent = !showContent }) {
Text("Click me!")
}
AnimatedVisibility(showContent) {
val greeting = remember { Greeting().greet() }
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
Text("Compose: $greeting")
}
}
}
}
}
================================================
FILE: composeApp/src/commonMain/kotlin/org/example/project/Greeting.kt
================================================
package org.example.project
class Greeting {
private val platform = getPlatform()
fun greet(): String {
return "Hello, ${platform.name}!"
}
}
================================================
FILE: composeApp/src/commonMain/kotlin/org/example/project/Platform.kt
================================================
package org.example.project
interface Platform {
val name: String
}
expect fun getPlatform(): Platform
================================================
FILE: composeApp/src/iosMain/kotlin/org/example/project/MainViewController.kt
================================================
package org.example.project
import androidx.compose.ui.window.ComposeUIViewController
fun MainViewController() = ComposeUIViewController { App() }
================================================
FILE: composeApp/src/iosMain/kotlin/org/example/project/Platform.ios.kt
================================================
package org.example.project
import platform.UIKit.UIDevice
class IOSPlatform: Platform {
override val name: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
}
actual fun getPlatform(): Platform = IOSPlatform()
================================================
FILE: composeApp/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher_test"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_test"
android:supportsRtl="true"
tools:replace="android:theme"
android:theme="@android:style/Theme.Material.Light.NoActionBar">
<activity
android:exported="true"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|mnc|colorMode|density|fontScale|fontWeightAdjustment|keyboard|layoutDirection|locale|mcc|navigation|smallestScreenSize|touchscreen|uiMode"
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: composeApp/src/main/java/com/aether/composeapp/example/ReflectableExample.kt
================================================
package com.aether.composeapp.example
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.aether.annotations.ReflectableFunction
import com.aether.core.runtime.reflectable.ComposeComponentFactory
/**
* 一个可反射的文本组件
*/
@ReflectableFunction(
name = "CustomText",
description = "A custom text component with padding"
)
@Composable
fun CustomText(text: String, modifier: Modifier = Modifier) {
Text(
text = text,
modifier = modifier.padding(16.dp)
)
}
/**
* 一个可反射的按钮组件
*/
@ReflectableFunction(
name = "CustomButton",
description = "A custom button component with text"
)
@Composable
fun CustomButton(
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
Button(
onClick = onClick,
modifier = modifier
) {
Text(text)
}
}
/**
* 一个可反射的容器组件
*/
@ReflectableFunction(
name = "CustomContainer",
description = "A custom container component"
)
@Composable
fun CustomContainer(
content: @Composable () -> Unit,
modifier: Modifier = Modifier
) {
Column(modifier = modifier) {
content()
}
}
/**
* 一个可反射的复合组件
*/
//@ReflectableFunction(
// name = "ComplexComponent",
// description = "A complex component combining multiple elements"
//)
//@Composable
//fun ComplexComponent(
// title: String,
// buttonText: String,
// onButtonClick: () -> Unit
//) {
// CustomContainer {
// CustomText(text = title)
// CustomButton(
// text = buttonText,
// onClick = onButtonClick
// )
// }
//}
/**
* 示例用法
*/
@Composable
fun ExampleUsage() {
// 注册组件
}
================================================
FILE: core/.gitignore
================================================
/build
================================================
FILE: core/build.gradle.kts
================================================
plugins {
alias(libs.plugins.androidLibrary)
alias(libs.plugins.kotlinAndroid)
}
android {
namespace = "com.aether.core.runtime"
compileSdk = 34
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.8" // This version works with Kotlin 1.8.22
}
// android {
// composeOptions {
// kotlinCompilerExtensionVersion = "1.5.15"
// }
// }
// defaultConfig {
// minSdk = 34
// targetSdk = 34
// versionCode = 1
// versionName = "1.0"
//
// testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
// }
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
configurations.implementation {
exclude(group = "com.intellij", module = "annotations")
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.material)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.test.junit)
androidTestImplementation(libs.androidx.espresso.core)
// Kotlin 标准库
// implementation("org.jetbrains.kotlin:kotlin-stdlib:1.8.20")
// AndroidX Core KTX
implementation("androidx.core:core-ktx:1.3.1")
// AndroidX AppCompat
implementation("androidx.appcompat:appcompat:1.2.0")
// Material Design 组件
// implementation("com.google.android.material:material:1.2.1")
// ConstraintLayout
implementation("androidx.constraintlayout:constraintlayout:2.0.1")
// JUnit 测试框架
// testImplementation("junit:junit:4.13.2")
// AndroidX 测试扩展 JUnit
// androidTestImplementation("androidx.test.ext:junit:1.1.2")
// Espresso 测试框架
androidTestImplementation("androidx.test.espresso:espresso-core:3.3.0")
// Kotlin 编译器
implementation("org.jetbrains.kotlin:kotlin-compiler:1.8.20") {
exclude(group = "com.google.guava", module = "guava")
}
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.8.22")
implementation("androidx.compose.ui:ui:1.6.0")
implementation("androidx.compose.material:material:1.6.0")
// implementation("androidx.compose.runtime:runtime:1.6.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
// implementation("com.google.firebase:firebase-inappmessaging-display:17.2.0")
// implementation("com.google.guava:guava:27.0.1-android")
// implementation("com.google.guava:guava:27.0.1-jre")
implementation("com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava")
// implementation("com.google.code.gson:gson:2.8.8")
implementation("com.fasterxml.jackson.core:jackson-databind:2.14.2")
}
================================================
FILE: core/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-keep class androidx.compose.** { *; }
-dontwarn androidx.compose.**
================================================
FILE: core/src/androidTest/java/com/aether/core/runtime/ExampleInstrumentedTest.kt
================================================
package com.aether.core.runtime
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.aether.core.runtime", appContext.packageName)
}
}
================================================
FILE: core/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher_test"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_test"
android:supportsRtl="true"
android:theme="@style/Theme.KotlinProject" />
</manifest>
================================================
FILE: core/src/main/assets/test0_compose.json
================================================
{
"directives": [
{
"type": "ImportDirective",
"importPath": "androidx.compose.material.Text",
"alias": null,
"name": "Text"
},
{
"type": "ImportDirective",
"importPath": "androidx.compose.runtime.Composable",
"alias": null,
"name": "Composable"
}
],
"declarations": [
{
"type": "ClassDeclaration",
"name": "DemoCompose",
"members": [
{
"type": "MethodDeclaration",
"name": "Main",
"parameters": [],
"typeParameters": [],
"body": {
"type": "BlockStatement",
"body": [
{
"type": "InstanceCreationExpression",
"constructorName": "Text",
"argumentList": {
"type": "ArgumentList",
"arguments": [
{
"type": "Argument",
"body": {
"type": "StringTemplateExpression",
"name": null,
"body": {
"type": "StringTemplateEntry",
"body": null,
"value": "这个一个最小试验单位的动态化卡片,它的产物来自云端打包编译,可以根据产品诉求随意替换"
}
}
}
]
},
"valueArgument": []
}
]
},
"isStatic": false,
"isGetter": true,
"isSetter": false
}
],
"body": {}
}
],
"type": "CompilationUnit"
}
================================================
FILE: core/src/main/assets/test1_compose.json
================================================
{
"directives" : [ {
"type" : "ImportDirective",
"importPath" : "androidx.compose.foundation.background",
"alias" : null,
"name" : "background"
}, {
"type" : "ImportDirective",
"importPath" : "androidx.compose.foundation.layout.Box",
"alias" : null,
"name" : "Box"
}, {
"type" : "ImportDirective",
"importPath" : "androidx.compose.foundation.layout.Column",
"alias" : null,
"name" : "Column"
}, {
"type" : "ImportDirective",
"importPath" : "androidx.compose.foundation.layout.fillMaxWidth",
"alias" : null,
"name" : "fillMaxWidth"
}, {
"type" : "ImportDirective",
"importPath" : "androidx.compose.foundation.layout.height",
"alias" : null,
"name" : "height"
}, {
"type" : "ImportDirective",
"importPath" : "androidx.compose.foundation.layout.padding",
"alias" : null,
"name" : "padding"
}, {
"type" : "ImportDirective",
"importPath" : "androidx.compose.foundation.shape.RoundedCornerShape",
"alias" : null,
"name" : "RoundedCornerShape"
}, {
"type" : "ImportDirective",
"importPath" : "androidx.compose.material.Button",
"alias" : null,
"name" : "Button"
}, {
"type" : "ImportDirective",
"importPath" : "androidx.compose.material.Text",
"alias" : null,
"name" : "Text"
}, {
"type" : "ImportDirective",
"importPath" : "androidx.compose.runtime.Composable",
"alias" : null,
"name" : "Composable"
}, {
"type" : "ImportDirective",
"importPath" : "androidx.compose.ui.Alignment",
"alias" : null,
"name" : "Alignment"
}, {
"type" : "ImportDirective",
"importPath" : "androidx.compose.ui.Modifier",
"alias" : null,
"name" : "Modifier"
}, {
"type" : "ImportDirective",
"importPath" : "androidx.compose.ui.draw.clip",
"alias" : null,
"name" : "clip"
}, {
"type" : "ImportDirective",
"importPath" : "androidx.compose.ui.graphics.Color",
"alias" : null,
"name" : "Color"
}, {
"type" : "ImportDirective",
"importPath" : "androidx.compose.ui.unit.dp",
"alias" : null,
"name" : "dp"
} ],
"declarations" : [ {
"type" : "ClassDeclaration",
"name" : "DemoCompose",
"members" : [ {
"type" : "MethodDeclaration",
"name" : "Main",
"parameters" : [ ],
"typeParameters" : [ ],
"body" : {
"type" : "BlockStatement",
"body" : [ {
"type" : "InstanceCreationExpression",
"constructorName" : "Column",
"argumentList" : {
"type" : "ArgumentList",
"arguments" : [ {
"type" : "Argument",
"body" : {
"type" : "MethodInvocation",
"name" : null,
"methodName" : {
"type" : "CallExpression",
"methodName" : {
"type" : "Identifier",
"name" : "fillMaxWidth"
},
"target" : {
"type" : "Identifier",
"name" : "fillMaxWidth"
},
"argumentList" : {
"type" : "ArgumentList",
"arguments" : [ ]
},
"valueArgument" : [ ]
},
"target" : {
"type" : "Identifier",
"name" : "Modifier"
}
}
}, {
"type" : "Argument",
"body" : {
"type" : "MethodInvocation",
"name" : null,
"methodName" : {
"type" : "Identifier",
"name" : "CenterHorizontally"
},
"target" : {
"type" : "Identifier",
"name" : "Alignment"
}
}
} ]
},
"valueArgument" : [ ]
} ]
},
"isStatic" : false,
"isGetter" : true,
"isSetter" : false
} ],
"body" : { }
} ],
"type" : "CompilationUnit"
}
================================================
FILE: core/src/main/java/com/aether/core/runtime/AppContextManager.kt
================================================
package com.aether.core.runtime
import com.aether.core.runtime.AppContext
object AppContextManager {
private val contextHolder = ThreadLocal.withInitial { AppContext(null, "ROOT", emptyMap(), emptyMap()) }
// 获取当前线程的 AppContext
val context: AppContext
get() = contextHolder.get()
// 设置当前线程的 AppContext
fun set(context: AppContext) {
contextHolder.set(context)
}
fun get() :AppContext{
return context
}
// 移除当前线程的 AppContext
fun removeContext() {
contextHolder.remove()
}
}
================================================
FILE: core/src/main/java/com/aether/core/runtime/AstRuntime.kt
================================================
package com.aether.core.runtime
import android.text.TextUtils
import com.aether.core.runtime.AppContextManager.context
import com.aether.core.runtime.deliver.ComposableHolder
import com.aether.core.runtime.deliver.invokeRunMain
import com.aether.core.runtime.proxy.ProxyBinding
import com.aether.core.runtime.reflectable.ComposeComponentDescriptor
import com.aether.core.runtime.reflectable.ComposeComponentFactory
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.psi.PsiFileFactory
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFile
import java.io.File
import java.lang.reflect.Modifier
import java.util.Collections
import java.util.UUID
import kotlin.reflect.KClass
import kotlin.reflect.jvm.javaMethod
/// The `import` directive.
class Import(
/// The absolute URI of the imported library.
val uri: String,
/// The import prefix, or `null` if not specified.
val prefix: String?,
/// The list of namespace combinators to apply, not `null`.
val combinators: List<Combinator>?
) {
override fun toString(): String {
return "Import(uri: $uri, prefix: $prefix, combinators: $combinators)"
}
}
fun _exeAndRecMethodInvocation(methodInvocation: MethodInvocation): Any? {
val programStack = context.get<ProgramStack>(ProgramStack::class.java)
val scope = StackScope("Call method: ") // 创建 StackScope 实例
scope["node"] = methodInvocation // 将 methodInvocation 存入 scope
programStack?.push(scope = scope) // 将 scope 压入程序栈
val result = _executeMethodInvocation2(methodInvocation) // 执行方法调用逻辑
programStack?.pop() // 弹出栈顶
return result // 返回结果
}
fun _executeMethodInvocation2(methodInvocation: MethodInvocation): Any? {
val runtime = context.get<AstRuntime>(AstRuntime::class.java)!! // 获取 AstRuntime,使用 !! 表示非空断言
val programStack = context.get<ProgramStack>(ProgramStack::class.java)!! // 获取 ProgramStack
val methodName = methodInvocation.methodName
val positionalArguments = mutableListOf<Any?>() // 位置参数列表
val namedArguments = mutableMapOf<String, Any?>() // 命名参数 Map
// 处理方法的参数
if (!(methodInvocation.argumentList?.arguments == null || methodInvocation.argumentList.arguments.isEmpty())) {
for (argument in methodInvocation.argumentList!!.arguments!!) {
if (argument.isNamedExpression) {
namedArguments.putAll(executeExpression(argument) as Map<String, Any?>)
} else {
val arg = executeExpression(argument)
if (arg != null) {
positionalArguments.add(
arg
)
}
}
}
}
// 检查是否有 ComposableHolder 上下文
val holder = context.get(ComposableHolder::class.java)
if (holder != null) {
if (methodName?.name == "build" && methodInvocation.argumentList?.arguments?.isNotEmpty() == true) {
// 确保有参数
// val arg = methodInvocation.argumentList?.arguments?.get(0)
// if (arg != null && arg.isFunctionExpression) {
// return doRunBuild(arg.asFunctionExpression())
// }
} else if (methodName?.name == "runApp" && methodInvocation.argumentList?.arguments?.isNotEmpty() == true) {
// val arg = methodInvocation.argumentList?.arguments?.get(0)
// if (arg != null) {
// return invokeRunApp(arg)
// }
}
}
var target: Any? = null
if (methodInvocation.isCascaded) {
// target = findCascadeAncestorTargetValue(methodInvocation)
} else if (methodInvocation.target != null) {
target = executeExpression(methodInvocation.target)
}
//
// if (target == null) {
// if (methodInvocation.isNullAware) {
// return null
// }
// if (methodInvocation.target != null) {
// throw RuntimeException("Null check operator used on a null value -> $methodName")
// }
// }
// 如果没有目标对象
if (target == null) {
// 查找实例 AST 方法或静态 AST 方法
val method = programStack.get<AstMethod>(methodName!!.name)
if (method != null) {
return AstMethod.apply2(method, positionalArguments, namedArguments)
}
// 默认 AST 构造函数
val clazz = AstClass.forName(methodName!!.name)
if (clazz != null) {
return clazz.newInstance("", positionalArguments, namedArguments)
}
} else {
methodInvocation.methodName
// 如果目标是 AstClass
if (target is AstClass) {
if (target.hasConstructor(methodName!!.name)) {
return target.newInstance(methodName.name, positionalArguments, namedArguments)
} else {
return target.invoke(methodName.name, positionalArguments, namedArguments)
}
}
// 如果目标是 AstInstance
val instance = AstInstance.forObject(target)
if (instance != null) {
val positionalArguments = mutableListOf<Any?>() // 位置参数列表
val namedArguments = mutableMapOf<String, Any?>() // 命名参数 Map
return instance.invoke(methodName!!.name, positionalArguments, namedArguments)
}
throw RuntimeException("InstanceMirror for ${target::class} not found")
}
// 检查是否有顶层函数
// if (runtime.hasTopLevelFunction(methodName)) {
// return runtime.invoke(methodName, positionalArguments, namedArguments)
// }
//
// // 尝试通过反射调用顶层方法
// val libraryMirror = ReflectionBinding.instance.reflectTopLevelInvoke(methodName)
// if (libraryMirror != null) {
// val function = AstMethod.fromMirror(libraryMirror.declarations[methodName] as MethodMirror)
// processArguments(function.parameters, positionalArguments, namedArguments)
// return libraryMirror.invoke(methodName, positionalArguments, namedArguments)
// }
throw RuntimeException("Error: MethodInvocation -> $methodName, target: $target, runtimeType: ${target?.toString()}")
}
//fun executeMethodTarget(
// methodInvocation: MethodInvocation,
// methodName: String,
// positionalArguments: List<Any?>,
// namedArguments: Map<String, Any?>? = null
//): Any? {
// if (methodInvocation?.target != null) {
// var target = executeExpression(methodInvocation.target!!)
// if (target is AstClass) {
// if (target.hasConstructor(methodName)) {
// return target.newInstance(methodName, positionalArguments, namedArguments)
// } else {
// return target.invoke(methodName, positionalArguments, namedArguments)
// }
// }
// val instance = AstInstance.forObject(target)
// if (instance != null) {
// return instance.invokeGetter(methodInvocation.methodName!!.name)
// }
// }
// return null
//}
fun executeInstanceCreationExpression(instanceCreationExpression: InstanceCreationExpression): Any? {
val positionalArguments = mutableListOf<Any?>()
val namedArguments = mutableMapOf<String, Any?>()
if (instanceCreationExpression.argumentList?.arguments?.isNotEmpty() == true) {
for (arg in instanceCreationExpression!!.argumentList!!.arguments!!) {
if (arg.isNamedExpression) {
namedArguments.putAll(executeExpression(arg) as Map<out String, Any?>)
} else {
positionalArguments.add(executeExpression(arg))
}
}
}
val constructorName = instanceCreationExpression.constructorName?.name
val typeName = instanceCreationExpression.constructorName?.typeName
if (typeName == null || constructorName == null) {
println("Type $typeName is ${typeName == null} not found, constructorName is ${constructorName == null} not found")
null
}
//TODO 这里依然有问题,需要
// 对于Compose组件,返回一个包含路径和参数的描述对象
// 而不是直接返回@Composable函数
val runtime = context.get<AstRuntime>(AstRuntime::class.java)
val importDirective = runtime?.getReflectClass(typeName ?: "")
val children = mutableListOf<ComposeComponentDescriptor>()
instanceCreationExpression.children?.forEach {
if (it.isInstanceCreationExpression) {
val element = executeExpression(it)
children.add(element as ComposeComponentDescriptor)
}
}
if (ComposeComponentFactory.isComponentAvailable(importDirective?.uri ?: "")) {
return ComposeComponentDescriptor(
importDirective?.uri ?: "",
positionalArguments,
namedArguments,
children
)
}
val astClass: AstClass? = AstClass.forName(typeName ?: "")
return if (astClass != null) {
astClass.newInstance(constructorName!!, positionalArguments, namedArguments)
} else {
println("Type $typeName not found")
null
}
}
fun executeExpression(
expression: Expression, flag: String? = null, keepVariable: Boolean = false
): Any? {
return try {
val programStack = context.get<ProgramStack>(ProgramStack::class.java)
if (expression.isIdentifier) {
val name = expression.asIdentifier.name
val variable = programStack?.getVariable(name)
if (variable != null) {
if (keepVariable) {
return variable
} else {
if (variable.value is Expression) {
return executeExpression(variable.value as Expression)
}
return variable.value
}
}
val runtime = context.get<AstRuntime>(AstRuntime::class.java)!!
val method = programStack?.get<AstMethod>(name)
if (method != null) {
if (method.isGetter) {
return AstMethod.apply2(
method,
positionalArguments = mutableListOf(),
namedArguments = mutableMapOf()
)
}
val length = method.parameters.size
val thisReference = context.get(ThisReference::class.java)
val superReference = context.get(SuperReference::class.java)
val innerStack = ProgramStack("closure", programStack)
val overrides = mapOf(
ProgramStack::class.java to { innerStack },
AstRuntime::class.java to { runtime },
ThisReference::class.java to { thisReference },
SuperReference::class.java to { superReference })
return when (length) {
0 -> {
{
context.run(
name = "closure override", body = {
AstMethod.apply2(
method,
positionalArguments = mutableListOf(),
namedArguments = mutableMapOf()
)
}, overrides = overrides
)
}
}
// 1 -> {
// { a ->
// context.run(
// name = "closure override",
// body = { AstMethod.apply2(method, listOf(a)) },
// overrides = overrides
// )
// }
// }
// 2 -> {
// { a, b ->
// context.run(
// name = "closure override",
// body = { AstMethod.apply2(method, listOf(a, b)) },
// overrides = overrides
// )
// }
// }
// 3 -> {
// { a, b, c ->
// context.run(
// name = "closure override",
// body = { AstMethod.apply2(method, listOf(a, b, c)) },
// overrides = overrides
// )
// }
// }
// 4 -> {
// { a, b, c, d ->
// context.run(
// name = "closure override",
// body = { AstMethod.apply2(method, listOf(a, b, c, d)) },
// overrides = overrides
// )
// }
// }
// 5 -> {
// { a, b, c, d, e ->
// context.run(
// name = "closure override",
// body = { AstMethod.apply2(method, listOf(a, b, c, d, e)) },
// overrides = overrides
// )
// }
// }
// 6 -> {
// { a, b, c, d, e, f ->
// context.run(
// name = "closure override",
// body = { AstMethod.apply2(method, listOf(a, b, c, d, e, f)) },
// overrides = overrides
// )
// }
// }
else -> {
{
context.run(
name = "closure override", body = {
AstMethod.apply2(
method,
positionalArguments = mutableListOf(),
namedArguments = mutableMapOf()
)
}, overrides = overrides
)
}
}
}
} else {
}
// val topLevelVariable = runtime.getTopLevelVariable(name)
// if (topLevelVariable != null) {
// if (keepVariable) {
// return topLevelVariable
// } else {
// return topLevelVariable.value
// }
// }
//
val clazz = AstClass.forName(name)
if (clazz != null) {
return clazz
}
// 1. 通过反射获取 Log 类
// val reflectClass = runtime.getReflectClass(name)
// if (reflectClass != null) {
// val classInstance = Class.forName(reflectClass?.uri)
// val methodArgs = ArrayList<String>()
// methodArgs.add("你好")
// parseKtClass(reflectClass?.uri, "info", methodArgs)
// if (classInstance != null) {
// return classInstance
// }
// }
return null
// val libraryMirror = ReflectionBinding.instance.reflectTopLevelInvoke(name)
// if (libraryMirror != null) {
// return libraryMirror.invokeGetter(name)
// }
//
// throw "Should not happen execute Identifier: ${expression.asIdentifier.name}"
} else if (expression.isBlockStatement) {
return _executeBlockStatement(expression.asBlockStatement, flag = flag);
} else if (expression.isEmptyFunctionBody) {
return null
} else if (expression.isInstanceCreationExpression) {
return executeInstanceCreationExpression(
expression.asInstanceCreationExpression
);
} else if (expression.isPropertyAccess) {
// 取值表达式,如demo.test()
val propertyAccess = expression.asPropertyAccess
var target: Any? = null
// if (propertyAccess.isCascaded) {
// target = findCascadeAncestorTargetValue(propertyAccess)
// } else {
// target = executeExpression(propertyAccess.targetExpression!!)
target = executeExpression(propertyAccess.targetExpression!!)
// }
val instance = AstInstance.forObject(target)
if (instance != null && !propertyAccess.name.isNullOrEmpty()) {
propertyAccess.name?.let {
return instance.invokeGetter(it)
}
}
if (target == null) {
// if (propertyAccess.isNullAware) {
// return null
// } else {
// throw IllegalArgumentException("Null check operator used on a null value")
// }
} else {
}
} else if (expression.isVariableDeclarationList) {
return _executeVariableDeclaration(expression.asVariableDeclarationList)
} else if (expression.isBinaryExpression) {
return _executeBinaryExpression(expression.asBinaryExpression);
} else if (expression.isReturnStatement) {
var result: Any? = null
if (expression.asReturnStatement.argument != null) {
result = executeExpression(expression.asReturnStatement.argument!!)
}
returnFlags[flag ?: ""] = true
return result
} else if (expression.isIntegerLiteral) {
return expression.asIntegerLiteral.value
} else if (expression.isMethodInvocation) {
//method调用
return _exeAndRecMethodInvocation(expression.asMethodInvocation);
} else if (expression.isStringTemplateExpression) {
//string
var result: Any? = null
if (expression.asStringTemplateExpression != null && expression.asStringTemplateExpression.target != null) {
result = executeExpression(expression.asStringTemplateExpression.target!!)
return result
}
return result
} else if (expression.isStringLiteral) {
return expression.asIntegerLiteral.value
} else if (expression.isStringTemplateEntry) {
return expression.asStringTemplateEntry.value
} else if (expression.isBooleanLiteral) {
return expression.asBooleanLiteral.value
} else if (expression.isNamedExpression) {
//获取named 参数值
val namedExpression = expression.asNamedExpression
val mutableMapOf = mutableMapOf<String?, Any?>()
mutableMapOf.put(
namedExpression.name,
executeExpression(namedExpression.argument!!)
)
return mutableMapOf
} else if (expression.isCallExpression) {
//callFunction调用
val clazz = AstClass.forName(expression.asCallExpression.methodName)
if (clazz != null) {
return clazz
} else {
val runtime = context.get<AstRuntime>(AstRuntime::class.java)!!
val function = runtime._program.getFunction(expression.asCallExpression.methodName)
if (function != null) {
val result = AstMethod.apply2(
function,
expression.asCallExpression.argumentList.arguments ?: emptyList(),
emptyMap(),
)
return result
}
return null
}
} else {
println("executeExpression ${expression.type} not implement")
}
} catch (e: Exception) {
// if (e is DynamicCardException) {
// throw e
// } else {
throw DynamicException.fromExpression(expression, e.toString())
// }
}
return null
}
fun parseKtClass(className: String, methodName: String, methodArgs: List<*>) {
// 假设这是从 PSI 解析生成的 Map<String, Any>
val parsedMap: Map<String, Any> = mapOf(
"className" to "org.example.MyClass",
"methodName" to "myMethod",
"methodArgs" to listOf("arg1", "arg2")
)
// // 动态加载类并调用方法
// val className = parsedMap["className"] as String
// val methodName = parsedMap["methodName"] as String
// val methodArgs = parsedMap["methodArgs"] as List<*>
try {
// 1. 动态加载类
val clazz: Class<*> = Class.forName(className)
val kClass: KClass<*> = clazz.kotlin
// 2. 获取目标方法
val memberFunction = kClass.members.find { it.name == methodName }
?: throw NoSuchMethodException("No such method: $methodName")
// 3. 调用方法
if (memberFunction is kotlin.reflect.KFunction<*>) {
// 创建实例(如果需要)
val instance = if (!clazz.isInterface && !Modifier.isStatic(
memberFunction.javaMethod?.modifiers ?: 0
)
) {
clazz.getDeclaredConstructor().newInstance()
} else {
null
}
// 调用方法
val messages = arrayOf("你好")
val result = memberFunction.call(instance, messages)
println("Result of $methodName: $result")
} else {
throw IllegalArgumentException("$methodName is not a callable function")
}
} catch (e: Exception) {
e.printStackTrace()
}
}
class DynamicException(message: String?) : RuntimeException(message) {
var stackTrace = ""
companion object {
fun fromExpression(expression: Expression, e: String): Throwable {
System.out.println("error:" + e)
return DynamicException(message = e)
}
}
}
fun _executeVariableDeclaration(variableDeclarationList: PropertyStatement): Any? {
val programStack = context.get<ProgramStack>(ProgramStack::class.java)!!
val variableDeclarator = variableDeclarationList.target
// ignore: unnecessary_null_comparison
// if (variableDeclarator.init == null) {
// // 光定义,没有赋值的场景
// programStack.putVariable(variableDeclarator.name, null)
// return null // TODO
// }
// if (variableDeclarator.init!!.isAwaitExpression) {
// //await expression;
// val value = _exeAndRecMethodInvocation(variableDeclarator.init!!.asAwaitExpression.expression)
// programStack.putVariable(variableDeclarator.name, value)
// } else if (variableDeclarator.init!!.isMethodInvocation) {
// val value = _exeAndRecMethodInvocation(variableDeclarator.init!!.asMethodInvocation)
// //存入声明的初始化变量值
// programStack.putVariable(variableDeclarator.name, value)
// } else {
// //存入声明的初始化变量值
val value = executeExpression(variableDeclarator!!)
programStack.putVariable(variableDeclarationList.name, value)
// }
return null
}
//fun findCascadeAncestorTargetValue(child: Node): Any? {
// fun helper(node: Node?): Any? {
// return when {
// node == null -> null
// node is CascadeExpression -> node.targetValue
// else -> helper(node.parent)
// }
// }
// return helper(child)
//}
fun _executeBinaryExpression(binaryExpression: BinaryExpression): Any? {
val evalLeft = executeExpression(binaryExpression.left)
val evalRight = executeExpression(binaryExpression.right)
val operator = binaryExpression.operator
if (evalLeft is String || evalRight is String) {
return when (operator) {
"+" -> "$evalLeft$evalRight"
else -> throw UnimplementedError("operator Int ${binaryExpression.operator}")
}
}
if (evalLeft is Int && evalRight is Int) {
return when (operator) {
"+" -> evalLeft + evalRight
"-" -> evalLeft - evalRight
"*" -> evalLeft * evalRight
"/" -> evalLeft / evalRight
"<" -> evalLeft < evalRight
">" -> evalLeft > evalRight
"<=" -> evalLeft <= evalRight
">=" -> evalLeft >= evalRight
"==" -> evalLeft == evalRight
"%" -> evalLeft % evalRight
"<<" -> evalLeft shl evalRight
"|" -> evalLeft or evalRight
"&" -> evalLeft and evalRight
">>" -> evalLeft shr evalRight
"!=" -> evalLeft != evalRight
"/" -> evalLeft / evalRight
else -> throw UnimplementedError("operator Int ${binaryExpression.operator}")
}
}
if (evalLeft is Boolean && evalRight is Boolean) {
return when (operator) {
"&&" -> evalLeft && evalRight
"||" -> evalLeft || evalRight
else -> throw UnimplementedError("operator Boolean ${binaryExpression.operator}")
}
}
return null
}
val returnFlags: MutableMap<String, Boolean> = mutableMapOf()
fun _executeBlockStatement(block: BlockStatement, flag: String? = null): Any? {
var flagTemp = flag
if (flag == null) {
flagTemp = UUID.randomUUID().toString()
}
val programStack = context.get<ProgramStack>(ProgramStack::class.java)
programStack?.push(name = "Block statement")
var result: Any? = null
if (block.body?.isNotEmpty() == true) {
for (expression in block.body!!) {
if (returnFlags[flag] == true) {
returnFlags.remove(flagTemp)
break
}
result = executeExpression(expression, flag = flagTemp)
}
}
programStack?.pop()
return result
}
class AstRuntime(val _program: ProgramNode) {
public var programStack: ProgramStack? = null
init {
// 创建并初始化 ProxyBinding 实例
val proxyBinding = ProxyBinding()
proxyBinding.initInstances()
this.programStack = ProgramStack("root stack:${_program.compilation.toUnit()["source"]}")
}
fun invoke2(memberName: String): AstMethod? {
val function = _program.getFunction(memberName)
return function
}
val classes: List<AstClass>
get() {
return context.run(
name = "AstRuntime",
body = {
_program.classes
},
overrides = mapOf(
ProgramStack::class.java to { programStack },
AstRuntime::class.java to { this }
)
) as List<AstClass>
}
fun getClass(className: String): AstClass? {
return context.run(
name = "AstRuntime",
body = {
_program?.getClass(className)
},
overrides = mapOf(
ProgramStack::class.java to { programStack },
AstRuntime::class.java to { this }
)
) as AstClass?
}
fun getReflectClass(className: String): ImportDirective? {
return _program?.getReflectClass(className)
}
fun invoke2(
memberName: String,
positionalArguments: List<Any?>? = null,
namedArguments: Map<String, Any?>? = null
): Any? {
return context.run(
name = "Invoke top-level function or variables",
body = {
val function = _program?.getFunction(memberName)
if (function != null) {
context.run(name = "", body = {
val result = AstMethod.apply2(
function, positionalArguments ?: emptyList(), namedArguments
)
if (result is Variable) {
return@run result.value
}
invokeRunMain(result)
return@run result
}, overrides = mapOf(ProgramNode::class.java to { function.programNode }))
} else {
null
}
},
overrides = mapOf(
ProgramStack::class.java to { programStack },
AstRuntime::class.java to { this })
)
}
fun invoke(
memberName: String,
positionalArguments: List<Any?>? = null,
namedArguments: Map<String, Any?>? = null
): Any? {
return context.run(
name = "Invoke top-level function or variables",
body = {
val function = _program?.getFunction(memberName)
if (function != null) {
context.run(name = "", body = {
val result = AstMethod.apply2(
function, positionalArguments ?: emptyList(), namedArguments
)
if (result is Variable) {
return@run result.value
}
return@run result
}, overrides = mapOf(ProgramNode::class.java to { function.programNode }))
} else {
null
}
},
overrides = mapOf(
ProgramStack::class.java to { programStack },
AstRuntime::class.java to { this })
)
}
class LocalJson(val json: String) : ProgramEntity() {
override val exists: Boolean
get() = !TextUtils.isEmpty(json)
val walker = ProgramDependencyWalker();
override fun createNode(): ProgramNode {
val transformMap = transformMap(json)
val node = walker.getNode(this, CompilationUnit.fromUnit(transformMap))
return node
}
fun transformMap(json: String): Map<String, Any> {
try {
// 序列化 Map 对象为 JSON 字符串
val objectMapper = ObjectMapper()
// 禁用 FAIL_ON_EMPTY_BEANS 特性
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// 反序列化 JSON 字符串为 Map 对象
@Suppress("UNCHECKED_CAST")
val deserializedMap =
objectMapper.readValue(json, HashMap::class.java) as Map<String, Any>
println("Deserialized Map: $deserializedMap")
return deserializedMap
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
return emptyMap()
}
fun getClassFilePath(clazz: Class<*>): String? {
// 尝试从保护域获取类文件的位置
clazz.protectionDomain?.codeSource?.location?.let {
return try {
// 如果是文件形式存在,则返回其路径
it.toURI().path
} catch (e: Exception) {
e.printStackTrace()
null
}
}
// 尝试通过类加载器获取资源路径
val resource = clazz.name.replace('.', '/') + ".class"
val resourcePath = clazz.classLoader.getResource(resource)?.toURI()?.path
if (resourcePath != null && resourcePath.endsWith(".jar")) {
// 如果是在JAR内,则返回JAR文件路径
return resourcePath
}
return resourcePath?.removeSuffix(".class")
}
fun convertClassToPath(fullClassName: String): String {
return "src/test/java/" + fullClassName.replace('.', '/') + ".kt"
}
override fun getRelativeEntity(uri: String): ProgramEntity {
// 获取文件的目录路径
// val basePath = File(convertClassToPath(uri)).parentFile?.absolutePath
// ?: throw IllegalArgumentException("Invalid base file path")
return LocalFile(File(convertClassToPath(uri)))
}
private fun createCoreEnvironment(): KotlinCoreEnvironment {
val disposable = Disposer.newDisposable()
return KotlinCoreEnvironment.createForProduction(
disposable,
ProjectHelper.getConfiguration(),
EnvironmentConfigFiles.JVM_CONFIG_FILES
)
}
fun parseKotlinCode(content: String, fileName: String = "DummyFile.kt"): KtFile {
val project: Project = createCoreEnvironment().project
val psiFileFactory = PsiFileFactory.getInstance(project)
return psiFileFactory.createFileFromText(fileName, content) as KtFile
}
}
class GeneraJson(val file: File) {
fun createNodeToJson(): String? {
val ktFile = parseKotlinCode(file.readText())
val visitor = MyKtVisitorV2()
ktFile.accept(visitor)
val unit = visitor.getResult()
val json = transformJson(unit)
return json
}
private fun transformJson(unit: Map<String, Any>): String? {
try {
// 序列化 Map 对象为 JSON 字符串
val objectMapper = ObjectMapper()
// 禁用 FAIL_ON_EMPTY_BEANS 特性
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
val json: String? = objectMapper.writeValueAsString(unit)
// 输出 JSON 字符串
println(json)
return json
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
return null
}
private fun transformMap(json: String): Map<String, Any> {
try {
// 序列化 Map 对象为 JSON 字符串
val objectMapper = ObjectMapper()
// 禁用 FAIL_ON_EMPTY_BEANS 特性
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// 反序列化 JSON 字符串为 Map 对象
@Suppress("UNCHECKED_CAST")
val deserializedMap =
objectMapper.readValue(json, HashMap::class.java) as Map<String, Any>
println("Deserialized Map: $deserializedMap")
return deserializedMap
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
return emptyMap()
}
private fun createCoreEnvironment(): KotlinCoreEnvironment {
val disposable = Disposer.newDisposable()
return KotlinCoreEnvironment.createForProduction(
disposable,
ProjectHelper.getConfiguration(),
EnvironmentConfigFiles.JVM_CONFIG_FILES
)
}
fun parseKotlinCode(content: String, fileName: String = "DummyFile.kt"): KtFile {
val project: Project = createCoreEnvironment().project
val psiFileFactory = PsiFileFactory.getInstance(project)
return psiFileFactory.createFileFromText(fileName, content) as KtFile
}
}
class LocalFile(val file: File) : ProgramEntity() {
override val exists: Boolean
get() = file.exists()
val walker = ProgramDependencyWalker();
override fun createNode(): ProgramNode {
val ktFile = parseKotlinCode(file.readText())
val visitor = MyKtVisitorV2()
ktFile.accept(visitor)
// val unit = visitor.getResult()
val transformMap = transformMap(getDefaultJson())
val node = walker.getNode(this, CompilationUnit.fromUnit(transformMap))
return node
}
private fun transformJson(unit: Map<String, Any>) {
try {
// 序列化 Map 对象为 JSON 字符串
val objectMapper = ObjectMapper()
// 禁用 FAIL_ON_EMPTY_BEANS 特性
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
val json: String? = objectMapper.writeValueAsString(unit)
// 输出 JSON 字符串
println(json)
// 反序列化 JSON 字符串为 Map 对象
@Suppress("UNCHECKED_CAST")
val deserializedMap =
objectMapper.readValue(json, HashMap::class.java) as Map<String, Any>
println("Deserialized Map: $deserializedMap")
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
fun transformMap(json: String): Map<String, Any> {
try {
// 序列化 Map 对象为 JSON 字符串
val objectMapper = ObjectMapper()
// 禁用 FAIL_ON_EMPTY_BEANS 特性
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// 反序列化 JSON 字符串为 Map 对象
@Suppress("UNCHECKED_CAST")
val deserializedMap =
objectMapper.readValue(json, HashMap::class.java) as Map<String, Any>
println("Deserialized Map: $deserializedMap")
return deserializedMap
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
return emptyMap()
}
fun getDefaultJson(): String {
return "{\n" +
" \"directives\" : [ ],\n" +
" \"declarations\" : [ {\n" +
" \"type\" : \"ClassDeclaration\",\n" +
" \"name\" : \"DemoEmptyFunctionExpress\",\n" +
" \"members\" : [ {\n" +
" \"type\" : \"MethodDeclaration\",\n" +
" \"name\" : \"test2\",\n" +
" \"parameters\" : [ {\n" +
" \"type\" : \"SimpleFormalParameter\",\n" +
" \"name\" : \"index\",\n" +
" \"typeName\" : \"Int\"\n" +
" }, {\n" +
" \"type\" : \"SimpleFormalParameter\",\n" +
" \"name\" : \"item\",\n" +
" \"typeName\" : \"String\"\n" +
" } ],\n" +
" \"typeParameters\" : [ ],\n" +
" \"body\" : {\n" +
" \"type\" : \"BlockStatement\",\n" +
" \"body\" : [ {\n" +
" \"type\" : \"PropertyStatement\",\n" +
" \"name\" : \"a\",\n" +
" \"initializer\" : {\n" +
" \"type\" : \"INTEGER_CONSTANT\",\n" +
" \"value\" : \"2\",\n" +
" \"name\" : \"ConstantExpression\"\n" +
" }\n" +
" }, {\n" +
" \"type\" : \"PropertyStatement\",\n" +
" \"name\" : \"b\",\n" +
" \"initializer\" : {\n" +
" \"type\" : \"BinaryExpression\",\n" +
" \"name\" : null,\n" +
" \"operator\" : \"+\",\n" +
" \"left\" : {\n" +
" \"type\" : \"INTEGER_CONSTANT\",\n" +
" \"value\" : \"2\",\n" +
" \"name\" : \"ConstantExpression\"\n" +
" },\n" +
" \"right\" : {\n" +
" \"type\" : \"Identifier\",\n" +
" \"name\" : \"index\"\n" +
" }\n" +
" }\n" +
" }, {\n" +
" \"type\" : \"ReturnStatement\",\n" +
" \"argument\" : {\n" +
" \"type\" : \"BinaryExpression\",\n" +
" \"name\" : null,\n" +
" \"operator\" : \"*\",\n" +
" \"left\" : {\n" +
" \"type\" : \"Identifier\",\n" +
" \"name\" : \"a\"\n" +
" },\n" +
" \"right\" : {\n" +
" \"type\" : \"Identifier\",\n" +
" \"name\" : \"b\"\n" +
" }\n" +
" }\n" +
" } ]\n" +
" },\n" +
" \"isStatic\" : true,\n" +
" \"isGetter\" : false,\n" +
" \"isSetter\" : false\n" +
" } ],\n" +
" \"body\" : { }\n" +
" } ],\n" +
" \"type\" : \"CompilationUnit\"\n" +
"}"
}
fun getClassFilePath(clazz: Class<*>): String? {
// 尝试从保护域获取类文件的位置
clazz.protectionDomain?.codeSource?.location?.let {
return try {
// 如果是文件形式存在,则返回其路径
it.toURI().path
} catch (e: Exception) {
e.printStackTrace()
null
}
}
// 尝试通过类加载器获取资源路径
val resource = clazz.name.replace('.', '/') + ".class"
val resourcePath = clazz.classLoader.getResource(resource)?.toURI()?.path
if (resourcePath != null && resourcePath.endsWith(".jar")) {
// 如果是在JAR内,则返回JAR文件路径
return resourcePath
}
return resourcePath?.removeSuffix(".class")
}
fun convertClassToPath(fullClassName: String): String {
return "src/test/java/" + fullClassName.replace('.', '/') + ".kt"
}
override fun getRelativeEntity(uri: String): ProgramEntity {
// 获取文件的目录路径
// val basePath = File(convertClassToPath(uri)).parentFile?.absolutePath
// ?: throw IllegalArgumentException("Invalid base file path")
return LocalFile(File(convertClassToPath(uri)))
}
private fun createCoreEnvironment(): KotlinCoreEnvironment {
val disposable = Disposer.newDisposable()
return KotlinCoreEnvironment.createForProduction(
disposable,
ProjectHelper.getConfiguration(),
EnvironmentConfigFiles.JVM_CONFIG_FILES
)
}
fun parseKotlinCode(content: String, fileName: String = "DummyFile.kt"): KtFile {
val project: Project = createCoreEnvironment().project
val psiFileFactory = PsiFileFactory.getInstance(project)
return psiFileFactory.createFileFromText(fileName, content) as KtFile
}
}
class ProgramDependencyWalker {
val nodeMap = mutableMapOf<ProgramEntity, ProgramNode>()
fun evaluate(node: ProgramNode) {
node.evaluate()
}
fun evaluateScc(scc: List<ProgramNode>) {
for (node in scc) {
node.markCircular()
}
}
fun getNode(entity: ProgramEntity, compilation: CompilationUnit): ProgramNode {
val programNode = nodeMap.getOrPut(entity) { ProgramNode(entity, this, compilation) }
programNode.dependencies = programNode.computeDependencies()
return programNode
}
}
// Assuming the ProgramNode class has these methods:
class ProgramNode(
val entity: ProgramEntity,
val walker: ProgramDependencyWalker,
val compilation: CompilationUnit
) {
var _classDeclarations: Map<String, ClassDeclaration>? = null
var _methodDeclarations: Map<String, MethodDeclaration>? = null
var _variableDeclarators: Map<String, VariableDeclarator>? = null
private val _classes: MutableMap<String, AstClass> = mutableMapOf()
private val _functions: MutableMap<String, AstMethod> = mutableMapOf()
private val _topLevelVariables: MutableMap<String, AstVariable> = mutableMapOf()
var dependencies: List<ProgramNode> = emptyList()
var data: MutableMap<String, ImportDirective> = mutableMapOf()
fun evaluate() {
// Implement the evaluation logic here
TODO("Implement evaluate for ProgramNode")
}
fun markCircular() {
// Implement the circular marking logic here
TODO("Implement markCircular for ProgramNode")
}
private val methodDeclarations: Map<String, MethodDeclaration>?
get() {
if (_methodDeclarations == null) {
// val result = mutableMapOf<String, FunctionDeclaration>()
// compilation.declarations
// ?.filterIsInstance<FunctionDeclaration>()
// ?.forEach { declaration ->
// result[declaration.name] = declaration
// }
// _functionDeclarations = result
val result = mutableMapOf<String, MethodDeclaration>()
compilation.declarations?.forEach {
(it.get() as ClassDeclaration).members?.forEach { declaration ->
if (declaration.get() is MethodDeclaration) {
result[((declaration?.get() as MethodDeclaration).name ?: "")] =
declaration.get() as MethodDeclaration
_methodDeclarations = result
}
}
}
}
return _methodDeclarations
}
val classes: List<AstClass>
get() = compilation.declarations?.filter { it.isClassDeclaration }
?.map { it.asClassDeclaration }
?.mapNotNull { getClass(it.name) }
?.toList() ?: emptyList()
fun ensureClassDeclarations() {
var classDeclarations = _classDeclarations
if (classDeclarations == null) {
val result = mutableMapOf<String, ClassDeclaration>()
compilation.declarations
?.filter { it.isClassDeclaration }
?.map { it.asClassDeclaration }
?.forEach { declaration ->
result[declaration.name] = declaration
}
_classDeclarations = result.unmodifiable()
}
}
fun getReflectClass(className: String, recursive: Boolean = true): ImportDirective? {
val importDirective = data[className]
return importDirective
}
fun getClass(className: String, recursive: Boolean = true): AstClass? {
ensureClassDeclarations()
_classes[className]?.let { return it }
_classDeclarations?.get(className)?.let {
val clazz = AstClass.fromClass(it, this)
_classes[className] = clazz
return clazz
}
if (!recursive) return null
dependencies.forEach {
it.getClass(className, recursive = false)?.let { clazz -> return clazz }
}
return null
}
fun <K, V> Map<K, V>.unmodifiable(): Map<K, V> {
return Collections.unmodifiableMap(this)
}
// 获取函数声明
fun getFunction(functionName: String, recursive: Boolean = true): AstMethod? {
val functions = methodDeclarations
if (functions != null && functions.containsKey(functionName)) {
val functionDeclaration = functions[functionName]
if (functionDeclaration != null) {
return AstMethod.fromFunction(functionDeclaration, this)
}
}
if (!recursive) {
return null
}
for (dependency in dependencies) {
val function = dependency.getFunction(functionName, recursive = false)
if (function != null) {
return function
}
}
return null
}
private fun _visitNode(
entity: ProgramEntity,
dependencies: MutableSet<ProgramNode>,
node: ProgramNode
) {
for (directive in node.compilation.directives!!) {
when (directive) {
is ImportDirective -> {
val import = Import(directive.uri, "", null)
val newEntity = entity.getRelativeEntity(import.uri)
val newNode = walker.nodeMap[newEntity] ?: run {
if (newEntity.exists) {
val newNode = newEntity.createNode()
walker.nodeMap.putIfAbsent(newEntity, newNode)
newNode
} else null
}
if (newNode != null) {
if (!dependencies.contains(newNode)) {
dependencies.add(newNode)
_visitNode(newEntity, dependencies, newNode)
}
} else {
//反射
data[directive.name] = directive
}
}
// is PartDirective -> {
// val newEntity = entity.getRelativeEntity(directive.uri)
// val newNode = walker.nodeMap[newEntity] ?: run {
// if (newEntity.exists) {
// val newNode = newEntity.createNode()
// walker.nodeMap.putIfAbsent(newEntity, newNode)
// newNode
// } else null
// }
// newNode?.let {
// if (!dependencies.contains(it)) {
// dependencies.add(it)
// _visitNode(newEntity, dependencies, it)
// }
// }
// }
}
}
}
fun computeDependencies(): List<ProgramNode> {
val dependencies = mutableSetOf<ProgramNode>()
_visitNode(entity, dependencies, this)
return dependencies.toList()
}
}
abstract class ProgramEntity {
abstract val exists: Boolean
abstract fun createNode(): ProgramNode
abstract fun getRelativeEntity(uri: String): ProgramEntity
}
// class ProgramNode(
// private val walker: ProgramDependencyWalker,
// private val compilation: CompilationUnit,
// private val entity: ProgramEntity
// ){
//
//// private var imports: List<Import>? = null
//
//// val importsList: List<Import>
//// get() {
//// if (imports == null) {
//// imports = compilation.directives
//// .filterIsInstance<ImportDirective>()
//// .map { directive ->
//// Import(directive.uri, directive.prefix, _getCombinators(directive))
//// }
//// .toList()
//// }
//// return imports!!
//// }
//
// var isEvaluated: Boolean = false
//
//// val dependencies: List<ProgramNode>
//// get() = if (isRecursive) super.getDependencies(this) else emptyList()
//
// var isRecursive: Boolean = true
//
//
// private fun _evaluate() {
// isEvaluated = true
// }
//
// private fun _markCircular() {
// isEvaluated = true
// }
//
// private var classDeclarations: MutableMap<String, ClassDeclaration>? = null
// private var functionDeclarations: MutableMap<String, FunctionDeclaration>? = null
// private var variableDeclarators: MutableMap<String, VariableDeclarator>? = null
//
// fun ensureClassDeclarations() {
// var classDeclarations = this.classDeclarations
// if (classDeclarations == null) {
// val result = mutableMapOf<String, ClassDeclaration>()
// compilation.declarations
// .filterIsInstance<ClassDeclaration>()
// .forEach { declaration ->
// result[declaration.name] = declaration
// }
// classDeclarations = this.classDeclarations =
// Collections.unmodifiableMap(result)
// }
// }
//
// private val classes = mutableMapOf<String, AstClass>()
// private val functions = mutableMapOf<String, AstMethod>()
// private val topLevelVariables = mutableMapOf<String, AstVariable>()
//
//// val classesList: List<AstClass>
//// get() = compilation.declarations
//// .filterIsInstance<ClassDeclaration>()
//// .map { declaration ->
//// getClass(declaration.name, recursive = false)!!
//// }
//
//// fun getClass(className: String, recursive: Boolean = true): AstClass? {
//// ensureClassDeclarations()
//// if (classes.containsKey(className)) {
//// return classes[className]
//// }
//// val classDecl = classDeclarations?.get(className)
//// if (classDecl != null) {
//// val clazz = AstClass.fromClass(classDecl, this)
//// classes[className] = clazz
//// return clazz
//// }
//// if (!recursive) return null
////
//// for (dependency in dependencies) {
//// val clazz = dependency.getClass(className, recursive = false)
//// if (clazz != null) return clazz
//// }
//// return null
//// }
//
// fun getFunction(functionName: String, recursive: Boolean = true): AstMethod? {
// var functions = this.functionDeclarations
// if (functions == null) {
// val result = mutableMapOf<String, FunctionDeclaration>()
// compilation.declarations
// .filterIsInstance<FunctionDeclaration>()
// .forEach { declaration ->
// result[declaration.name] = declaration
// }
// functions = this.functionDeclarations =
// Collections.unmodifiableMap(result)
// }
// functions?.get(functionName)?.let {
// return AstMethod.fromFunction(it, this)
// }
// if (!recursive) return null
//
// for (dependency in dependencies) {
// val function = dependency.getFunction(functionName, recursive = false)
// if (function != null) return function
// }
// return null
// }
//
// private val topLevel = mutableMapOf<String, Variable>()
//
// fun getTopLevelVariable(variableName: String, recursive: Boolean = true): Variable? {
// var topLevelVariables = this.variableDeclarators
// if (topLevelVariables == null) {
// val result = mutableMapOf<String, VariableDeclarator>()
// compilation.declarations
// .filterIsInstance<TopLevelVariableDeclaration>()
// .forEach { declaration ->
// declaration.variables.declarationList.forEach { declarator ->
// result[declarator.name] = declarator
// }
// }
// topLevelVariables = this.variableDeclarators =
// Collections.unmodifiableMap(result)
// }
// topLevelVariables?.get(variableName)?.let {
// val variable = AstVariable.fromDeclarator(it)
// return topLevel.computeIfAbsent(variableName) {
// Variable.lazily(variableName) {
// if (variable.initializer != null) {
// val programStack = context.get<ProgramStack>()!!
// programStack.push(name = "Top-Level variable initializer")
// try {
// executeExpression(variable.initializer)
// } finally {
// programStack.pop()
// }
// }
// }
// }
// }
// if (!recursive) return null
//
// for (dependency in dependencies) {
// val topLevelVariable = dependency.getTopLevelVariable(variableName, recursive = false)
// if (topLevelVariable != null) return topLevelVariable
// }
// return null
// }
//
// // Helper methods and properties that need to be implemented or mapped to Kotlin equivalents
// private fun _getCombinators(directive: ImportDirective): List<String> {
// // Implementation of _getCombinators
// TODO("Implement _getCombinators")
// }
//
//// private fun isPlatformUri(uri: Uri): Boolean {
//// // Implementation of isPlatformUri
//// TODO("Implement isPlatformUri")
//// }
//
// private fun executeExpression(expression: Expression): Any? {
// // Implementation of executeExpression
// TODO("Implement executeExpression")
// }
//
// companion object {
// // Context or other static members can be placed here if needed
// }
// }
//
open fun executeExpression(
expression: KtExpression, flag: String? = null, keepVariable: Boolean = false
): Any? {
return try {
// val programStack = context.get<ProgramStack>() ?: throw IllegalStateException("ProgramStack not found in context")
// if (expression.isIdentifier) {
//
// } else if (expression.isStringLiteral) {
// //string
// return expression?.asStringLiteral()?.value;
// } else {
// println("executeExpression ${expression::class.simpleName} not implemented")
// }
} catch (e: Exception) {
return null
}
}
}
================================================
FILE: core/src/main/java/com/aether/core/runtime/ClassMirror.kt
================================================
package com.aether.core.runtime
import androidx.compose.runtime.Composable
import com.aether.core.runtime.reflectable.ClassMirror
import com.aether.core.runtime.reflectable.ClassMirrorBase
import com.aether.core.runtime.reflectable.ComposeComponentDescriptor
import com.aether.core.runtime.reflectable.ComposeComponentDescriptor2
import com.aether.core.runtime.reflectable.ComposeReflector
import com.aether.core.runtime.reflectable.MethodMirror
import org.jetbrains.kotlin.builtins.StandardNames.FqNames.kProperty
import java.lang.reflect.Modifier
import kotlin.reflect.KCallable
import kotlin.reflect.KClass
import kotlin.reflect.KFunction
import kotlin.reflect.KMutableProperty
import kotlin.reflect.KParameter
import kotlin.reflect.KProperty
import kotlin.reflect.KType
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaMethod
class _ClassMirror(
private val classMirror: ClassMirrorBase,
private val _name: String,
override val superclass: AstClass?,
private val _staticFields: Map<String, _VariableImpl>,
private val _staticGetters: Map<String, AstMethod>,
private val _staticSetters: Map<String, AstMethod>,
val _instanceFields: Map<String, _VariableImpl>,
val _instanceGetters: Map<String, _MethodImpl>,
val _instanceSetters: Map<String, _MethodImpl>,
private val _constructors: Map<String, _ConstructorImpl>,
// private val _node: ClassDeclaration,
override val programNode: AstRuntime.ProgramNode
) : AstObject, AstClass() {
companion object {
fun fromMirror(mirror: ClassMirrorBase, programNode: AstRuntime.ProgramNode): _ClassMirror {
var staticFields: Map<String, _VariableImpl> = HashMap<String, _VariableImpl>()
val staticGetters: HashMap<String, AstMethod> = HashMap<String, AstMethod>()
val staticSetters: HashMap<String, AstMethod> = HashMap<String, AstMethod>()
val instanceFields: Map<String, _VariableImpl> = mapOf<String, _VariableImpl>()
val instanceGetters: Map<String, _MethodImpl> = mapOf<String, _MethodImpl>()
val instanceSetters: Map<String, _MethodImpl> = mapOf<String, _MethodImpl>()
val constructors: Map<String, _ConstructorImpl> = mapOf<String, _ConstructorImpl>()
return _ClassMirror(
mirror,
_name = mirror.simpleName ?: "",
superclass = null,
_staticFields = staticFields,
_staticGetters = staticGetters,
_staticSetters = staticSetters,
_instanceFields = instanceFields,
_instanceGetters = instanceGetters,
_instanceSetters = instanceSetters,
_constructors = constructors,
programNode = programNode,
);
}
}
private var _declarations: Map<String, AstDeclaration>? = null
private var _staticMembers: Map<String, AstMethod>? = null
private var _instanceMembers: Map<String, AstMethod>? = null
override val isAbstract: Boolean
get() = TODO("Not yet implemented")
override val declarations: Map<String, AstDeclaration>
get() = _declarations ?: run {
val result = mutableMapOf<String, AstDeclaration>()
// kClass.members.forEach { member ->
// when (member) {
// is kotlin.reflect.KFunction -> result[member.name] =
// AstMethod.fromMirror(member)
// is kotlin.reflect.KProperty<*> -> result[member.name] =
// AstVariable.fromKCallable(member)
// }
// }
result.toMap().also { _declarations = it }
}
override val instanceFields: Map<String, AstVariable>
get() = TODO("Not yet implemented")
override val instanceGetters: Map<String, AstMethod>
get() = TODO("Not yet implemented")
override val instanceSetters: Map<String, AstMethod>
get() = TODO("Not yet implemented")
override val staticFields: Map<String, AstVariable>
get() = TODO("Not yet implemented")
override val staticGetters: Map<String, AstMethod>
get() = _staticMembers ?: run {
val result = mutableMapOf<String, AstMethod>()
classMirror.staticMembers.forEach { simpleName, member ->
result[simpleName] = AstMethod.fromMirror(member)
}
result.toMap().also { _staticMembers = it }
}
override val staticSetters: Map<String, AstMethod>
get() = TODO("Not yet implemented")
override fun newInstance(
constructorName: String,
positionalArguments: List<Any?>,
namedArguments: Map<String, Any?>?
): Any? {
return classMirror.invoke(constructorName, positionalArguments, namedArguments)
}
override fun isSubclassOf(other: AstClass): Boolean {
TODO("Not yet implemented")
}
override fun hasConstructor(constructorName: String): Boolean {
return false
}
override val simpleName: String
get() = _name
override val qualifiedName: String
get() = _name
override val owner: AstDeclaration?
get() = TODO("Not yet implemented")
override val isPrivate: Boolean
get() = throw NotImplementedError()
override fun invoke(
memberName: String,
positionalArguments: List<Any?>,
namedArguments: Map<String, Any?>?
): Any? {
val method = staticGetters[memberName] ?: throw NoSuchMethodError("Member $memberName not found")
return invokeStaticMethod(method, positionalArguments, namedArguments)
}
override fun invokeGetter(getterName: String): Any? {
TODO("Not yet implemented")
}
override fun hasGetter(getterName: String): Boolean {
TODO("Not yet implemented")
}
override fun invokeSetter(setterName: String, value: Any?): Any? {
TODO("Not yet implemented")
}
override fun hasSetter(setterName: String): Boolean {
TODO("Not yet implemented")
}
override fun hasRegularMethod(methodName: String): Boolean {
TODO("Not yet implemented")
}
private fun invokeStaticMethod(
name: AstMethod,
positionalArguments: List<Any?>,
namedArguments: Map<String, Any?>?
): Any? {
val methodMirror = (name as _MethodMirror2)._methodMirror
return ComposeComponentDescriptor2(
methodMirror = methodMirror,
"",
positionalArguments = positionalArguments,
namedArguments = namedArguments,
children = null
)
// return methodMirror?.invoke(null,namedArguments)
}
private fun buildParameters(
kFunction: KFunction<*>,
positionalArgs: List<Any?>,
namedArgs: Map<String, Any?>?
): Map<KParameter, Any?> {
val parameters = kFunction.parameters
val result = mutableMapOf<KParameter, Any?>()
// 处理位置参数
var positionalIndex = 0
for (param in parameters) {
if (positionalIndex < positionalArgs.size && !param.isVararg) {
result[param] = positionalArgs[positionalIndex]
positionalIndex++
} else if (namedArgs?.containsKey(param.name) == true) {
// 处理命名参数
result[param] = namedArgs[param.name]
} else if (param.isVararg) {
// 如果是可变参数,则需要特殊处理
val remainingPosArgs = positionalArgs.drop(positionalIndex)
result[param] = if (remainingPosArgs.isNotEmpty())
remainingPosArgs.toTypedArray()
else
null
}
}
return result
}
private fun convertType(type: KType, value: Any?): Any? {
return when (type.classifier) {
Double::class -> value?.toString()?.toDoubleOrNull()
else -> value
}
}
}
//class _ClassMirror(private val _classMirror: ClassMirror) : AstObject, AstClass() {
// private var _declarations: Map<String, AstDeclaration>? = null
// private var _staticMembers: Map<String, AstMethod>? = null
// private var _instanceMembers: Map<String, AstMethod>? = null
//
// override val declarations: Map<String, AstDeclaration>
// get() = _declarations ?: run {
// val result = mutableMapOf<String, AstDeclaration>()
// _classMirror.declarations.forEach { (name, mirror) ->
// when (mirror) {
// is MethodMirror -> result[name] = AstMethod.fromMirror(mirror)
// is VariableMirrorBase -> result[name] = AstVariable.fromMirror(mirror)
// }
// }
// result.toMap().also { _declarations = it }
// }
//
// override val staticMembers: Map<String, AstMethod>
// get() = _staticMembers ?: run {
// val result = mutableMapOf<String, AstMethod>()
// _classMirror.staticMembers.forEach { (name, mirror) ->
// result[name] = AstMethod.fromMirror(mirror)
// }
// result.toMap().also { _staticMembers = it }
// }
//
// override fun hasConstructor(constructorName: String): Boolean {
// val methodName = if (constructorName.isEmpty()) simpleName else "$simpleName.$constructorName"
// return (_classMirror.declarations[methodName] as? MethodMirror)?.isConstructor ?: false
// }
//
// override fun invoke(memberName: String, positionalArguments: List<Any?>, namedArguments: MutableMap<String, Any?>?): Any? {
// val method = staticMembers[memberName] ?: throw NoSuchMethodError("Member $memberName not found")
//// processArguments(method.parameters, positionalArguments, namedArguments)
// processArguments(mutableListOf<AstParameter>(), positionalArguments, namedArguments)
// return _classMirror.invoke(memberName, positionalArguments, namedArguments)
// }
//
// // 其他方法类似转换...
//}
class _MethodMirror2(methodMirror: MethodMirror) : AstMethod {
var _methodMirror: MethodMirror? = null
init {
this._methodMirror = methodMirror
}
companion object {
fun fromMirror(mirror: KFunction<*>): _MethodMirror {
return _MethodMirror(mirror);
}
fun fromMirror(mirror: MethodMirror): _MethodMirror2 {
return _MethodMirror2(mirror);
}
}
fun fromKCallable(member: KFunction<*>): AstDeclaration {
return _MethodMirror.fromMirror(member)
}
val isMutable: Boolean
// get() = kProperty is KMutableProperty<*>
get() = true
val setter: KCallable<*>?
get() = if (isMutable) (kProperty as? KMutableProperty<*>)?.setter else null
val isConstConstructor: Boolean
get() = false // Kotlin does not have a direct equivalent of Dart's const constructors
val isRedirectingConstructor: Boolean
get() = false // Kotlin does not have redirecting constructors
override val owner: AstDeclaration?
get() = null // Unimplemented for simplicity
override val isPrivate: Boolean
get() = TODO("Not yet implemented")
private var _parameters: List<AstParameter>? = null
override val parameters: List<_ParameterImpl>
get() {
return mutableListOf()
}
override val isStatic: Boolean
get() = TODO("Not yet implemented")
override val isAbstract: Boolean
get() = TODO("Not yet implemented")
override val returnType: AstType
get() = throw UnimplementedError("returnType error")
override val simpleName: String
get() = _methodMirror?.simpleName ?: ""
override val qualifiedName: String
get() = _methodMirror?.qualifiedName ?: ""
override fun toString(): String = "_MethodMirror($qualifiedName)"
override val isSynthetic: Boolean
// get() = kFunction.isSynthetic
get() = true
override val isRegularMethod: Boolean
get() = TODO("Not yet implemented")
override val isGetter: Boolean
get() = TODO("Not yet implemented")
override val isSetter: Boolean
get() = TODO("Not yet implemented")
override val isOperator: Boolean
get() = TODO("Not yet implemented")
override val isConstructor: Boolean
get() = TODO("Not yet implemented")
override val constructorName: String
get() = TODO("Not yet implemented")
override val programNode: AstRuntime.ProgramNode
get() = throw UnsupportedOperationException()
}
class _MethodMirror(val kFunction: KFunction<*>) : AstMethod {
var function: KFunction<*>? = null
init {
this.function = kFunction
}
companion object {
fun fromMirror(mirror: KFunction<*>): _MethodMirror {
return _MethodMirror(mirror);
}
fun fromMirror(mirror: MethodMirror): _MethodMirror2 {
return _MethodMirror2(mirror);
}
}
fun fromKCallable(member: KFunction<*>): AstDeclaration {
return fromMirror(member)
}
val isBound: Boolean
get() = kFunction.isInstanceBound()
private fun KFunction<*>.isInstanceBound(): Boolean {
return when {
this is Function<*> -> {
// 如果是 lambda 或局部函数,可能无法直接判断
false
}
else -> {
// 检查是否有接收者参数
// parameters.firstOrNull()?.isInstanceParameter == true
true
}
}
}
val isMutable: Boolean
// get() = kProperty is KMutableProperty<*>
get() = true
val setter: KCallable<*>?
get() = if (isMutable) (kProperty as? KMutableProperty<*>)?.setter else null
val declaringClass: KClass<*>?
get() = kFunction.declaringClass()
private fun KFunction<*>.declaringClass(): KClass<*>? {
return when {
javaMethod != null -> javaMethod!!.declaringClass.kotlin // 如果是 Java 方法
else -> this.parameters.firstOrNull()?.type?.classifier as? KClass<*>
}
}
override val constructorName: String
get() = if (kFunction.name == "<init>") declaringClass?.simpleName ?: "" else ""
override val isAbstract: Boolean
get() = kFunction.isAbstract
val isConstConstructor: Boolean
get() = false // Kotlin does not have a direct equivalent of Dart's const constructors
override val isConstructor: Boolean
get() = kFunction.name == "<init>"
val isFactoryConstructor: Boolean
get() = false // Kotlin does not have factory constructors
override val isGetter: Boolean
get() = kFunction is KProperty<*> && !setter!!.isAccessible
override val isOperator: Boolean
get() = kFunction.name.startsWith("operator")
override val isPrivate: Boolean
get() = Modifier.isPrivate(kFunction.javaMethod?.modifiers ?: 0)
val isRedirectingConstructor: Boolean
get() = false // Kotlin does not have redirecting constructors
override val isSetter: Boolean
get() = kFunction is KMutableProperty<*>
override val isStatic: Boolean
get() = isBound
override val owner: AstDeclaration?
get() = null // Unimplemented for simplicity
private var _parameters: List<AstParameter>? = null
override val parameters: List<_ParameterImpl>
get() {
// if (_parameters == null) {
// _parameters = kFunction.parameters.map { AstParameter.fromKParameter(it) }
// }
// return _parameters!!
return mutableListOf()
}
override val returnType: AstType
get() = throw UnimplementedError("returnType error")
override val simpleName: String
get() = kFunction.name
override val qualifiedName: String
get() = "${kFunction.name}"
override fun toString(): String = "_MethodMirror($qualifiedName)"
override val isRegularMethod: Boolean
get() = kFunction.name != "<init>" && kFunction.name != "<clinit>"
override val isSynthetic: Boolean
// get() = kFunction.isSynthetic
get() = true
override val programNode: AstRuntime.ProgramNode
get() = throw UnsupportedOperationException()
}
private fun <T> processArguments(
parameters: List<AstParameter>?,
positionalArgs: List<Any?>,
namedArgs: Map<String, Any?>?
) {
// parameters.forEachIndexed { i, param ->
// when {
// param.isNamed && namedArgs?.containsKey(param.simpleName) == true -> {
// namedArgs[param.simpleName] =
// convertType(param, namedArgs.getValue(param.simpleName))
// }
// i < positionalArgs.size -> {
// positionalArgs[i] = convertType(param, positionalArgs[i])
// }
// }
// }
}
// _InstanceMirror.kt
//class _InstanceMirror(private val _instanceMirror: InstanceMirror) : AstObject(), AstInstance {
// override val type: AstClass get() = AstClass.fromMirror(_instanceMirror.type)
//
// override fun invoke(memberName: String, positionalArguments: List<Any?>, namedArguments: Map<Symbol, Any?>?): Any? {
// return context.run{
// val method = (type as _ClassMirror).instanceMembers[memberName]
// ?: throw NoSuchMethodError("Method $memberName not found")
// processArguments(method.parameters, positionalArguments, namedArguments)
// _instanceMirror.invoke(memberName, positionalArguments, namedArguments)
// }
// }
// 其他方法转换...
//}
//private fun convertType(param: AstParameter, value: Any?): Any? {
// return when (param.reflectedType) {
// Double::class -> value?.toString()?.toDoubleOrNull()
// else -> value
// }
//}
================================================
FILE: core/src/main/java/com/aether/core/runtime/KtAstVisitor.kt
================================================
package com.aether.core.runtime
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.lexer.KtSingleValueToken
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
// 自定义访问者类,继承 KtTreeVisitorVoid
class MyKtVisitorV2 : KtVisitor<Map<String, Any?>, Void?>() {
// 用于存储遍历结果的 Map
private val result = mutableMapOf<String, Any>()
// 获取遍历结果
fun getResult(): Map<String, Any> {
return result.toMap()
}
// 遍历单个节点
private fun visitNode(node: KtElement?, data: Void?): Map<String, Any?>? {
// 调用 accept 方法,启动访问者模式的遍历
if (node != null) {
return node.accept(this, data)
}
return null
}
// 遍历节点列表
private fun visitNodeList(nodes: List<KtElement>, data: Void?): List<Map<String, Any?>> {
val maps = mutableListOf<Map<String, Any?>>()
for (node in nodes) {
val res = visitNode(node, data)
if (res != null) {
maps.add(res)
}
}
return maps
}
override fun visitKtElement(element: KtElement, data: Void?): Map<String, Any>? {
// println("Visiting element: ${element.text}")
super.visitElement(element)
return mutableMapOf()
}
override fun visitElement(element: PsiElement) {
super.visitElement(element)
}
// override fun visitSimpleNameExpression(
// node: KtSimpleNameExpression,
// data: Void?
// ): Map<String, Any?> {
// super.visitSimpleNameExpression(node, data)
// println("Visiting Identifier: ${node.name}")
// return mapOf(
// "type" to "Identifier",
// "name" to node.name,
// )
// }
override fun visitKtFile(file: KtFile, data: Void?): Map<String, Any>? {
println("Visiting file: ${file.name}")
// result["file"] = file.name
// 处理包声明
// val packageDirective = file.packageDirective
// if (packageDirective != null) {
// println("Package: ${packageDirective.fqName.asString()}")
// result["package"] = packageDirective.fqName.asString()
// }
// 处理导入语句
// for (import in file.importDirectives) {
// println("Import: ${import.importPath?.toString()}")
// result["directives"] =
// result.getOrDefault("imports", mutableListOf<String>()) as MutableList<String>
// (result["directives"] as MutableList<String>).add(
// import.importPath?.toString() ?: "Unknown"
// )
// }
val declarations = file.declarations
if (declarations != null) {
val directives = file.importDirectives
println("Import: ${directives?.toString()}")
result["directives"] = visitNodeList(directives, data)
println("declarations: ${declarations.asSequence()}")
result["declarations"] = visitNodeList(declarations, data)
result["type"] = "CompilationUnit"
}
file.acceptChildren(this)
return result
}
override fun visitBlockExpression(
node: KtBlockExpression, data: Void?
): Map<String, Any?> {
super.visitBlockExpression(node, data)
println("Visiting class: ${node.name}")
return mapOf(
"type" to "BlockStatement",
"body" to visitNodeList(node.statements, data),
)
}
override fun visitObjectDeclaration(
node: KtObjectDeclaration, data: Void?
): Map<String, Any?> {
// 1 val annotations = node.annotationEntries
// return annotations.any { it.shortName()?.asString() == "JvmStatic" }
// 2 val containingClass = function.containingClassOrObject
// return containingClass is KtObjectDeclaration && containingClass.isCompanion()
// 3 function.parent is KtFile
println("Visiting visitObjectDeclaration: ${node.name}")
return mapOf(
"type" to "ClassDeclaration",
"name" to node.name,
"members" to visitNodeList(node.declarations, data),
"body" to visitNode(node.body, data),
)
}
// 重写 visitClass 方法,处理类节点
override fun visitClass(klass: KtClass, data: Void?): Map<String, Any?>? {
println("Visiting class: ${klass.name}")
super.visitClass(klass, data)
return mapOf(
"type" to "ClassDeclaration",
"name" to klass.name,
"members" to visitNodeList(klass.declarations, data),
"body" to visitNode(klass.body, data),
)
}
override fun visitCallableReferenceExpression(
expression: KtCallableReferenceExpression,
data: Void?
): Map<String, Any?> {
super.visitCallableReferenceExpression(expression, data)
return mapOf(
"type" to "visitCallableReferenceExpression",
"name" to expression.name,
"targetExpression" to visitNode(expression.receiverExpression, data),//右边部分
)
}
override fun visitLambdaExpression(
expression: KtLambdaExpression,
data: Void?
): Map<String, Any?> {
super.visitLambdaExpression(expression, data)
println("Visiting visitLambdaExpression: ${expression.name}")
return mapOf(
"type" to "LambdaExpression",
"name" to expression.name,
"parameters" to visitNodeList(expression.valueParameters, data),
"body" to visitNode(expression.bodyExpression, data),
"returnType" to visitNode(expression.functionLiteral, data),
)
}
// override fun visitFunctionDeclaration(node: KtNamedFunction, data: Void?): Map<String, Any?>? {
// println("Visiting function: ${node.name}")
// super.visitNamedFunction(node, data)
// val parameters = visitNodeList(node.valueParameters, data)
// return mapOf(
// "type" to "FunctionDeclaration",
// "name" to node.name,
// "parameters" to parameters,
// "typeParameters" to visitNodeList(node.typeParameters, data),
// "body" to visitNode(node.bodyExpression, data),
// "isStatic" to isStaticMethod(node),
// "isGetter" to parameters.isEmpty(),
// "isSetter" to (parameters.size == 1 && node.name!!.startsWith("set")),
// "node" to node
// )
//
// }
override fun visitNamedFunction(node: KtNamedFunction, data: Void?): Map<String, Any?>? {
println("Visiting function: ${node.name}")
super.visitNamedFunction(node, data)
val parameters = visitNodeList(node.valueParameters, data)
return mapOf(
"type" to "MethodDeclaration",
"name" to node.name,
"parameters" to parameters,
"typeParameters" to visitNodeList(node.typeParameters, data),
"body" to visitNode(node.bodyExpression, data),
"isStatic" to isStaticMethod(node),
"isGetter" to parameters.isEmpty(),
"isSetter" to (parameters.size == 1 && node.name!!.startsWith("set")),
// "node" to node
)
}
override fun visitValueArgumentList(node: KtValueArgumentList, data: Void?): Map<String, Any?> {
println("visitValueArgumentList: ${node.name}")
super.visitValueArgumentList(node, data)
return mapOf(
"type" to "ArgumentList",
"arguments" to visitNodeList(node.arguments, data),
)
}
override fun visitParameterList(node: KtParameterList, data: Void?): Map<String, Any?> {
println("Visiting function: ${node.name}")
super.visitParameterList(node, data)
return mapOf(
"type" to "ParameterList",
"name" to node.name,
"parameters" to visitNodeList(node.parameters, data),
)
}
// 重写 visitProperty 方法,处理属性节点
override fun visitProperty(property: KtProperty, data: Void?): Map<String, Any?>? {
println("Visiting property: ${property.name}")
super.visitProperty(property, data)
return if (property.containingClassOrObject != null) {
mapOf(
"type" to "FieldDeclaration",
"name" to property.name,
"initializer" to visitNode(property.initializer, data),
)
} else {
mapOf(
"type" to "PropertyStatement",
"name" to property.name,
"initializer" to visitNode(property.initializer, data),
)
}
}
// 重写 visitBinaryExpression 方法,处理二元表达式
override fun visitBinaryExpression(
expression: KtBinaryExpression, data: Void?
): Map<String, Any?>? {
println("Visiting binary expression: ${expression.text}")
super.visitBinaryExpression(expression, data)
return mapOf(
"type" to "BinaryExpression",
"name" to expression.name,
"operator" to (expression.operationToken as KtSingleValueToken).value,
"left" to visitNode(expression.left, data),
"right" to visitNode(expression.right, data),
// "node" to expression,
)
}
override fun visitReferenceExpression(
expression: KtReferenceExpression,
data: Void?
): Map<String, Any?> {
println("Visiting visitReferenceExpression: ${expression.text}")
super.visitReferenceExpression(expression, data)//visitSimpleIdentifier
return mapOf(
"type" to "Identifier",
"name" to expression.text,
)
}
override fun visitSecondaryConstructor(
constructor: KtSecondaryConstructor,
data: Void?
): Map<String, Any?>? {
super.visitSecondaryConstructor(constructor, null)
println("Visiting visitSecondaryConstructor: ${constructor.name}")
return mapOf(
"type" to "SecondaryConstructor",
"name" to constructor.name,
"body" to visitNode(constructor.bodyExpression, data),
"parameters" to visitNode(constructor.valueParameterList, data),
)
}
override fun visitStringTemplateExpression(
expression: KtStringTemplateExpression,
data: Void?
): Map<String, Any?> {
// 手动遍历子节点
for (entry in expression.entries) {
when (entry) {
is KtLiteralStringTemplateEntry -> {
return mapOf(
"type" to "StringTemplateExpression",
"name" to entry.name,
"body" to visitNode(entry, data),
)
}
is KtSimpleNameStringTemplateEntry -> visitNode(entry, data)
// is KtExpressionStringTemplateEntry -> visitExpressionStringTemplateEntry(entry)
else -> entry.accept(this) // 对于未知类型,可以使用 accept 方法
}
}
return super.visitStringTemplateExpression(expression, data)
}
override fun visitLiteralStringTemplateEntry(
entry: KtLiteralStringTemplateEntry,
data: Void?
): Map<String, Any?> {
super.visitLiteralStringTemplateEntry(entry, data)
return mapOf(
"type" to "StringTemplateEntry",
"body" to visitNode(entry.expression, data),
"value" to entry.text
)
}
override fun visitConstantExpression(
expression: KtConstantExpression,
data: Void?
): Map<String, Any?> {
super.visitConstantExpression(expression, data)
return mapOf(
"type" to expression.elementType.debugName,
"value" to expression.text,
"name" to "ConstantExpression",
)
}
override fun visitPrimaryConstructor(
constructor: KtPrimaryConstructor,
data: Void?
): Map<String, Any?>? {
println("Visiting visitPrimaryConstructor: ${constructor.name}")
super.visitPrimaryConstructor(constructor, null)
return mapOf(
"type" to "PrimaryConstructor",
"name" to constructor.name,
"body" to visitNode(constructor.bodyExpression, data),
"parameters" to visitNode(constructor.valueParameterList, data),
)
}
//
// override fun visitTypeAlias(typeAlias: KtTypeAlias) {
// println("Visiting visitTypeAlias: ${typeAlias.name}")
// super.visitTypeAlias(typeAlias, null)
// }
//
// override fun visitDestructuringDeclaration(destructuringDeclaration: KtDestructuringDeclaration) {
// println("Visiting visitDestructuringDeclaration: ${destructuringDeclaration.name}")
// super.visitDestructuringDeclaration(destructuringDeclaration, null)
// }
//
// override fun visitDestructuringDeclarationEntry(multiDeclarationEntry: KtDestructuringDeclarationEntry) {
// println("Visiting visitDestructuringDeclarationEntry: ${multiDeclarationEntry.name}")
// super.visitDestructuringDeclarationEntry(multiDeclarationEntry, null)
// }
//
// override fun visitScript(script: KtScript) {
// println("Visiting visitScript: ${script?.name}")
// super.visitScript(script, null)
// }
//
// override fun visitImportAlias(importAlias: KtImportAlias) {
// println("Visiting visitImportAlias: ${importAlias?.name}")
// super.visitImportAlias(importAlias, null)
// }
//
override fun visitImportDirective(
node: KtImportDirective,
data: Void?
): Map<String, Any?>? {
println("Visiting visitImportDirective: ${node?.name}")
super.visitImportDirective(node, null)
// node.importPath?.fqName?.asString()
return mapOf(
"type" to "ImportDirective",
"importPath" to node.importPath?.pathStr,
"alias" to node.alias?.text,
"name" to node.importedFqName?.shortName()?.identifier,
)
}
// override fun visitImportList(importList: KtImportList, data: Void?): Map<String, Any?> {
// super.visitImportList(importList, data)
// return mapOf(
// "type" to "ImportList",
// "imports" to visitNodeList(importList.imports, data),
//// "prefix" to visitNode(node.pre,data),
//// "combinators" to visitNode(node.comb,data),
// )
//
// }
//
// override fun visitModifierList(list: KtModifierList) {
// println("Visiting visitModifierList: ${list?.name}")
// super.visitModifierList(list, null)
// }
//
// override fun visitAnnotation(annotation: KtAnnotation) {
// println("Visiting visitAnnotation: ${annotation?.name}")
// super.visitAnnotation(annotation, null)
// }
//
// override fun visitAnnotationEntry(annotationEntry: KtAnnotationEntry) {
// println("Visiting visitAnnotationEntry: ${annotationEntry?.name}")
// super.visitAnnotationEntry(annotationEntry, null)
// }
//
// override fun visitConstructorCalleeExpression(constructorCalleeExpression: KtConstructorCalleeExpression) {
// println("Visiting visitConstructorCalleeExpression: ${constructorCalleeExpression?.name}")
// super.visitConstructorCalleeExpression(constructorCalleeExpression, null)
// }
//
override fun visitTypeParameterList(
node: KtTypeParameterList, data: Void?
): Map<String, Any?>? {
println("Visiting visitTypeParameterList: ${node?.name}")
super.visitTypeParameterList(node, null)
return mapOf(
"type" to "TypeParameterList",
"typeParameters" to visitNodeList(node.parameters, data),
)
}
override fun visitTypeParameter(node: KtTypeParameter, data: Void?): Map<String, Any?>? {
println("Visiting visitTypeParameter: ${node?.name}")
super.visitTypeParameter(node, null)
return mapOf(
"type" to "TypeParameter",
"name" to node.name,
"bound" to visitNode(node.extendsBound, data),
)
}
//
// override fun visitEnumEntry(enumEntry: KtEnumEntry) {
// println("Visiting visitEnumEntry: ${enumEntry?.name}")
// super.visitEnumEntry(enumEntry, null)
// }
//
override fun visitParameter(parameter: KtParameter, data: Void?): Map<String, Any?>? {
println("Visiting visitParameter: ${parameter?.name}")
super.visitParameter(parameter, null)
parameter
return mapOf(
"type" to "SimpleFormalParameter",
"name" to parameter.name,
"typeName" to parameter.typeReference?.text,
)
}
//
// override fun visitSuperTypeList(list: KtSuperTypeList) {
// println("Visiting visitSuperTypeList: ${list?.name}")
// super.visitSuperTypeList(list, null)
// }
//
// override fun visitSuperTypeListEntry(specifier: KtSuperTypeListEntry) {
// println("Visiting visitSuperTypeList: ${specifier?.name}")
// super.visitSuperTypeListEntry(specifier, null)
// }
//
// override fun visitDelegatedSuperTypeEntry(specifier: KtDelegatedSuperTypeEntry) {
// println("Visiting visitDelegatedSuperTypeEntry: ${specifier?.name}")
// super.visitDelegatedSuperTypeEntry(specifier, null)
// }
//
// override fun visitSuperTypeCallEntry(call: KtSuperTypeCallEntry) {
// println("Visiting visitSuperTypeCallEntry: ${call?.name}")
// super.visitSuperTypeCallEntry(call, null)
// }
//
// override fun visitSuperTypeEntry(specifier: KtSuperTypeEntry) {
// super.visitSuperTypeEntry(specifier, null)
// }
//
// override fun visitContextReceiverList(contextReceiverList: KtContextReceiverList) {
// super.visitContextReceiverList(contextReceiverList, null)
// }
//
// override fun visitConstructorDelegationCall(call: KtConstructorDelegationCall) {
// super.visitConstructorDelegationCall(call, null)
// }
//
// override fun visitPropertyDelegate(delegate: KtPropertyDelegate) {
// super.visitPropertyDelegate(delegate, null)
// }
//
override fun visitArgument(argument: KtValueArgument, data: Void?): Map<String, Any?>? {
super.visitArgument(argument, null)
return mapOf(
"type" to "Argument",
"isNamed" to argument.isNamed(),
"name" to argument.getArgumentName()?.text,
"body" to visitNode(argument.getArgumentExpression(), data),
)
}
//
// override fun visitLoopExpression(loopExpression: KtLoopExpression) {
// super.visitLoopExpression(loopExpression, null)
// }
//
override fun visitLabeledExpression(
node: KtLabeledExpression, data: Void?
): Map<String, Any?>? {
super.visitLabeledExpression(node, null)
return visitNode(node.labelQualifier, data)
}
//
// override fun visitPrefixExpression(expression: KtPrefixExpression) {
// super.visitPrefixExpression(expression, null)
// }
//
// override fun visitPostfixExpression(expression: KtPostfixExpression) {
// super.visitPostfixExpression(expression, null)
// }
//
// override fun visitUnaryExpression(expression: KtUnaryExpression) {
// super.visitUnaryExpression(expression, null)
// }
//
override fun visitReturnExpression(
expression: KtReturnExpression, data: Void?
): Map<String, Any?>? {
println("Visiting visitReturnExpression: ${expression?.name}")
return mapOf(
"type" to "ReturnStatement",
"argument" to visitNode(expression.returnedExpression, null),
)
}
//
// override fun visitExpressionWithLabel(expression: KtExpressionWithLabel) {
// super.visitExpressionWithLabel(expression, null)
// }
//
override fun visitThrowExpression(
node: KtThrowExpression,
data: Void?
): Map<String, Any?>? {
super.visitThrowExpression(node, null)
println("Visiting visitThrowExpression: ${node?.name}")
return mapOf(
"type" to "ThrowExpression",
"expression" to visitNode(node.thrownExpression, data),
// "node" to node,
)
}
override fun visitBreakExpression(
node: KtBreakExpression,
data: Void?
): Map<String, Any?>? {
super.visitBreakExpression(node, null)
println("Visiting visitBreakExpression: ${node?.name}")
return mapOf(
"type" to "BreakStatement",
"label" to visitNode(node.labelQualifier, data),
"target" to visitNode(node.getTargetLabel(), data),
)
}
//
// override fun visitContinueExpression(expression: KtContinueExpression) {
// super.visitContinueExpression(expression, null)
// }
//
override fun visitIfExpression(node: KtIfExpression, data: Void?): Map<String, Any?>? {
super.visitIfExpression(node, null)
println("Visiting visitIfExpression: ${node?.name}")
return mapOf(
"type" to "IfExpression",
"condition" to visitNode(node.condition, data),
"consequent" to visitNode(node.then, data),
"alternate" to visitNode(node.`else`, data),
)
}
//
// override fun visitWhenExpression(expression: KtWhenExpression) {
// super.visitWhenExpression(expression, null)
// }
//
// override fun visitCollectionLiteralExpression(expression: KtCollectionLiteralExpression) {
// super.visitCollectionLiteralExpression(expression, null)
// }
//
// override fun visitTryExpression(expression: KtTryExpression) {
// super.visitTryExpression(expression, null)
// }
//
// override fun visitForExpression(expression: KtForExpression) {
// super.visitForExpression(expression, null)
// }
//
// override fun visitWhileExpression(expression: KtWhileExpression) {
// super.visitWhileExpression(expression, null)
// }
//
// override fun visitDoWhileExpression(expression: KtDoWhileExpression) {
// super.visitDoWhileExpression(expression, null)
// }
//
// override fun visitLambdaExpression(lambdaExpression: KtLambdaExpression) {
// super.visitLambdaExpression(lambdaExpression, null)
// }
//
// override fun visitAnnotatedExpression(expression: KtAnnotatedExpression) {
// super.visitAnnotatedExpression(expression, null)
// }
//
override fun visitConstructorCalleeExpression(
expression: KtConstructorCalleeExpression,
data: Void?
): Map<String, Any?> {
println("Visiting visitConstructorCalleeExpression: ${expression?.name}")
return super.visitConstructorCalleeExpression(expression, data)
}
/**
* visitCallExpression 方法在 Kotlin 的 AST(抽象语法树)访问器模式中用于处理函数或构造函数的调用。
* 这意味着它不仅处理普通函数的调用,也包括对象实例化时构造函数的调用
* KtConstructorCalleeExpression专门用于表示对构造函数的引用
*/
// override fun visitCallExpression(
// expression: KtCallExpression,
// data: Void?
// ): Map<String, Any?>? {
// super.visitCallExpression(expression, null)
// println("Visiting visitCallExpression: ${expression?.name}")
// val callee = expression.calleeExpression
// if (callee is KtConstructorCalleeExpression) {
// // 这是一个构造函数调用
// println("Detected constructor call: ${callee.text}")
// }
// //这里因为没有办法区分是构造方法还是普通方法,所以通过方法名称的大写暂时先这样判断,后续优化吧
// if (expression.calleeExpression!!.text[0].isUpperCase()) {
// return mapOf(
// "type" to "InstanceCreationExpression",
// "constructorName" to expression.calleeExpression?.text,
// "argumentList" to visitNode(expression.valueArgumentList, data),
// "valueArgument" to visitNodeList(expression.typeArguments, data),
// )
// } else {
// return mapOf(
// "type" to "CallExpression",
// "methodName" to visitNode(expression.calleeExpression, data),
// "target" to visitNode(expression.calleeExpression, data),
// "argumentList" to visitNode(expression.valueArgumentList, data),
// "valueArgument" to visitNodeList(expression.typeArguments, data),
// )
// }
// }
override fun visitCallExpression(
expression: KtCallExpression,
data: Void?
): Map<String, Any?>? {
super.visitCallExpression(expression, null)
println("Visiting visitCallExpression: ${expression.calleeExpression?.text}")
val callee = expression.calleeExpression
if (callee is KtConstructorCalleeExpression) {
// 这是一个构造函数调用
println("Detected constructor call: ${callee.text}")
}
// 检查是否有尾随 lambda
val lambdaArgument = expression.lambdaArguments.firstOrNull()
val childElements = mutableListOf<Map<String, Any?>?>()
// 访问 lambda 体中的表达式
if (lambdaArgument != null) {
val lambdaExpression = lambdaArgument.getLambdaExpression()
val lambdaBody = lambdaExpression?.bodyExpression
// 访问 lambda 体中的所有语句
if (lambdaBody != null) {
val bodyStatements = when (lambdaBody) {
is KtBlockExpression -> lambdaBody.statements
else -> listOf(lambdaBody) // 如果不是块表达式,则将整个表达式视为单个语句
}
// 遍历 lambda 体中的所有语句
for (statement in bodyStatements) {
if (statement is KtCallExpression) {
// 递归访问子调用表达式
childElements.add(visitCallExpression(statement, data))
}
}
}
}
// 判断是构造方法还是普通方法
if (expression.calleeExpression?.text?.firstOrNull()?.isUpperCase() == true) {
return mapOf(
"type" to "InstanceCreationExpression",
"constructorName" to expression.calleeExpression?.text,
"argumentList" to visitNode(expression.valueArgumentList, data),
"typeArguments" to visitNodeList(expression.typeArguments, data),
"children" to childElements // 添加子元素列表
)
} else {
return mapOf(
"type" to "CallExpression",
"methodName" to visitNode(expression.calleeExpression, data),
"target" to visitNode(expression.calleeExpression, data),
"argumentList" to visitNode(expression.valueArgumentList, data),
"typeArguments" to visitNodeList(expression.typeArguments, data),
"children" to childElements // 添加子元素列表
)
}
}
override fun visitDotQualifiedExpression(
expression: KtDotQualifiedExpression,
data: Void?
): Map<String, Any?> {
//对应visitPropertyAccess
println("Visiting DotQualifiedExpression: ${expression.name}")
super.visitDotQualifiedExpression(expression, data)
return mapOf(
"type" to "MethodInvocation",
"name" to expression.name,
"methodName" to visitNode(
expression.selectorExpression,
data
),//右边部分 ,要执行的方法test1,指令的部分比如比如DemoTest.test1.
"target" to visitNode(expression.receiverExpression, data),//左边部分,指令的部分比如比如DemoTest
)
// return {
// 'type': 'PropertyAccess',
// 'id': _visitNode(node.propertyName),
// 'target': _visitNode(node.target),
// 'isCascaded': node.isCascaded,
// 'isNullAware': node.isNullAware,
// 'node': node,
// };
}
//
// override fun visitArrayAccessExpression(expression: KtArrayAccessExpression) {
// super.visitArrayAccessExpression(expression, null)
// }
//
// override fun visitQualifiedExpression(expression: KtQualifiedExpression) {
// super.visitQualifiedExpression(expression, null)
// }
//
// override fun visitDoubleColonExpression(expression: KtDoubleColonExpression) {
// super.visitDoubleColonExpression(expression, null)
// }
//
// override fun visitCallableReferenceExpression(expression: KtCallableReferenceExpression) {
// super.visitCallableReferenceExpression(expression, null)
// }
//
// override fun visitClassLiteralExpression(expression: KtClassLiteralExpression) {
// super.visitClassLiteralExpression(expression, null)
// }
//
// override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) {
// super.visitDotQualifiedExpression(expression, null)
// }
//
// override fun visitSafeQualifiedExpression(expression: KtSafeQualifiedExpression) {
// super.visitSafeQualifiedExpression(expression, null)
// }
//
// override fun visitObjectLiteralExpression(expression: KtObjectLiteralExpression) {
// super.visitObjectLiteralExpression(expression, null)
// }
override fun visitCatchSection(catchClause: KtCatchClause, data: Void?): Map<String, Any?>? {
super.visitCatchSection(catchClause, null)
println("Visiting visitCatchSection: ${catchClause?.name}")
return mapOf(
"type" to "CatchSection",
"name" to catchClause.name,
)
}
//
// override fun visitFinallySection(finallySection: KtFinallySection) {
// super.visitFinallySection(finallySection, null)
// }
//
override fun visitTypeArgumentList(
node: KtTypeArgumentList,
data: Void?
): Map<String, Any?>? {
super.visitTypeArgumentList(node, null)
println("Visiting visitTypeArgumentList: ${node?.name}")
return mapOf(
"type" to "TypeArgumentList",
"arguments" to visitNodeList(node.arguments, data),
)
}
override fun visitThisExpression(
node: KtThisExpression,
data: Void?
): Map<String, Any?>? {
super.visitThisExpression(node, null)
println("Visiting visitThisExpression: ${node?.name}")
return mapOf(
"type" to "ThisExpression",
)
}
override fun visitSuperExpression(
node: KtSuperExpression,
data: Void?
): Map<String, Any?>? {
super.visitSuperExpression(node, null)
println("Visiting visitSuperExpression: ${node?.name}")
return mapOf(
"type" to "SuperExpression",
)
}
//
// override fun visitParenthesizedExpression(expression: KtParenthesizedExpression) {
// super.visitParenthesizedExpression(expression, null)
// }
//
// override fun visitInitializerList(list: KtInitializerList) {
// super.visitInitializerList(list, null)
// }
//
// override fun visitAnonymousInitializer(initializer: KtAnonymousInitializer) {
// super.visitAnonymousInitializer(initializer, null)
// }
//
// override fun visitScriptInitializer(initializer: KtScriptInitializer) {
// super.visitScriptInitializer(initializer, null)
// }
//
// override fun visitClassInitializer(initializer: KtClassInitializer) {
// super.visitClassInitializer(initializer, null)
// }
//
// override fun visitPropertyAccessor(
// node: KtPropertyAccessor,
// data: Void?
// ): Map<String, Any?>? {
// super.visitPropertyAccessor(node, null)
// println("Visiting visitProperty: ${node?.name}")
// return mapOf(
// "type" to "Property",
// "id" to visitNode(node.property, data),
// )
// }
//
// override fun visitTypeConstraintList(list: KtTypeConstraintList) {
// super.visitTypeConstraintList(list, null)
// }
//
// override fun visitTypeConstraint(constraint: KtTypeConstraint) {
// super.visitTypeConstraint(constraint, null)
// }
//
//
//
// override fun visitFunctionType(type: KtFunctionType) {
// super.visitFunctionType(type, null)
// }
//
// override fun visitSelfType(type: KtSelfType) {
// super.visitSelfType(type, null)
// }
//
// override fun visitBinaryWithTypeRHSExpression(expression: KtBinaryExpressionWithTypeRHS) {
// super.visitBinaryWithTypeRHSExpression(expression, null)
// }
//
// override fun visitStringTemplateExpression(expression: KtStringTemplateExpression) {
// super.visitStringTemplateExpression(expression, null)
// }
//
// override fun visitNullableType(nullableType: KtNullableType) {
// super.visitNullableType(nullableType, null)
// }
//
// override fun visitIntersectionType(intersectionType: KtIntersectionType) {
// super.visitIntersectionType(intersectionType, null)
// }
//
// override fun visitTypeProjection(typeProjection: KtTypeProjection) {
// super.visitTypeProjection(typeProjection, null)
// }
//
// override fun visitWhenEntry(jetWhenEntry: KtWhenEntry) {
// super.visitWhenEntry(jetWhenEntry, null)
// }
//
// override fun visitIsExpression(expression: KtIsExpression) {
// super.visitIsExpression(expression, null)
// }
//
// override fun visitWhenConditionIsPattern(condition: KtWhenConditionIsPattern) {
// super.visitWhenConditionIsPattern(condition, null)
// }
//
// override fun visitWhenConditionInRange(condition: KtWhenConditionInRange) {
// super.visitWhenConditionInRange(condition, null)
// }
//
// override fun visitWhenConditionWithExpression(condition: KtWhenConditionWithExpression) {
// super.visitWhenConditionWithExpression(condition, null)
// }
//
// override fun visitObjectDeclaration(declaration: KtObjectDeclaration) {
// super.visitObjectDeclaration(declaration, null)
// }
private fun isStaticMethod(function: KtNamedFunction): Boolean {
// 1. 检查是否为顶层函数
if (isTopLevelFunction(function)) {
return true
}
if (isObjectMember(function)) {
return true
}
// 2. 检查是否为伴生对象内的成员函数
if (isCompanionObjectMember(function)) {
return true
}
// 3. 检查是否使用了 @JvmStatic 注解
if (hasJvmStaticAnnotation(function)) {
return true
}
return false
}
private fun isTopLevelFunction(function: KtNamedFunction): Boolean {
val parent = function.parent
return parent is KtFile
}
private fun isObjectMember(function: KtNamedFunction): Boolean {
val containingClass = function.containingClassOrObject
return containingClass is KtObjectDeclaration
}
private fun isCompanionObjectMember(function: KtNamedFunction): Boolean {
val containingClass = function.containingClassOrObject
return containingClass is KtObjectDeclaration && containingClass.isCompanion()
}
private fun hasJvmStaticAnnotation(function: KtNamedFunction): Boolean {
return function.annotationEntries.any { it.shortName?.asString() == "JvmStatic" }
}
}
================================================
FILE: core/src/main/java/com/aether/core/runtime/Node.kt
================================================
package com.aether.core.runtime
fun parseError(unit: Any): Nothing {
throw Exception("Parse error: ${unit.toString()}")
}
abstract class Node(
private val unit: Map<String, Any>
) {
val type: String =
unit["type"] as? String ?: throw IllegalArgumentException("Type not found in unit")
var parent: Node? = null
init {
if (unit["type"] == null) {
throw IllegalArgumentException("Type not found in unit")
}
}
protected fun <T : Node> becomeParentOf(child: T?): T? {
child?.parent = this
return child
}
fun toUnit(): Map<String, Any> = unit
// Assuming Expression is a subclass of Node and has a specific property or behavior
// If Expression has a special way of setting its parent, you might need to adjust this method.
// For now, we'll assume that all Nodes have the same parent-setting logic.
}
class Expression(
expression: Node,
isIdentifier: Boolean = false,
isConstructorDeclaration: Boolean = false,
isMethodInvocation: Boolean = false,
isCallExpression: Boolean = false,
isNamedExpression: Boolean = false,
isMethodDeclaration: Boolean = false,
isBlockStatement: Boolean = false,
isEmptyFunctionBody: Boolean = false,
isInstanceCreationExpression: Boolean = false,
isClassDeclaration: Boolean = false,
isPropertyAccess: Boolean = false,
isIntegerLiteral: Boolean = false,
isStringLiteral: Boolean = false,
isStringTemplateEntry: Boolean = false,
isStringTemplateExpression: Boolean = false,
isBooleanLiteral: Boolean = false,
isBinaryExpression: Boolean = false,
isReturnStatement: Boolean = false,
isVariableDeclarationList: Boolean = false,
isFieldDeclaration: Boolean = false,
isReferenceExpression: Boolean = false,
unit: Map<String, Any>
) : Node(unit) {
var expression: Node? = null;
var isIdentifier: Boolean = false
var isConstructorDeclaration: Boolean = false
var isMethodInvocation: Boolean = false
var isMethodDeclaration: Boolean = false
var isCallExpression: Boolean = false
var isNamedExpression: Boolean = false
var isBlockStatement: Boolean = false
var isEmptyFunctionBody: Boolean = false
var isInstanceCreationExpression: Boolean = false
var isClassDeclaration: Boolean = false
var isPropertyAccess: Boolean = false
var isIntegerLiteral: Boolean = false
var isStringLiteral: Boolean = false
var isStringTemplateEntry: Boolean = false
var isStringTemplateExpression: Boolean = false
var isBooleanLiteral: Boolean = false
var isBinaryExpression: Boolean = false
var isReturnStatement: Boolean = false
var isVariableDeclarationList: Boolean = false
var isFieldDeclaration: Boolean = false
var isReferenceExpression: Boolean = false
init {
this.expression = expression
this.isIdentifier = isIdentifier
this.isConstructorDeclaration = isConstructorDeclaration
this.isMethodInvocation = isMethodInvocation
this.isMethodDeclaration = isMethodDeclaration
this.isCallExpression = isCallExpression
this.isNamedExpression = isNamedExpression
this.isBlockStatement = isBlockStatement
this.isEmptyFunctionBody = isEmptyFunctionBody
this.isInstanceCreationExpression = isInstanceCreationExpression
this.isClassDeclaration = isClassDeclaration
this.isPropertyAccess = isPropertyAccess
this.isIntegerLiteral = isIntegerLiteral
this.isStringLiteral = isStringLiteral
this.isStringTemplateEntry = isStringTemplateEntry
this.isStringTemplateExpression = isStringTemplateExpression
this.isBooleanLiteral = isBooleanLiteral
this.isBinaryExpression = isBinaryExpression
this.isReturnStatement = isReturnStatement
this.isVariableDeclarationList = isVariableDeclarationList
this.isFieldDeclaration = isFieldDeclaration
this.isReferenceExpression = isReferenceExpression
}
fun get(): Node? {
return expression
}
val asConstructorDeclaration: ConstructorDeclaration
get() = expression as ConstructorDeclaration
val asBlockStatement: BlockStatement
get() = expression as BlockStatement
val asInstanceCreationExpression: InstanceCreationExpression
get() = expression as InstanceCreationExpression
val asClassDeclaration: ClassDeclaration
get() = expression as ClassDeclaration
val asVariableDeclarationList: PropertyStatement
get() = expression as PropertyStatement
val asFieldDeclaration: FieldDeclaration
get() = expression as FieldDeclaration
val asPropertyAccess: PropertyAccess
get() = expression as PropertyAccess
val asReturnStatement: ReturnStatement
get() = expression as ReturnStatement
val asBinaryExpression: BinaryExpression
get() = expression as BinaryExpression
val asIntegerLiteral: IntegerLiteral
get() = expression as IntegerLiteral
val asStringLiteral: StringTemplateExpression
get() = expression as StringTemplateExpression
val asStringTemplateEntry: StringTemplateEntry
get() = expression as StringTemplateEntry
val asNamedExpression: Argument
get() = expression as Argument
val asBooleanLiteral: BooleanLiteral
get() = expression as BooleanLiteral
val asStringTemplateExpression: StringTemplateExpression
get() = expression as StringTemplateExpression
val asIdentifier: Identifier
get() = expression as Identifier
val asMethodInvocation: MethodInvocation
get() = expression as MethodInvocation
val asCallExpression: CallExpression
get() = expression as CallExpression
val asMethodExpression: MethodDeclaration
get() = expression as MethodDeclaration
companion object {
fun fromUnit(unit: Map<String, Any>): Expression {
val type = unit["type"]
if (type == "ClassDeclaration") {
return Expression(
ClassDeclaration.fromUnit(unit),
isClassDeclaration = true,
unit = unit
)
} else if (type == "MethodDeclaration") {
return Expression(
MethodDeclaration.fromUnit(unit), isMethodDeclaration = true, unit = unit
);
} else if (type == "BlockStatement") {
return Expression(
BlockStatement.fromUnit(unit), isBlockStatement = true, unit = unit
);
} else if (type == "EmptyFunctionBody") {
return Expression(
EmptyFunctionBody.fromUnit(unit), isEmptyFunctionBody = true, unit = unit
);
} else if (type == "InstanceCreationExpression") {
return Expression(
InstanceCreationExpression.fromUnit(unit),
isInstanceCreationExpression = true,
unit = unit
);
} else if (type == "ReturnStatement") {
return Expression(
ReturnStatement.fromUnit(unit), isReturnStatement = true, unit = unit
);
} else if (type == "PropertyAccess") {
return Expression(
PropertyAccess.fromUnit(unit),
isPropertyAccess = true,
unit = unit
)
} else if (type == "FieldDeclaration") {
return Expression(
FieldDeclaration.fromUnit(unit),
isFieldDeclaration = true,
unit = unit
)
} else if (type == "PropertyStatement") {
return Expression(
PropertyStatement.fromUnit(unit),
isVariableDeclarationList = true,
unit = unit
)
} else if (type == "ConstantExpression") {
return Expression(
ConstantExpression.fromUnit(unit), unit = unit
)
} else if (type == "INTEGER_CONSTANT") {
return Expression(
IntegerLiteral.fromUnit(unit), isIntegerLiteral = true, unit = unit
);
} else if (type == "StringTemplateExpression") {
return Expression(
StringTemplateExpression.fromUnit(unit),
isStringTemplateExpression = true,
unit = unit
)
} else if (type == "StringLiteral") {
return Expression(
StringTemplateExpression.fromUnit(unit), isStringLiteral = true, unit = unit
)
} else if (type == "BOOLEAN_CONSTANT") {
return Expression(
BooleanLiteral.fromUnit(unit), isBooleanLiteral = true, unit = unit
)
} else if (type == "BinaryExpression") {
return Expression(
BinaryExpression.fromUnit(unit), isBinaryExpression = true, unit = unit
)
} else if (type == "Identifier") {
return Expression(
Identifier.fromUnit(unit),
isReferenceExpression = true,
isIdentifier = true,
unit = unit
)
} else if (type == "ImportDirective") {
return Expression(
ImportDirective.fromUnit(unit), isIdentifier = false, unit = unit
)
} else if (type == "CallExpression") {
return Expression(
CallExpression.fromUnit(unit),
isCallExpression = true,
isIdentifier = false,
unit = unit
)
} else if (type == "MethodInvocation") {
return Expression(
MethodInvocation.fromUnit(unit),
isMethodInvocation = true,
isIdentifier = false,
unit = unit
)
} else if (type == "StringTemplateEntry") {
return Expression(
StringTemplateEntry.fromUnit(unit),
isStringTemplateEntry = true,
isMethodInvocation = false,
isIdentifier = false,
unit = unit
)
} else if (type == "SecondaryConstructor") {
return Expression(
ConstructorDeclaration.fromUnit(unit),
isConstructorDeclaration = true,
unit = unit
)
} else if (type == "Argument") {
val isNamed = (unit["isNamed"] ?: false) as Boolean
return Expression(
Argument.fromUnit(unit), isNamedExpression = isNamed, unit = unit
);
} else if (type == "Column") {
val isNamed = (unit["isNamed"] ?: false) as Boolean
return Expression(
Argument.fromUnit(unit), isNamedExpression = isNamed, unit = unit
);
}
return Expression(
ClassDeclaration.fromUnit(unit), unit = mapOf(
"type" to "e"
)
)
}
}
}
class BlockStatement(body: List<Expression>, unit: Map<String, Any>) : Node(unit) {
var body: List<Expression>? = null
init {
this.body = body
}
companion object {
fun fromUnit(unit: Map<String, Any>): BlockStatement {
if (unit["type"] != "BlockStatement") {
parseError(unit)
}
val body = mutableListOf<Expression>()
if (unit["type"] == "BlockStatement") {
if (unit["body"].isNotEmptyCollection()) {
val items = unit["body"] as List<Map<String, Any>>
for (item in items) {
body.add(Expression.fromUnit(item))
}
}
}
return BlockStatement(body = body, unit)
}
}
}
class EmptyFunctionBody(unit: Map<String, Any>) : Node(unit) {
companion object {
fun fromUnit(unit: Map<String, Any>): EmptyFunctionBody {
if (unit["type"] != "EmptyFunctionBody") {
parseError(unit)
}
return EmptyFunctionBody(unit)
}
}
}
class PropertyAccess : Node {
var name: String?
var targetExpression: Expression?
var selectorExpression: Expression?
var isCascaded: Boolean
var isNullAware: Boolean
constructor(
name: String?,
targetExpression: Expression?,
selectorExpression: Expression?,
isCascaded: Boolean,
isNullAware: Boolean,
unit: Map<String, Any>
) : super(unit) {
this.name = name
this.targetExpression = targetExpression
this.selectorExpression = selectorExpression
this.isCascaded = isCascaded
this.isNullAware = isNullAware
}
companion object {
fun fromUnit(unit: Map<String, Any>): PropertyAccess {
if (unit["type"] == "PropertyAccess") {
val targetExpression =
unit["targetExpression"]?.let { Expression.fromUnit(it as Map<String, Any>) }
val selectorExpression =
unit["selectorExpression"]?.let { Expression.fromUnit(it as Map<String, Any>) }
return PropertyAccess(
((unit["selectorExpression"] as Map<String, Any>)["target"] as Map<String, Any>)["name"] as String,
// unit["name"] as String?,
targetExpression,
selectorExpression,
unit["isCascaded"] as? Boolean ?: false,
unit["isNullAware"] as? Boolean ?: false,
unit
)
}
parseError(unit)
}
}
}
class FieldDeclaration(
name: String,
isStatic: Boolean,
target: Expression?,
unit: Map<String, Any>
) : Node(unit) {
var target: Expression? = null
var name: String
var isStatic: Boolean = false
init {
this.target = target
this.name = name
this.isStatic = isStatic
}
companion object {
fun fromUnit(unit: Map<String, Any>): FieldDeclaration {
if (unit["type"] != "FieldDeclaration") {
return parseError(unit)
}
var target: Expression? = null
if (unit["initializer"] != null) {
target = Expression.fromUnit(unit["initializer"] as Map<String, Any>);
}
return FieldDeclaration(
unit["name"] as String,
false,
// unit["isStatic"] as Boolean,
target = target,
unit = unit
)
}
}
}
class PropertyStatement(
name: String,
isStatic: Boolean,
target: Expression?,
unit: Map<String, Any>
) : Node(unit) {
var target: Expression? = null
var name: String
var isStatic: Boolean = false
init {
this.target = target
this.name = name
this.isStatic = isStatic
}
companion object {
fun fromUnit(unit: Map<String, Any>): PropertyStatement {
if (unit["type"] != "PropertyStatement") {
parseError(unit)
}
var target: Expression? = null
if (unit["type"] == "PropertyStatement") {
if (unit["initializer"] != null) {
target = Expression.fromUnit(unit["initializer"] as Map<String, Any>);
}
// if (unit["parameters"].isNotEmptyMap()) {
// var argument: Expression? = null
// if (unit["argument"] != null) {
// argument = Expression.fromUnit(unit["parameters"] as Map<String, Any>);
// }
// return PropertyStatement(argument = argument, unit = unit)
// }
}
return PropertyStatement(
unit["name"] as String,
false,
// unit["isStatic"] as Boolean,
target = target,
unit = unit
)
}
}
}
class StringLiteral(value: String?, unit: Map<String, Any>) : Node(unit) {
var value: String? = null
init {
this.value = value
}
companion object {
fun fromUnit(unit: Map<String, Any>): StringLiteral {
if (unit["type"] != "StringLiteral") {
parseError(unit)
}
if (unit["type"] == "StringLiteral") {
return StringLiteral(value = (unit["value"].toString()), unit = unit)
}
return StringLiteral(value = null, unit = unit)
}
}
}
class StringTemplateEntry(value: String?, unit: Map<String, Any>) : Node(unit) {
var value: String? = null
init {
this.value = value
}
companion object {
fun fromUnit(unit: Map<String, Any>): StringTemplateEntry {
if (unit["type"] != "StringTemplateEntry") {
parseError(unit)
}
if (unit["type"] == "StringTemplateEntry") {
return StringTemplateEntry(value = (unit["value"].toString()), unit = unit)
}
return StringTemplateEntry(value = null, unit = unit)
}
}
}
class ConstructorName(name: String, typeName: String?, unit: Map<String, Any>) : Node(unit) {
val name: String = name
val typeName: String? = typeName
companion object {
fun fromUnit(unit: Map<String, Any>): ConstructorName {
return ConstructorName(
name = unit["name"] as String,
typeName = unit["typeName"] as String,
unit = unit
)
}
private fun parseError(unit: Map<String, Any?>): Nothing {
throw IllegalArgumentException("Parse error on unit: $unit")
}
}
}
class InstanceCreationExpression(
constructorName: ConstructorName?,
argumentList: ArgumentList?,
children: List<Expression>?,
unit: Map<String, Any>
) : Node(unit) {
var constructorName: ConstructorName? = null
var children: List<Expression>? = null
var argumentList: ArgumentList? = null
init {
this.constructorName = constructorName
this.children = children
this.argumentList = argumentList
}
companion object {
fun fromUnit(unit: Map<String, Any>): InstanceCreationExpression {
if (unit["type"] != "InstanceCreationExpression") {
return parseError(unit)
}
val name = unit["constructorName"] as String
val children = mutableListOf<Expression>()
// 处理子元素
val childrenList = unit["children"]
if (childrenList is List<*> && childrenList.isNotEmpty()) {
// 遍历子元素列表
for (child in childrenList) {
if (child is Map<*, *>) {
@Suppress("UNCHECKED_CAST")
// 将每个子元素转换为Expression
val childExpr = Expression.fromUnit(child as Map<String, Any>)
children.add(childExpr)
}
}
}
return InstanceCreationExpression(
ConstructorName(name, name, unit),
if (unit["argumentList"] == null) null else ArgumentList.fromUnit(unit["argumentList"] as Map<String, Any>),
children,
unit = unit
)
}
}
}
class StringTemplateExpression(target: Expression?, unit: Map<String, Any>) : Node(unit) {
var target: Expression? = null
init {
this.target = target
}
companion object {
fun fromUnit(unit: Map<String, Any>): StringTemplateExpression {
if (unit["type"] != "StringTemplateExpression") {
parseError(unit)
}
if (unit["type"] == "StringTemplateExpression") {
var target: Expression? = null
if (unit["body"] != null) {
target = Expression.fromUnit(unit["body"] as Map<String, Any>)
return StringTemplateExpression(
target = target,
unit = unit["body"] as Map<String, Any>
)
}
}
return StringTemplateExpression(target = null, unit = unit)
}
}
}
class BinaryExpression(
operator: String, left: Expression, right: Expression, unit: Map<String, Any>
) : Node(unit) {
///运算符
/// * +
/// * -
/// * *
/// * /
/// * <
/// * >
/// * <=
/// * >=
/// * ==
/// * &&
/// * ||
/// * %
/// * <<
/// * |
/// * &
/// * >>
///
val operator: String = operator
///左操作表达式
val left: Expression = left
///右操作表达式
val right: Expression = right
companion object {
fun fromUnit(unit: Map<String, Any>): BinaryExpression {
if (unit["type"] != "BinaryExpression") {
parseError(unit)
}
if (unit["type"] == "BinaryExpression") {
// return BinaryExpression(unit = unit)
}
return BinaryExpression(
unit["operator"] as String,
Expression.fromUnit(unit["left"] as Map<String, Any>),
Expression.fromUnit(unit["right"] as Map<String, Any>),
unit = unit
)
}
}
}
class Identifier : Node {
constructor(name: String, unit: Map<String, Any>) : super(unit) {
this.name = name
}
var name: String
companion object {
fun fromUnit(unit: Map<String, Any>): Identifier {
if (unit["type"] == "Identifier") {
return Identifier(
name = (unit["name"].toString()), unit = unit
)
}
parseError(unit)
}
fun isPrivateName(name: String): Boolean {
return false
}
}
}
class BooleanLiteral(value: Boolean, unit: Map<String, Any>) : Node(unit) {
var value: Boolean = false
init {
this.value = value
}
companion object {
fun fromUnit(unit: Map<String, Any>): BooleanLiteral {
if (unit["type"] != "BOOLEAN_CONSTANT") {
parseError(unit)
}
if (unit["type"] == "BOOLEAN_CONSTANT") {
return BooleanLiteral(value = (unit["value"].toString().toBoolean()), unit = unit)
}
return BooleanLiteral(value = false, unit = unit)
}
}
}
class IntegerLiteral(value: Int, unit: Map<String, Any>) : Node(unit) {
var value: Int? = 0
init {
this.value = value
}
companion object {
fun fromUnit(unit: Map<String, Any>): IntegerLiteral {
if (unit["type"] != "INTEGER_CONSTANT") {
parseError(unit)
}
if (unit["type"] == "INTEGER_CONSTANT") {
return IntegerLiteral(value = (unit["value"].toString().toInt()), unit = unit)
}
return IntegerLiteral(value = 0, unit = unit)
}
}
}
class ConstantExpression(unit: Map<String, Any>) : Node(unit) {
companion object {
fun fromUnit(unit: Map<String, Any>): ConstantExpression {
if (unit["type"] != "ConstantExpression") {
parseError(unit)
}
if (unit["type"] == "ConstantExpression") {
// if (unit["parameters"].isNotEmptyMap()) {
// var argument: Expression? = null
// if (unit["argument"] != null) {
// argument = Expression.fromUnit(unit["parameters"] as Map<String, Any>);
// }
// return PropertyStatement(argument = argument, unit = unit)
// }
}
return ConstantExpression(unit = unit)
}
}
}
class ReturnStatement(val argument: Expression?, unit: Map<String, Any>) : Node(unit) {
companion object {
fun fromUnit(unit: Map<String, Any>): ReturnStatement {
if (unit["type"] != "ReturnStatement") {
parseError(unit)
}
if (unit["type"] == "ReturnStatement") {
var argument: Expression? = null
if (unit["argument"] != null) {
argument = Expression.fromUnit(unit["argument"] as Map<String, Any>);
}
return ReturnStatement(argument = argument, unit = unit)
}
return ReturnStatement(null, unit = unit)
}
}
}
class ClassDeclaration(members: List<Expression>, name: String, unit: Map<String, Any>) :
Node(unit) {
var name: String = ""
var members: List<Expression>? = null
init {
this.members = members
this.name = name
}
companion object {
fun fromUnit(unit: Map<String, Any>): ClassDeclaration {
if (unit["type"] != "ClassDeclaration") {
parseError(unit)
}
val members = mutableListOf<Expression>()
if (unit["type"] == "ClassDeclaration") {
if (unit["members"] is List<*>) {
val list = unit["members"] as List<Map<String, Any>>
for (member in list) {
members.add(Expression.fromUnit(member))
}
}
}
return ClassDeclaration(members = members, name = (unit["name"] ?: "") as String, unit)
}
}
}
class MethodDeclaration : Node {
var parameters: FormalParameterList?
var name: String
var isStatic: Boolean
var isSetter: Boolean
var bodyExpression: Expression
var isAsync: Boolean
constructor(
parameters: FormalParameterList?,
name: String,
isStatic: Boolean,
isSetter: Boolean,
bodyExpression: Expression,
isAsync: Boolean,
unit: Map<String, Any>
) : super(unit) {
this.name = name
this.isStatic = isStatic
this.isSetter = isSetter
this.parameters = parameters
this.bodyExpression = bodyExpression
this.isAsync = isAsync
}
companion object {
fun fromUnit(unit: Map<String, Any>): Node {
if (unit["type"] != "MethodDeclaration") {
parseError(unit)
}
var parameters: FormalParameterList? = null;
if (unit["parameters"].isNotEmptyCollection()) {
val any = unit["parameters"]
val map = mutableMapOf<String, Any>()
map["type"] = "ParameterList"
map["parameters"] = unit["parameters"] as Any
parameters = FormalParameterList.fromUnit(map);
}
return MethodDeclaration(
parameters = parameters,
unit["name"] as String,
unit["isStatic"] as Boolean,
unit["isSetter"] as Boolean,
bodyExpression = Expression.fromUnit(unit["body"] as Map<String, Any>),
isAsync = false,
unit = unit
)
}
}
}
class VariableDeclarator : Node {
var name: String
var typeName: String?
var init: Expression?
var isStatic: Boolean
var isFinal: Boolean
var isConst: Boolean
var isLate: Boolean
var isTopLevel: Boolean
constructor(
name: String,
typeName: String?,
init: Expression?,
isStatic: Boolean,
isFinal: Boolean,
isConst: Boolean,
isLate: Boolean,
isTopLevel: Boolean,
unit: Map<String, Any>
) : super(unit) {
this.name = name
this.typeName = typeName
this.init = init
this.isStatic = isStatic
this.isFinal = isFinal
this.isConst = isConst
this.isLate = isLate
this.isTopLevel = isTopLevel
}
companion object {
fun fromUnit(unit: Map<String, Any>): VariableDeclarator {
if (unit["type"] == "VariableDeclarator") {
val init = unit["init"]?.let { Expression.fromUnit(it as Map<String, Any>) }
val isStatic = unit["isStatic"] as? Boolean ?: false
val isTopLevel = unit["isTopLevel"] as? Boolean ?: false
return VariableDeclarator(
Identifier.fromUnit(unit["id"] as Map<String, Any>).name,
unit["typeName"] as? String,
init,
isStatic,
unit["isFinal"] as? Boolean ?: false,
unit["isConst"] as? Boolean ?: false,
unit["isLate"] as? Boolean ?: false,
isTopLevel,
unit
)
}
return parseError(unit)
}
}
}
//class FunctionDeclaration(
// name: String,
// unit: Map<String, Any>
//) : Node(unit) {
// var name: String = ""
//
// init {
// this.name = name
// }
//
// companion object {
// fun fromUnit(unit: Map<String, Any>): Node {
// if (unit["type"] != "FunctionDeclaration") {
// parseError(unit)
// }
// return FunctionDeclaration(
// unit["name"] as String,
// unit = unit
// )
// }
// }
//}
class FormalParameterList(
val parameters: List<FormalParameter>,
unit: Map<String, Any>
) : Node(unit) {
init {
parameters.forEach { becomeParentOf(it) }
}
companion object {
fun fromUnit(unit: Map<String, Any>): FormalParameterList {
if (unit["type"] == "ParameterList") {
return FormalParameterList(
(unit["parameters"] as List<Map<String, Any>>)
.map { FormalParameter.fromUnit(it) },
unit
)
}
parseError(unit)
}
}
}
abstract class FormalParameter(unit: Map<String, Any>) : Node(unit) {
abstract val name: String
abstract val typeName: String?
abstract val isFinal: Boolean
abstract val isNamed: Boolean
abstract val isPositional: Boolean
abstract val isOptional: Boolean
abstract val isOptionalNamed: Boolean
abstract val isOptionalPositional: Boolean
abstract val isRequired: Boolean
abstract val isRequiredNamed: Boolean
abstract val isRequiredPositional: Boolean
companion object {
fun fromUnit(unit: Map<String, Any>): FormalParameter {
return when (unit["type"]) {
"SimpleFormalParameter" -> SimpleFormalParameter.fromUnit(unit)
"DefaultFormalParameter" -> DefaultFormalParameter.fromUnit(unit)
// "FieldFormalParameter" -> FieldFormalParameter.fromUnit(unit)
else -> parseError(unit)
}
}
}
}
class FieldFormalParameter(
name: String,
typeName: String?,
isFinal: Boolean,
isNamed: Boolean,
isPositional: Boolean,
isOptional: Boolean,
isOptionalNamed: Boolean,
isOptionalPositional: Boolean,
isRequired: Boolean,
isRequiredNamed: Boolean,
isRequiredPositional: Boolean,
val parameters: FormalParameterList?,
unit: Map<String, Any>
) : SimpleFormalParameter(
name,
typeName,
isFinal,
isNamed,
isPositional,
isOptional,
isOptionalNamed,
isOptionalPositional,
isRequired,
isRequiredNamed,
isRequiredPositional,
unit
) {
companion object {
fun fromUnit(unit: Map<String, Any>): FieldFormalParameter {
if (unit["type"] == "FieldFormalParameter") {
val parameters =
unit["parameters"]?.let { FormalParameterList.fromUnit(it as Map<String, Any>) }
val typeName =
unit["typeName"]?.let { TypeName.fromUnit(it as Map<String, Any>).name }
return FieldFormalParameter(
unit["name"] as String,
typeName,
unit["isFinal"] as Boolean,
unit["isNamed"] as Boolean,
unit["isPositional"] as Boolean,
unit["isOptional"] as Boolean,
unit["isOptionalNamed"] as Boolean,
unit["isOptionalPositional"] as Boolean,
unit["isRequired"] as Boolean,
unit["isRequiredNamed"] as Boolean,
unit["isRequiredPositional"] as Boolean,
parameters,
unit
)
}
parseError(unit)
}
}
}
abstract class NormalFormalParameter(unit: Map<String, Any>) : FormalParameter(unit)
open class SimpleFormalParameter(
val _name: String,
val _typeName: String?,
val _isFinal: Boolean,
val _isNamed: Boolean,
val _isPositional: Boolean,
val _isOptional: Boolean,
val _isOptionalNamed: Boolean,
val _isOptionalPositional: Boolean,
val _isRequired: Boolean,
val _isRequiredNamed: Boolean,
val _isRequiredPositional: Boolean,
unit: Map<String, Any>
) : NormalFormalParameter(unit) {
companion object {
fun fromUnit(unit: Map<String, Any>): SimpleFormalParameter {
if (unit["type"] == "SimpleFormalParameter") {
val typeName = unit["typeName"]
// val typeName = unit["typeName"]?.let { TypeName.fromUnit(it as Map<String, Any>).name }
return SimpleFormalParameter(
unit["name"] as String,
(typeName ?: "").toString(),
unit["isFinal"] as? Boolean ?: false,
unit["isNamed"] as? Boolean ?: false,
unit["isPositional"] as? Boolean ?: false,
unit["isOptional"] as? Boolean ?: false,
unit["isOptionalNamed"] as? Boolean ?: false,
unit["isOptionalPositional"] as? Boolean ?: false,
unit["isRequired"] as? Boolean ?: false,
unit["isRequiredNamed"] as? Boolean ?: false,
unit["isRequiredPositional"] as? Boolean ?: false,
unit
)
}
parseError(unit)
}
}
override val isFinal: Boolean
get() = _isFinal
override val isNamed: Boolean
get() = _isNamed
override val isOptional: Boolean
get() = _isOptional
override val isOptionalNamed: Boolean
get() = _isOptionalNamed
override val isOptionalPositional: Boolean
get() = _isOptionalPositional
override val isPositional: Boolean
get() = _isPositional
override val isRequired: Boolean
get() = _isRequired
override val isRequiredNamed: Boolean
get() = _isRequiredNamed
override val isRequiredPositional: Boolean
get() = _isRequiredPositional
override val name: String
get() = _name
override val typeName: String?
get() = _typeName
}
class TypeName(
name: String,
typeArguments: TypeArgumentList?,
unit: Map<String, Any>
) : NamedType(name, typeArguments, unit) {
companion object {
fun fromUnit(unit: Map<String, Any>): TypeName {
if (unit["type"] == "TypeName") {
val typeArguments =
unit["typeArguments"]?.let { TypeArgumentList.fromUnit(it as Map<String, Any>) }
return TypeName(
unit["name"] as String,
typeArguments,
unit
)
}
parseError(unit)
}
}
}
class TypeArgumentList : Node {
val arguments: List<TypeAnnotation>
constructor(arguments: List<TypeAnnotation>, unit: Map<String, Any>) : super(unit) {
this.arguments = arguments
}
companion object {
fun fromUnit(unit: Map<String, Any>): TypeArgumentList {
if (unit["type"] == "TypeArgumentList") {
val arguments = unit["arguments"]?.let {
if (it is List<*>) {
it.mapNotNull { argument ->
if (argument is Map<*, *>) {
TypeAnnotation.fromUnit(argument as Map<String, Any>)
} else {
null
}
}
} else {
emptyList()
}
} ?: emptyList()
return TypeArgumentList(arguments, unit)
}
parseError(unit)
}
}
}
abstract class NamedType(
val name: String,
val typeArguments: TypeArgumentList?,
unit: Map<String, Any>
) : TypeAnnotation(unit) {
init {
becomeParentOf(typeArguments)
}
}
abstract class TypeAnnotation(unit: Map<String, Any>) : Node(unit) {
companion object {
fun fromUnit(unit: Map<String, Any>): TypeAnnotation {
val type = unit["type"]
return when (type) {
"TypeName" -> TypeName.fromUnit(unit)
// "GenericFunctionType" -> GenericFunctionType.fromUnit(unit)
else -> parseError(unit)
}
}
}
}
class DefaultFormalParameter(
val parameter: FormalParameter,
val defaultValue: Expression?,
unit: Map<String, Any>
) : FormalParameter(unit) {
init {
becomeParentOf(parameter)
becomeParentOf(defaultValue)
}
companion object {
fun fromUnit(unit: Map<String, Any>): DefaultFormalParameter {
if (unit["type"] == "DefaultFormalParameter") {
val defaultValue =
unit["defaultValue"]?.let { Expression.fromUnit(it as Map<String, Any>) }
return DefaultFormalParameter(
FormalParameter.fromUnit(unit["parameter"] as Map<String, Any>),
defaultValue,
unit
)
}
parseError(unit)
}
}
override val isFinal: Boolean
get() = parameter.isFinal
override val isNamed: Boolean
get() = parameter.isNamed
override val isOptional: Boolean
get() = parameter.isOptional
override val isOptionalNamed: Boolean
get() = parameter.isOptionalNamed
override val isOptionalPositional: Boolean
get() = parameter.isOptionalPositional
override val isPositional: Boolean
get() = parameter.isPositional
override val isRequired: Boolean
get() = parameter.isRequired
override val isRequiredNamed: Boolean
get() = parameter.isRequiredNamed
override val isRequiredPositional: Boolean
get() = parameter.isRequiredPositional
override val name: String
get() = parameter.name
override val typeName: String?
get() = parameter.typeName
}
class CompilationUnit(unit: Map<String, Any>) : Node(unit) {
var declarations: List<Expression>? = null
var directives: List<Directive>? = null
//
constructor(
declarations: List<Expression>, directives: List<Directive>, unit: Map<String, Any>
) : this(unit) {
this.declarations = declarations
this.directives = directives
}
// 从单元数据创建CompilationUnit实例的工厂方法
companion object {
fun fromUnit(unit: Map<String, Any>): CompilationUnit {
if (unit["type"] != "CompilationUnit") {
parseError(unit)
}
val declarations = unit["declarations"]?.let { it as? List<Map<String, Any>> }
?.map { Expression.fromUnit(it) } ?: emptyList()
val directives = unit["directives"]?.let { it as? List<Map<String, Any>> }
?.map { Directive.fromUnit(it) } ?: emptyList()
return CompilationUnit(declarations, directives, unit)
}
}
}
class ImportDirective : NamespaceDirective {
var refix: String?
var name: String
private constructor(uri: String, prefix: String?, name: String, unit: Map<String, Any>) : super(
uri,
unit
) {
this.refix = prefix;
this.name = name
}
companion object {
fun fromUnit(unit: Map<String, Any>): ImportDirective {
if (unit["type"] == "ImportDirective") {
// val combinators = (unit["combinators"] as List<Map<String, Any>>).map { Combinator.fromUnit(it as Map<String, Any>) }
val prefix = unit["alias"]
return ImportDirective(
unit["importPath"] as String,
prefix as String?,
unit["name"] as String,
unit
)
}
parseError(unit)
}
}
}
class CallExpression : Node {
val methodName: String
val target: Expression?
val argumentList: ArgumentList
val isCascaded: Boolean
val isNullAware: Boolean
private constructor(
methodName: String,
target: Expression?,
argumentList: ArgumentList,
isCascaded: Boolean,
isNullAware: Boolean,
unit: Map<String, Any>
) : super(unit) {
this.methodName = methodName
this.target = target
this.argumentList = argumentList
this.isCascaded = isCascaded
this.isNullAware = isNullAware
becomeParentOf(target)
becomeParentOf(argumentList)
}
companion object {
fun fromUnit(unit: Map<String, Any>): CallExpression {
if (unit["type"] == "CallExpression") {
val target = unit["target"]?.let { Expression.fromUnit(it as Map<String, Any>) }
return CallExpression(
Identifier.fromUnit(unit["methodName"] as Map<String, Any>).name,
target,
ArgumentList.fromUnit(unit["argumentList"] as Map<String, Any>),
unit["isCascaded"] as? Boolean ?: false,
unit["isNullAware"] as? Boolean ?: false,
unit
)
}
parseError(unit)
}
}
}
class MethodInvocation : Node {
val methodName: Identifier?
var isStatic: Boolean = true
var isSetter: Boolean = false
val target: Expression?
val argumentList: ArgumentList?
val isCascaded: Boolean
val isNullAware: Boolean
private constructor(
methodName: Identifier,
target: Expression?,
argumentList: ArgumentList?,
isCascaded: Boolean,
isNullAware: Boolean,
unit: Map<String, Any>
) : super(unit) {
this.methodName = methodName
this.target = target
this.argumentList = argumentList
this.isCascaded = isCascaded
this.isNullAware = isNullAware
becomeParentOf(target)
becomeParentOf(argumentList)
}
companion object {
fun fromUnit(unit: Map<String, Any>): MethodInvocation {
if (unit["type"] == "MethodInvocation") {
val target = unit["target"]?.let { Expression.fromUnit(it as Map<String, Any>) }
return MethodInvocation(
// if ((unit["methodName"] as Map<String, Any>)["target"] == null) "" else ((unit["methodName"] as Map<String, Any>)["target"] as Map<String, Any>)["name"] as String,
Identifier.fromUnit(unit["methodName"] as Map<String, Any>),
target,
if ((unit["methodName"] as Map<String, Any>)["argumentList"] == null) null else ArgumentList.fromUnit(
(unit["methodName"] as Map<String, Any>)["argumentList"] as Map<String, Any>
),
unit["isCascaded"] as? Boolean ?: false,
unit["isNullAware"] as? Boolean ?: false,
unit
)
}
parseError(unit)
}
}
}
class Argument : Node {
var name: String? = null
var isNamed: Boolean? = false
var argument: Expression? = null
private constructor(
name: String?,
isNamed: Boolean,
argument: Expression,
unit: Map<String, Any>
) : super(unit) {
gitextract_t7d67c2l/ ├── .fleet/ │ └── receipt.json ├── .gitignore ├── README.md ├── annotations/ │ ├── build.gradle.kts │ └── src/ │ └── main/ │ └── java/ │ └── com/ │ └── aether/ │ └── annotations/ │ ├── ComposeMirror.kt │ └── Reflectable.kt ├── build.gradle.kts ├── composeApp/ │ ├── build.gradle.kts │ └── src/ │ ├── androidMain/ │ │ ├── AndroidManifest.xml │ │ ├── kotlin/ │ │ │ ├── Myapplicaton.kt │ │ │ └── org/ │ │ │ └── example/ │ │ │ └── project/ │ │ │ ├── MainActivity.kt │ │ │ └── Platform.android.kt │ │ └── res/ │ │ ├── drawable/ │ │ │ └── ic_launcher_background.xml │ │ ├── drawable-v24/ │ │ │ └── ic_launcher_foreground.xml │ │ ├── mipmap-anydpi-v26/ │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ └── values/ │ │ └── strings.xml │ ├── commonMain/ │ │ ├── composeResources/ │ │ │ └── drawable/ │ │ │ └── compose-multiplatform.xml │ │ └── kotlin/ │ │ └── org/ │ │ └── example/ │ │ └── project/ │ │ ├── App.kt │ │ ├── Greeting.kt │ │ └── Platform.kt │ ├── iosMain/ │ │ └── kotlin/ │ │ └── org/ │ │ └── example/ │ │ └── project/ │ │ ├── MainViewController.kt │ │ └── Platform.ios.kt │ └── main/ │ ├── AndroidManifest.xml │ └── java/ │ └── com/ │ └── aether/ │ └── composeapp/ │ └── example/ │ └── ReflectableExample.kt ├── core/ │ ├── .gitignore │ ├── build.gradle.kts │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── aether/ │ │ └── core/ │ │ └── runtime/ │ │ └── ExampleInstrumentedTest.kt │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── assets/ │ │ │ ├── test0_compose.json │ │ │ └── test1_compose.json │ │ ├── java/ │ │ │ └── com/ │ │ │ └── aether/ │ │ │ └── core/ │ │ │ └── runtime/ │ │ │ ├── AppContextManager.kt │ │ │ ├── AstRuntime.kt │ │ │ ├── ClassMirror.kt │ │ │ ├── KtAstVisitor.kt │ │ │ ├── Node.kt │ │ │ ├── ProgramStack.kt │ │ │ ├── ProjectHelper.kt │ │ │ ├── Structs.kt │ │ │ ├── StructsImpl.kt │ │ │ ├── context.kt │ │ │ ├── deliver/ │ │ │ │ ├── TemplateProvider.kt │ │ │ │ └── binding.kt │ │ │ ├── entity/ │ │ │ │ └── SimpleMember.kt │ │ │ ├── mirror/ │ │ │ │ └── MirrorHelper.kt │ │ │ ├── proxy/ │ │ │ │ └── ProxyBinding.kt │ │ │ ├── reflectable/ │ │ │ │ ├── ClassMirror.kt │ │ │ │ ├── ClassMirrorBase.kt │ │ │ │ ├── ComposeComponentDescriptor.kt │ │ │ │ ├── ComposeComponentRegistry.kt │ │ │ │ ├── ComposeMirror.kt │ │ │ │ ├── ComposeMirrorRuntime.kt │ │ │ │ ├── ComposeReflectRuntime.kt │ │ │ │ ├── DeclarationMirror.kt │ │ │ │ ├── MethodMirrorImpl.kt │ │ │ │ ├── Mirror.kt │ │ │ │ ├── ParamInfo.kt │ │ │ │ └── widgets/ │ │ │ │ ├── ColumnMirror.kt │ │ │ │ ├── MaterialThemeMirror.kt │ │ │ │ ├── TextMirror.kt │ │ │ │ ├── TextStyleMirror.kt │ │ │ │ └── TypographyMirror.kt │ │ │ └── utils/ │ │ │ └── JsonReader.kt │ │ └── res/ │ │ ├── drawable/ │ │ │ ├── ic_launcher_background.xml │ │ │ └── ic_launcher_foreground.xml │ │ ├── mipmap-anydpi/ │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── values/ │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── themes.xml │ │ └── values-night/ │ │ └── themes.xml │ └── test/ │ └── java/ │ └── com/ │ └── aether/ │ └── core/ │ ├── ExampleUnitTest.kt │ ├── compose/ │ │ ├── ColumArgsComposeExpressText.kt │ │ ├── ColumComposeNameExpressText.kt │ │ ├── DemoCompose.kt │ │ ├── DemoComposeColor.kt │ │ └── NameExpressComposeNameExpressText.kt │ ├── express/ │ │ ├── ArgsComposeTest.kt │ │ ├── ColumArgsExpressComposeTest.kt │ │ ├── ColumExpressComposeTest.kt │ │ ├── DemoEmptyFunctionExpress.kt │ │ ├── DemoFunctionExpress.kt │ │ ├── DemoTest.kt │ │ ├── InstanceComposeTest.kt │ │ ├── InstanceCreationExpressionTest.kt │ │ ├── InstanceJsonEmptyCreationExpressionTest.kt │ │ ├── InstanceTest.kt │ │ └── NameExpressComposeTest.kt │ └── runtime/ │ └── ExampleUnitTest.kt ├── gradle/ │ ├── libs.versions.toml │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── iosApp/ │ ├── Configuration/ │ │ └── Config.xcconfig │ ├── iosApp/ │ │ ├── Assets.xcassets/ │ │ │ ├── AccentColor.colorset/ │ │ │ │ └── Contents.json │ │ │ ├── AppIcon.appiconset/ │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── ContentView.swift │ │ ├── Info.plist │ │ ├── Preview Content/ │ │ │ └── Preview Assets.xcassets/ │ │ │ └── Contents.json │ │ └── iOSApp.swift │ └── iosApp.xcodeproj/ │ └── project.pbxproj ├── processor/ │ ├── build.gradle.kts │ └── src/ │ └── main/ │ ├── java/ │ │ └── com/ │ │ └── aether/ │ │ └── processor/ │ │ ├── ComposeMirrorProcessor.kt │ │ ├── ComposeMirrorProcessor2.kt │ │ ├── ComposeReflectProcessor.kt │ │ └── ReflectableProcessor.kt │ └── resources/ │ └── META-INF/ │ └── services/ │ └── com.google.devtools.ksp.processing.SymbolProcessorProvider └── settings.gradle.kts
Condensed preview — 112 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (501K chars).
[
{
"path": ".fleet/receipt.json",
"chars": 406,
"preview": "// Project generated by Kotlin Multiplatform Wizard\n{\n \"spec\": {\n \"template_id\": \"kmt\",\n \"targets\": {\n "
},
{
"path": ".gitignore",
"chars": 315,
"preview": "*.iml\n.kotlin\n.gradle\n**/build/\nxcuserdata\n!src/**/build/\nlocal.properties\n.idea\n.DS_Store\ncaptures\n.externalNativeBuild"
},
{
"path": "README.md",
"chars": 823,
"preview": "\n**一、介绍**\n\n* **Aether**:业内首次创新性基于 AST + Runtime 构建 KMP + CMP 的动态化方案,实现逻辑页面动态下发。\n* 全流程覆盖开发至运维。提升发版效率与热修复能力,有效缓解 KMP 缺失的动态"
},
{
"path": "annotations/build.gradle.kts",
"chars": 345,
"preview": "plugins {\n kotlin(\"jvm\")\n}\n\njava {\n sourceCompatibility = JavaVersion.VERSION_17\n targetCompatibility = JavaVer"
},
{
"path": "annotations/src/main/java/com/aether/annotations/ComposeMirror.kt",
"chars": 134,
"preview": "package com.aether.annotations\n\n@Target(AnnotationTarget.CLASS)\n@Retention(AnnotationRetention.SOURCE)\nannotation class "
},
{
"path": "annotations/src/main/java/com/aether/annotations/Reflectable.kt",
"chars": 537,
"preview": "package com.aether.annotations\n\n/**\n * 用于标记可反射的Compose组件类\n */\n@Target(AnnotationTarget.CLASS)\n@Retention(AnnotationReten"
},
{
"path": "build.gradle.kts",
"chars": 394,
"preview": "plugins {\n // this is necessary to avoid the plugins to be loaded multiple times\n // in each subproject's classloa"
},
{
"path": "composeApp/build.gradle.kts",
"chars": 3128,
"preview": "import org.jetbrains.compose.desktop.application.dsl.TargetFormat\nimport org.jetbrains.compose.ExperimentalComposeLibrar"
},
{
"path": "composeApp/src/androidMain/AndroidManifest.xml",
"chars": 1114,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:to"
},
{
"path": "composeApp/src/androidMain/kotlin/Myapplicaton.kt",
"chars": 341,
"preview": "package org.example.project\nimport android.app.Application\nimport com.aether.core.runtime.reflectable.ComposeComponentFa"
},
{
"path": "composeApp/src/androidMain/kotlin/org/example/project/MainActivity.kt",
"chars": 577,
"preview": "package org.example.project\n\nimport android.os.Bundle\nimport androidx.activity.ComponentActivity\nimport androidx.activit"
},
{
"path": "composeApp/src/androidMain/kotlin/org/example/project/Platform.android.kt",
"chars": 213,
"preview": "package org.example.project\n\nimport android.os.Build\n\nclass AndroidPlatform : Platform {\n override val name: String ="
},
{
"path": "composeApp/src/androidMain/res/drawable/ic_launcher_background.xml",
"chars": 5605,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:wi"
},
{
"path": "composeApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml",
"chars": 1702,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:aapt=\"http://schemas.android.com/aapt\"\n "
},
{
"path": "composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml",
"chars": 272,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <b"
},
{
"path": "composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml",
"chars": 272,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <b"
},
{
"path": "composeApp/src/androidMain/res/values/strings.xml",
"chars": 75,
"preview": "<resources>\n <string name=\"app_name\">KotlinProject</string>\n</resources>"
},
{
"path": "composeApp/src/commonMain/composeResources/drawable/compose-multiplatform.xml",
"chars": 4513,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"600dp\"\n android:height=\"600dp\"\n"
},
{
"path": "composeApp/src/commonMain/kotlin/org/example/project/App.kt",
"chars": 1264,
"preview": "package org.example.project\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.Ima"
},
{
"path": "composeApp/src/commonMain/kotlin/org/example/project/Greeting.kt",
"chars": 163,
"preview": "package org.example.project\n\nclass Greeting {\n private val platform = getPlatform()\n\n fun greet(): String {\n "
},
{
"path": "composeApp/src/commonMain/kotlin/org/example/project/Platform.kt",
"chars": 108,
"preview": "package org.example.project\n\ninterface Platform {\n val name: String\n}\n\nexpect fun getPlatform(): Platform"
},
{
"path": "composeApp/src/iosMain/kotlin/org/example/project/MainViewController.kt",
"chars": 148,
"preview": "package org.example.project\n\nimport androidx.compose.ui.window.ComposeUIViewController\n\nfun MainViewController() = Compo"
},
{
"path": "composeApp/src/iosMain/kotlin/org/example/project/Platform.ios.kt",
"chars": 257,
"preview": "package org.example.project\n\nimport platform.UIKit.UIDevice\n\nclass IOSPlatform: Platform {\n override val name: String"
},
{
"path": "composeApp/src/main/AndroidManifest.xml",
"chars": 1077,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:to"
},
{
"path": "composeApp/src/main/java/com/aether/composeapp/example/ReflectableExample.kt",
"chars": 1887,
"preview": "package com.aether.composeapp.example\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundati"
},
{
"path": "core/.gitignore",
"chars": 6,
"preview": "/build"
},
{
"path": "core/build.gradle.kts",
"chars": 3067,
"preview": "plugins {\n alias(libs.plugins.androidLibrary)\n alias(libs.plugins.kotlinAndroid)\n}\n\nandroid {\n namespace = \"com"
},
{
"path": "core/proguard-rules.pro",
"chars": 819,
"preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
},
{
"path": "core/src/androidTest/java/com/aether/core/runtime/ExampleInstrumentedTest.kt",
"chars": 673,
"preview": "package com.aether.core.runtime\n\nimport androidx.test.platform.app.InstrumentationRegistry\nimport androidx.test.ext.juni"
},
{
"path": "core/src/main/AndroidManifest.xml",
"chars": 405,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n <appli"
},
{
"path": "core/src/main/assets/test0_compose.json",
"chars": 1620,
"preview": "{\n \"directives\": [\n {\n \"type\": \"ImportDirective\",\n \"importPath\": \"androidx.compose.material.Text\",\n \""
},
{
"path": "core/src/main/assets/test1_compose.json",
"chars": 4119,
"preview": "{\n \"directives\" : [ {\n \"type\" : \"ImportDirective\",\n \"importPath\" : \"androidx.compose.foundation.background\",\n "
},
{
"path": "core/src/main/java/com/aether/core/runtime/AppContextManager.kt",
"chars": 551,
"preview": "package com.aether.core.runtime\n\nimport com.aether.core.runtime.AppContext\n\nobject AppContextManager {\n private val co"
},
{
"path": "core/src/main/java/com/aether/core/runtime/AstRuntime.kt",
"chars": 59347,
"preview": "package com.aether.core.runtime\n\nimport android.text.TextUtils\nimport com.aether.core.runtime.AppContextManager.context\n"
},
{
"path": "core/src/main/java/com/aether/core/runtime/ClassMirror.kt",
"chars": 17875,
"preview": "package com.aether.core.runtime\n\nimport androidx.compose.runtime.Composable\nimport com.aether.core.runtime.reflectable.C"
},
{
"path": "core/src/main/java/com/aether/core/runtime/KtAstVisitor.kt",
"chars": 35027,
"preview": "package com.aether.core.runtime\n\nimport com.intellij.psi.PsiElement\nimport org.jetbrains.kotlin.lexer.KtSingleValueToken"
},
{
"path": "core/src/main/java/com/aether/core/runtime/Node.kt",
"chars": 49153,
"preview": "package com.aether.core.runtime\n\n\nfun parseError(unit: Any): Nothing {\n throw Exception(\"Parse error: ${unit.toString"
},
{
"path": "core/src/main/java/com/aether/core/runtime/ProgramStack.kt",
"chars": 3853,
"preview": "package com.aether.core.runtime\n\ntypealias LazilyInitializer = () -> Any?\n\nclass Variable(\n private var _value: Any?,"
},
{
"path": "core/src/main/java/com/aether/core/runtime/ProjectHelper.kt",
"chars": 2144,
"preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "core/src/main/java/com/aether/core/runtime/Structs.kt",
"chars": 52296,
"preview": "package com.aether.core.runtime\n\nimport android.text.TextUtils\nimport com.aether.core.runtime.AppContextManager.context\n"
},
{
"path": "core/src/main/java/com/aether/core/runtime/StructsImpl.kt",
"chars": 3871,
"preview": "package com.aether.core.runtime\n\nclass StructsImpl {\n}\n\nabstract class _VariableBase(\n val _name: String,\n val _ty"
},
{
"path": "core/src/main/java/com/aether/core/runtime/context.kt",
"chars": 4145,
"preview": "package com.aether.core.runtime\n\nimport java.util.Collections\n\ntypealias Generator = () -> Any?\n\nclass ContextDependency"
},
{
"path": "core/src/main/java/com/aether/core/runtime/deliver/TemplateProvider.kt",
"chars": 67038,
"preview": "package com.aether.core.runtime.deliver\n\nimport com.aether.core.runtime.AstRuntime\nimport android.util.Log\nimport androi"
},
{
"path": "core/src/main/java/com/aether/core/runtime/deliver/binding.kt",
"chars": 2204,
"preview": "package com.aether.core.runtime.deliver\n\nimport com.aether.core.runtime.AppContextManager.context\nimport com.aether.core"
},
{
"path": "core/src/main/java/com/aether/core/runtime/entity/SimpleMember.kt",
"chars": 227,
"preview": "package com.aether.core.runtime.entity\n\n// 简单的成员表示,用于替代可能导致问题的KCallable\nclass SimpleMember(val name: String, val modifie"
},
{
"path": "core/src/main/java/com/aether/core/runtime/mirror/MirrorHelper.kt",
"chars": 4213,
"preview": "package com.aether.core.runtime.mirror\n\nimport android.util.Log\nimport androidx.compose.ui.Modifier\nimport java.lang.ref"
},
{
"path": "core/src/main/java/com/aether/core/runtime/proxy/ProxyBinding.kt",
"chars": 4157,
"preview": "package com.aether.core.runtime.proxy\n\nimport com.aether.core.runtime.ImportDirective\nimport com.aether.core.runtime.ref"
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/ClassMirror.kt",
"chars": 1689,
"preview": "package com.aether.core.runtime.reflectable\n\nimport androidx.compose.runtime.Composable\nimport kotlin.reflect.KClass\n\nab"
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/ClassMirrorBase.kt",
"chars": 1094,
"preview": "package com.aether.core.runtime.reflectable\n\nopen class ClassMirrorBase(\n override val simpleName: String,\n overri"
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/ComposeComponentDescriptor.kt",
"chars": 1428,
"preview": "package com.aether.core.runtime.reflectable\n\nimport androidx.compose.runtime.Composable\nimport com.aether.core.runtime.E"
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/ComposeComponentRegistry.kt",
"chars": 6877,
"preview": "package com.aether.core.runtime.reflectable\n\nimport androidx.compose.foundation.background\nimport androidx.compose.found"
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/ComposeMirror.kt",
"chars": 544,
"preview": "package com.aether.core.runtime.reflectable\n\nimport androidx.compose.runtime.Composable\n\nobject ComposeMirror {\n priv"
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/ComposeMirrorRuntime.kt",
"chars": 2375,
"preview": "package com.aether.core.runtime.reflectable\n\nimport androidx.compose.runtime.Composable\nimport kotlin.reflect.KClass\nimp"
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/ComposeReflectRuntime.kt",
"chars": 2222,
"preview": "package com.aether.core.runtime.reflectable\n\nimport androidx.compose.runtime.Composable\nimport kotlin.reflect.KClass\nimp"
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/DeclarationMirror.kt",
"chars": 639,
"preview": "package com.aether.core.runtime.reflectable\n\nabstract class DeclarationMirror : Mirror {\n\n /**\n * 返回此声明的简单名称。\n "
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/MethodMirrorImpl.kt",
"chars": 560,
"preview": "package com.aether.core.runtime.reflectable\n\nimport androidx.compose.runtime.Composable\n\nclass MethodMirrorImpl(override"
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/Mirror.kt",
"chars": 910,
"preview": "package com.aether.core.runtime.reflectable\n\n//Mirror 接口作为父接口存在。\ninterface Mirror {\n}\n\n interface ObjectMirror : Mirror "
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/ParamInfo.kt",
"chars": 415,
"preview": "package com.aether.core.runtime.reflectable\n\nimport androidx.compose.runtime.Composable\n\n// 参数信息\ndata class ParamInfo(\n "
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/widgets/ColumnMirror.kt",
"chars": 4035,
"preview": "package com.aether.core.runtime.reflectable.widgets\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androi"
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/widgets/MaterialThemeMirror.kt",
"chars": 1752,
"preview": "package com.aether.core.runtime.reflectable.widgets\n\nimport android.util.Log\nimport androidx.compose.material.MaterialTh"
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/widgets/TextMirror.kt",
"chars": 3714,
"preview": "package com.aether.core.runtime.reflectable.widgets\n\nimport android.graphics.fonts.FontFamily\nimport android.os.Build\nim"
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/widgets/TextStyleMirror.kt",
"chars": 1772,
"preview": "package com.aether.core.runtime.reflectable.widgets\n\nimport android.util.Log\nimport androidx.compose.material.MaterialTh"
},
{
"path": "core/src/main/java/com/aether/core/runtime/reflectable/widgets/TypographyMirror.kt",
"chars": 2584,
"preview": "package com.aether.core.runtime.reflectable.widgets\n\nimport android.text.TextUtils\nimport android.util.Log\nimport androi"
},
{
"path": "core/src/main/java/com/aether/core/runtime/utils/JsonReader.kt",
"chars": 928,
"preview": "package com.aether.core.runtime.utils\n\nimport android.content.Context\nimport android.content.res.AssetManager\nimport org"
},
{
"path": "core/src/main/res/drawable/ic_launcher_background.xml",
"chars": 5606,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:wi"
},
{
"path": "core/src/main/res/drawable/ic_launcher_foreground.xml",
"chars": 1702,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:aapt=\"http://schemas.android.com/aapt\"\n "
},
{
"path": "core/src/main/res/mipmap-anydpi/ic_launcher.xml",
"chars": 343,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <b"
},
{
"path": "core/src/main/res/mipmap-anydpi/ic_launcher_round.xml",
"chars": 343,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <b"
},
{
"path": "core/src/main/res/values/colors.xml",
"chars": 378,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"purple_200\">#FFBB86FC</color>\n <color name=\"purpl"
},
{
"path": "core/src/main/res/values/strings.xml",
"chars": 66,
"preview": "<resources>\n <string name=\"app_name\">core</string>\n</resources>"
},
{
"path": "core/src/main/res/values/themes.xml",
"chars": 815,
"preview": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n <!-- Base application theme. -->\n <style name=\"Theme.K"
},
{
"path": "core/src/main/res/values-night/themes.xml",
"chars": 815,
"preview": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n <!-- Base application theme. -->\n <style name=\"Theme.K"
},
{
"path": "core/src/test/java/com/aether/core/ExampleUnitTest.kt",
"chars": 339,
"preview": "package com.aether.core\n\nimport org.junit.Test\n\nimport org.junit.Assert.*\n\n/**\n * Example local unit test, which will ex"
},
{
"path": "core/src/test/java/com/aether/core/compose/ColumArgsComposeExpressText.kt",
"chars": 1304,
"preview": "package com.aether.core.compose\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.material.Mater"
},
{
"path": "core/src/test/java/com/aether/core/compose/ColumComposeNameExpressText.kt",
"chars": 796,
"preview": "package com.aether.core.compose\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.material.Text\ni"
},
{
"path": "core/src/test/java/com/aether/core/compose/DemoCompose.kt",
"chars": 1679,
"preview": "package com.aether.core.compose\n\nimport androidx.compose.material.Text\nimport androidx.compose.runtime.Composable\nimport"
},
{
"path": "core/src/test/java/com/aether/core/compose/DemoComposeColor.kt",
"chars": 305,
"preview": "package com.aether.core.compose\n\nimport androidx.compose.material.Text\nimport androidx.compose.runtime.Composable\nimport"
},
{
"path": "core/src/test/java/com/aether/core/compose/NameExpressComposeNameExpressText.kt",
"chars": 360,
"preview": "package com.aether.core.compose\n\nimport androidx.compose.material.Text\nimport androidx.compose.runtime.Composable\nimport"
},
{
"path": "core/src/test/java/com/aether/core/express/ArgsComposeTest.kt",
"chars": 816,
"preview": "package com.aether.core.express\n\nimport com.aether.core.runtime.AstRuntime\nimport org.junit.Test\nimport java.io.File\n\ncl"
},
{
"path": "core/src/test/java/com/aether/core/express/ColumArgsExpressComposeTest.kt",
"chars": 438,
"preview": "package com.aether.core.express\n\nimport com.aether.core.runtime.AstRuntime\nimport org.junit.Test\nimport java.io.File\n\ncl"
},
{
"path": "core/src/test/java/com/aether/core/express/ColumExpressComposeTest.kt",
"chars": 835,
"preview": "package com.aether.core.express\n\nimport com.aether.core.runtime.AstRuntime\nimport org.junit.Test\nimport java.io.File\n\ncl"
},
{
"path": "core/src/test/java/com/aether/core/express/DemoEmptyFunctionExpress.kt",
"chars": 257,
"preview": "package com.aether.core.express\n\n\nobject DemoEmptyFunctionExpress {\n /**\n * result =10\n * result2 =10\n * "
},
{
"path": "core/src/test/java/com/aether/core/express/DemoFunctionExpress.kt",
"chars": 606,
"preview": "package com.aether.core.express\n\nimport com.aether.core.express.DemoTest\nimport com.aether.core.express.InstanceTest\nimp"
},
{
"path": "core/src/test/java/com/aether/core/express/DemoTest.kt",
"chars": 306,
"preview": "package com.aether.core.express\n\n\nclass DemoTest {\n\n companion object{\n fun demo1Test1(): Int {\n re"
},
{
"path": "core/src/test/java/com/aether/core/express/InstanceComposeTest.kt",
"chars": 4723,
"preview": "package com.aether.core.express\n\nimport com.aether.core.runtime.AstRuntime\nimport org.jline.utils.Log\nimport org.junit.T"
},
{
"path": "core/src/test/java/com/aether/core/express/InstanceCreationExpressionTest.kt",
"chars": 593,
"preview": "package com.aether.core.express\n\nimport com.aether.core.runtime.AstRuntime\nimport org.jline.utils.Log\nimport org.junit.T"
},
{
"path": "core/src/test/java/com/aether/core/express/InstanceJsonEmptyCreationExpressionTest.kt",
"chars": 3977,
"preview": "package com.aether.core.express\n\nimport com.aether.core.runtime.AstRuntime\nimport org.junit.Test\n\nclass InstanceJsonEmpt"
},
{
"path": "core/src/test/java/com/aether/core/express/InstanceTest.kt",
"chars": 465,
"preview": "package com.aether.core.express\n\nimport org.jline.utils.Log\n\nclass InstanceTest {\n private var age = 18;\n private "
},
{
"path": "core/src/test/java/com/aether/core/express/NameExpressComposeTest.kt",
"chars": 840,
"preview": "package com.aether.core.express\n\nimport com.aether.core.runtime.AstRuntime\nimport org.junit.Test\nimport java.io.File\n\ncl"
},
{
"path": "core/src/test/java/com/aether/core/runtime/ExampleUnitTest.kt",
"chars": 347,
"preview": "package com.aether.core.runtime\n\nimport org.junit.Test\n\nimport org.junit.Assert.*\n\n/**\n * Example local unit test, which"
},
{
"path": "gradle/libs.versions.toml",
"chars": 2310,
"preview": "[versions]\nagp = \"8.2.0\"\nandroid-compileSdk = \"34\"\nandroid-minSdk = \"26\"\nandroid-targetSdk = \"34\"\nandroidx-activityCompo"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 229,
"preview": "#Mon Apr 07 01:51:47 CST 2025\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://"
},
{
"path": "gradle.properties",
"chars": 354,
"preview": "#Kotlin\nkotlin.code.style=official\nkotlin.daemon.jvmargs=-Xmx2048M\n\n#Gradle\norg.gradle.jvmargs=-Xmx2048M -Dfile.encoding"
},
{
"path": "gradlew",
"chars": 8739,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "gradlew.bat",
"chars": 2966,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "iosApp/Configuration/Config.xcconfig",
"chars": 75,
"preview": "TEAM_ID=\nBUNDLE_ID=org.example.project.KotlinProject\nAPP_NAME=KotlinProject"
},
{
"path": "iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json",
"chars": 122,
"preview": "{\n \"colors\" : [\n {\n \"idiom\" : \"universal\"\n }\n ],\n \"info\" : {\n \"author\" : \"xcode\",\n \"version\" : 1\n }"
},
{
"path": "iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 217,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"app-icon-1024.png\",\n \"idiom\" : \"universal\",\n \"platform\" : \"ios\",\n "
},
{
"path": "iosApp/iosApp/Assets.xcassets/Contents.json",
"chars": 62,
"preview": "{\n \"info\" : {\n \"author\" : \"xcode\",\n \"version\" : 1\n }\n}"
},
{
"path": "iosApp/iosApp/ContentView.swift",
"chars": 486,
"preview": "import UIKit\nimport SwiftUI\nimport ComposeApp\n\nstruct ComposeView: UIViewControllerRepresentable {\n func makeUIViewCo"
},
{
"path": "iosApp/iosApp/Info.plist",
"chars": 1577,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json",
"chars": 62,
"preview": "{\n \"info\" : {\n \"author\" : \"xcode\",\n \"version\" : 1\n }\n}"
},
{
"path": "iosApp/iosApp/iOSApp.swift",
"chars": 135,
"preview": "import SwiftUI\n\n@main\nstruct iOSApp: App {\n var body: some Scene {\n WindowGroup {\n ContentView()\n "
},
{
"path": "iosApp/iosApp.xcodeproj/project.pbxproj",
"chars": 14377,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 56;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "processor/build.gradle.kts",
"chars": 438,
"preview": "plugins {\n kotlin(\"jvm\")\n id(\"com.google.devtools.ksp\") version \"1.8.22-1.0.11\"\n}\n\n// 确保处理器可以作为工件发布\nsourceSets.mai"
},
{
"path": "processor/src/main/java/com/aether/processor/ComposeMirrorProcessor.kt",
"chars": 2940,
"preview": "package com.aether.processor\n\nimport com.google.devtools.ksp.processing.*\nimport com.google.devtools.ksp.symbol.*\nimport"
},
{
"path": "processor/src/main/java/com/aether/processor/ComposeMirrorProcessor2.kt",
"chars": 6018,
"preview": "package com.aether.processor\n\nimport com.aether.annotations.GenerateMirror\nimport com.google.devtools.ksp.processing.Cod"
},
{
"path": "processor/src/main/java/com/aether/processor/ComposeReflectProcessor.kt",
"chars": 3981,
"preview": "package com.aether.processor\n\nimport com.google.devtools.ksp.processing.*\nimport com.google.devtools.ksp.symbol.*\nimport"
},
{
"path": "processor/src/main/java/com/aether/processor/ReflectableProcessor.kt",
"chars": 2603,
"preview": "package com.aether.processor\n\nimport com.google.devtools.ksp.processing.*\nimport com.google.devtools.ksp.symbol.*\nimport"
},
{
"path": "processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider",
"chars": 51,
"preview": "com.aether.processor.ComposeMirrorProcessorProvider"
},
{
"path": "settings.gradle.kts",
"chars": 455,
"preview": "rootProject.name = \"KotlinProject\"\nenableFeaturePreview(\"TYPESAFE_PROJECT_ACCESSORS\")\n\npluginManagement {\n repositori"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the JyAether/Aether GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 112 files (442.6 KB), approximately 104.9k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.