Compare commits
31 Commits
v1.2.0
...
42c7d11c09
| Author | SHA1 | Date | |
|---|---|---|---|
| 42c7d11c09 | |||
| 5ca5aa64c7 | |||
| eda7ef771e | |||
| 593c4d7783 | |||
| d24a522b32 | |||
| 41afb834ae | |||
| b745329e26 | |||
| 1fb4f64cb3 | |||
| 1f8e8981ce | |||
| a257d30dba | |||
| 97ee3b0667 | |||
| 8e2bafba5f | |||
| 6149bc133d | |||
| 5f22ee3b1f | |||
| fa72ff8061 | |||
| 65f24860e6 | |||
|
|
4881233211 | ||
| bc01fdf362 | |||
| 709998ff9c | |||
| 6adeadeed4 | |||
| 7b70a39b23 | |||
| 873a3c0e60 | |||
| 5b88efcfbe | |||
| f37c659c89 | |||
| 9fff7bcfca | |||
| b4b0ad9bba | |||
| 6d8fdf62f1 | |||
| 9f53d7421d | |||
| 80c8ecb4cf | |||
| d10059a82d | |||
| 737f83cd5f |
16
README.md
16
README.md
@@ -1,10 +1,10 @@
|
|||||||
# <img src="./frontend/public/appicon.png" alt="VoidRaft Logo" width="32" height="32" style="vertical-align: middle;"> VoidRaft
|
# <img src="./frontend/public/appicon.png" alt="voidraft Logo" width="32" height="32" style="vertical-align: middle;"> voidraft
|
||||||
|
|
||||||
[中文](README_ZH.md) | **English**
|
[中文](README_ZH.md) | **English**
|
||||||
|
|
||||||
> *An elegant text snippet recording tool designed for developers.*
|
> *An elegant text snippet recording tool designed for developers.*
|
||||||
|
|
||||||
VoidRaft is a modern developer-focused text editor that allows you to record, organize, and manage various text snippets anytime, anywhere. Whether it's temporary code snippets, API responses, meeting notes, or daily to-do lists, VoidRaft provides a smooth and elegant editing experience.
|
voidraft is a modern developer-focused text editor that allows you to record, organize, and manage various text snippets anytime, anywhere. Whether it's temporary code snippets, API responses, meeting notes, or daily to-do lists, voidraft provides a smooth and elegant editing experience.
|
||||||
|
|
||||||
## Core Features
|
## Core Features
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ After building, the executable will be generated in the `bin` directory.
|
|||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
Voidraft/
|
voidraft/
|
||||||
├── frontend/ # Vue 3 frontend application
|
├── frontend/ # Vue 3 frontend application
|
||||||
│ ├── src/
|
│ ├── src/
|
||||||
│ │ ├── views/editor/ # Editor core views
|
│ │ ├── views/editor/ # Editor core views
|
||||||
@@ -121,19 +121,19 @@ Voidraft/
|
|||||||
### Planned Features
|
### Planned Features
|
||||||
- ✅ Custom themes - Customize editor themes
|
- ✅ Custom themes - Customize editor themes
|
||||||
- ✅ Multi-window support - Support editing multiple documents simultaneously
|
- ✅ Multi-window support - Support editing multiple documents simultaneously
|
||||||
|
- ✅ Data synchronization - Cloud backup for documents
|
||||||
- [ ] Enhanced clipboard - Monitor and manage clipboard history
|
- [ ] Enhanced clipboard - Monitor and manage clipboard history
|
||||||
- [ ] Data synchronization - Cloud backup for configurations and documents
|
|
||||||
- [ ] Extension system - Support for custom plugins
|
- [ ] Extension system - Support for custom plugins
|
||||||
|
|
||||||
## Acknowledgments
|
## Acknowledgments
|
||||||
|
|
||||||
> Standing on the shoulders of giants, paying tribute to the open source spirit
|
> Standing on the shoulders of giants, paying tribute to the open source spirit
|
||||||
|
|
||||||
The birth of VoidRaft is inseparable from the following excellent open source projects:
|
The birth of voidraft is inseparable from the following excellent open source projects:
|
||||||
|
|
||||||
### Special Thanks
|
### Special Thanks
|
||||||
|
|
||||||
- **[Heynote](https://github.com/heyman/heynote/)** - VoidRaft is a feature-enhanced version based on Heynote's concept
|
- **[Heynote](https://github.com/heyman/heynote/)** - voidraft is a feature-enhanced version based on Heynote's concept
|
||||||
- Inherits Heynote's elegant block editing philosophy
|
- Inherits Heynote's elegant block editing philosophy
|
||||||
- Adds more practical features on the original foundation
|
- Adds more practical features on the original foundation
|
||||||
- Rebuilt with modern technology stack
|
- Rebuilt with modern technology stack
|
||||||
@@ -157,7 +157,7 @@ This project is open source under the [MIT License](LICENSE).
|
|||||||
Welcome to Fork, Star, and contribute code.
|
Welcome to Fork, Star, and contribute code.
|
||||||
|
|
||||||
[](https://opensource.org/licenses/MIT)
|
[](https://opensource.org/licenses/MIT)
|
||||||
[](https://github.com/yourusername/Voidraft)
|
[](https://github.com/yourusername/voidraft)
|
||||||
[](https://github.com/yourusername/Voidraft)
|
[](https://github.com/yourusername/voidraft)
|
||||||
|
|
||||||
*Made with ❤️ by landaiqing*
|
*Made with ❤️ by landaiqing*
|
||||||
16
README_ZH.md
16
README_ZH.md
@@ -1,10 +1,10 @@
|
|||||||
# <img src="./frontend/public/appicon.png" alt="Voidraft Logo" width="32" height="32" style="vertical-align: middle;"> Voidraft
|
# <img src="./frontend/public/appicon.png" alt="voidraft Logo" width="32" height="32" style="vertical-align: middle;"> voidraft
|
||||||
|
|
||||||
**中文** | [English](README.md)
|
**中文** | [English](README.md)
|
||||||
|
|
||||||
> *一个专为开发者打造的优雅文本片段记录工具。*
|
> *一个专为开发者打造的优雅文本片段记录工具。*
|
||||||
|
|
||||||
Voidraft 是一个现代化的开发者专用文本编辑器,让你能够随时随地记录、整理和管理各种文本片段。无论是临时的代码片段、API 响应、会议笔记,还是日常的待办事项,Voidraft 都能为你提供流畅而优雅的编辑体验。
|
voidraft 是一个现代化的开发者专用文本编辑器,让你能够随时随地记录、整理和管理各种文本片段。无论是临时的代码片段、API 响应、会议笔记,还是日常的待办事项,voidraft 都能为你提供流畅而优雅的编辑体验。
|
||||||
|
|
||||||
## 核心特性
|
## 核心特性
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ wails3 package
|
|||||||
## 项目结构
|
## 项目结构
|
||||||
|
|
||||||
```
|
```
|
||||||
Voidraft/
|
voidraft/
|
||||||
├── frontend/ # Vue 3 前端应用
|
├── frontend/ # Vue 3 前端应用
|
||||||
│ ├── src/
|
│ ├── src/
|
||||||
│ │ ├── views/editor/ # 编辑器核心视图
|
│ │ ├── views/editor/ # 编辑器核心视图
|
||||||
@@ -122,8 +122,8 @@ Voidraft/
|
|||||||
### 计划添加的功能
|
### 计划添加的功能
|
||||||
- ✅ 自定义主题 - 自定义编辑器主题
|
- ✅ 自定义主题 - 自定义编辑器主题
|
||||||
- ✅ 多窗口支持 - 支持同时编辑多个文档
|
- ✅ 多窗口支持 - 支持同时编辑多个文档
|
||||||
|
- ✅ 数据同步 - 文档云端备份
|
||||||
- [ ] 剪切板增强 - 监听和管理剪切板历史
|
- [ ] 剪切板增强 - 监听和管理剪切板历史
|
||||||
- [ ] 数据同步 - 配置和文档云端备份
|
|
||||||
- [ ] 扩展系统 - 支持自定义插件
|
- [ ] 扩展系统 - 支持自定义插件
|
||||||
|
|
||||||
|
|
||||||
@@ -131,11 +131,11 @@ Voidraft/
|
|||||||
|
|
||||||
> 站在巨人的肩膀上,致敬开源精神
|
> 站在巨人的肩膀上,致敬开源精神
|
||||||
|
|
||||||
Voidraft 的诞生离不开以下优秀的开源项目:
|
voidraft 的诞生离不开以下优秀的开源项目:
|
||||||
|
|
||||||
### 特别感谢
|
### 特别感谢
|
||||||
|
|
||||||
- **[Heynote](https://github.com/heyman/heynote/)** - Voidraft 是基于 Heynote 概念的功能增强版本
|
- **[Heynote](https://github.com/heyman/heynote/)** - voidraft 是基于 Heynote 概念的功能增强版本
|
||||||
- 继承了 Heynote 优雅的块状编辑理念
|
- 继承了 Heynote 优雅的块状编辑理念
|
||||||
- 在原有基础上增加了更多实用功能
|
- 在原有基础上增加了更多实用功能
|
||||||
- 采用现代化技术栈重新构建
|
- 采用现代化技术栈重新构建
|
||||||
@@ -159,7 +159,7 @@ Voidraft 的诞生离不开以下优秀的开源项目:
|
|||||||
欢迎 Fork、Star 和贡献代码。
|
欢迎 Fork、Star 和贡献代码。
|
||||||
|
|
||||||
[](https://opensource.org/licenses/MIT)
|
[](https://opensource.org/licenses/MIT)
|
||||||
[](https://github.com/yourusername/Voidraft)
|
[](https://github.com/yourusername/voidraft)
|
||||||
[](https://github.com/yourusername/Voidraft)
|
[](https://github.com/yourusername/voidraft)
|
||||||
|
|
||||||
*Made with ❤️ by landaiqing*
|
*Made with ❤️ by landaiqing*
|
||||||
|
|||||||
12
Taskfile.yml
12
Taskfile.yml
@@ -12,13 +12,25 @@ vars:
|
|||||||
VITE_PORT: '{{.WAILS_VITE_PORT | default 9245}}'
|
VITE_PORT: '{{.WAILS_VITE_PORT | default 9245}}'
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
|
version:
|
||||||
|
summary: Generate version information
|
||||||
|
cmds:
|
||||||
|
- '{{if eq OS "windows"}}cmd /c ".\scripts\version.bat"{{else}}bash ./scripts/version.sh{{end}}'
|
||||||
|
sources:
|
||||||
|
- scripts/version.bat
|
||||||
|
- scripts/version.sh
|
||||||
|
generates:
|
||||||
|
- version.txt
|
||||||
|
|
||||||
build:
|
build:
|
||||||
summary: Builds the application
|
summary: Builds the application
|
||||||
|
deps: [version]
|
||||||
cmds:
|
cmds:
|
||||||
- task: "{{OS}}:build"
|
- task: "{{OS}}:build"
|
||||||
|
|
||||||
package:
|
package:
|
||||||
summary: Packages a production build of the application
|
summary: Packages a production build of the application
|
||||||
|
deps: [version]
|
||||||
cmds:
|
cmds:
|
||||||
- task: "{{OS}}:package"
|
- task: "{{OS}}:package"
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ version: '3'
|
|||||||
|
|
||||||
# This information is used to generate the build assets.
|
# This information is used to generate the build assets.
|
||||||
info:
|
info:
|
||||||
companyName: "Voidraft" # The name of the company
|
companyName: "voidraft" # The name of the company
|
||||||
productName: "Voidraft" # The name of the application
|
productName: "voidraft" # The name of the application
|
||||||
productIdentifier: "landaiqing" # The unique product identifier
|
productIdentifier: "landaiqing" # The unique product identifier
|
||||||
description: "Voidraft" # The application description
|
description: "voidraft" # The application description
|
||||||
copyright: "© 2025 Voidraft. All rights reserved." # Copyright text
|
copyright: "© 2025 voidraft. All rights reserved." # Copyright text
|
||||||
comments: "Voidraft" # Comments
|
comments: "voidraft" # Comments
|
||||||
version: "0.0.1.0" # The application version
|
version: "0.0.1.0" # The application version
|
||||||
|
|
||||||
# Dev mode configuration
|
# Dev mode configuration
|
||||||
|
|||||||
@@ -4,15 +4,15 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>Voidraft</string>
|
<string>voidraft</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>Voidraft</string>
|
<string>voidraft</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>landaiqing</string>
|
<string>landaiqing</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>0.0.1.0</string>
|
<string>0.0.1.0</string>
|
||||||
<key>CFBundleGetInfoString</key>
|
<key>CFBundleGetInfoString</key>
|
||||||
<string>Voidraft</string>
|
<string>voidraft</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.0.1.0</string>
|
<string>0.0.1.0</string>
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<key>NSHighResolutionCapable</key>
|
<key>NSHighResolutionCapable</key>
|
||||||
<string>true</string>
|
<string>true</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>© 2025 Voidraft. All rights reserved.</string>
|
<string>© 2025 voidraft. All rights reserved.</string>
|
||||||
<key>NSAppTransportSecurity</key>
|
<key>NSAppTransportSecurity</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSAllowsLocalNetworking</key>
|
<key>NSAllowsLocalNetworking</key>
|
||||||
|
|||||||
@@ -4,15 +4,15 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>Voidraft</string>
|
<string>voidraft</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>Voidraft</string>
|
<string>voidraft</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>landaiqing</string>
|
<string>landaiqing</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>0.0.1.0</string>
|
<string>0.0.1.0</string>
|
||||||
<key>CFBundleGetInfoString</key>
|
<key>CFBundleGetInfoString</key>
|
||||||
<string>Voidraft</string>
|
<string>voidraft</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.0.1.0</string>
|
<string>0.0.1.0</string>
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
@@ -22,6 +22,6 @@
|
|||||||
<key>NSHighResolutionCapable</key>
|
<key>NSHighResolutionCapable</key>
|
||||||
<string>true</string>
|
<string>true</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>© 2025 Voidraft. All rights reserved.</string>
|
<string>© 2025 voidraft. All rights reserved.</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
@@ -11,9 +11,12 @@ tasks:
|
|||||||
- task: common:build:frontend
|
- task: common:build:frontend
|
||||||
- task: common:generate:icons
|
- task: common:generate:icons
|
||||||
cmds:
|
cmds:
|
||||||
- go build {{.BUILD_FLAGS}} -o {{.OUTPUT}}
|
- go build {{.BUILD_FLAGS}} -ldflags="{{.LDFLAGS}} {{.VERSION_FLAGS}}" -o {{.OUTPUT}}
|
||||||
vars:
|
vars:
|
||||||
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
|
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
|
||||||
|
LDFLAGS: '{{if eq .PRODUCTION "true"}}-w -s{{else}}{{end}}'
|
||||||
|
VERSION_FLAGS:
|
||||||
|
sh: 'grep "VERSION=" version.txt | cut -d"=" -f2 | xargs -I {} echo "-X voidraft/internal/version.Version={}"'
|
||||||
DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}'
|
DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}'
|
||||||
OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}'
|
OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}'
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -11,9 +11,12 @@ tasks:
|
|||||||
- task: common:build:frontend
|
- task: common:build:frontend
|
||||||
- task: common:generate:icons
|
- task: common:generate:icons
|
||||||
cmds:
|
cmds:
|
||||||
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}
|
- go build {{.BUILD_FLAGS}} -ldflags="{{.LDFLAGS}} {{.VERSION_FLAGS}}" -o {{.BIN_DIR}}/{{.APP_NAME}}
|
||||||
vars:
|
vars:
|
||||||
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
|
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
|
||||||
|
LDFLAGS: '{{if eq .PRODUCTION "true"}}-w -s{{else}}{{end}}'
|
||||||
|
VERSION_FLAGS:
|
||||||
|
sh: 'grep "VERSION=" version.txt | cut -d"=" -f2 | xargs -I {} echo "-X voidraft/internal/version.Version={}"'
|
||||||
env:
|
env:
|
||||||
GOOS: linux
|
GOOS: linux
|
||||||
CGO_ENABLED: 1
|
CGO_ENABLED: 1
|
||||||
|
|||||||
@@ -3,26 +3,26 @@
|
|||||||
#
|
#
|
||||||
# The lines below are called `modelines`. See `:help modeline`
|
# The lines below are called `modelines`. See `:help modeline`
|
||||||
|
|
||||||
name: "Voidraft"
|
name: "voidraft"
|
||||||
arch: ${GOARCH}
|
arch: ${GOARCH}
|
||||||
platform: "linux"
|
platform: "linux"
|
||||||
version: "0.0.1.0"
|
version: "0.0.1.0"
|
||||||
section: "default"
|
section: "default"
|
||||||
priority: "extra"
|
priority: "extra"
|
||||||
maintainer: ${GIT_COMMITTER_NAME} <${GIT_COMMITTER_EMAIL}>
|
maintainer: ${GIT_COMMITTER_NAME} <${GIT_COMMITTER_EMAIL}>
|
||||||
description: "Voidraft"
|
description: "voidraft"
|
||||||
vendor: "Voidraft"
|
vendor: "voidraft"
|
||||||
homepage: "https://wails.io"
|
homepage: "https://voidraft.landaiqing.cn"
|
||||||
license: "MIT"
|
license: "MIT"
|
||||||
release: "1"
|
release: "1"
|
||||||
|
|
||||||
contents:
|
contents:
|
||||||
- src: "./bin/Voidraft"
|
- src: "./bin/voidraft"
|
||||||
dst: "/usr/local/bin/Voidraft"
|
dst: "/usr/local/bin/voidraft"
|
||||||
- src: "./build/appicon.png"
|
- src: "./build/appicon.png"
|
||||||
dst: "/usr/share/icons/hicolor/128x128/apps/Voidraft.png"
|
dst: "/usr/share/icons/hicolor/128x128/apps/voidraft.png"
|
||||||
- src: "./build/linux/Voidraft.desktop"
|
- src: "./build/linux/voidraft.desktop"
|
||||||
dst: "/usr/share/applications/Voidraft.desktop"
|
dst: "/usr/share/applications/voidraft.desktop"
|
||||||
|
|
||||||
depends:
|
depends:
|
||||||
- gtk3
|
- gtk3
|
||||||
|
|||||||
@@ -14,13 +14,16 @@ tasks:
|
|||||||
- task: common:generate:icons
|
- task: common:generate:icons
|
||||||
cmds:
|
cmds:
|
||||||
- task: generate:syso
|
- task: generate:syso
|
||||||
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}.exe
|
- go build {{.BUILD_FLAGS}} -ldflags="{{.LDFLAGS}} {{.VERSION_FLAGS}}" -o {{.BIN_DIR}}/{{.APP_NAME}}.exe
|
||||||
- cmd: powershell Remove-item *.syso
|
- cmd: powershell Remove-item *.syso
|
||||||
platforms: [windows]
|
platforms: [windows]
|
||||||
- cmd: rm -f *.syso
|
- cmd: rm -f *.syso
|
||||||
platforms: [linux, darwin]
|
platforms: [linux, darwin]
|
||||||
vars:
|
vars:
|
||||||
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s -H windowsgui"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
|
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
|
||||||
|
LDFLAGS: '{{if eq .PRODUCTION "true"}}-w -s -H windowsgui{{else}}{{end}}'
|
||||||
|
VERSION_FLAGS:
|
||||||
|
sh: 'powershell -Command "(Get-Content version.txt) -replace ''VERSION='', ''-X voidraft/internal/version.Version=''"'
|
||||||
env:
|
env:
|
||||||
GOOS: windows
|
GOOS: windows
|
||||||
CGO_ENABLED: 1
|
CGO_ENABLED: 1
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
"info": {
|
"info": {
|
||||||
"0000": {
|
"0000": {
|
||||||
"ProductVersion": "0.0.1.0",
|
"ProductVersion": "0.0.1.0",
|
||||||
"CompanyName": "Voidraft",
|
"CompanyName": "voidraft",
|
||||||
"FileDescription": "Voidraft",
|
"FileDescription": "voidraft",
|
||||||
"LegalCopyright": "© 2025 Voidraft. All rights reserved.",
|
"LegalCopyright": "© 2025 voidraft. All rights reserved.",
|
||||||
"ProductName": "Voidraft",
|
"ProductName": "voidraft",
|
||||||
"Comments": "Voidraft"
|
"Comments": "voidraft"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,19 +5,19 @@
|
|||||||
!include "FileFunc.nsh"
|
!include "FileFunc.nsh"
|
||||||
|
|
||||||
!ifndef INFO_PROJECTNAME
|
!ifndef INFO_PROJECTNAME
|
||||||
!define INFO_PROJECTNAME "Voidraft"
|
!define INFO_PROJECTNAME "voidraft"
|
||||||
!endif
|
!endif
|
||||||
!ifndef INFO_COMPANYNAME
|
!ifndef INFO_COMPANYNAME
|
||||||
!define INFO_COMPANYNAME "Voidraft"
|
!define INFO_COMPANYNAME "voidraft"
|
||||||
!endif
|
!endif
|
||||||
!ifndef INFO_PRODUCTNAME
|
!ifndef INFO_PRODUCTNAME
|
||||||
!define INFO_PRODUCTNAME "Voidraft"
|
!define INFO_PRODUCTNAME "voidraft"
|
||||||
!endif
|
!endif
|
||||||
!ifndef INFO_PRODUCTVERSION
|
!ifndef INFO_PRODUCTVERSION
|
||||||
!define INFO_PRODUCTVERSION "0.0.1.0"
|
!define INFO_PRODUCTVERSION "0.0.1.0"
|
||||||
!endif
|
!endif
|
||||||
!ifndef INFO_COPYRIGHT
|
!ifndef INFO_COPYRIGHT
|
||||||
!define INFO_COPYRIGHT "© 2025 Voidraft. All rights reserved."
|
!define INFO_COPYRIGHT "© 2025 voidraft. All rights reserved."
|
||||||
!endif
|
!endif
|
||||||
!ifndef PRODUCT_EXECUTABLE
|
!ifndef PRODUCT_EXECUTABLE
|
||||||
!define PRODUCT_EXECUTABLE "${INFO_PROJECTNAME}.exe"
|
!define PRODUCT_EXECUTABLE "${INFO_PROJECTNAME}.exe"
|
||||||
|
|||||||
1
docs/CNAME
Normal file
1
docs/CNAME
Normal file
@@ -0,0 +1 @@
|
|||||||
|
voidraft.landaiqing.cn
|
||||||
75
docs/changelog.html
Normal file
75
docs/changelog.html
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>voidraft - Changelog</title>
|
||||||
|
<link rel="stylesheet" href="css/styles.css">
|
||||||
|
<link rel="stylesheet" href="css/changelog.css">
|
||||||
|
<link rel="icon" href="img/favicon.ico">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Space+Mono&display=swap" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
</head>
|
||||||
|
<body class="theme-dark">
|
||||||
|
<div class="container">
|
||||||
|
<!-- 主卡片 -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h1 class="card-title" data-en="voidraft Changelog" data-zh="voidraft 更新日志">voidraft Changelog</h1>
|
||||||
|
<div class="card-controls">
|
||||||
|
<button id="theme-toggle" class="btn btn-secondary" title="切换主题">
|
||||||
|
<i class="fas fa-sun"></i> <span data-en="Theme" data-zh="主题">Theme</span>
|
||||||
|
</button>
|
||||||
|
<button id="lang-toggle" class="btn btn-secondary">
|
||||||
|
<i class="fas fa-language"></i> 中/EN
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-content">
|
||||||
|
<!-- 导航区域 -->
|
||||||
|
<div class="nav-links">
|
||||||
|
<a href="index.html" class="btn btn-secondary">
|
||||||
|
<i class="fas fa-home"></i> <span data-en="Home" data-zh="首页">Home</span>
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/landaiqing/voidraft" class="btn btn-secondary">
|
||||||
|
<i class="fab fa-github"></i> <span data-en="Source Code" data-zh="源代码">Source Code</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 加载中提示 -->
|
||||||
|
<div id="loading" class="loading-container">
|
||||||
|
<div class="loading-spinner"></div>
|
||||||
|
<p data-en="Loading releases..." data-zh="正在加载版本信息...">Loading releases...</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 更新日志内容 -->
|
||||||
|
<div id="changelog" class="changelog-container">
|
||||||
|
<!-- 通过JavaScript动态填充内容 -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 错误信息 -->
|
||||||
|
<div id="error-message" class="error-container" style="display: none;">
|
||||||
|
<i class="fas fa-exclamation-triangle"></i>
|
||||||
|
<p data-en="Failed to load release information. Please try again later."
|
||||||
|
data-zh="加载版本信息失败,请稍后再试。">Failed to load release information. Please try again later.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 页脚 -->
|
||||||
|
<footer class="footer">
|
||||||
|
<p class="footer-text" data-en="© 2025 voidraft - An elegant text snippet recording tool designed for developers" data-zh="© 2025 voidraft - 专为开发者打造的优雅文本片段记录工具">© 2023-2024 voidraft - An elegant text snippet recording tool designed for developers</p>
|
||||||
|
<div class="footer-links">
|
||||||
|
<a href="https://github.com/landaiqing/voidraft" target="_blank" class="footer-link">GitHub</a>
|
||||||
|
<a href="https://github.com/landaiqing/voidraft/issues" target="_blank" class="footer-link" data-en="Issues" data-zh="问题反馈">Issues</a>
|
||||||
|
<a href="https://github.com/landaiqing/voidraft/releases" target="_blank" class="footer-link" data-en="Releases" data-zh="版本发布">Releases</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="js/script.js"></script>
|
||||||
|
<script src="js/changelog.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
347
docs/css/changelog.css
Normal file
347
docs/css/changelog.css
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
/* 更新日志页面样式 */
|
||||||
|
.nav-links {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
display: flex;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-container {
|
||||||
|
text-align: center;
|
||||||
|
padding: 40px 0;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-spinner {
|
||||||
|
border: 4px solid rgba(0, 0, 0, 0.1);
|
||||||
|
border-left-color: var(--primary-color);
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
margin: 0 auto 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-dark .loading-spinner {
|
||||||
|
border-color: rgba(255, 255, 255, 0.1);
|
||||||
|
border-left-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-container {
|
||||||
|
text-align: center;
|
||||||
|
color: var(--error-color);
|
||||||
|
padding: 20px;
|
||||||
|
border: 2px dashed var(--error-color);
|
||||||
|
margin: 20px 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: rgba(var(--card-bg-rgb), 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-container i {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 更新日志容器 */
|
||||||
|
.changelog-container {
|
||||||
|
display: none;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release {
|
||||||
|
margin-bottom: 40px;
|
||||||
|
border-left: 4px solid var(--primary-color);
|
||||||
|
padding-left: 20px;
|
||||||
|
background-color: rgba(var(--card-bg-rgb), 0.5);
|
||||||
|
padding: 15px 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-version {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-date {
|
||||||
|
color: var(--text-color);
|
||||||
|
opacity: 0.7;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 3px 8px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-left: 10px;
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-badge.pre-release {
|
||||||
|
background-color: var(--warning-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-description {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-assets {
|
||||||
|
background-color: rgba(var(--light-bg-rgb), 0.7);
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-assets-title {
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-list {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 8px 0;
|
||||||
|
border-bottom: 1px solid rgba(128, 128, 128, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-icon {
|
||||||
|
margin-right: 10px;
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-name {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-size {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--text-color);
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 资源下载按钮 */
|
||||||
|
.download-btn {
|
||||||
|
margin-left: 10px;
|
||||||
|
padding: 3px 10px;
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 12px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-btn:hover {
|
||||||
|
background-color: var(--secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content {
|
||||||
|
line-height: 1.8;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content h1,
|
||||||
|
.markdown-content h2,
|
||||||
|
.markdown-content h3 {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content ul,
|
||||||
|
.markdown-content ol {
|
||||||
|
padding-left: 20px;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content li {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content li:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content hr {
|
||||||
|
border: none;
|
||||||
|
border-top: 2px dashed var(--border-color);
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content br {
|
||||||
|
display: block;
|
||||||
|
content: "";
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content code {
|
||||||
|
font-family: 'IBM Plex Mono', monospace;
|
||||||
|
background-color: rgba(128, 128, 128, 0.1);
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content pre {
|
||||||
|
background-color: rgba(128, 128, 128, 0.1);
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow-x: auto;
|
||||||
|
margin: 15px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content pre code {
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content a {
|
||||||
|
color: var(--primary-color);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-source {
|
||||||
|
padding: 10px 15px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
background-color: rgba(var(--light-bg-rgb), 0.7);
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: right;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-source a {
|
||||||
|
color: var(--primary-color);
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-source a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Markdown内容样式增强 */
|
||||||
|
.markdown-content blockquote {
|
||||||
|
border-left: 4px solid var(--primary-color);
|
||||||
|
padding: 10px 15px;
|
||||||
|
margin: 15px 0;
|
||||||
|
background-color: rgba(var(--light-bg-rgb), 0.5);
|
||||||
|
border-radius: 0 4px 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content ul,
|
||||||
|
.markdown-content ol {
|
||||||
|
padding-left: 20px;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 移动设备响应式优化 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.release-header {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-assets {
|
||||||
|
padding: 12px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-item {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: 12px 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-name {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-size {
|
||||||
|
margin-left: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-btn {
|
||||||
|
margin-left: 10px;
|
||||||
|
padding: 5px 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.release {
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-item {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-icon {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-size {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-btn {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content pre {
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确保日志页面页脚样式一致 */
|
||||||
|
.footer {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-text {
|
||||||
|
margin: 0 0 15px 0;
|
||||||
|
}
|
||||||
45
docs/css/ibm-plex-mono-font.css
Normal file
45
docs/css/ibm-plex-mono-font.css
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/* cyrillic-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'IBM Plex Mono';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1iIq129k.woff2) format('woff2');
|
||||||
|
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||||
|
}
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'IBM Plex Mono';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1isq129k.woff2) format('woff2');
|
||||||
|
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||||
|
}
|
||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'IBM Plex Mono';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1iAq129k.woff2) format('woff2');
|
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'IBM Plex Mono';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1iEq129k.woff2) format('woff2');
|
||||||
|
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'IBM Plex Mono';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1i8q1w.woff2) format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
27
docs/css/space-mono-font.css
Normal file
27
docs/css/space-mono-font.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/* vietnamese */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Mono';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/space-mono/i7dPIFZifjKcF5UAWdDRYE58RWq7.woff2) format('woff2');
|
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
|
||||||
|
}
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Mono';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/space-mono/i7dPIFZifjKcF5UAWdDRYE98RWq7.woff2) format('woff2');
|
||||||
|
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||||
|
}
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Space Mono';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(../font/space-mono/i7dPIFZifjKcF5UAWdDRYEF8RQ.woff2) format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
717
docs/css/styles.css
Normal file
717
docs/css/styles.css
Normal file
@@ -0,0 +1,717 @@
|
|||||||
|
@import url('./space-mono-font.css');
|
||||||
|
@import url('./ibm-plex-mono-font.css');
|
||||||
|
|
||||||
|
/* 浅色主题 */
|
||||||
|
:root {
|
||||||
|
--bg-color: #fefefe;
|
||||||
|
--text-color: #000000;
|
||||||
|
--primary-color: #F08080;
|
||||||
|
--primary-color-rgb: 240, 128, 128;
|
||||||
|
--secondary-color: #ff006e;
|
||||||
|
--accent-color: #073B4C;
|
||||||
|
--card-bg: #ffffff;
|
||||||
|
--card-bg-rgb: 255, 255, 255;
|
||||||
|
--border-color: #000000;
|
||||||
|
--light-bg: #f0f0f0;
|
||||||
|
--light-bg-rgb: 240, 240, 240;
|
||||||
|
--shadow-color: rgba(240, 128, 128, 0.5);
|
||||||
|
--success-color: #27c93f;
|
||||||
|
--warning-color: #FFD166;
|
||||||
|
--error-color: #ff006e;
|
||||||
|
--info-color: #118ab2;
|
||||||
|
--code-bg: #ffffff;
|
||||||
|
--code-bg-rgb: 255, 255, 255;
|
||||||
|
--preview-header-bg: #f0f0f0;
|
||||||
|
--preview-header-bg-rgb: 240, 240, 240;
|
||||||
|
--grid-color-1: rgba(0, 0, 0, 0.08);
|
||||||
|
--grid-color-2: rgba(0, 0, 0, 0.05);
|
||||||
|
--header-title-color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 暗色主题变量 */
|
||||||
|
.theme-dark {
|
||||||
|
--bg-color: #121212;
|
||||||
|
--text-color: #ffffff;
|
||||||
|
--primary-color: #F08080;
|
||||||
|
--primary-color-rgb: 240, 128, 128;
|
||||||
|
--secondary-color: #ff006e;
|
||||||
|
--accent-color: #118ab2;
|
||||||
|
--card-bg: #1e1e1e;
|
||||||
|
--card-bg-rgb: 30, 30, 30;
|
||||||
|
--border-color: #ffffff;
|
||||||
|
--light-bg: #2a2a2a;
|
||||||
|
--light-bg-rgb: 42, 42, 42;
|
||||||
|
--shadow-color: rgba(240, 128, 128, 0.5);
|
||||||
|
--success-color: #27c93f;
|
||||||
|
--warning-color: #FFD166;
|
||||||
|
--error-color: #ff006e;
|
||||||
|
--info-color: #118ab2;
|
||||||
|
--code-bg: #1e1e1e;
|
||||||
|
--code-bg-rgb: 30, 30, 30;
|
||||||
|
--preview-header-bg: #252526;
|
||||||
|
--preview-header-bg-rgb: 37, 37, 38;
|
||||||
|
--grid-color-1: rgba(255, 255, 255, 0.08);
|
||||||
|
--grid-color-2: rgba(255, 255, 255, 0.05);
|
||||||
|
--header-title-color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 主题切换和语言切换的过渡效果 */
|
||||||
|
.theme-transition,
|
||||||
|
.theme-transition *,
|
||||||
|
.lang-transition,
|
||||||
|
.lang-transition * {
|
||||||
|
transition: all 0.3s ease !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes gridMove {
|
||||||
|
0% {
|
||||||
|
background-position: 0px 0px, 0px 0px, 0px 0px, 0px 0px;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 80px 80px, 80px 80px, 20px 20px, 20px 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--bg-color);
|
||||||
|
background-image:
|
||||||
|
linear-gradient(var(--grid-color-1) 1px, transparent 1px),
|
||||||
|
linear-gradient(90deg, var(--grid-color-1) 1px, transparent 1px),
|
||||||
|
linear-gradient(var(--grid-color-2) 0.5px, transparent 0.5px),
|
||||||
|
linear-gradient(90deg, var(--grid-color-2) 0.5px, transparent 0.5px);
|
||||||
|
background-size: 80px 80px, 80px 80px, 20px 20px, 20px 20px;
|
||||||
|
background-position: center;
|
||||||
|
animation: gridMove 40s linear infinite;
|
||||||
|
font-family: 'Space Mono', monospace;
|
||||||
|
color: var(--text-color);
|
||||||
|
line-height: 1.6;
|
||||||
|
padding: 20px;
|
||||||
|
transition: background-color 0.3s ease, color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 卡片容器 */
|
||||||
|
.card {
|
||||||
|
background-color: var(--card-bg);
|
||||||
|
background-image:
|
||||||
|
linear-gradient(var(--grid-color-1) 1px, transparent 1px),
|
||||||
|
linear-gradient(90deg, var(--grid-color-1) 1px, transparent 1px),
|
||||||
|
linear-gradient(var(--grid-color-2) 0.5px, transparent 0.5px),
|
||||||
|
linear-gradient(90deg, var(--grid-color-2) 0.5px, transparent 0.5px);
|
||||||
|
background-size: 80px 80px, 80px 80px, 20px 20px, 20px 20px;
|
||||||
|
background-position: center;
|
||||||
|
border: 4px solid var(--border-color);
|
||||||
|
box-shadow: 12px 12px 0 var(--shadow-color);
|
||||||
|
margin-bottom: 40px;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 16px 16px 0 var(--shadow-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 卡片头部 */
|
||||||
|
.card-header {
|
||||||
|
background-color: rgba(var(--primary-color-rgb), 0.9);
|
||||||
|
border-bottom: 4px solid var(--border-color);
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
color: var(--header-title-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-controls {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 10px 20px;
|
||||||
|
background: var(--secondary-color);
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
border: 3px solid var(--border-color);
|
||||||
|
box-shadow: 4px 4px 0 var(--shadow-color);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: 'Space Mono', monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
background: var(--card-bg);
|
||||||
|
color: var(--primary-color);
|
||||||
|
border: 3px solid var(--primary-color);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background: var(--light-bg);
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background: var(--card-bg);
|
||||||
|
color: var(--primary-color);
|
||||||
|
border: 3px solid var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 卡片内容 */
|
||||||
|
.card-content {
|
||||||
|
padding: 30px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
background-color: rgba(var(--card-bg-rgb), 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Logo区域 */
|
||||||
|
.logo-container {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-frame {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
background: var(--card-bg);
|
||||||
|
border: 4px solid var(--border-color);
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-image {
|
||||||
|
width: 130px;
|
||||||
|
height: 130px;
|
||||||
|
object-fit: contain;
|
||||||
|
border: 2px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-text {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tagline {
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 10px 0 0;
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 介绍区域 */
|
||||||
|
.intro-box {
|
||||||
|
border: 2px dashed var(--border-color);
|
||||||
|
padding: 20px;
|
||||||
|
background-color: rgba(var(--light-bg-rgb), 0.7);
|
||||||
|
margin-bottom: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-text {
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮组 */
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 20px;
|
||||||
|
margin: 30px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 特性网格 */
|
||||||
|
.features-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
margin: 40px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 特性卡片 */
|
||||||
|
.feature-card {
|
||||||
|
background-color: rgba(var(--card-bg-rgb), 0.8);
|
||||||
|
border: 3px solid var(--border-color);
|
||||||
|
box-shadow: 5px 5px 0 var(--shadow-color);
|
||||||
|
padding: 20px;
|
||||||
|
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-card:hover {
|
||||||
|
transform: translateY(-3px);
|
||||||
|
box-shadow: 7px 7px 0 var(--shadow-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: var(--secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-desc {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 预览区域 */
|
||||||
|
.preview-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 20px;
|
||||||
|
margin: 30px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.preview-container {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 预览窗口 */
|
||||||
|
.preview-window {
|
||||||
|
border: 3px solid var(--border-color);
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 10px;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 300px;
|
||||||
|
background-color: rgba(var(--card-bg-rgb), 0.7);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-shadow: 5px 5px 0 var(--shadow-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 预览头部 */
|
||||||
|
.preview-header {
|
||||||
|
background-color: rgba(var(--preview-header-bg-rgb), 0.9);
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 2px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-controls {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-btn {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 0.5px solid rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-btn:nth-child(1) {
|
||||||
|
background-color: #ff5f56;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-btn:nth-child(2) {
|
||||||
|
background-color: #ffbd2e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-btn:nth-child(3) {
|
||||||
|
background-color: #27c93f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-title {
|
||||||
|
font-size: 13px;
|
||||||
|
opacity: 0.8;
|
||||||
|
color: var(--text-color);
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 预览内容 */
|
||||||
|
.preview-content {
|
||||||
|
padding: 15px;
|
||||||
|
flex-grow: 1;
|
||||||
|
overflow: auto;
|
||||||
|
background-color: rgba(var(--code-bg-rgb), 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 代码块容器 */
|
||||||
|
.code-block-wrapper {
|
||||||
|
background-color: rgba(var(--code-bg-rgb), 0.8);
|
||||||
|
border: 2px solid var(--border-color);
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 块头部 */
|
||||||
|
.block-header {
|
||||||
|
background-color: rgba(var(--light-bg-rgb), 0.8);
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-bottom: 2px solid var(--border-color);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-language {
|
||||||
|
color: rgba(128, 128, 128, 0.8);
|
||||||
|
font-family: 'IBM Plex Mono', monospace;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-language::before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
margin-right: 5px;
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23888'%3E%3Cpath d='M9.7,16.7L5.3,12.3C4.9,11.9 4.9,11.1 5.3,10.7C5.7,10.3 6.3,10.3 6.7,10.7L10.5,14.5L17.3,7.7C17.7,7.3 18.3,7.3 18.7,7.7C19.1,8.1 19.1,8.7 18.7,9.1L11.3,16.7C10.9,17.1 10.1,17.1 9.7,16.7Z'/%3E%3C/svg%3E");
|
||||||
|
background-size: contain;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-block {
|
||||||
|
font-family: 'IBM Plex Mono', monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin: 0;
|
||||||
|
white-space: pre;
|
||||||
|
tab-size: 4;
|
||||||
|
-moz-tab-size: 4;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-dark .code-block-wrapper {
|
||||||
|
border-color: rgba(255, 255, 255, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-dark .block-header {
|
||||||
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
|
border-color: rgba(255, 255, 255, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-dark .block-language {
|
||||||
|
color: rgba(255, 255, 255, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-dark .block-language::before {
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23aaa'%3E%3Cpath d='M9.7,16.7L5.3,12.3C4.9,11.9 4.9,11.1 5.3,10.7C5.7,10.3 6.3,10.3 6.7,10.7L10.5,14.5L17.3,7.7C17.7,7.3 18.3,7.3 18.7,7.7C19.1,8.1 19.1,8.7 18.7,9.1L11.3,16.7C10.9,17.1 10.1,17.1 9.7,16.7Z'/%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-dark .code-block {
|
||||||
|
color: #d4d4d4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 代码高亮 */
|
||||||
|
.theme-dark .keyword { color: #c586c0; }
|
||||||
|
.theme-dark .function { color: #dcdcaa; }
|
||||||
|
.theme-dark .variable { color: #9cdcfe; }
|
||||||
|
.theme-dark .string { color: #ce9178; }
|
||||||
|
.theme-dark .comment { color: #6a9955; }
|
||||||
|
.theme-dark .class { color: #4ec9b0; }
|
||||||
|
.theme-dark .parameter { color: #9cdcfe; }
|
||||||
|
.theme-dark .built-in { color: #4ec9b0; }
|
||||||
|
|
||||||
|
/* 浅色主题代码高亮 */
|
||||||
|
.keyword { color: #af00db; }
|
||||||
|
.function { color: #795e26; }
|
||||||
|
.variable { color: #001080; }
|
||||||
|
.string { color: #a31515; }
|
||||||
|
.comment { color: #008000; }
|
||||||
|
.class { color: #267f99; }
|
||||||
|
.parameter { color: #001080; }
|
||||||
|
.built-in { color: #267f99; }
|
||||||
|
|
||||||
|
.preview-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
display: block;
|
||||||
|
border: none;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-dark .light-theme-img {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-dark .dark-theme-img {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
body:not(.theme-dark) .dark-theme-img {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body:not(.theme-dark) .light-theme-img {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 技术栈列表 */
|
||||||
|
.tech-list {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 技术栈列表 */
|
||||||
|
.tech-item {
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
border: 2px solid var(--border-color);
|
||||||
|
background-color: rgba(var(--light-bg-rgb), 0.7);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-icon {
|
||||||
|
margin-right: 15px;
|
||||||
|
color: var(--secondary-color);
|
||||||
|
font-size: 20px;
|
||||||
|
width: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-name {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-desc {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 页脚 */
|
||||||
|
.footer {
|
||||||
|
border-top: 2px solid var(--border-color);
|
||||||
|
padding: 20px 0;
|
||||||
|
margin-top: 40px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
background-color: transparent;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-text {
|
||||||
|
margin: 0 0 15px 0;
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-links {
|
||||||
|
display: flex;
|
||||||
|
gap: 15px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link {
|
||||||
|
color: var(--secondary-color);
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式设计 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.button-group {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.features-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.card-header {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-controls {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-frame {
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-image {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 针对移动设备的响应式优化 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
body {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 15px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-controls {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 预览区域优化 */
|
||||||
|
.preview-content {
|
||||||
|
max-width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-block {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-word;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-header {
|
||||||
|
padding: 6px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 日志界面导航链接优化 */
|
||||||
|
.nav-links {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-links .btn {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
/* 特性卡片优化 */
|
||||||
|
.features-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 预览窗口优化 */
|
||||||
|
.preview-container {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-window {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 技术栈列表小屏幕优化 */
|
||||||
|
.tech-item {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tech-desc {
|
||||||
|
width: 100%;
|
||||||
|
padding-left: 40px; /* 图标宽度+右边距 */
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 日志界面资源列表项优化 */
|
||||||
|
.asset-item {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: 15px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-name {
|
||||||
|
width: 100%;
|
||||||
|
word-break: break-all;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-size {
|
||||||
|
order: 2;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-btn {
|
||||||
|
order: 3;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 页脚链接优化 */
|
||||||
|
.footer {
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-links {
|
||||||
|
margin-top: 15px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
docs/font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1i8q1w.woff2
Normal file
BIN
docs/font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1i8q1w.woff2
Normal file
Binary file not shown.
BIN
docs/font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1iAq129k.woff2
Normal file
BIN
docs/font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1iAq129k.woff2
Normal file
Binary file not shown.
BIN
docs/font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1iEq129k.woff2
Normal file
BIN
docs/font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1iEq129k.woff2
Normal file
Binary file not shown.
BIN
docs/font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1iIq129k.woff2
Normal file
BIN
docs/font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1iIq129k.woff2
Normal file
Binary file not shown.
BIN
docs/font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1isq129k.woff2
Normal file
BIN
docs/font/ibm-plex-mono/-F63fjptAgt5VM-kVkqdyU8n1isq129k.woff2
Normal file
Binary file not shown.
BIN
docs/font/space-mono/i7dPIFZifjKcF5UAWdDRYE58RWq7.woff2
Normal file
BIN
docs/font/space-mono/i7dPIFZifjKcF5UAWdDRYE58RWq7.woff2
Normal file
Binary file not shown.
BIN
docs/font/space-mono/i7dPIFZifjKcF5UAWdDRYE98RWq7.woff2
Normal file
BIN
docs/font/space-mono/i7dPIFZifjKcF5UAWdDRYE98RWq7.woff2
Normal file
Binary file not shown.
BIN
docs/font/space-mono/i7dPIFZifjKcF5UAWdDRYEF8RQ.woff2
Normal file
BIN
docs/font/space-mono/i7dPIFZifjKcF5UAWdDRYEF8RQ.woff2
Normal file
Binary file not shown.
BIN
docs/img/favicon.ico
Normal file
BIN
docs/img/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
BIN
docs/img/logo.png
Normal file
BIN
docs/img/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
BIN
docs/img/screenshot-dark.png
Normal file
BIN
docs/img/screenshot-dark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
BIN
docs/img/screenshot-light.png
Normal file
BIN
docs/img/screenshot-light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
256
docs/index.html
Normal file
256
docs/index.html
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>voidraft - An elegant text snippet recording tool designed for developers.</title>
|
||||||
|
<meta name="description" content="voidraft is an elegant text snippet recording tool designed for developers. Features multi-language code blocks, syntax highlighting, code formatting, custom themes, and more.">
|
||||||
|
<meta name="keywords" content="text editor, code snippets, developer tools, syntax highlighting, code formatting, multi-language, voidraft">
|
||||||
|
<meta name="author" content="voidraft Team">
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<link rel="canonical" href="https://landaiqing.github.io/voidraft/">
|
||||||
|
|
||||||
|
<!-- Internationalization / hreflang -->
|
||||||
|
<link rel="alternate" hreflang="en" href="https://landaiqing.github.io/voidraft/">
|
||||||
|
<link rel="alternate" hreflang="zh" href="https://landaiqing.github.io/voidraft/?lang=zh">
|
||||||
|
<link rel="alternate" hreflang="x-default" href="https://landaiqing.github.io/voidraft/">
|
||||||
|
|
||||||
|
<!-- Open Graph / Facebook -->
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:url" content="https://landaiqing.github.io/voidraft/">
|
||||||
|
<meta property="og:title" content="voidraft - An elegant text snippet recording tool designed for developers">
|
||||||
|
<meta property="og:description" content="voidraft is an elegant text snippet recording tool designed for developers. Features multi-language code blocks, syntax highlighting, code formatting, custom themes, and more.">
|
||||||
|
<meta property="og:image" content="https://landaiqing.github.io/voidraft/img/screenshot-dark.png">
|
||||||
|
<meta property="og:site_name" content="voidraft">
|
||||||
|
|
||||||
|
<!-- Twitter -->
|
||||||
|
<meta property="twitter:card" content="summary_large_image">
|
||||||
|
<meta property="twitter:url" content="https://landaiqing.github.io/voidraft/">
|
||||||
|
<meta property="twitter:title" content="voidraft - An elegant text snippet recording tool designed for developers">
|
||||||
|
<meta property="twitter:description" content="voidraft is an elegant text snippet recording tool designed for developers. Features multi-language code blocks, syntax highlighting, code formatting, custom themes, and more.">
|
||||||
|
<meta property="twitter:image" content="https://landaiqing.github.io/voidraft/img/screenshot-dark.png">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="./css/styles.css">
|
||||||
|
<link rel="icon" href="./img/favicon.ico" type="image/x-icon">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
|
||||||
|
<!-- Structured Data -->
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "SoftwareApplication",
|
||||||
|
"name": "voidraft",
|
||||||
|
"description": "An elegant text snippet recording tool designed for developers. Features multi-language code blocks, syntax highlighting, code formatting, custom themes, and more.",
|
||||||
|
"url": "https://landaiqing.github.io/voidraft/",
|
||||||
|
"downloadUrl": "https://github.com/landaiqing/voidraft/releases",
|
||||||
|
"author": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "voidraft"
|
||||||
|
},
|
||||||
|
"operatingSystem": ["Windows", "macOS", "Linux"],
|
||||||
|
"applicationCategory": "DeveloperApplication",
|
||||||
|
"offers": {
|
||||||
|
"@type": "Offer",
|
||||||
|
"price": "0",
|
||||||
|
"priceCurrency": "USD"
|
||||||
|
},
|
||||||
|
"screenshot": "https://landaiqing.github.io/voidraft/img/screenshot-dark.png",
|
||||||
|
"softwareVersion": "Latest",
|
||||||
|
"programmingLanguage": ["Go", "TypeScript", "Vue.js"],
|
||||||
|
"codeRepository": "https://github.com/landaiqing/voidraft"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body class="theme-dark">
|
||||||
|
<div class="container">
|
||||||
|
<!-- 主卡片 -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h1 class="card-title">voidraft</h1>
|
||||||
|
<div class="card-controls">
|
||||||
|
<button id="theme-toggle" class="btn btn-secondary" title="切换主题">
|
||||||
|
<i class="fas fa-sun"></i> <span data-en="Theme" data-zh="主题">Theme</span>
|
||||||
|
</button>
|
||||||
|
<button id="lang-toggle" class="btn btn-secondary">
|
||||||
|
<i class="fas fa-language"></i> 中/EN
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-content">
|
||||||
|
<!-- Logo和介绍 -->
|
||||||
|
<div class="logo-container">
|
||||||
|
<div class="logo-frame">
|
||||||
|
<img src="img/logo.png" alt="voidraft Logo" class="logo-image">
|
||||||
|
</div>
|
||||||
|
<h2 class="logo-text" data-en="voidraft" data-zh="voidraft">voidraft</h2>
|
||||||
|
<p class="tagline" data-en="An elegant text snippet recording tool" data-zh="优雅的文本片段记录工具">An elegant text snippet recording tool</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="intro-box">
|
||||||
|
<p class="intro-text" data-en="Designed for developers to record, organize, and manage various text snippets anytime, anywhere." data-zh="专为开发者打造,随时随地记录、整理和管理各种文本片段。">Designed for developers to record, organize, and manage various text snippets anytime, anywhere.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="button-group">
|
||||||
|
<a href="https://github.com/landaiqing/voidraft/releases" class="btn" data-en="Download" data-zh="下载">
|
||||||
|
<i class="fas fa-download"></i> Download
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/landaiqing/voidraft" class="btn btn-secondary" data-en="Source Code" data-zh="源代码">
|
||||||
|
<i class="fab fa-github"></i> Source Code
|
||||||
|
</a>
|
||||||
|
<a href="changelog.html" class="btn btn-secondary" data-en="Changelog" data-zh="更新日志">
|
||||||
|
<i class="fas fa-history"></i> Changelog
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 特性部分 -->
|
||||||
|
<h2 data-en="Core Features" data-zh="核心特性">Core Features</h2>
|
||||||
|
|
||||||
|
<div class="features-grid">
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<i class="fas fa-code"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="feature-title" data-en="Developer-Friendly" data-zh="开发者友好">Developer-Friendly</h3>
|
||||||
|
<p class="feature-desc" data-en="Multi-language code blocks with syntax highlighting for 30+ programming languages" data-zh="多语言代码块支持,为30+种编程语言提供语法高亮">Multi-language code blocks with syntax highlighting for 30+ programming languages</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<i class="fas fa-magic"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="feature-title" data-en="Code Formatting" data-zh="代码格式化">Code Formatting</h3>
|
||||||
|
<p class="feature-desc" data-en="Built-in Prettier support for one-click code beautification" data-zh="内置Prettier支持,一键美化代码">Built-in Prettier support for one-click code beautification</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<i class="fas fa-palette"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="feature-title" data-en="Custom Themes" data-zh="自定义主题">Custom Themes</h3>
|
||||||
|
<p class="feature-desc" data-en="Dark/Light themes with full customization options" data-zh="深色/浅色主题,支持完全自定义">Dark/Light themes with full customization options</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<i class="fas fa-clone"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="feature-title" data-en="Multi-Window" data-zh="多窗口支持">Multi-Window</h3>
|
||||||
|
<p class="feature-desc" data-en="Edit multiple documents simultaneously" data-zh="同时编辑多个文档">Edit multiple documents simultaneously</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<i class="fas fa-layer-group"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="feature-title" data-en="Block Editing" data-zh="块状编辑">Block Editing</h3>
|
||||||
|
<p class="feature-desc" data-en="Split content into independent code blocks with different language settings" data-zh="将内容分割为独立的代码块,每个块可设置不同语言">Split content into independent code blocks with different language settings</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon">
|
||||||
|
<i class="fas fa-puzzle-piece"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="feature-title" data-en="Extensions" data-zh="丰富扩展">Extensions</h3>
|
||||||
|
<p class="feature-desc" data-en="Rainbow brackets, VSCode-style search, color picker, translation tool, and more" data-zh="彩虹括号、VSCode风格搜索、颜色选择器、翻译工具等多种扩展">Rainbow brackets, VSCode-style search, color picker, translation tool, and more</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 预览部分 -->
|
||||||
|
<h2 data-en="Preview" data-zh="预览">Preview</h2>
|
||||||
|
|
||||||
|
<div class="preview-container">
|
||||||
|
<div class="preview-window">
|
||||||
|
<div class="preview-header">
|
||||||
|
<div class="preview-controls">
|
||||||
|
<span class="preview-btn"></span>
|
||||||
|
<span class="preview-btn"></span>
|
||||||
|
<span class="preview-btn"></span>
|
||||||
|
</div>
|
||||||
|
<div class="preview-title">voidraft</div>
|
||||||
|
</div>
|
||||||
|
<div class="preview-content">
|
||||||
|
<div class="code-block-wrapper">
|
||||||
|
<div class="block-header">
|
||||||
|
<div class="block-language">javascript</div>
|
||||||
|
</div>
|
||||||
|
<pre class="code-block">
|
||||||
|
<span class="keyword">function</span> <span class="function">createDocument</span>() {
|
||||||
|
<span class="keyword">const</span> <span class="variable">doc</span> = <span class="keyword">new</span> <span class="class">Document</span>();
|
||||||
|
|
||||||
|
<span class="variable">doc</span>.<span class="function">addCodeBlock</span>(<span class="string">'javascript'</span>, <span class="string">`
|
||||||
|
<span class="keyword">function</span> <span class="function">greeting</span>(<span class="parameter">name</span>) {
|
||||||
|
<span class="keyword">return</span> <span class="string">`Hello, </span>${<span class="parameter">name</span>}<span class="string">!`</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
<span class="built-in">console</span>.<span class="function">log</span>(<span class="function">greeting</span>(<span class="string">'World'</span>));
|
||||||
|
`</span>);
|
||||||
|
|
||||||
|
<span class="keyword">return</span> <span class="variable">doc</span>;
|
||||||
|
}</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="code-block-wrapper" style="margin-top: 10px;">
|
||||||
|
<div class="block-header">
|
||||||
|
<div class="block-language">text</div>
|
||||||
|
</div>
|
||||||
|
<pre class="code-block">
|
||||||
|
<span class="comment">// voidraft - An elegant text snippet recording tool</span>
|
||||||
|
<span class="comment">// Multi-language support | Code formatting | Custom themes</span>
|
||||||
|
<span class="comment">// A modern text editor designed for developers</span></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="preview-window">
|
||||||
|
<img src="img/screenshot-dark.png" alt="voidraft 界面预览" class="preview-image dark-theme-img">
|
||||||
|
<img src="img/screenshot-light.png" alt="voidraft 界面预览" class="preview-image light-theme-img" style="display: none;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 技术栈部分 -->
|
||||||
|
<h2 data-en="Technical Stack" data-zh="技术栈">Technical Stack</h2>
|
||||||
|
|
||||||
|
<ul class="tech-list">
|
||||||
|
<li class="tech-item">
|
||||||
|
<div class="tech-icon"><i class="fas fa-desktop"></i></div>
|
||||||
|
<span class="tech-name">Wails3</span>
|
||||||
|
<span class="tech-desc" data-en="Cross-platform desktop application framework" data-zh="跨平台桌面应用框架">Cross-platform desktop application framework</span>
|
||||||
|
</li>
|
||||||
|
<li class="tech-item">
|
||||||
|
<div class="tech-icon"><i class="fas fa-cogs"></i></div>
|
||||||
|
<span class="tech-name">Go 1.21+</span>
|
||||||
|
<span class="tech-desc" data-en="Fast and efficient backend language" data-zh="快速高效的后端语言">Fast and efficient backend language</span>
|
||||||
|
</li>
|
||||||
|
<li class="tech-item">
|
||||||
|
<div class="tech-icon"><i class="fab fa-vuejs"></i></div>
|
||||||
|
<span class="tech-name">Vue 3 + TypeScript</span>
|
||||||
|
<span class="tech-desc" data-en="Modern frontend framework" data-zh="现代化前端框架">Modern frontend framework</span>
|
||||||
|
</li>
|
||||||
|
<li class="tech-item">
|
||||||
|
<div class="tech-icon"><i class="fas fa-edit"></i></div>
|
||||||
|
<span class="tech-name">CodeMirror 6</span>
|
||||||
|
<span class="tech-desc" data-en="Modern code editor with extension support" data-zh="支持扩展的现代化代码编辑器">Modern code editor with extension support</span>
|
||||||
|
</li>
|
||||||
|
<li class="tech-item">
|
||||||
|
<div class="tech-icon"><i class="fas fa-database"></i></div>
|
||||||
|
<span class="tech-name">SQLite</span>
|
||||||
|
<span class="tech-desc" data-en="Lightweight database for document storage" data-zh="轻量级文档存储数据库">Lightweight database for document storage</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 页脚 -->
|
||||||
|
<footer class="footer">
|
||||||
|
<p class="footer-text" data-en="© 2025 voidraft - An elegant text snippet recording tool designed for developers" data-zh="© 2025 voidraft - 专为开发者打造的优雅文本片段记录工具">© 2025 voidraft - An elegant text snippet recording tool designed for developers</p>
|
||||||
|
<div class="footer-links">
|
||||||
|
<a href="https://github.com/landaiqing/voidraft" target="_blank" class="footer-link">GitHub</a>
|
||||||
|
<a href="https://github.com/landaiqing/voidraft/issues" target="_blank" class="footer-link" data-en="Issues" data-zh="问题反馈">Issues</a>
|
||||||
|
<a href="https://github.com/landaiqing/voidraft/releases" target="_blank" class="footer-link" data-en="Releases" data-zh="版本发布">Releases</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="js/script.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
705
docs/js/changelog.js
Normal file
705
docs/js/changelog.js
Normal file
@@ -0,0 +1,705 @@
|
|||||||
|
/**
|
||||||
|
* voidraft - Changelog Script
|
||||||
|
* 从GitHub API获取发布信息,支持Gitea备用源
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 仓库配置类
|
||||||
|
*/
|
||||||
|
class RepositoryConfig {
|
||||||
|
constructor() {
|
||||||
|
this.repos = {
|
||||||
|
github: {
|
||||||
|
owner: 'landaiqing',
|
||||||
|
name: 'voidraft',
|
||||||
|
apiUrl: 'https://api.github.com/repos/landaiqing/voidraft/releases',
|
||||||
|
releasesUrl: 'https://github.com/landaiqing/voidraft/releases'
|
||||||
|
},
|
||||||
|
gitea: {
|
||||||
|
owner: 'landaiqing',
|
||||||
|
name: 'voidraft',
|
||||||
|
domain: 'git.landaiqing.cn',
|
||||||
|
apiUrl: 'https://git.landaiqing.cn/api/v1/repos/landaiqing/voidraft/releases',
|
||||||
|
releasesUrl: 'https://git.landaiqing.cn/landaiqing/voidraft/releases'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取仓库配置
|
||||||
|
* @param {string} source - 'github' 或 'gitea'
|
||||||
|
*/
|
||||||
|
getRepo(source) {
|
||||||
|
return this.repos[source];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有仓库配置
|
||||||
|
*/
|
||||||
|
getAllRepos() {
|
||||||
|
return this.repos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际化消息管理类
|
||||||
|
*/
|
||||||
|
class I18nMessages {
|
||||||
|
constructor() {
|
||||||
|
this.messages = {
|
||||||
|
loading: {
|
||||||
|
en: 'Loading releases...',
|
||||||
|
zh: '正在加载版本信息...'
|
||||||
|
},
|
||||||
|
noReleases: {
|
||||||
|
en: 'No release information found',
|
||||||
|
zh: '没有找到版本发布信息'
|
||||||
|
},
|
||||||
|
fetchError: {
|
||||||
|
en: 'Failed to load release information. Please try again later.',
|
||||||
|
zh: '无法获取版本信息,请稍后再试'
|
||||||
|
},
|
||||||
|
githubApiError: {
|
||||||
|
en: 'GitHub API returned an error status: ',
|
||||||
|
zh: 'GitHub API返回错误状态: '
|
||||||
|
},
|
||||||
|
giteaApiError: {
|
||||||
|
en: 'Gitea API returned an error status: ',
|
||||||
|
zh: 'Gitea API返回错误状态: '
|
||||||
|
},
|
||||||
|
dataSource: {
|
||||||
|
en: 'Data source: ',
|
||||||
|
zh: '数据来源: '
|
||||||
|
},
|
||||||
|
downloads: {
|
||||||
|
en: 'Downloads',
|
||||||
|
zh: '下载资源'
|
||||||
|
},
|
||||||
|
download: {
|
||||||
|
en: 'Download',
|
||||||
|
zh: '下载'
|
||||||
|
},
|
||||||
|
preRelease: {
|
||||||
|
en: 'Pre-release',
|
||||||
|
zh: '预发布'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取消息
|
||||||
|
* @param {string} key - 消息键
|
||||||
|
* @param {string} lang - 语言代码
|
||||||
|
*/
|
||||||
|
getMessage(key, lang = 'en') {
|
||||||
|
return this.messages[key] && this.messages[key][lang] || this.messages[key]['en'] || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前语言
|
||||||
|
*/
|
||||||
|
getCurrentLang() {
|
||||||
|
return window.currentLang || 'en';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API客户端类
|
||||||
|
*/
|
||||||
|
class APIClient {
|
||||||
|
constructor(repositoryConfig, i18nMessages) {
|
||||||
|
this.repositoryConfig = repositoryConfig;
|
||||||
|
this.i18nMessages = i18nMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从指定源获取发布信息
|
||||||
|
* @param {string} source - 'github' 或 'gitea'
|
||||||
|
*/
|
||||||
|
async fetchReleases(source) {
|
||||||
|
const repo = this.repositoryConfig.getRepo(source);
|
||||||
|
const errorMessageKey = source === 'github' ? 'githubApiError' : 'giteaApiError';
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
headers: { 'Accept': 'application/json' }
|
||||||
|
};
|
||||||
|
|
||||||
|
if (source === 'github') {
|
||||||
|
return this.fetchFromGitHub(repo, options, errorMessageKey);
|
||||||
|
} else {
|
||||||
|
return this.fetchFromGitea(repo, options, errorMessageKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从GitHub获取数据
|
||||||
|
* @param {Object} repo - 仓库配置
|
||||||
|
* @param {Object} options - 请求选项
|
||||||
|
* @param {string} errorMessageKey - 错误消息键
|
||||||
|
*/
|
||||||
|
async fetchFromGitHub(repo, options, errorMessageKey) {
|
||||||
|
const controller = new AbortController();
|
||||||
|
const timeoutId = setTimeout(() => controller.abort(), 10000);
|
||||||
|
|
||||||
|
options.signal = controller.signal;
|
||||||
|
options.headers['Accept'] = 'application/vnd.github.v3+json';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(repo.apiUrl, options);
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`${this.i18nMessages.getMessage(errorMessageKey, this.i18nMessages.getCurrentLang())}${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const releases = await response.json();
|
||||||
|
|
||||||
|
if (!releases || releases.length === 0) {
|
||||||
|
throw new Error(this.i18nMessages.getMessage('noReleases', this.i18nMessages.getCurrentLang()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return releases;
|
||||||
|
} catch (error) {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从Gitea获取数据
|
||||||
|
* @param {Object} repo - 仓库配置
|
||||||
|
* @param {Object} options - 请求选项
|
||||||
|
* @param {string} errorMessageKey - 错误消息键
|
||||||
|
*/
|
||||||
|
async fetchFromGitea(repo, options, errorMessageKey) {
|
||||||
|
const response = await fetch(repo.apiUrl, options);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`${this.i18nMessages.getMessage(errorMessageKey, this.i18nMessages.getCurrentLang())}${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const releases = await response.json();
|
||||||
|
|
||||||
|
if (!releases || releases.length === 0) {
|
||||||
|
throw new Error(this.i18nMessages.getMessage('noReleases', this.i18nMessages.getCurrentLang()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return releases;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UI管理类
|
||||||
|
*/
|
||||||
|
class UIManager {
|
||||||
|
constructor(i18nMessages) {
|
||||||
|
this.i18nMessages = i18nMessages;
|
||||||
|
this.elements = {
|
||||||
|
loading: document.getElementById('loading'),
|
||||||
|
changelog: document.getElementById('changelog'),
|
||||||
|
error: document.getElementById('error-message')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示加载状态
|
||||||
|
*/
|
||||||
|
showLoading() {
|
||||||
|
this.elements.loading.style.display = 'block';
|
||||||
|
this.elements.error.style.display = 'none';
|
||||||
|
this.elements.changelog.innerHTML = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 隐藏加载状态
|
||||||
|
*/
|
||||||
|
hideLoading() {
|
||||||
|
this.elements.loading.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示错误消息
|
||||||
|
* @param {string} message - 错误消息
|
||||||
|
*/
|
||||||
|
showError(message) {
|
||||||
|
const errorMessageElement = this.elements.error.querySelector('p');
|
||||||
|
if (errorMessageElement) {
|
||||||
|
errorMessageElement.textContent = message;
|
||||||
|
} else {
|
||||||
|
this.elements.error.textContent = message;
|
||||||
|
}
|
||||||
|
this.elements.error.style.display = 'block';
|
||||||
|
this.hideLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示发布信息
|
||||||
|
* @param {Array} releases - 发布信息数组
|
||||||
|
* @param {string} source - 数据源
|
||||||
|
*/
|
||||||
|
displayReleases(releases, source) {
|
||||||
|
this.hideLoading();
|
||||||
|
|
||||||
|
// 清除现有内容
|
||||||
|
this.elements.changelog.innerHTML = '';
|
||||||
|
|
||||||
|
// 创建数据源元素
|
||||||
|
const sourceElement = this.createSourceElement(source);
|
||||||
|
this.elements.changelog.appendChild(sourceElement);
|
||||||
|
|
||||||
|
// 创建发布信息元素
|
||||||
|
releases.forEach(release => {
|
||||||
|
const releaseElement = this.createReleaseElement(release, source);
|
||||||
|
this.elements.changelog.appendChild(releaseElement);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.elements.changelog.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建数据源元素
|
||||||
|
* @param {string} source - 数据源
|
||||||
|
*/
|
||||||
|
createSourceElement(source) {
|
||||||
|
const sourceElement = document.createElement('div');
|
||||||
|
sourceElement.className = 'data-source';
|
||||||
|
|
||||||
|
// 创建带有国际化支持的源标签
|
||||||
|
const sourceLabel = document.createElement('span');
|
||||||
|
sourceLabel.setAttribute('data-en', this.i18nMessages.getMessage('dataSource', 'en'));
|
||||||
|
sourceLabel.setAttribute('data-zh', this.i18nMessages.getMessage('dataSource', 'zh'));
|
||||||
|
sourceLabel.textContent = this.i18nMessages.getMessage('dataSource', this.i18nMessages.getCurrentLang());
|
||||||
|
|
||||||
|
// 创建链接
|
||||||
|
const sourceLink = document.createElement('a');
|
||||||
|
const repositoryConfig = new RepositoryConfig();
|
||||||
|
sourceLink.href = repositoryConfig.getRepo(source).releasesUrl;
|
||||||
|
sourceLink.textContent = source === 'github' ? 'GitHub' : 'Gitea';
|
||||||
|
sourceLink.target = '_blank';
|
||||||
|
|
||||||
|
// 组装元素
|
||||||
|
sourceElement.appendChild(sourceLabel);
|
||||||
|
sourceElement.appendChild(sourceLink);
|
||||||
|
|
||||||
|
return sourceElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建发布信息元素
|
||||||
|
* @param {Object} release - 发布信息对象
|
||||||
|
* @param {string} source - 数据源
|
||||||
|
*/
|
||||||
|
createReleaseElement(release, source) {
|
||||||
|
const releaseElement = document.createElement('div');
|
||||||
|
releaseElement.className = 'release';
|
||||||
|
|
||||||
|
// 格式化发布日期
|
||||||
|
const releaseDate = new Date(release.published_at || release.created_at);
|
||||||
|
const formattedDate = DateFormatter.formatDate(releaseDate);
|
||||||
|
|
||||||
|
// 创建头部
|
||||||
|
const headerElement = this.createReleaseHeader(release, formattedDate);
|
||||||
|
releaseElement.appendChild(headerElement);
|
||||||
|
|
||||||
|
// 添加发布说明
|
||||||
|
if (release.body) {
|
||||||
|
const descriptionElement = document.createElement('div');
|
||||||
|
descriptionElement.className = 'release-description markdown-content';
|
||||||
|
descriptionElement.innerHTML = MarkdownParser.parseMarkdown(release.body);
|
||||||
|
releaseElement.appendChild(descriptionElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加下载资源
|
||||||
|
const assets = AssetManager.getAssetsFromRelease(release, source);
|
||||||
|
if (assets && assets.length > 0) {
|
||||||
|
const assetsElement = this.createAssetsElement(assets);
|
||||||
|
releaseElement.appendChild(assetsElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
return releaseElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建发布信息头部
|
||||||
|
*/
|
||||||
|
createReleaseHeader(release, formattedDate) {
|
||||||
|
const headerElement = document.createElement('div');
|
||||||
|
headerElement.className = 'release-header';
|
||||||
|
|
||||||
|
// 版本元素
|
||||||
|
const versionElement = document.createElement('div');
|
||||||
|
versionElement.className = 'release-version';
|
||||||
|
|
||||||
|
// 版本文本
|
||||||
|
const versionText = document.createElement('span');
|
||||||
|
versionText.textContent = release.name || release.tag_name;
|
||||||
|
versionElement.appendChild(versionText);
|
||||||
|
|
||||||
|
// 预发布标记
|
||||||
|
if (release.prerelease) {
|
||||||
|
const preReleaseTag = document.createElement('span');
|
||||||
|
preReleaseTag.className = 'release-badge pre-release';
|
||||||
|
preReleaseTag.setAttribute('data-en', this.i18nMessages.getMessage('preRelease', 'en'));
|
||||||
|
preReleaseTag.setAttribute('data-zh', this.i18nMessages.getMessage('preRelease', 'zh'));
|
||||||
|
preReleaseTag.textContent = this.i18nMessages.getMessage('preRelease', this.i18nMessages.getCurrentLang());
|
||||||
|
versionElement.appendChild(preReleaseTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日期元素
|
||||||
|
const dateElement = document.createElement('div');
|
||||||
|
dateElement.className = 'release-date';
|
||||||
|
dateElement.textContent = formattedDate;
|
||||||
|
|
||||||
|
headerElement.appendChild(versionElement);
|
||||||
|
headerElement.appendChild(dateElement);
|
||||||
|
|
||||||
|
return headerElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建资源文件元素
|
||||||
|
* @param {Array} assets - 资源文件数组
|
||||||
|
*/
|
||||||
|
createAssetsElement(assets) {
|
||||||
|
const assetsElement = document.createElement('div');
|
||||||
|
assetsElement.className = 'release-assets';
|
||||||
|
|
||||||
|
// 资源标题
|
||||||
|
const assetsTitle = document.createElement('div');
|
||||||
|
assetsTitle.className = 'release-assets-title';
|
||||||
|
assetsTitle.setAttribute('data-en', this.i18nMessages.getMessage('downloads', 'en'));
|
||||||
|
assetsTitle.setAttribute('data-zh', this.i18nMessages.getMessage('downloads', 'zh'));
|
||||||
|
assetsTitle.textContent = this.i18nMessages.getMessage('downloads', this.i18nMessages.getCurrentLang());
|
||||||
|
|
||||||
|
// 资源列表
|
||||||
|
const assetList = document.createElement('ul');
|
||||||
|
assetList.className = 'asset-list';
|
||||||
|
|
||||||
|
// 添加每个资源
|
||||||
|
assets.forEach(asset => {
|
||||||
|
const assetItem = this.createAssetItem(asset);
|
||||||
|
assetList.appendChild(assetItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
assetsElement.appendChild(assetsTitle);
|
||||||
|
assetsElement.appendChild(assetList);
|
||||||
|
|
||||||
|
return assetsElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建资源文件项
|
||||||
|
* @param {Object} asset - 资源文件对象
|
||||||
|
*/
|
||||||
|
createAssetItem(asset) {
|
||||||
|
const assetItem = document.createElement('li');
|
||||||
|
assetItem.className = 'asset-item';
|
||||||
|
|
||||||
|
// 文件图标
|
||||||
|
const iconElement = document.createElement('i');
|
||||||
|
iconElement.className = `asset-icon fas fa-${FileIconHelper.getFileIcon(asset.name)}`;
|
||||||
|
|
||||||
|
// 文件名
|
||||||
|
const nameElement = document.createElement('span');
|
||||||
|
nameElement.className = 'asset-name';
|
||||||
|
nameElement.textContent = asset.name;
|
||||||
|
|
||||||
|
// 文件大小
|
||||||
|
const sizeElement = document.createElement('span');
|
||||||
|
sizeElement.className = 'asset-size';
|
||||||
|
sizeElement.textContent = FileSizeFormatter.formatFileSize(asset.size);
|
||||||
|
|
||||||
|
// 下载链接
|
||||||
|
const downloadLink = document.createElement('a');
|
||||||
|
downloadLink.className = 'download-btn';
|
||||||
|
downloadLink.href = asset.browser_download_url;
|
||||||
|
downloadLink.target = '_blank';
|
||||||
|
downloadLink.setAttribute('data-en', this.i18nMessages.getMessage('download', 'en'));
|
||||||
|
downloadLink.setAttribute('data-zh', this.i18nMessages.getMessage('download', 'zh'));
|
||||||
|
downloadLink.textContent = this.i18nMessages.getMessage('download', this.i18nMessages.getCurrentLang());
|
||||||
|
|
||||||
|
// 组装资源项
|
||||||
|
assetItem.appendChild(iconElement);
|
||||||
|
assetItem.appendChild(nameElement);
|
||||||
|
assetItem.appendChild(sizeElement);
|
||||||
|
assetItem.appendChild(downloadLink);
|
||||||
|
|
||||||
|
return assetItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源管理器类
|
||||||
|
*/
|
||||||
|
class AssetManager {
|
||||||
|
/**
|
||||||
|
* 从发布信息中获取资源文件
|
||||||
|
* @param {Object} release - 发布信息对象
|
||||||
|
* @param {string} source - 数据源
|
||||||
|
*/
|
||||||
|
static getAssetsFromRelease(release, source) {
|
||||||
|
let assets = [];
|
||||||
|
|
||||||
|
if (source === 'github') {
|
||||||
|
assets = release.assets || [];
|
||||||
|
} else { // Gitea
|
||||||
|
assets = release.assets || [];
|
||||||
|
// 检查Gitea特定的资源结构
|
||||||
|
if (!assets.length && release.attachments) {
|
||||||
|
assets = release.attachments.map(attachment => ({
|
||||||
|
name: attachment.name,
|
||||||
|
size: attachment.size,
|
||||||
|
browser_download_url: attachment.browser_download_url
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return assets;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件图标助手类
|
||||||
|
*/
|
||||||
|
class FileIconHelper {
|
||||||
|
/**
|
||||||
|
* 根据文件扩展名获取图标
|
||||||
|
* @param {string} filename - 文件名
|
||||||
|
*/
|
||||||
|
static getFileIcon(filename) {
|
||||||
|
const extension = filename.split('.').pop().toLowerCase();
|
||||||
|
|
||||||
|
const iconMap = {
|
||||||
|
'exe': 'download',
|
||||||
|
'msi': 'download',
|
||||||
|
'dmg': 'download',
|
||||||
|
'pkg': 'download',
|
||||||
|
'deb': 'download',
|
||||||
|
'rpm': 'download',
|
||||||
|
'tar': 'file-archive',
|
||||||
|
'gz': 'file-archive',
|
||||||
|
'zip': 'file-archive',
|
||||||
|
'7z': 'file-archive',
|
||||||
|
'rar': 'file-archive',
|
||||||
|
'pdf': 'file-pdf',
|
||||||
|
'txt': 'file-alt',
|
||||||
|
'md': 'file-alt',
|
||||||
|
'json': 'file-code',
|
||||||
|
'xml': 'file-code',
|
||||||
|
'yml': 'file-code',
|
||||||
|
'yaml': 'file-code'
|
||||||
|
};
|
||||||
|
|
||||||
|
return iconMap[extension] || 'file';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件大小格式化器类
|
||||||
|
*/
|
||||||
|
class FileSizeFormatter {
|
||||||
|
/**
|
||||||
|
* 格式化文件大小
|
||||||
|
* @param {number} bytes - 字节数
|
||||||
|
*/
|
||||||
|
static formatFileSize(bytes) {
|
||||||
|
if (!bytes) return '';
|
||||||
|
|
||||||
|
const sizes = ['B', 'KB', 'MB', 'GB'];
|
||||||
|
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
||||||
|
|
||||||
|
return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期格式化器类
|
||||||
|
*/
|
||||||
|
class DateFormatter {
|
||||||
|
/**
|
||||||
|
* 格式化日期
|
||||||
|
* @param {Date} date - 日期对象
|
||||||
|
*/
|
||||||
|
static formatDate(date) {
|
||||||
|
const options = {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric'
|
||||||
|
};
|
||||||
|
|
||||||
|
const lang = window.currentLang || 'en';
|
||||||
|
const locale = lang === 'zh' ? 'zh-CN' : 'en-US';
|
||||||
|
|
||||||
|
return date.toLocaleDateString(locale, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Markdown解析器类
|
||||||
|
*/
|
||||||
|
class MarkdownParser {
|
||||||
|
/**
|
||||||
|
* 简单的Markdown解析
|
||||||
|
* @param {string} markdown - Markdown文本
|
||||||
|
*/
|
||||||
|
static parseMarkdown(markdown) {
|
||||||
|
if (!markdown) return '';
|
||||||
|
|
||||||
|
// 预处理:保留原始换行符,用特殊标记替换
|
||||||
|
const preservedLineBreaks = '___LINE_BREAK___';
|
||||||
|
markdown = markdown.replace(/\n/g, preservedLineBreaks);
|
||||||
|
|
||||||
|
// 引用块 - > text
|
||||||
|
markdown = markdown.replace(/>\s*(.*?)(?=>|$)/g, '<blockquote>$1</blockquote>');
|
||||||
|
markdown = markdown.replace(/>\s*(.*?)(?=>|$)/g, '<blockquote>$1</blockquote>');
|
||||||
|
|
||||||
|
// 链接 - [text](url)
|
||||||
|
markdown = markdown.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank">$1</a>');
|
||||||
|
|
||||||
|
// 标题 - # Heading
|
||||||
|
markdown = markdown.replace(/^### (.*?)(?=___LINE_BREAK___|$)/gm, '<h3>$1</h3>');
|
||||||
|
markdown = markdown.replace(/^## (.*?)(?=___LINE_BREAK___|$)/gm, '<h2>$1</h2>');
|
||||||
|
markdown = markdown.replace(/^# (.*?)(?=___LINE_BREAK___|$)/gm, '<h1>$1</h1>');
|
||||||
|
|
||||||
|
// 粗体 - **text**
|
||||||
|
markdown = markdown.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
|
||||||
|
|
||||||
|
// 斜体 - *text*
|
||||||
|
markdown = markdown.replace(/\*(.*?)\*/g, '<em>$1</em>');
|
||||||
|
|
||||||
|
// 代码块 - ```code```
|
||||||
|
markdown = markdown.replace(/```([\s\S]*?)```/g, '<pre><code>$1</code></pre>');
|
||||||
|
|
||||||
|
// 行内代码 - `code`
|
||||||
|
markdown = markdown.replace(/`([^`]+)`/g, '<code>$1</code>');
|
||||||
|
|
||||||
|
// 处理列表项
|
||||||
|
// 先将每个列表项转换为HTML
|
||||||
|
markdown = markdown.replace(/- (.*?)(?=___LINE_BREAK___- |___LINE_BREAK___$|$)/g, '<li>$1</li>');
|
||||||
|
markdown = markdown.replace(/\* (.*?)(?=___LINE_BREAK___\* |___LINE_BREAK___$|$)/g, '<li>$1</li>');
|
||||||
|
markdown = markdown.replace(/\d+\. (.*?)(?=___LINE_BREAK___\d+\. |___LINE_BREAK___$|$)/g, '<li>$1</li>');
|
||||||
|
|
||||||
|
// 然后将连续的列表项包装在ul或ol中
|
||||||
|
const listItemRegex = /<li>.*?<\/li>/g;
|
||||||
|
const listItems = markdown.match(listItemRegex) || [];
|
||||||
|
|
||||||
|
if (listItems.length > 0) {
|
||||||
|
// 将连续的列表项组合在一起
|
||||||
|
let lastIndex = 0;
|
||||||
|
let result = '';
|
||||||
|
let inList = false;
|
||||||
|
|
||||||
|
listItems.forEach(item => {
|
||||||
|
const itemIndex = markdown.indexOf(item, lastIndex);
|
||||||
|
|
||||||
|
// 添加列表项之前的内容
|
||||||
|
if (itemIndex > lastIndex) {
|
||||||
|
result += markdown.substring(lastIndex, itemIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果不在列表中,开始一个新列表
|
||||||
|
if (!inList) {
|
||||||
|
result += '<ul>';
|
||||||
|
inList = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加列表项
|
||||||
|
result += item;
|
||||||
|
|
||||||
|
// 更新lastIndex
|
||||||
|
lastIndex = itemIndex + item.length;
|
||||||
|
|
||||||
|
// 检查下一个内容是否是列表项
|
||||||
|
const nextItemIndex = markdown.indexOf('<li>', lastIndex);
|
||||||
|
if (nextItemIndex === -1 || nextItemIndex > lastIndex + 20) { // 如果下一个列表项不紧邻
|
||||||
|
result += '</ul>';
|
||||||
|
inList = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加剩余内容
|
||||||
|
if (lastIndex < markdown.length) {
|
||||||
|
result += markdown.substring(lastIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
markdown = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理水平分隔线
|
||||||
|
markdown = markdown.replace(/---/g, '<hr>');
|
||||||
|
|
||||||
|
// 恢复换行符
|
||||||
|
markdown = markdown.replace(/___LINE_BREAK___/g, '<br>');
|
||||||
|
|
||||||
|
// 处理段落
|
||||||
|
markdown = markdown.replace(/<br><br>/g, '</p><p>');
|
||||||
|
|
||||||
|
// 包装在段落标签中
|
||||||
|
if (!markdown.startsWith('<p>')) {
|
||||||
|
markdown = `<p>${markdown}</p>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return markdown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新日志主应用类
|
||||||
|
*/
|
||||||
|
class ChangelogApp {
|
||||||
|
constructor() {
|
||||||
|
this.repositoryConfig = new RepositoryConfig();
|
||||||
|
this.i18nMessages = new I18nMessages();
|
||||||
|
this.apiClient = new APIClient(this.repositoryConfig, this.i18nMessages);
|
||||||
|
this.uiManager = new UIManager(this.i18nMessages);
|
||||||
|
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化应用
|
||||||
|
*/
|
||||||
|
init() {
|
||||||
|
this.uiManager.showLoading();
|
||||||
|
|
||||||
|
// 首先尝试GitHub API
|
||||||
|
this.apiClient.fetchReleases('github')
|
||||||
|
.then(releases => {
|
||||||
|
this.uiManager.displayReleases(releases, 'github');
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
// GitHub失败时尝试Gitea
|
||||||
|
return this.apiClient.fetchReleases('gitea')
|
||||||
|
.then(releases => {
|
||||||
|
this.uiManager.displayReleases(releases, 'gitea');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('获取发布信息失败:', error);
|
||||||
|
this.uiManager.showError(this.i18nMessages.getMessage('fetchError', this.i18nMessages.getCurrentLang()));
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听语言变化事件
|
||||||
|
document.addEventListener('languageChanged', () => this.updateUI());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新UI元素(当语言变化时)
|
||||||
|
*/
|
||||||
|
updateUI() {
|
||||||
|
const elementsToUpdate = document.querySelectorAll('[data-en][data-zh]');
|
||||||
|
const currentLang = this.i18nMessages.getCurrentLang();
|
||||||
|
|
||||||
|
elementsToUpdate.forEach(element => {
|
||||||
|
const text = element.getAttribute(`data-${currentLang}`);
|
||||||
|
if (text) {
|
||||||
|
element.textContent = text;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当DOM加载完成时初始化应用
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
new ChangelogApp();
|
||||||
|
});
|
||||||
443
docs/js/script.js
Normal file
443
docs/js/script.js
Normal file
@@ -0,0 +1,443 @@
|
|||||||
|
/**
|
||||||
|
* voidraft - Website Script
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主题管理类
|
||||||
|
*/
|
||||||
|
class ThemeManager {
|
||||||
|
constructor() {
|
||||||
|
this.themeToggle = document.getElementById('theme-toggle');
|
||||||
|
this.currentTheme = this.getInitialTheme();
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取初始主题
|
||||||
|
*/
|
||||||
|
getInitialTheme() {
|
||||||
|
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
|
const savedTheme = localStorage.getItem('theme');
|
||||||
|
return savedTheme || (prefersDarkScheme.matches ? 'dark' : 'light');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化主题管理器
|
||||||
|
*/
|
||||||
|
init() {
|
||||||
|
if (!this.themeToggle) return;
|
||||||
|
|
||||||
|
this.setTheme(this.currentTheme);
|
||||||
|
this.bindEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定事件
|
||||||
|
*/
|
||||||
|
bindEvents() {
|
||||||
|
this.themeToggle.addEventListener('click', () => {
|
||||||
|
this.toggleTheme();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换主题
|
||||||
|
*/
|
||||||
|
toggleTheme() {
|
||||||
|
document.body.classList.add('theme-transition');
|
||||||
|
|
||||||
|
const newTheme = this.currentTheme === 'dark' ? 'light' : 'dark';
|
||||||
|
this.setTheme(newTheme);
|
||||||
|
this.saveTheme(newTheme);
|
||||||
|
|
||||||
|
setTimeout(() => document.body.classList.remove('theme-transition'), 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置主题
|
||||||
|
* @param {string} theme - 'dark' 或 'light'
|
||||||
|
*/
|
||||||
|
setTheme(theme) {
|
||||||
|
this.currentTheme = theme;
|
||||||
|
const isDark = theme === 'dark';
|
||||||
|
|
||||||
|
document.body.classList.toggle('theme-dark', isDark);
|
||||||
|
document.body.classList.toggle('theme-light', !isDark);
|
||||||
|
|
||||||
|
this.updateToggleIcon(isDark);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新切换按钮图标
|
||||||
|
* @param {boolean} isDark - 是否为暗色主题
|
||||||
|
*/
|
||||||
|
updateToggleIcon(isDark) {
|
||||||
|
if (this.themeToggle) {
|
||||||
|
const icon = this.themeToggle.querySelector('i');
|
||||||
|
if (icon) {
|
||||||
|
icon.className = isDark ? 'fas fa-sun' : 'fas fa-moon';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存主题到本地存储
|
||||||
|
* @param {string} theme - 主题名称
|
||||||
|
*/
|
||||||
|
saveTheme(theme) {
|
||||||
|
localStorage.setItem('theme', theme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 语言管理类
|
||||||
|
*/
|
||||||
|
class LanguageManager {
|
||||||
|
constructor() {
|
||||||
|
this.langToggle = document.getElementById('lang-toggle');
|
||||||
|
this.currentLang = this.getInitialLanguage();
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取初始语言
|
||||||
|
*/
|
||||||
|
getInitialLanguage() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const urlLang = urlParams.get('lang');
|
||||||
|
const savedLang = localStorage.getItem('lang');
|
||||||
|
const browserLang = navigator.language.startsWith('zh') ? 'zh' : 'en';
|
||||||
|
return urlLang || savedLang || browserLang;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化语言管理器
|
||||||
|
*/
|
||||||
|
init() {
|
||||||
|
if (!this.langToggle) return;
|
||||||
|
|
||||||
|
window.currentLang = this.currentLang;
|
||||||
|
this.setLanguage(this.currentLang);
|
||||||
|
this.bindEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定事件
|
||||||
|
*/
|
||||||
|
bindEvents() {
|
||||||
|
this.langToggle.addEventListener('click', () => {
|
||||||
|
this.toggleLanguage();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换语言
|
||||||
|
*/
|
||||||
|
toggleLanguage() {
|
||||||
|
document.body.classList.add('lang-transition');
|
||||||
|
|
||||||
|
const newLang = this.currentLang === 'zh' ? 'en' : 'zh';
|
||||||
|
this.setLanguage(newLang);
|
||||||
|
this.saveLanguage(newLang);
|
||||||
|
this.updateURL(newLang);
|
||||||
|
this.notifyLanguageChange(newLang);
|
||||||
|
|
||||||
|
setTimeout(() => document.body.classList.remove('lang-transition'), 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置页面语言
|
||||||
|
* @param {string} lang - 'zh' 或 'en'
|
||||||
|
*/
|
||||||
|
setLanguage(lang) {
|
||||||
|
this.currentLang = lang;
|
||||||
|
window.currentLang = lang;
|
||||||
|
|
||||||
|
this.updatePageElements(lang);
|
||||||
|
this.updateHTMLLang(lang);
|
||||||
|
this.updateToggleButton(lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新页面元素文本
|
||||||
|
* @param {string} lang - 语言代码
|
||||||
|
*/
|
||||||
|
updatePageElements(lang) {
|
||||||
|
document.querySelectorAll('[data-zh][data-en]').forEach(el => {
|
||||||
|
el.textContent = el.getAttribute(`data-${lang}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新HTML语言属性
|
||||||
|
* @param {string} lang - 语言代码
|
||||||
|
*/
|
||||||
|
updateHTMLLang(lang) {
|
||||||
|
document.documentElement.lang = lang === 'zh' ? 'zh-CN' : 'en';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新切换按钮文本
|
||||||
|
* @param {string} lang - 语言代码
|
||||||
|
*/
|
||||||
|
updateToggleButton(lang) {
|
||||||
|
if (this.langToggle) {
|
||||||
|
const text = lang === 'zh' ? 'EN/中' : '中/EN';
|
||||||
|
this.langToggle.innerHTML = `<i class="fas fa-language"></i> ${text}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存语言到本地存储
|
||||||
|
* @param {string} lang - 语言代码
|
||||||
|
*/
|
||||||
|
saveLanguage(lang) {
|
||||||
|
localStorage.setItem('lang', lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新URL参数
|
||||||
|
* @param {string} lang - 语言代码
|
||||||
|
*/
|
||||||
|
updateURL(lang) {
|
||||||
|
const newUrl = new URL(window.location);
|
||||||
|
if (lang === 'zh') {
|
||||||
|
newUrl.searchParams.set('lang', 'zh');
|
||||||
|
} else {
|
||||||
|
newUrl.searchParams.delete('lang');
|
||||||
|
}
|
||||||
|
window.history.replaceState({}, '', newUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通知语言变更
|
||||||
|
* @param {string} lang - 语言代码
|
||||||
|
*/
|
||||||
|
notifyLanguageChange(lang) {
|
||||||
|
window.dispatchEvent(new CustomEvent('languageChanged', { detail: { lang } }));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前语言
|
||||||
|
*/
|
||||||
|
getCurrentLanguage() {
|
||||||
|
return this.currentLang;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SEO管理类
|
||||||
|
*/
|
||||||
|
class SEOManager {
|
||||||
|
constructor(languageManager) {
|
||||||
|
this.languageManager = languageManager;
|
||||||
|
this.metaTexts = {
|
||||||
|
en: {
|
||||||
|
description: 'voidraft is an elegant text snippet recording tool designed for developers. Features multi-language code blocks, syntax highlighting, code formatting, custom themes, and more.',
|
||||||
|
title: 'voidraft - An elegant text snippet recording tool designed for developers.',
|
||||||
|
ogTitle: 'voidraft - An elegant text snippet recording tool designed for developers'
|
||||||
|
},
|
||||||
|
zh: {
|
||||||
|
description: 'voidraft 是专为开发者打造的优雅文本片段记录工具。支持多语言代码块、语法高亮、代码格式化、自定义主题等功能。',
|
||||||
|
title: 'voidraft - 专为开发者打造的优雅文本片段记录工具',
|
||||||
|
ogTitle: 'voidraft - 专为开发者打造的优雅文本片段记录工具'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化SEO管理器
|
||||||
|
*/
|
||||||
|
init() {
|
||||||
|
this.bindEvents();
|
||||||
|
this.updateMetaTags(this.languageManager.getCurrentLanguage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定事件
|
||||||
|
*/
|
||||||
|
bindEvents() {
|
||||||
|
window.addEventListener('languageChanged', (event) => {
|
||||||
|
this.updateMetaTags(event.detail.lang);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新SEO元标签
|
||||||
|
* @param {string} lang - 当前语言
|
||||||
|
*/
|
||||||
|
updateMetaTags(lang) {
|
||||||
|
const texts = this.metaTexts[lang];
|
||||||
|
|
||||||
|
this.updateMetaDescription(texts.description);
|
||||||
|
this.updateOpenGraphTags(texts.ogTitle, texts.description);
|
||||||
|
this.updateTwitterCardTags(texts.ogTitle, texts.description);
|
||||||
|
this.updatePageTitle(texts.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新meta描述
|
||||||
|
* @param {string} description - 描述文本
|
||||||
|
*/
|
||||||
|
updateMetaDescription(description) {
|
||||||
|
const metaDesc = document.querySelector('meta[name="description"]');
|
||||||
|
if (metaDesc) {
|
||||||
|
metaDesc.content = description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新Open Graph标签
|
||||||
|
* @param {string} title - 标题
|
||||||
|
* @param {string} description - 描述
|
||||||
|
*/
|
||||||
|
updateOpenGraphTags(title, description) {
|
||||||
|
const ogTitle = document.querySelector('meta[property="og:title"]');
|
||||||
|
const ogDesc = document.querySelector('meta[property="og:description"]');
|
||||||
|
|
||||||
|
if (ogTitle) ogTitle.content = title;
|
||||||
|
if (ogDesc) ogDesc.content = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新Twitter Card标签
|
||||||
|
* @param {string} title - 标题
|
||||||
|
* @param {string} description - 描述
|
||||||
|
*/
|
||||||
|
updateTwitterCardTags(title, description) {
|
||||||
|
const twitterTitle = document.querySelector('meta[property="twitter:title"]');
|
||||||
|
const twitterDesc = document.querySelector('meta[property="twitter:description"]');
|
||||||
|
|
||||||
|
if (twitterTitle) twitterTitle.content = title;
|
||||||
|
if (twitterDesc) twitterDesc.content = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新页面标题
|
||||||
|
* @param {string} title - 标题
|
||||||
|
*/
|
||||||
|
updatePageTitle(title) {
|
||||||
|
document.title = title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UI效果管理类
|
||||||
|
*/
|
||||||
|
class UIEffects {
|
||||||
|
constructor() {
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化UI效果
|
||||||
|
*/
|
||||||
|
init() {
|
||||||
|
this.initCardEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化卡片悬停效果
|
||||||
|
*/
|
||||||
|
initCardEffects() {
|
||||||
|
const cards = document.querySelectorAll('.feature-card');
|
||||||
|
|
||||||
|
cards.forEach(card => {
|
||||||
|
card.addEventListener('mouseenter', () => {
|
||||||
|
this.animateCardHover(card, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
card.addEventListener('mouseleave', () => {
|
||||||
|
this.animateCardHover(card, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 卡片悬停动画
|
||||||
|
* @param {Element} card - 卡片元素
|
||||||
|
* @param {boolean} isHover - 是否悬停
|
||||||
|
*/
|
||||||
|
animateCardHover(card, isHover) {
|
||||||
|
if (isHover) {
|
||||||
|
card.style.transform = 'translateY(-8px)';
|
||||||
|
card.style.boxShadow = '7px 7px 0 var(--shadow-color)';
|
||||||
|
} else {
|
||||||
|
card.style.transform = 'translateY(0)';
|
||||||
|
card.style.boxShadow = '5px 5px 0 var(--shadow-color)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* voidraft主应用类
|
||||||
|
*/
|
||||||
|
class voidraftApp {
|
||||||
|
constructor() {
|
||||||
|
this.themeManager = null;
|
||||||
|
this.languageManager = null;
|
||||||
|
this.seoManager = null;
|
||||||
|
this.uiEffects = null;
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化应用
|
||||||
|
*/
|
||||||
|
init() {
|
||||||
|
this.initializeManagers();
|
||||||
|
this.showConsoleBranding();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化各个管理器
|
||||||
|
*/
|
||||||
|
initializeManagers() {
|
||||||
|
this.themeManager = new ThemeManager();
|
||||||
|
this.languageManager = new LanguageManager();
|
||||||
|
this.seoManager = new SEOManager(this.languageManager);
|
||||||
|
this.uiEffects = new UIEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示控制台品牌信息
|
||||||
|
*/
|
||||||
|
showConsoleBranding() {
|
||||||
|
console.log('%c voidraft', 'color: #ff006e; font-size: 20px; font-family: "Space Mono", monospace;');
|
||||||
|
console.log('%c An elegant text snippet recording tool designed for developers.', 'color: #073B4C; font-family: "Space Mono", monospace;');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取主题管理器
|
||||||
|
*/
|
||||||
|
getThemeManager() {
|
||||||
|
return this.themeManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取语言管理器
|
||||||
|
*/
|
||||||
|
getLanguageManager() {
|
||||||
|
return this.languageManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取SEO管理器
|
||||||
|
*/
|
||||||
|
getSEOManager() {
|
||||||
|
return this.seoManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取UI效果管理器
|
||||||
|
*/
|
||||||
|
getUIEffects() {
|
||||||
|
return this.uiEffects;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当DOM加载完成时初始化应用
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
window.voidRaftApp = new voidraftApp();
|
||||||
|
});
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service represents the notifications service
|
||||||
|
* @module
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import * as application$0 from "../../application/models.js";
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import * as $models from "./models.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RemoveBadge removes the badge label from the application icon.
|
||||||
|
*/
|
||||||
|
export function RemoveBadge(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2374916939) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ServiceName returns the name of the service.
|
||||||
|
*/
|
||||||
|
export function ServiceName(): Promise<string> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2428202016) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ServiceShutdown is called when the service is unloaded.
|
||||||
|
*/
|
||||||
|
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3893755233) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ServiceStartup is called when the service is loaded.
|
||||||
|
*/
|
||||||
|
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(4078800764, options) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetBadge sets the badge label on the application icon.
|
||||||
|
*/
|
||||||
|
export function SetBadge(label: string): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(784276339, label) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SetCustomBadge(label: string, options: $models.Options): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3058653106, label, options) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
import * as Service from "./service.js";
|
import * as BadgeService from "./badgeservice.js";
|
||||||
export {
|
export {
|
||||||
Service
|
BadgeService
|
||||||
};
|
};
|
||||||
|
|
||||||
export * from "./models.js";
|
export * from "./models.js";
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import {Create as $Create} from "@wailsio/runtime";
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import * as color$0 from "../../../../../../../image/color/models.js";
|
||||||
|
|
||||||
|
export class Options {
|
||||||
|
"TextColour": color$0.RGBA;
|
||||||
|
"BackgroundColour": color$0.RGBA;
|
||||||
|
"FontName": string;
|
||||||
|
"FontSize": number;
|
||||||
|
"SmallFontSize": number;
|
||||||
|
|
||||||
|
/** Creates a new Options instance. */
|
||||||
|
constructor($$source: Partial<Options> = {}) {
|
||||||
|
if (!("TextColour" in $$source)) {
|
||||||
|
this["TextColour"] = (new color$0.RGBA());
|
||||||
|
}
|
||||||
|
if (!("BackgroundColour" in $$source)) {
|
||||||
|
this["BackgroundColour"] = (new color$0.RGBA());
|
||||||
|
}
|
||||||
|
if (!("FontName" in $$source)) {
|
||||||
|
this["FontName"] = "";
|
||||||
|
}
|
||||||
|
if (!("FontSize" in $$source)) {
|
||||||
|
this["FontSize"] = 0;
|
||||||
|
}
|
||||||
|
if (!("SmallFontSize" in $$source)) {
|
||||||
|
this["SmallFontSize"] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(this, $$source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Options instance from a string or object.
|
||||||
|
*/
|
||||||
|
static createFrom($$source: any = {}): Options {
|
||||||
|
const $$createField0_0 = $$createType0;
|
||||||
|
const $$createField1_0 = $$createType0;
|
||||||
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
|
if ("TextColour" in $$parsedSource) {
|
||||||
|
$$parsedSource["TextColour"] = $$createField0_0($$parsedSource["TextColour"]);
|
||||||
|
}
|
||||||
|
if ("BackgroundColour" in $$parsedSource) {
|
||||||
|
$$parsedSource["BackgroundColour"] = $$createField1_0($$parsedSource["BackgroundColour"]);
|
||||||
|
}
|
||||||
|
return new Options($$parsedSource as Partial<Options>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private type creation functions
|
||||||
|
const $$createType0 = color$0.RGBA.createFrom;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
import * as NotificationService from "./notificationservice.js";
|
||||||
|
export {
|
||||||
|
NotificationService
|
||||||
|
};
|
||||||
|
|
||||||
|
export * from "./models.js";
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import {Create as $Create} from "@wailsio/runtime";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NotificationAction represents an action button for a notification.
|
||||||
|
*/
|
||||||
|
export class NotificationAction {
|
||||||
|
"id"?: string;
|
||||||
|
"title"?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (macOS-specific)
|
||||||
|
*/
|
||||||
|
"destructive"?: boolean;
|
||||||
|
|
||||||
|
/** Creates a new NotificationAction instance. */
|
||||||
|
constructor($$source: Partial<NotificationAction> = {}) {
|
||||||
|
|
||||||
|
Object.assign(this, $$source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new NotificationAction instance from a string or object.
|
||||||
|
*/
|
||||||
|
static createFrom($$source: any = {}): NotificationAction {
|
||||||
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
|
return new NotificationAction($$parsedSource as Partial<NotificationAction>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NotificationCategory groups actions for notifications.
|
||||||
|
*/
|
||||||
|
export class NotificationCategory {
|
||||||
|
"id"?: string;
|
||||||
|
"actions"?: NotificationAction[];
|
||||||
|
"hasReplyField"?: boolean;
|
||||||
|
"replyPlaceholder"?: string;
|
||||||
|
"replyButtonTitle"?: string;
|
||||||
|
|
||||||
|
/** Creates a new NotificationCategory instance. */
|
||||||
|
constructor($$source: Partial<NotificationCategory> = {}) {
|
||||||
|
|
||||||
|
Object.assign(this, $$source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new NotificationCategory instance from a string or object.
|
||||||
|
*/
|
||||||
|
static createFrom($$source: any = {}): NotificationCategory {
|
||||||
|
const $$createField1_0 = $$createType1;
|
||||||
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
|
if ("actions" in $$parsedSource) {
|
||||||
|
$$parsedSource["actions"] = $$createField1_0($$parsedSource["actions"]);
|
||||||
|
}
|
||||||
|
return new NotificationCategory($$parsedSource as Partial<NotificationCategory>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NotificationOptions contains configuration for a notification
|
||||||
|
*/
|
||||||
|
export class NotificationOptions {
|
||||||
|
"id": string;
|
||||||
|
"title": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (macOS and Linux only)
|
||||||
|
*/
|
||||||
|
"subtitle"?: string;
|
||||||
|
"body"?: string;
|
||||||
|
"categoryId"?: string;
|
||||||
|
"data"?: { [_: string]: any };
|
||||||
|
|
||||||
|
/** Creates a new NotificationOptions instance. */
|
||||||
|
constructor($$source: Partial<NotificationOptions> = {}) {
|
||||||
|
if (!("id" in $$source)) {
|
||||||
|
this["id"] = "";
|
||||||
|
}
|
||||||
|
if (!("title" in $$source)) {
|
||||||
|
this["title"] = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(this, $$source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new NotificationOptions instance from a string or object.
|
||||||
|
*/
|
||||||
|
static createFrom($$source: any = {}): NotificationOptions {
|
||||||
|
const $$createField5_0 = $$createType2;
|
||||||
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
|
if ("data" in $$parsedSource) {
|
||||||
|
$$parsedSource["data"] = $$createField5_0($$parsedSource["data"]);
|
||||||
|
}
|
||||||
|
return new NotificationOptions($$parsedSource as Partial<NotificationOptions>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private type creation functions
|
||||||
|
const $$createType0 = NotificationAction.createFrom;
|
||||||
|
const $$createType1 = $Create.Array($$createType0);
|
||||||
|
const $$createType2 = $Create.Map($Create.Any, $Create.Any);
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service represents the notifications service
|
||||||
|
* @module
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import * as application$0 from "../../application/models.js";
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import * as $models from "./models.js";
|
||||||
|
|
||||||
|
export function CheckNotificationAuthorization(): Promise<boolean> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2216952893) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OnNotificationResponse registers a callback function that will be called when
|
||||||
|
* a notification response is received from the user.
|
||||||
|
*/
|
||||||
|
export function OnNotificationResponse(callback: any): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(1642697808, callback) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RegisterNotificationCategory(category: $models.NotificationCategory): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2917562919, category) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RemoveAllDeliveredNotifications(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3956282340) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RemoveAllPendingNotifications(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(108821341) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RemoveDeliveredNotification(identifier: string): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(975691940, identifier) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RemoveNotification(identifier: string): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3966653866, identifier) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RemoveNotificationCategory(categoryID: string): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2032615554, categoryID) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RemovePendingNotification(identifier: string): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3729049703, identifier) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public methods that delegate to the implementation.
|
||||||
|
*/
|
||||||
|
export function RequestNotificationAuthorization(): Promise<boolean> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3933442950) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SendNotification(options: $models.NotificationOptions): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3968228732, options) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SendNotificationWithActions(options: $models.NotificationOptions): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(1886542847, options) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ServiceName returns the name of the service.
|
||||||
|
*/
|
||||||
|
export function ServiceName(): Promise<string> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2704532675) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ServiceShutdown is called when the service is unloaded.
|
||||||
|
*/
|
||||||
|
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2550195434) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ServiceStartup is called when the service is loaded.
|
||||||
|
*/
|
||||||
|
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(4047820929, options) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
|
||||||
// This file is automatically generated. DO NOT EDIT
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore: Unused imports
|
|
||||||
import {Create as $Create} from "@wailsio/runtime";
|
|
||||||
|
|
||||||
export class Config {
|
|
||||||
/**
|
|
||||||
* DBSource is the database URI to use.
|
|
||||||
* The string ":memory:" can be used to create an in-memory database.
|
|
||||||
* The sqlite driver can be configured through query parameters.
|
|
||||||
* For more details see https://pkg.go.dev/modernc.org/sqlite#Driver.Open
|
|
||||||
*/
|
|
||||||
"DBSource": string;
|
|
||||||
|
|
||||||
/** Creates a new Config instance. */
|
|
||||||
constructor($$source: Partial<Config> = {}) {
|
|
||||||
if (!("DBSource" in $$source)) {
|
|
||||||
this["DBSource"] = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(this, $$source);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new Config instance from a string or object.
|
|
||||||
*/
|
|
||||||
static createFrom($$source: any = {}): Config {
|
|
||||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
|
||||||
return new Config($$parsedSource as Partial<Config>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Row holds a single row in the result of a query.
|
|
||||||
* It is a key-value map where keys are column names.
|
|
||||||
*/
|
|
||||||
export type Row = { [_: string]: any };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rows holds the result of a query
|
|
||||||
* as an array of key-value maps where keys are column names.
|
|
||||||
*/
|
|
||||||
export type Rows = Row[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stmt wraps a prepared sql statement pointer.
|
|
||||||
* It provides the same methods as the [sql.Stmt] type.
|
|
||||||
*/
|
|
||||||
export type Stmt = string;
|
|
||||||
@@ -1,223 +0,0 @@
|
|||||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
|
||||||
// This file is automatically generated. DO NOT EDIT
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore: Unused imports
|
|
||||||
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore: Unused imports
|
|
||||||
import * as application$0 from "../../application/models.js";
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore: Unused imports
|
|
||||||
import * as $models from "./models.js";
|
|
||||||
|
|
||||||
export {
|
|
||||||
ExecContext as Execute,
|
|
||||||
QueryContext as Query
|
|
||||||
};
|
|
||||||
|
|
||||||
import { Stmt } from "./stmt.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare creates a prepared statement for later queries or executions.
|
|
||||||
* Multiple queries or executions may be run concurrently from the returned statement.
|
|
||||||
*
|
|
||||||
* The caller must call the statement's Close method when it is no longer needed.
|
|
||||||
* Statements are closed automatically
|
|
||||||
* when the connection they are associated with is closed.
|
|
||||||
*
|
|
||||||
* Prepare supports early cancellation.
|
|
||||||
*/
|
|
||||||
export function Prepare(query: string): Promise<Stmt | null> & { cancel(): void } {
|
|
||||||
const promise = PrepareContext(query);
|
|
||||||
const wrapper: any = (promise.then(function (id) {
|
|
||||||
return id == null ? null : new Stmt(
|
|
||||||
ClosePrepared.bind(null, id),
|
|
||||||
ExecPrepared.bind(null, id),
|
|
||||||
QueryPrepared.bind(null, id));
|
|
||||||
}));
|
|
||||||
wrapper.cancel = promise.cancel;
|
|
||||||
return wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close closes the current database connection if one is open, otherwise has no effect.
|
|
||||||
* Additionally, Close closes all open prepared statements associated to the connection.
|
|
||||||
*
|
|
||||||
* Even when a non-nil error is returned,
|
|
||||||
* the database service is left in a consistent state,
|
|
||||||
* ready for a call to [Service.Open].
|
|
||||||
*/
|
|
||||||
export function Close(): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(1888105376) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ClosePrepared closes a prepared statement
|
|
||||||
* obtained with [Service.Prepare] or [Service.PrepareContext].
|
|
||||||
* ClosePrepared is idempotent:
|
|
||||||
* it has no effect on prepared statements that are already closed.
|
|
||||||
*/
|
|
||||||
function ClosePrepared(stmt: $models.Stmt | null): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(2526200629, stmt) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure changes the database service configuration.
|
|
||||||
* The connection state at call time is preserved.
|
|
||||||
* Consumers will need to call [Service.Open] manually after Configure
|
|
||||||
* in order to reconnect with the new configuration.
|
|
||||||
*
|
|
||||||
* See [NewWithConfig] for details on configuration.
|
|
||||||
*/
|
|
||||||
export function Configure(config: $models.Config | null): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(1939578712, config) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ExecContext executes a query without returning any rows.
|
|
||||||
* It supports early cancellation.
|
|
||||||
*/
|
|
||||||
function ExecContext(query: string, ...args: any[]): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(674944556, query, args) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ExecPrepared executes a prepared statement
|
|
||||||
* obtained with [Service.Prepare] or [Service.PrepareContext]
|
|
||||||
* without returning any rows.
|
|
||||||
* It supports early cancellation.
|
|
||||||
*/
|
|
||||||
function ExecPrepared(stmt: $models.Stmt | null, ...args: any[]): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(2086877656, stmt, args) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute executes a query without returning any rows.
|
|
||||||
*/
|
|
||||||
export function Execute(query: string, ...args: any[]): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(3811930203, query, args) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open validates the current configuration,
|
|
||||||
* closes the current connection if one is present,
|
|
||||||
* then opens and validates a new connection.
|
|
||||||
*
|
|
||||||
* Even when a non-nil error is returned,
|
|
||||||
* the database service is left in a consistent state,
|
|
||||||
* ready for a new call to Open.
|
|
||||||
*/
|
|
||||||
export function Open(): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(2012175612) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare creates a prepared statement for later queries or executions.
|
|
||||||
* Multiple queries or executions may be run concurrently from the returned statement.
|
|
||||||
*
|
|
||||||
* The caller should call the statement's Close method when it is no longer needed.
|
|
||||||
* Statements are closed automatically
|
|
||||||
* when the connection they are associated with is closed.
|
|
||||||
*/
|
|
||||||
export function Prepare(query: string): Promise<$models.Stmt | null> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(1801965143, query) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PrepareContext creates a prepared statement for later queries or executions.
|
|
||||||
* Multiple queries or executions may be run concurrently from the returned statement.
|
|
||||||
*
|
|
||||||
* The caller must call the statement's Close method when it is no longer needed.
|
|
||||||
* Statements are closed automatically
|
|
||||||
* when the connection they are associated with is closed.
|
|
||||||
*
|
|
||||||
* PrepareContext supports early cancellation.
|
|
||||||
*/
|
|
||||||
function PrepareContext(query: string): Promise<$models.Stmt | null> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(570941694, query) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query executes a query and returns a slice of key-value records,
|
|
||||||
* one per row, with column names as keys.
|
|
||||||
*/
|
|
||||||
export function Query(query: string, ...args: any[]): Promise<$models.Rows> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(860757720, query, args) as any;
|
|
||||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
|
||||||
return $$createType1($result);
|
|
||||||
}) as any;
|
|
||||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
|
||||||
return $typingPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* QueryContext executes a query and returns a slice of key-value records,
|
|
||||||
* one per row, with column names as keys.
|
|
||||||
* It supports early cancellation, returning the slice of results fetched so far.
|
|
||||||
*/
|
|
||||||
function QueryContext(query: string, ...args: any[]): Promise<$models.Rows> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(4115542347, query, args) as any;
|
|
||||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
|
||||||
return $$createType1($result);
|
|
||||||
}) as any;
|
|
||||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
|
||||||
return $typingPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* QueryPrepared executes a prepared statement
|
|
||||||
* obtained with [Service.Prepare] or [Service.PrepareContext]
|
|
||||||
* and returns a slice of key-value records, one per row, with column names as keys.
|
|
||||||
* It supports early cancellation, returning the slice of results fetched so far.
|
|
||||||
*/
|
|
||||||
function QueryPrepared(stmt: $models.Stmt | null, ...args: any[]): Promise<$models.Rows> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(3885083725, stmt, args) as any;
|
|
||||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
|
||||||
return $$createType1($result);
|
|
||||||
}) as any;
|
|
||||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
|
||||||
return $typingPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ServiceName returns the name of the plugin.
|
|
||||||
* You should use the go module format e.g. github.com/myuser/myplugin
|
|
||||||
*/
|
|
||||||
export function ServiceName(): Promise<string> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(1637123084) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ServiceShutdown closes the database connection.
|
|
||||||
* It returns a non-nil error in case of failures.
|
|
||||||
*/
|
|
||||||
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(3650435925) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ServiceStartup opens the database connection.
|
|
||||||
* It returns a non-nil error in case of failures.
|
|
||||||
*/
|
|
||||||
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(1113159936, options) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private type creation functions
|
|
||||||
const $$createType0 = $Create.Map($Create.Any, $Create.Any);
|
|
||||||
const $$createType1 = $Create.Array($$createType0);
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
//@ts-check
|
|
||||||
|
|
||||||
//@ts-ignore: Unused imports
|
|
||||||
import * as $models from "./models.js";
|
|
||||||
|
|
||||||
const execSymbol = Symbol("exec"),
|
|
||||||
querySymbol = Symbol("query"),
|
|
||||||
closeSymbol = Symbol("close");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stmt represents a prepared statement for later queries or executions.
|
|
||||||
* Multiple queries or executions may be run concurrently on the same statement.
|
|
||||||
*
|
|
||||||
* The caller must call the statement's Close method when it is no longer needed.
|
|
||||||
* Statements are closed automatically
|
|
||||||
* when the connection they are associated with is closed.
|
|
||||||
*/
|
|
||||||
export class Stmt {
|
|
||||||
/**
|
|
||||||
* Constructs a new prepared statement instance.
|
|
||||||
* @param {(...args: any[]) => Promise<void>} close
|
|
||||||
* @param {(...args: any[]) => Promise<void> & { cancel(): void }} exec
|
|
||||||
* @param {(...args: any[]) => Promise<$models.Rows> & { cancel(): void }} query
|
|
||||||
*/
|
|
||||||
constructor(close, exec, query) {
|
|
||||||
/**
|
|
||||||
* @member
|
|
||||||
* @private
|
|
||||||
* @type {typeof close}
|
|
||||||
*/
|
|
||||||
this[closeSymbol] = close;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @member
|
|
||||||
* @private
|
|
||||||
* @type {typeof exec}
|
|
||||||
*/
|
|
||||||
this[execSymbol] = exec;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @member
|
|
||||||
* @private
|
|
||||||
* @type {typeof query}
|
|
||||||
*/
|
|
||||||
this[querySymbol] = query;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes the prepared statement.
|
|
||||||
* It has no effect when the statement is already closed.
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
Close() {
|
|
||||||
return this[closeSymbol]();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes the prepared statement without returning any rows.
|
|
||||||
* It supports early cancellation.
|
|
||||||
*
|
|
||||||
* @param {any[]} args
|
|
||||||
* @returns {Promise<void> & { cancel(): void }}
|
|
||||||
*/
|
|
||||||
Exec(...args) {
|
|
||||||
return this[execSymbol](...args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes the prepared statement
|
|
||||||
* and returns a slice of key-value records, one per row, with column names as keys.
|
|
||||||
* It supports early cancellation, returning the array of results fetched so far.
|
|
||||||
*
|
|
||||||
* @param {any[]} args
|
|
||||||
* @returns {Promise<$models.Rows> & { cancel(): void }}
|
|
||||||
*/
|
|
||||||
Query(...args) {
|
|
||||||
return this[querySymbol](...args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
4
frontend/bindings/image/color/index.ts
Normal file
4
frontend/bindings/image/color/index.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
export * from "./models.js";
|
||||||
46
frontend/bindings/image/color/models.ts
Normal file
46
frontend/bindings/image/color/models.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import {Create as $Create} from "@wailsio/runtime";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RGBA represents a traditional 32-bit alpha-premultiplied color, having 8
|
||||||
|
* bits for each of red, green, blue and alpha.
|
||||||
|
*
|
||||||
|
* An alpha-premultiplied color component C has been scaled by alpha (A), so
|
||||||
|
* has valid values 0 <= C <= A.
|
||||||
|
*/
|
||||||
|
export class RGBA {
|
||||||
|
"R": number;
|
||||||
|
"G": number;
|
||||||
|
"B": number;
|
||||||
|
"A": number;
|
||||||
|
|
||||||
|
/** Creates a new RGBA instance. */
|
||||||
|
constructor($$source: Partial<RGBA> = {}) {
|
||||||
|
if (!("R" in $$source)) {
|
||||||
|
this["R"] = 0;
|
||||||
|
}
|
||||||
|
if (!("G" in $$source)) {
|
||||||
|
this["G"] = 0;
|
||||||
|
}
|
||||||
|
if (!("B" in $$source)) {
|
||||||
|
this["B"] = 0;
|
||||||
|
}
|
||||||
|
if (!("A" in $$source)) {
|
||||||
|
this["A"] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(this, $$source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new RGBA instance from a string or object.
|
||||||
|
*/
|
||||||
|
static createFrom($$source: any = {}): RGBA {
|
||||||
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
|
return new RGBA($$parsedSource as Partial<RGBA>);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,6 +33,11 @@ export class AppConfig {
|
|||||||
*/
|
*/
|
||||||
"updates": UpdatesConfig;
|
"updates": UpdatesConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Git备份设置
|
||||||
|
*/
|
||||||
|
"backup": GitBackupConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配置元数据
|
* 配置元数据
|
||||||
*/
|
*/
|
||||||
@@ -52,6 +57,9 @@ export class AppConfig {
|
|||||||
if (!("updates" in $$source)) {
|
if (!("updates" in $$source)) {
|
||||||
this["updates"] = (new UpdatesConfig());
|
this["updates"] = (new UpdatesConfig());
|
||||||
}
|
}
|
||||||
|
if (!("backup" in $$source)) {
|
||||||
|
this["backup"] = (new GitBackupConfig());
|
||||||
|
}
|
||||||
if (!("metadata" in $$source)) {
|
if (!("metadata" in $$source)) {
|
||||||
this["metadata"] = (new ConfigMetadata());
|
this["metadata"] = (new ConfigMetadata());
|
||||||
}
|
}
|
||||||
@@ -68,6 +76,7 @@ export class AppConfig {
|
|||||||
const $$createField2_0 = $$createType2;
|
const $$createField2_0 = $$createType2;
|
||||||
const $$createField3_0 = $$createType3;
|
const $$createField3_0 = $$createType3;
|
||||||
const $$createField4_0 = $$createType4;
|
const $$createField4_0 = $$createType4;
|
||||||
|
const $$createField5_0 = $$createType5;
|
||||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
if ("general" in $$parsedSource) {
|
if ("general" in $$parsedSource) {
|
||||||
$$parsedSource["general"] = $$createField0_0($$parsedSource["general"]);
|
$$parsedSource["general"] = $$createField0_0($$parsedSource["general"]);
|
||||||
@@ -81,8 +90,11 @@ export class AppConfig {
|
|||||||
if ("updates" in $$parsedSource) {
|
if ("updates" in $$parsedSource) {
|
||||||
$$parsedSource["updates"] = $$createField3_0($$parsedSource["updates"]);
|
$$parsedSource["updates"] = $$createField3_0($$parsedSource["updates"]);
|
||||||
}
|
}
|
||||||
|
if ("backup" in $$parsedSource) {
|
||||||
|
$$parsedSource["backup"] = $$createField4_0($$parsedSource["backup"]);
|
||||||
|
}
|
||||||
if ("metadata" in $$parsedSource) {
|
if ("metadata" in $$parsedSource) {
|
||||||
$$parsedSource["metadata"] = $$createField4_0($$parsedSource["metadata"]);
|
$$parsedSource["metadata"] = $$createField5_0($$parsedSource["metadata"]);
|
||||||
}
|
}
|
||||||
return new AppConfig($$parsedSource as Partial<AppConfig>);
|
return new AppConfig($$parsedSource as Partial<AppConfig>);
|
||||||
}
|
}
|
||||||
@@ -102,11 +114,6 @@ export class AppearanceConfig {
|
|||||||
*/
|
*/
|
||||||
"systemTheme": SystemThemeType;
|
"systemTheme": SystemThemeType;
|
||||||
|
|
||||||
/**
|
|
||||||
* 自定义主题配置
|
|
||||||
*/
|
|
||||||
"customTheme": CustomThemeConfig;
|
|
||||||
|
|
||||||
/** Creates a new AppearanceConfig instance. */
|
/** Creates a new AppearanceConfig instance. */
|
||||||
constructor($$source: Partial<AppearanceConfig> = {}) {
|
constructor($$source: Partial<AppearanceConfig> = {}) {
|
||||||
if (!("language" in $$source)) {
|
if (!("language" in $$source)) {
|
||||||
@@ -115,9 +122,6 @@ export class AppearanceConfig {
|
|||||||
if (!("systemTheme" in $$source)) {
|
if (!("systemTheme" in $$source)) {
|
||||||
this["systemTheme"] = ("" as SystemThemeType);
|
this["systemTheme"] = ("" as SystemThemeType);
|
||||||
}
|
}
|
||||||
if (!("customTheme" in $$source)) {
|
|
||||||
this["customTheme"] = (new CustomThemeConfig());
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(this, $$source);
|
Object.assign(this, $$source);
|
||||||
}
|
}
|
||||||
@@ -126,15 +130,30 @@ export class AppearanceConfig {
|
|||||||
* Creates a new AppearanceConfig instance from a string or object.
|
* Creates a new AppearanceConfig instance from a string or object.
|
||||||
*/
|
*/
|
||||||
static createFrom($$source: any = {}): AppearanceConfig {
|
static createFrom($$source: any = {}): AppearanceConfig {
|
||||||
const $$createField2_0 = $$createType5;
|
|
||||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
if ("customTheme" in $$parsedSource) {
|
|
||||||
$$parsedSource["customTheme"] = $$createField2_0($$parsedSource["customTheme"]);
|
|
||||||
}
|
|
||||||
return new AppearanceConfig($$parsedSource as Partial<AppearanceConfig>);
|
return new AppearanceConfig($$parsedSource as Partial<AppearanceConfig>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Git备份相关类型定义
|
||||||
|
*
|
||||||
|
* AuthMethod 定义Git认证方式
|
||||||
|
*/
|
||||||
|
export enum AuthMethod {
|
||||||
|
/**
|
||||||
|
* The Go zero value for the underlying type of the enum.
|
||||||
|
*/
|
||||||
|
$zero = "",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 认证方式
|
||||||
|
*/
|
||||||
|
Token = "token",
|
||||||
|
SSHKey = "ssh_key",
|
||||||
|
UserPass = "user_pass",
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ConfigMetadata 配置元数据
|
* ConfigMetadata 配置元数据
|
||||||
*/
|
*/
|
||||||
@@ -170,49 +189,6 @@ export class ConfigMetadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* CustomThemeConfig 自定义主题配置
|
|
||||||
*/
|
|
||||||
export class CustomThemeConfig {
|
|
||||||
/**
|
|
||||||
* 深色主题配置
|
|
||||||
*/
|
|
||||||
"darkTheme": ThemeColorConfig;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 浅色主题配置
|
|
||||||
*/
|
|
||||||
"lightTheme": ThemeColorConfig;
|
|
||||||
|
|
||||||
/** Creates a new CustomThemeConfig instance. */
|
|
||||||
constructor($$source: Partial<CustomThemeConfig> = {}) {
|
|
||||||
if (!("darkTheme" in $$source)) {
|
|
||||||
this["darkTheme"] = (new ThemeColorConfig());
|
|
||||||
}
|
|
||||||
if (!("lightTheme" in $$source)) {
|
|
||||||
this["lightTheme"] = (new ThemeColorConfig());
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(this, $$source);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new CustomThemeConfig instance from a string or object.
|
|
||||||
*/
|
|
||||||
static createFrom($$source: any = {}): CustomThemeConfig {
|
|
||||||
const $$createField0_0 = $$createType6;
|
|
||||||
const $$createField1_0 = $$createType6;
|
|
||||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
|
||||||
if ("darkTheme" in $$parsedSource) {
|
|
||||||
$$parsedSource["darkTheme"] = $$createField0_0($$parsedSource["darkTheme"]);
|
|
||||||
}
|
|
||||||
if ("lightTheme" in $$parsedSource) {
|
|
||||||
$$parsedSource["lightTheme"] = $$createField1_0($$parsedSource["lightTheme"]);
|
|
||||||
}
|
|
||||||
return new CustomThemeConfig($$parsedSource as Partial<CustomThemeConfig>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Document represents a document in the system
|
* Document represents a document in the system
|
||||||
*/
|
*/
|
||||||
@@ -224,6 +200,11 @@ export class Document {
|
|||||||
"updatedAt": time$0.Time;
|
"updatedAt": time$0.Time;
|
||||||
"is_deleted": boolean;
|
"is_deleted": boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 锁定标志,锁定的文档无法被删除
|
||||||
|
*/
|
||||||
|
"is_locked": boolean;
|
||||||
|
|
||||||
/** Creates a new Document instance. */
|
/** Creates a new Document instance. */
|
||||||
constructor($$source: Partial<Document> = {}) {
|
constructor($$source: Partial<Document> = {}) {
|
||||||
if (!("id" in $$source)) {
|
if (!("id" in $$source)) {
|
||||||
@@ -244,6 +225,9 @@ export class Document {
|
|||||||
if (!("is_deleted" in $$source)) {
|
if (!("is_deleted" in $$source)) {
|
||||||
this["is_deleted"] = false;
|
this["is_deleted"] = false;
|
||||||
}
|
}
|
||||||
|
if (!("is_locked" in $$source)) {
|
||||||
|
this["is_locked"] = false;
|
||||||
|
}
|
||||||
|
|
||||||
Object.assign(this, $$source);
|
Object.assign(this, $$source);
|
||||||
}
|
}
|
||||||
@@ -389,7 +373,7 @@ export class Extension {
|
|||||||
* Creates a new Extension instance from a string or object.
|
* Creates a new Extension instance from a string or object.
|
||||||
*/
|
*/
|
||||||
static createFrom($$source: any = {}): Extension {
|
static createFrom($$source: any = {}): Extension {
|
||||||
const $$createField3_0 = $$createType7;
|
const $$createField3_0 = $$createType6;
|
||||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
if ("config" in $$parsedSource) {
|
if ("config" in $$parsedSource) {
|
||||||
$$parsedSource["config"] = $$createField3_0($$parsedSource["config"]);
|
$$parsedSource["config"] = $$createField3_0($$parsedSource["config"]);
|
||||||
@@ -483,6 +467,12 @@ export class GeneralConfig {
|
|||||||
*/
|
*/
|
||||||
"startAtLogin": boolean;
|
"startAtLogin": boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 窗口吸附设置
|
||||||
|
* 是否启用窗口吸附功能(阈值现在是自适应的)
|
||||||
|
*/
|
||||||
|
"enableWindowSnap": boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局热键设置
|
* 全局热键设置
|
||||||
* 是否启用全局热键
|
* 是否启用全局热键
|
||||||
@@ -508,6 +498,9 @@ export class GeneralConfig {
|
|||||||
if (!("startAtLogin" in $$source)) {
|
if (!("startAtLogin" in $$source)) {
|
||||||
this["startAtLogin"] = false;
|
this["startAtLogin"] = false;
|
||||||
}
|
}
|
||||||
|
if (!("enableWindowSnap" in $$source)) {
|
||||||
|
this["enableWindowSnap"] = false;
|
||||||
|
}
|
||||||
if (!("enableGlobalHotkey" in $$source)) {
|
if (!("enableGlobalHotkey" in $$source)) {
|
||||||
this["enableGlobalHotkey"] = false;
|
this["enableGlobalHotkey"] = false;
|
||||||
}
|
}
|
||||||
@@ -522,15 +515,64 @@ export class GeneralConfig {
|
|||||||
* Creates a new GeneralConfig instance from a string or object.
|
* Creates a new GeneralConfig instance from a string or object.
|
||||||
*/
|
*/
|
||||||
static createFrom($$source: any = {}): GeneralConfig {
|
static createFrom($$source: any = {}): GeneralConfig {
|
||||||
const $$createField5_0 = $$createType9;
|
const $$createField6_0 = $$createType8;
|
||||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
if ("globalHotkey" in $$parsedSource) {
|
if ("globalHotkey" in $$parsedSource) {
|
||||||
$$parsedSource["globalHotkey"] = $$createField5_0($$parsedSource["globalHotkey"]);
|
$$parsedSource["globalHotkey"] = $$createField6_0($$parsedSource["globalHotkey"]);
|
||||||
}
|
}
|
||||||
return new GeneralConfig($$parsedSource as Partial<GeneralConfig>);
|
return new GeneralConfig($$parsedSource as Partial<GeneralConfig>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GitBackupConfig Git备份配置
|
||||||
|
*/
|
||||||
|
export class GitBackupConfig {
|
||||||
|
"enabled": boolean;
|
||||||
|
"repo_url": string;
|
||||||
|
"auth_method": AuthMethod;
|
||||||
|
"username"?: string;
|
||||||
|
"password"?: string;
|
||||||
|
"token"?: string;
|
||||||
|
"ssh_key_path"?: string;
|
||||||
|
"ssh_key_passphrase"?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分钟
|
||||||
|
*/
|
||||||
|
"backup_interval": number;
|
||||||
|
"auto_backup": boolean;
|
||||||
|
|
||||||
|
/** Creates a new GitBackupConfig instance. */
|
||||||
|
constructor($$source: Partial<GitBackupConfig> = {}) {
|
||||||
|
if (!("enabled" in $$source)) {
|
||||||
|
this["enabled"] = false;
|
||||||
|
}
|
||||||
|
if (!("repo_url" in $$source)) {
|
||||||
|
this["repo_url"] = "";
|
||||||
|
}
|
||||||
|
if (!("auth_method" in $$source)) {
|
||||||
|
this["auth_method"] = ("" as AuthMethod);
|
||||||
|
}
|
||||||
|
if (!("backup_interval" in $$source)) {
|
||||||
|
this["backup_interval"] = 0;
|
||||||
|
}
|
||||||
|
if (!("auto_backup" in $$source)) {
|
||||||
|
this["auto_backup"] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(this, $$source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new GitBackupConfig instance from a string or object.
|
||||||
|
*/
|
||||||
|
static createFrom($$source: any = {}): GitBackupConfig {
|
||||||
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
|
return new GitBackupConfig($$parsedSource as Partial<GitBackupConfig>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GiteaConfig Gitea配置
|
* GiteaConfig Gitea配置
|
||||||
*/
|
*/
|
||||||
@@ -1083,6 +1125,58 @@ export enum TabType {
|
|||||||
TabTypeTab = "tab",
|
TabTypeTab = "tab",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Theme 主题数据库模型
|
||||||
|
*/
|
||||||
|
export class Theme {
|
||||||
|
"id": number;
|
||||||
|
"name": string;
|
||||||
|
"type": ThemeType;
|
||||||
|
"colors": ThemeColorConfig;
|
||||||
|
"isDefault": boolean;
|
||||||
|
"createdAt": time$0.Time;
|
||||||
|
"updatedAt": time$0.Time;
|
||||||
|
|
||||||
|
/** Creates a new Theme instance. */
|
||||||
|
constructor($$source: Partial<Theme> = {}) {
|
||||||
|
if (!("id" in $$source)) {
|
||||||
|
this["id"] = 0;
|
||||||
|
}
|
||||||
|
if (!("name" in $$source)) {
|
||||||
|
this["name"] = "";
|
||||||
|
}
|
||||||
|
if (!("type" in $$source)) {
|
||||||
|
this["type"] = ("" as ThemeType);
|
||||||
|
}
|
||||||
|
if (!("colors" in $$source)) {
|
||||||
|
this["colors"] = (new ThemeColorConfig());
|
||||||
|
}
|
||||||
|
if (!("isDefault" in $$source)) {
|
||||||
|
this["isDefault"] = false;
|
||||||
|
}
|
||||||
|
if (!("createdAt" in $$source)) {
|
||||||
|
this["createdAt"] = null;
|
||||||
|
}
|
||||||
|
if (!("updatedAt" in $$source)) {
|
||||||
|
this["updatedAt"] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(this, $$source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Theme instance from a string or object.
|
||||||
|
*/
|
||||||
|
static createFrom($$source: any = {}): Theme {
|
||||||
|
const $$createField3_0 = $$createType9;
|
||||||
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
|
if ("colors" in $$parsedSource) {
|
||||||
|
$$parsedSource["colors"] = $$createField3_0($$parsedSource["colors"]);
|
||||||
|
}
|
||||||
|
return new Theme($$parsedSource as Partial<Theme>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ThemeColorConfig 主题颜色配置
|
* ThemeColorConfig 主题颜色配置
|
||||||
*/
|
*/
|
||||||
@@ -1291,6 +1385,19 @@ export class ThemeColorConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ThemeType 主题类型枚举
|
||||||
|
*/
|
||||||
|
export enum ThemeType {
|
||||||
|
/**
|
||||||
|
* The Go zero value for the underlying type of the enum.
|
||||||
|
*/
|
||||||
|
$zero = "",
|
||||||
|
|
||||||
|
ThemeTypeDark = "dark",
|
||||||
|
ThemeTypeLight = "light",
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateSourceType 更新源类型
|
* UpdateSourceType 更新源类型
|
||||||
*/
|
*/
|
||||||
@@ -1407,16 +1514,16 @@ const $$createType0 = GeneralConfig.createFrom;
|
|||||||
const $$createType1 = EditingConfig.createFrom;
|
const $$createType1 = EditingConfig.createFrom;
|
||||||
const $$createType2 = AppearanceConfig.createFrom;
|
const $$createType2 = AppearanceConfig.createFrom;
|
||||||
const $$createType3 = UpdatesConfig.createFrom;
|
const $$createType3 = UpdatesConfig.createFrom;
|
||||||
const $$createType4 = ConfigMetadata.createFrom;
|
const $$createType4 = GitBackupConfig.createFrom;
|
||||||
const $$createType5 = CustomThemeConfig.createFrom;
|
const $$createType5 = ConfigMetadata.createFrom;
|
||||||
const $$createType6 = ThemeColorConfig.createFrom;
|
var $$createType6 = (function $$initCreateType6(...args): any {
|
||||||
var $$createType7 = (function $$initCreateType7(...args): any {
|
if ($$createType6 === $$initCreateType6) {
|
||||||
if ($$createType7 === $$initCreateType7) {
|
$$createType6 = $$createType7;
|
||||||
$$createType7 = $$createType8;
|
|
||||||
}
|
}
|
||||||
return $$createType7(...args);
|
return $$createType6(...args);
|
||||||
});
|
});
|
||||||
const $$createType8 = $Create.Map($Create.Any, $Create.Any);
|
const $$createType7 = $Create.Map($Create.Any, $Create.Any);
|
||||||
const $$createType9 = HotkeyCombo.createFrom;
|
const $$createType8 = HotkeyCombo.createFrom;
|
||||||
|
const $$createType9 = ThemeColorConfig.createFrom;
|
||||||
const $$createType10 = GithubConfig.createFrom;
|
const $$createType10 = GithubConfig.createFrom;
|
||||||
const $$createType11 = GiteaConfig.createFrom;
|
const $$createType11 = GiteaConfig.createFrom;
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BackupService 提供基于Git的备份功能
|
||||||
|
* @module
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import * as models$0 from "../models/models.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HandleConfigChange 处理备份配置变更
|
||||||
|
*/
|
||||||
|
export function HandleConfigChange(config: models$0.GitBackupConfig | null): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(395287784, config) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize 初始化备份服务
|
||||||
|
*/
|
||||||
|
export function Initialize(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(1052437974) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PushToRemote 推送本地更改到远程仓库
|
||||||
|
*/
|
||||||
|
export function PushToRemote(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(262644139) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reinitialize 重新初始化备份服务,用于响应配置变更
|
||||||
|
*/
|
||||||
|
export function Reinitialize(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(301562543) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ServiceShutdown 服务关闭时的清理工作
|
||||||
|
*/
|
||||||
|
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(422131801) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StartAutoBackup 启动自动备份定时器
|
||||||
|
*/
|
||||||
|
export function StartAutoBackup(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3035755449) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StopAutoBackup 停止自动备份
|
||||||
|
*/
|
||||||
|
export function StopAutoBackup(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2641894021) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
@@ -34,6 +34,30 @@ export function GetConfig(): Promise<models$0.AppConfig | null> & { cancel(): vo
|
|||||||
return $typingPromise;
|
return $typingPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetConfigDir 获取配置目录
|
||||||
|
*/
|
||||||
|
export function GetConfigDir(): Promise<string> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2275626561) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetSettingsPath 获取设置文件路径
|
||||||
|
*/
|
||||||
|
export function GetSettingsPath(): Promise<string> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2175583370) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MigrateConfig 执行配置迁移
|
||||||
|
*/
|
||||||
|
export function MigrateConfig(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(434292783) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ResetConfig 强制重置所有配置为默认值
|
* ResetConfig 强制重置所有配置为默认值
|
||||||
*/
|
*/
|
||||||
@@ -58,6 +82,14 @@ export function Set(key: string, value: any): Promise<void> & { cancel(): void }
|
|||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetBackupConfigChangeCallback 设置备份配置变更回调
|
||||||
|
*/
|
||||||
|
export function SetBackupConfigChangeCallback(callback: any): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3264871659, callback) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SetDataPathChangeCallback 设置数据路径配置变更回调
|
* SetDataPathChangeCallback 设置数据路径配置变更回调
|
||||||
*/
|
*/
|
||||||
@@ -74,6 +106,14 @@ export function SetHotkeyChangeCallback(callback: any): Promise<void> & { cancel
|
|||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetWindowSnapConfigChangeCallback 设置窗口吸附配置变更回调
|
||||||
|
*/
|
||||||
|
export function SetWindowSnapConfigChangeCallback(callback: any): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2324961653, callback) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
// Private type creation functions
|
// Private type creation functions
|
||||||
const $$createType0 = models$0.AppConfig.createFrom;
|
const $$createType0 = models$0.AppConfig.createFrom;
|
||||||
const $$createType1 = $Create.Nullable($$createType0);
|
const $$createType1 = $Create.Nullable($$createType0);
|
||||||
|
|||||||
@@ -22,6 +22,14 @@ export function OnDataPathChanged(): Promise<void> & { cancel(): void } {
|
|||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RegisterModel 注册模型与表的映射关系
|
||||||
|
*/
|
||||||
|
export function RegisterModel(tableName: string, model: any): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(175397515, tableName, model) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServiceShutdown shuts down the service when the application closes
|
* ServiceShutdown shuts down the service when the application closes
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -22,6 +22,14 @@ export function SelectDirectory(): Promise<string> & { cancel(): void } {
|
|||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SelectFile 打开文件选择对话框
|
||||||
|
*/
|
||||||
|
export function SelectFile(): Promise<string> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(37302920) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SetWindow 设置绑定的窗口
|
* SetWindow 设置绑定的窗口
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -81,6 +81,14 @@ export function ListDeletedDocumentsMeta(): Promise<(models$0.Document | null)[]
|
|||||||
return $typingPromise;
|
return $typingPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LockDocument 锁定文档,防止删除
|
||||||
|
*/
|
||||||
|
export function LockDocument(id: number): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(1889494473, id) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RestoreDocument restores a deleted document
|
* RestoreDocument restores a deleted document
|
||||||
*/
|
*/
|
||||||
@@ -97,6 +105,14 @@ export function ServiceStartup(options: application$0.ServiceOptions): Promise<v
|
|||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UnlockDocument 解锁文档
|
||||||
|
*/
|
||||||
|
export function UnlockDocument(id: number): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(222307930, id) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateDocumentContent updates the content of a document
|
* UpdateDocumentContent updates the content of a document
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ export function GetCurrentHotkey(): Promise<models$0.HotkeyCombo | null> & { can
|
|||||||
/**
|
/**
|
||||||
* Initialize 初始化热键服务
|
* Initialize 初始化热键服务
|
||||||
*/
|
*/
|
||||||
export function Initialize(app: application$0.App | null): Promise<void> & { cancel(): void } {
|
export function Initialize(app: application$0.App | null, mainWindow: application$0.WebviewWindow | null): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(3671360458, app) as any;
|
let $resultPromise = $Call.ByID(3671360458, app, mainWindow) as any;
|
||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
import * as BackupService from "./backupservice.js";
|
||||||
import * as ConfigService from "./configservice.js";
|
import * as ConfigService from "./configservice.js";
|
||||||
import * as DatabaseService from "./databaseservice.js";
|
import * as DatabaseService from "./databaseservice.js";
|
||||||
import * as DialogService from "./dialogservice.js";
|
import * as DialogService from "./dialogservice.js";
|
||||||
@@ -12,10 +13,13 @@ import * as MigrationService from "./migrationservice.js";
|
|||||||
import * as SelfUpdateService from "./selfupdateservice.js";
|
import * as SelfUpdateService from "./selfupdateservice.js";
|
||||||
import * as StartupService from "./startupservice.js";
|
import * as StartupService from "./startupservice.js";
|
||||||
import * as SystemService from "./systemservice.js";
|
import * as SystemService from "./systemservice.js";
|
||||||
|
import * as TestService from "./testservice.js";
|
||||||
|
import * as ThemeService from "./themeservice.js";
|
||||||
import * as TranslationService from "./translationservice.js";
|
import * as TranslationService from "./translationservice.js";
|
||||||
import * as TrayService from "./trayservice.js";
|
import * as TrayService from "./trayservice.js";
|
||||||
import * as WindowService from "./windowservice.js";
|
import * as WindowService from "./windowservice.js";
|
||||||
export {
|
export {
|
||||||
|
BackupService,
|
||||||
ConfigService,
|
ConfigService,
|
||||||
DatabaseService,
|
DatabaseService,
|
||||||
DialogService,
|
DialogService,
|
||||||
@@ -27,6 +31,8 @@ export {
|
|||||||
SelfUpdateService,
|
SelfUpdateService,
|
||||||
StartupService,
|
StartupService,
|
||||||
SystemService,
|
SystemService,
|
||||||
|
TestService,
|
||||||
|
ThemeService,
|
||||||
TranslationService,
|
TranslationService,
|
||||||
TrayService,
|
TrayService,
|
||||||
WindowService
|
WindowService
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ export class SelfUpdateResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WindowInfo 窗口信息
|
* WindowInfo 窗口信息(简化版)
|
||||||
*/
|
*/
|
||||||
export class WindowInfo {
|
export class WindowInfo {
|
||||||
"Window": application$0.WebviewWindow | null;
|
"Window": application$0.WebviewWindow | null;
|
||||||
@@ -238,6 +238,26 @@ export class WindowInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WindowSnapService 窗口吸附服务
|
||||||
|
*/
|
||||||
|
export class WindowSnapService {
|
||||||
|
|
||||||
|
/** Creates a new WindowSnapService instance. */
|
||||||
|
constructor($$source: Partial<WindowSnapService> = {}) {
|
||||||
|
|
||||||
|
Object.assign(this, $$source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new WindowSnapService instance from a string or object.
|
||||||
|
*/
|
||||||
|
static createFrom($$source: any = {}): WindowSnapService {
|
||||||
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
|
return new WindowSnapService($$parsedSource as Partial<WindowSnapService>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Private type creation functions
|
// Private type creation functions
|
||||||
const $$createType0 = application$0.WebviewWindow.createFrom;
|
const $$createType0 = application$0.WebviewWindow.createFrom;
|
||||||
const $$createType1 = $Create.Nullable($$createType0);
|
const $$createType1 = $Create.Nullable($$createType0);
|
||||||
|
|||||||
55
frontend/bindings/voidraft/internal/services/testservice.ts
Normal file
55
frontend/bindings/voidraft/internal/services/testservice.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TestService 测试服务 - 仅在开发环境使用
|
||||||
|
* @module
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClearAll 清除所有测试状态
|
||||||
|
*/
|
||||||
|
export function ClearAll(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2179720854) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ServiceStartup 服务启动时调用
|
||||||
|
*/
|
||||||
|
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(617408198, options) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TestBadge 测试Badge功能
|
||||||
|
*/
|
||||||
|
export function TestBadge(text: string): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(4242952145, text) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TestNotification 测试通知功能
|
||||||
|
*/
|
||||||
|
export function TestNotification(title: string, subtitle: string, body: string): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(1697553289, title, subtitle, body) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TestUpdateNotification 测试更新通知
|
||||||
|
*/
|
||||||
|
export function TestUpdateNotification(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3091730060) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
104
frontend/bindings/voidraft/internal/services/themeservice.ts
Normal file
104
frontend/bindings/voidraft/internal/services/themeservice.ts
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ThemeService 主题服务
|
||||||
|
* @module
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import * as models$0 from "../models/models.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreateTheme 创建新主题
|
||||||
|
*/
|
||||||
|
export function CreateTheme(theme: models$0.Theme | null): Promise<models$0.Theme | null> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3274757686, theme) as any;
|
||||||
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
|
return $$createType1($result);
|
||||||
|
}) as any;
|
||||||
|
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||||
|
return $typingPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetAllThemes 获取所有主题
|
||||||
|
*/
|
||||||
|
export function GetAllThemes(): Promise<(models$0.Theme | null)[]> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2425053076) as any;
|
||||||
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
|
return $$createType2($result);
|
||||||
|
}) as any;
|
||||||
|
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||||
|
return $typingPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetDefaultThemes 获取默认主题
|
||||||
|
*/
|
||||||
|
export function GetDefaultThemes(): Promise<{ [_: string]: models$0.Theme | null }> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3801788118) as any;
|
||||||
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
|
return $$createType3($result);
|
||||||
|
}) as any;
|
||||||
|
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||||
|
return $typingPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetThemeByType 根据类型获取默认主题
|
||||||
|
*/
|
||||||
|
export function GetThemeByType(themeType: models$0.ThemeType): Promise<models$0.Theme | null> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(1680465265, themeType) as any;
|
||||||
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
|
return $$createType1($result);
|
||||||
|
}) as any;
|
||||||
|
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||||
|
return $typingPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ResetThemeColors 重置主题颜色为默认值
|
||||||
|
*/
|
||||||
|
export function ResetThemeColors(themeType: models$0.ThemeType): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(342461245, themeType) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ServiceShutdown 服务关闭
|
||||||
|
*/
|
||||||
|
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(1676749034) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ServiceStartup 服务启动时初始化
|
||||||
|
*/
|
||||||
|
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2915959937, options) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateThemeColors 更新主题颜色
|
||||||
|
*/
|
||||||
|
export function UpdateThemeColors(themeType: models$0.ThemeType, colors: models$0.ThemeColorConfig): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(2750902529, themeType, colors) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private type creation functions
|
||||||
|
const $$createType0 = models$0.Theme.createFrom;
|
||||||
|
const $$createType1 = $Create.Nullable($$createType0);
|
||||||
|
const $$createType2 = $Create.Array($$createType1);
|
||||||
|
const $$createType3 = $Create.Map($Create.Any, $$createType1);
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WindowService 窗口管理服务
|
* WindowService 窗口管理服务(专注于窗口生命周期管理)
|
||||||
* @module
|
* @module
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -46,6 +46,14 @@ export function OpenDocumentWindow(documentID: number): Promise<void> & { cancel
|
|||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ServiceShutdown 实现服务关闭接口
|
||||||
|
*/
|
||||||
|
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(202192783) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SetAppReferences 设置应用和主窗口引用
|
* SetAppReferences 设置应用和主窗口引用
|
||||||
*/
|
*/
|
||||||
@@ -54,6 +62,14 @@ export function SetAppReferences(app: application$0.App | null, mainWindow: appl
|
|||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetWindowSnapService 设置窗口吸附服务引用
|
||||||
|
*/
|
||||||
|
export function SetWindowSnapService(snapService: $models.WindowSnapService | null): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(1105193745, snapService) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
// Private type creation functions
|
// Private type creation functions
|
||||||
const $$createType0 = $models.WindowInfo.createFrom;
|
const $$createType0 = $models.WindowInfo.createFrom;
|
||||||
const $$createType1 = $Create.Array($$createType0);
|
const $$createType1 = $Create.Array($$createType0);
|
||||||
|
|||||||
3220
frontend/package-lock.json
generated
3220
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -5,78 +5,90 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --host --mode development",
|
"dev": "vite --host --mode development",
|
||||||
"build:dev": "vue-tsc && vite build --minify false --mode development",
|
"build:dev": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" vue-tsc && cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" vite build --minify false --mode development",
|
||||||
"build": "vue-tsc && vite build --mode production",
|
"build": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" vue-tsc && cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" vite build --mode production",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"lint": "eslint",
|
"lint": "eslint",
|
||||||
"lint:fix": "eslint --fix"
|
"lint:fix": "eslint --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/autocomplete": "^6.18.6",
|
"@codemirror/autocomplete": "^6.18.7",
|
||||||
"@codemirror/commands": "^6.8.1",
|
"@codemirror/commands": "^6.8.1",
|
||||||
"@codemirror/lang-angular": "^0.1.4",
|
"@codemirror/lang-angular": "^0.1.4",
|
||||||
"@codemirror/lang-cpp": "^6.0.3",
|
"@codemirror/lang-cpp": "^6.0.3",
|
||||||
"@codemirror/lang-css": "^6.3.1",
|
"@codemirror/lang-css": "^6.3.1",
|
||||||
"@codemirror/lang-go": "^6.0.1",
|
"@codemirror/lang-go": "^6.0.1",
|
||||||
"@codemirror/lang-html": "^6.4.9",
|
"@codemirror/lang-html": "^6.4.10",
|
||||||
"@codemirror/lang-java": "^6.0.2",
|
"@codemirror/lang-java": "^6.0.2",
|
||||||
"@codemirror/lang-javascript": "^6.2.4",
|
"@codemirror/lang-javascript": "^6.2.4",
|
||||||
"@codemirror/lang-json": "^6.0.2",
|
"@codemirror/lang-json": "^6.0.2",
|
||||||
"@codemirror/lang-less": "^6.0.2",
|
"@codemirror/lang-less": "^6.0.2",
|
||||||
"@codemirror/lang-lezer": "^6.0.2",
|
"@codemirror/lang-lezer": "^6.0.2",
|
||||||
"@codemirror/lang-liquid": "^6.2.3",
|
"@codemirror/lang-liquid": "^6.3.0",
|
||||||
"@codemirror/lang-markdown": "^6.3.3",
|
"@codemirror/lang-markdown": "^6.3.4",
|
||||||
"@codemirror/lang-php": "^6.0.2",
|
"@codemirror/lang-php": "^6.0.2",
|
||||||
"@codemirror/lang-python": "^6.2.1",
|
"@codemirror/lang-python": "^6.2.1",
|
||||||
"@codemirror/lang-rust": "^6.0.2",
|
"@codemirror/lang-rust": "^6.0.2",
|
||||||
"@codemirror/lang-sass": "^6.0.2",
|
"@codemirror/lang-sass": "^6.0.2",
|
||||||
"@codemirror/lang-sql": "^6.9.0",
|
"@codemirror/lang-sql": "^6.9.1",
|
||||||
"@codemirror/lang-vue": "^0.1.3",
|
"@codemirror/lang-vue": "^0.1.3",
|
||||||
"@codemirror/lang-wast": "^6.0.2",
|
"@codemirror/lang-wast": "^6.0.2",
|
||||||
"@codemirror/lang-xml": "^6.1.0",
|
|
||||||
"@codemirror/lang-yaml": "^6.1.2",
|
"@codemirror/lang-yaml": "^6.1.2",
|
||||||
"@codemirror/language": "^6.11.2",
|
"@codemirror/language": "^6.11.3",
|
||||||
"@codemirror/language-data": "^6.5.1",
|
"@codemirror/language-data": "^6.5.1",
|
||||||
"@codemirror/legacy-modes": "^6.5.1",
|
"@codemirror/legacy-modes": "^6.5.1",
|
||||||
"@codemirror/lint": "^6.8.5",
|
"@codemirror/lint": "^6.8.5",
|
||||||
"@codemirror/search": "^6.5.11",
|
"@codemirror/search": "^6.5.11",
|
||||||
"@codemirror/state": "^6.5.2",
|
"@codemirror/state": "^6.5.2",
|
||||||
"@codemirror/view": "^6.38.0",
|
"@codemirror/view": "^6.38.2",
|
||||||
"@lezer/highlight": "^1.2.1",
|
"@lezer/highlight": "^1.2.1",
|
||||||
"@lezer/lr": "^1.4.2",
|
"@lezer/lr": "^1.4.2",
|
||||||
|
"@prettier/plugin-xml": "^3.4.2",
|
||||||
|
"@reteps/dockerfmt": "^0.3.6",
|
||||||
"codemirror": "^6.0.2",
|
"codemirror": "^6.0.2",
|
||||||
"codemirror-lang-elixir": "^4.0.0",
|
"codemirror-lang-elixir": "^4.0.0",
|
||||||
"colors-named": "^1.0.2",
|
"colors-named": "^1.0.2",
|
||||||
"colors-named-hex": "^1.0.2",
|
"colors-named-hex": "^1.0.2",
|
||||||
"franc-min": "^6.2.0",
|
"franc-min": "^6.2.0",
|
||||||
"hsl-matcher": "^1.2.4",
|
"hsl-matcher": "^1.2.4",
|
||||||
|
"java-parser": "^3.0.1",
|
||||||
|
"jinx-rust": "^0.1.6",
|
||||||
|
"jsox": "^1.2.123",
|
||||||
"lezer": "^0.13.5",
|
"lezer": "^0.13.5",
|
||||||
|
"linguist-languages": "^9.0.0",
|
||||||
|
"node-sql-parser": "^5.3.12",
|
||||||
|
"php-parser": "^3.2.5",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"pinia-plugin-persistedstate": "^4.4.1",
|
"pinia-plugin-persistedstate": "^4.5.0",
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
|
"prettier-plugin-toml": "^2.0.6",
|
||||||
"remarkable": "^2.0.1",
|
"remarkable": "^2.0.1",
|
||||||
"sass": "^1.89.2",
|
"sass": "^1.92.1",
|
||||||
"vue": "^3.5.17",
|
"sh-syntax": "^0.5.8",
|
||||||
"vue-i18n": "^11.1.9",
|
"sql-formatter": "^15.6.9",
|
||||||
|
"vue": "^3.5.21",
|
||||||
|
"vue-i18n": "^11.1.12",
|
||||||
"vue-pick-colors": "^1.8.0",
|
"vue-pick-colors": "^1.8.0",
|
||||||
"vue-router": "^4.5.1"
|
"vue-router": "^4.5.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.30.1",
|
"@eslint/js": "^9.35.0",
|
||||||
"@lezer/generator": "^1.8.0",
|
"@lezer/generator": "^1.8.0",
|
||||||
"@types/lodash": "^4.17.20",
|
"@types/node": "^24.3.1",
|
||||||
"@types/node": "^24.0.12",
|
|
||||||
"@types/remarkable": "^2.0.8",
|
"@types/remarkable": "^2.0.8",
|
||||||
"@vitejs/plugin-vue": "^6.0.0",
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
"@wailsio/runtime": "latest",
|
"@wailsio/runtime": "latest",
|
||||||
"eslint": "^9.30.1",
|
"cross-env": "^7.0.3",
|
||||||
"eslint-plugin-vue": "^10.3.0",
|
"eslint": "^9.35.0",
|
||||||
"globals": "^16.3.0",
|
"eslint-plugin-vue": "^10.4.0",
|
||||||
"typescript": "^5.8.3",
|
"globals": "^16.4.0",
|
||||||
"typescript-eslint": "^8.36.0",
|
"rollup-plugin-visualizer": "^6.0.3",
|
||||||
"unplugin-vue-components": "^28.8.0",
|
"typescript": "^5.9.2",
|
||||||
"vite": "^7.0.3",
|
"typescript-eslint": "^8.43.0",
|
||||||
|
"unplugin-vue-components": "^29.0.0",
|
||||||
|
"vite": "^7.1.5",
|
||||||
|
"vite-plugin-node-polyfills": "^0.24.0",
|
||||||
"vue-eslint-parser": "^10.2.0",
|
"vue-eslint-parser": "^10.2.0",
|
||||||
"vue-tsc": "^3.0.1"
|
"vue-tsc": "^3.0.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
frontend/public/go.wasm
Normal file
BIN
frontend/public/go.wasm
Normal file
Binary file not shown.
561
frontend/public/wasm_exec.js
Normal file
561
frontend/public/wasm_exec.js
Normal file
@@ -0,0 +1,561 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(() => {
|
||||||
|
const enosys = () => {
|
||||||
|
const err = new Error("not implemented");
|
||||||
|
err.code = "ENOSYS";
|
||||||
|
return err;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!globalThis.fs) {
|
||||||
|
let outputBuf = "";
|
||||||
|
globalThis.fs = {
|
||||||
|
constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1 }, // unused
|
||||||
|
writeSync(fd, buf) {
|
||||||
|
outputBuf += decoder.decode(buf);
|
||||||
|
const nl = outputBuf.lastIndexOf("\n");
|
||||||
|
if (nl != -1) {
|
||||||
|
console.log(outputBuf.substring(0, nl));
|
||||||
|
outputBuf = outputBuf.substring(nl + 1);
|
||||||
|
}
|
||||||
|
return buf.length;
|
||||||
|
},
|
||||||
|
write(fd, buf, offset, length, position, callback) {
|
||||||
|
if (offset !== 0 || length !== buf.length || position !== null) {
|
||||||
|
callback(enosys());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const n = this.writeSync(fd, buf);
|
||||||
|
callback(null, n);
|
||||||
|
},
|
||||||
|
chmod(path, mode, callback) { callback(enosys()); },
|
||||||
|
chown(path, uid, gid, callback) { callback(enosys()); },
|
||||||
|
close(fd, callback) { callback(enosys()); },
|
||||||
|
fchmod(fd, mode, callback) { callback(enosys()); },
|
||||||
|
fchown(fd, uid, gid, callback) { callback(enosys()); },
|
||||||
|
fstat(fd, callback) { callback(enosys()); },
|
||||||
|
fsync(fd, callback) { callback(null); },
|
||||||
|
ftruncate(fd, length, callback) { callback(enosys()); },
|
||||||
|
lchown(path, uid, gid, callback) { callback(enosys()); },
|
||||||
|
link(path, link, callback) { callback(enosys()); },
|
||||||
|
lstat(path, callback) { callback(enosys()); },
|
||||||
|
mkdir(path, perm, callback) { callback(enosys()); },
|
||||||
|
open(path, flags, mode, callback) { callback(enosys()); },
|
||||||
|
read(fd, buffer, offset, length, position, callback) { callback(enosys()); },
|
||||||
|
readdir(path, callback) { callback(enosys()); },
|
||||||
|
readlink(path, callback) { callback(enosys()); },
|
||||||
|
rename(from, to, callback) { callback(enosys()); },
|
||||||
|
rmdir(path, callback) { callback(enosys()); },
|
||||||
|
stat(path, callback) { callback(enosys()); },
|
||||||
|
symlink(path, link, callback) { callback(enosys()); },
|
||||||
|
truncate(path, length, callback) { callback(enosys()); },
|
||||||
|
unlink(path, callback) { callback(enosys()); },
|
||||||
|
utimes(path, atime, mtime, callback) { callback(enosys()); },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!globalThis.process) {
|
||||||
|
globalThis.process = {
|
||||||
|
getuid() { return -1; },
|
||||||
|
getgid() { return -1; },
|
||||||
|
geteuid() { return -1; },
|
||||||
|
getegid() { return -1; },
|
||||||
|
getgroups() { throw enosys(); },
|
||||||
|
pid: -1,
|
||||||
|
ppid: -1,
|
||||||
|
umask() { throw enosys(); },
|
||||||
|
cwd() { throw enosys(); },
|
||||||
|
chdir() { throw enosys(); },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!globalThis.crypto) {
|
||||||
|
throw new Error("globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!globalThis.performance) {
|
||||||
|
throw new Error("globalThis.performance is not available, polyfill required (performance.now only)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!globalThis.TextEncoder) {
|
||||||
|
throw new Error("globalThis.TextEncoder is not available, polyfill required");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!globalThis.TextDecoder) {
|
||||||
|
throw new Error("globalThis.TextDecoder is not available, polyfill required");
|
||||||
|
}
|
||||||
|
|
||||||
|
const encoder = new TextEncoder("utf-8");
|
||||||
|
const decoder = new TextDecoder("utf-8");
|
||||||
|
|
||||||
|
globalThis.Go = class {
|
||||||
|
constructor() {
|
||||||
|
this.argv = ["js"];
|
||||||
|
this.env = {};
|
||||||
|
this.exit = (code) => {
|
||||||
|
if (code !== 0) {
|
||||||
|
console.warn("exit code:", code);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this._exitPromise = new Promise((resolve) => {
|
||||||
|
this._resolveExitPromise = resolve;
|
||||||
|
});
|
||||||
|
this._pendingEvent = null;
|
||||||
|
this._scheduledTimeouts = new Map();
|
||||||
|
this._nextCallbackTimeoutID = 1;
|
||||||
|
|
||||||
|
const setInt64 = (addr, v) => {
|
||||||
|
this.mem.setUint32(addr + 0, v, true);
|
||||||
|
this.mem.setUint32(addr + 4, Math.floor(v / 4294967296), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const setInt32 = (addr, v) => {
|
||||||
|
this.mem.setUint32(addr + 0, v, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getInt64 = (addr) => {
|
||||||
|
const low = this.mem.getUint32(addr + 0, true);
|
||||||
|
const high = this.mem.getInt32(addr + 4, true);
|
||||||
|
return low + high * 4294967296;
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadValue = (addr) => {
|
||||||
|
const f = this.mem.getFloat64(addr, true);
|
||||||
|
if (f === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (!isNaN(f)) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = this.mem.getUint32(addr, true);
|
||||||
|
return this._values[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
const storeValue = (addr, v) => {
|
||||||
|
const nanHead = 0x7FF80000;
|
||||||
|
|
||||||
|
if (typeof v === "number" && v !== 0) {
|
||||||
|
if (isNaN(v)) {
|
||||||
|
this.mem.setUint32(addr + 4, nanHead, true);
|
||||||
|
this.mem.setUint32(addr, 0, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.mem.setFloat64(addr, v, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v === undefined) {
|
||||||
|
this.mem.setFloat64(addr, 0, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let id = this._ids.get(v);
|
||||||
|
if (id === undefined) {
|
||||||
|
id = this._idPool.pop();
|
||||||
|
if (id === undefined) {
|
||||||
|
id = this._values.length;
|
||||||
|
}
|
||||||
|
this._values[id] = v;
|
||||||
|
this._goRefCounts[id] = 0;
|
||||||
|
this._ids.set(v, id);
|
||||||
|
}
|
||||||
|
this._goRefCounts[id]++;
|
||||||
|
let typeFlag = 0;
|
||||||
|
switch (typeof v) {
|
||||||
|
case "object":
|
||||||
|
if (v !== null) {
|
||||||
|
typeFlag = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "string":
|
||||||
|
typeFlag = 2;
|
||||||
|
break;
|
||||||
|
case "symbol":
|
||||||
|
typeFlag = 3;
|
||||||
|
break;
|
||||||
|
case "function":
|
||||||
|
typeFlag = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.mem.setUint32(addr + 4, nanHead | typeFlag, true);
|
||||||
|
this.mem.setUint32(addr, id, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadSlice = (addr) => {
|
||||||
|
const array = getInt64(addr + 0);
|
||||||
|
const len = getInt64(addr + 8);
|
||||||
|
return new Uint8Array(this._inst.exports.mem.buffer, array, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadSliceOfValues = (addr) => {
|
||||||
|
const array = getInt64(addr + 0);
|
||||||
|
const len = getInt64(addr + 8);
|
||||||
|
const a = new Array(len);
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
a[i] = loadValue(array + i * 8);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadString = (addr) => {
|
||||||
|
const saddr = getInt64(addr + 0);
|
||||||
|
const len = getInt64(addr + 8);
|
||||||
|
return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len));
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeOrigin = Date.now() - performance.now();
|
||||||
|
this.importObject = {
|
||||||
|
_gotest: {
|
||||||
|
add: (a, b) => a + b,
|
||||||
|
},
|
||||||
|
gojs: {
|
||||||
|
// Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters)
|
||||||
|
// may synchronously trigger a Go event handler. This makes Go code get executed in the middle of the imported
|
||||||
|
// function. A goroutine can switch to a new stack if the current stack is too small (see morestack function).
|
||||||
|
// This changes the SP, thus we have to update the SP used by the imported function.
|
||||||
|
|
||||||
|
// func wasmExit(code int32)
|
||||||
|
"runtime.wasmExit": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
const code = this.mem.getInt32(sp + 8, true);
|
||||||
|
this.exited = true;
|
||||||
|
delete this._inst;
|
||||||
|
delete this._values;
|
||||||
|
delete this._goRefCounts;
|
||||||
|
delete this._ids;
|
||||||
|
delete this._idPool;
|
||||||
|
this.exit(code);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
|
||||||
|
"runtime.wasmWrite": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
const fd = getInt64(sp + 8);
|
||||||
|
const p = getInt64(sp + 16);
|
||||||
|
const n = this.mem.getInt32(sp + 24, true);
|
||||||
|
fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func resetMemoryDataView()
|
||||||
|
"runtime.resetMemoryDataView": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
this.mem = new DataView(this._inst.exports.mem.buffer);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func nanotime1() int64
|
||||||
|
"runtime.nanotime1": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func walltime() (sec int64, nsec int32)
|
||||||
|
"runtime.walltime": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
const msec = (new Date).getTime();
|
||||||
|
setInt64(sp + 8, msec / 1000);
|
||||||
|
this.mem.setInt32(sp + 16, (msec % 1000) * 1000000, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func scheduleTimeoutEvent(delay int64) int32
|
||||||
|
"runtime.scheduleTimeoutEvent": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
const id = this._nextCallbackTimeoutID;
|
||||||
|
this._nextCallbackTimeoutID++;
|
||||||
|
this._scheduledTimeouts.set(id, setTimeout(
|
||||||
|
() => {
|
||||||
|
this._resume();
|
||||||
|
while (this._scheduledTimeouts.has(id)) {
|
||||||
|
// for some reason Go failed to register the timeout event, log and try again
|
||||||
|
// (temporary workaround for https://github.com/golang/go/issues/28975)
|
||||||
|
console.warn("scheduleTimeoutEvent: missed timeout event");
|
||||||
|
this._resume();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getInt64(sp + 8),
|
||||||
|
));
|
||||||
|
this.mem.setInt32(sp + 16, id, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func clearTimeoutEvent(id int32)
|
||||||
|
"runtime.clearTimeoutEvent": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
const id = this.mem.getInt32(sp + 8, true);
|
||||||
|
clearTimeout(this._scheduledTimeouts.get(id));
|
||||||
|
this._scheduledTimeouts.delete(id);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func getRandomData(r []byte)
|
||||||
|
"runtime.getRandomData": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
crypto.getRandomValues(loadSlice(sp + 8));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func finalizeRef(v ref)
|
||||||
|
"syscall/js.finalizeRef": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
const id = this.mem.getUint32(sp + 8, true);
|
||||||
|
this._goRefCounts[id]--;
|
||||||
|
if (this._goRefCounts[id] === 0) {
|
||||||
|
const v = this._values[id];
|
||||||
|
this._values[id] = null;
|
||||||
|
this._ids.delete(v);
|
||||||
|
this._idPool.push(id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// func stringVal(value string) ref
|
||||||
|
"syscall/js.stringVal": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
storeValue(sp + 24, loadString(sp + 8));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueGet(v ref, p string) ref
|
||||||
|
"syscall/js.valueGet": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
const result = Reflect.get(loadValue(sp + 8), loadString(sp + 16));
|
||||||
|
sp = this._inst.exports.getsp() >>> 0; // see comment above
|
||||||
|
storeValue(sp + 32, result);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueSet(v ref, p string, x ref)
|
||||||
|
"syscall/js.valueSet": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueDelete(v ref, p string)
|
||||||
|
"syscall/js.valueDelete": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
Reflect.deleteProperty(loadValue(sp + 8), loadString(sp + 16));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueIndex(v ref, i int) ref
|
||||||
|
"syscall/js.valueIndex": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
|
||||||
|
},
|
||||||
|
|
||||||
|
// valueSetIndex(v ref, i int, x ref)
|
||||||
|
"syscall/js.valueSetIndex": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueCall(v ref, m string, args []ref) (ref, bool)
|
||||||
|
"syscall/js.valueCall": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
try {
|
||||||
|
const v = loadValue(sp + 8);
|
||||||
|
const m = Reflect.get(v, loadString(sp + 16));
|
||||||
|
const args = loadSliceOfValues(sp + 32);
|
||||||
|
const result = Reflect.apply(m, v, args);
|
||||||
|
sp = this._inst.exports.getsp() >>> 0; // see comment above
|
||||||
|
storeValue(sp + 56, result);
|
||||||
|
this.mem.setUint8(sp + 64, 1);
|
||||||
|
} catch (err) {
|
||||||
|
sp = this._inst.exports.getsp() >>> 0; // see comment above
|
||||||
|
storeValue(sp + 56, err);
|
||||||
|
this.mem.setUint8(sp + 64, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueInvoke(v ref, args []ref) (ref, bool)
|
||||||
|
"syscall/js.valueInvoke": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
try {
|
||||||
|
const v = loadValue(sp + 8);
|
||||||
|
const args = loadSliceOfValues(sp + 16);
|
||||||
|
const result = Reflect.apply(v, undefined, args);
|
||||||
|
sp = this._inst.exports.getsp() >>> 0; // see comment above
|
||||||
|
storeValue(sp + 40, result);
|
||||||
|
this.mem.setUint8(sp + 48, 1);
|
||||||
|
} catch (err) {
|
||||||
|
sp = this._inst.exports.getsp() >>> 0; // see comment above
|
||||||
|
storeValue(sp + 40, err);
|
||||||
|
this.mem.setUint8(sp + 48, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueNew(v ref, args []ref) (ref, bool)
|
||||||
|
"syscall/js.valueNew": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
try {
|
||||||
|
const v = loadValue(sp + 8);
|
||||||
|
const args = loadSliceOfValues(sp + 16);
|
||||||
|
const result = Reflect.construct(v, args);
|
||||||
|
sp = this._inst.exports.getsp() >>> 0; // see comment above
|
||||||
|
storeValue(sp + 40, result);
|
||||||
|
this.mem.setUint8(sp + 48, 1);
|
||||||
|
} catch (err) {
|
||||||
|
sp = this._inst.exports.getsp() >>> 0; // see comment above
|
||||||
|
storeValue(sp + 40, err);
|
||||||
|
this.mem.setUint8(sp + 48, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueLength(v ref) int
|
||||||
|
"syscall/js.valueLength": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
setInt64(sp + 16, parseInt(loadValue(sp + 8).length));
|
||||||
|
},
|
||||||
|
|
||||||
|
// valuePrepareString(v ref) (ref, int)
|
||||||
|
"syscall/js.valuePrepareString": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
const str = encoder.encode(String(loadValue(sp + 8)));
|
||||||
|
storeValue(sp + 16, str);
|
||||||
|
setInt64(sp + 24, str.length);
|
||||||
|
},
|
||||||
|
|
||||||
|
// valueLoadString(v ref, b []byte)
|
||||||
|
"syscall/js.valueLoadString": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
const str = loadValue(sp + 8);
|
||||||
|
loadSlice(sp + 16).set(str);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueInstanceOf(v ref, t ref) bool
|
||||||
|
"syscall/js.valueInstanceOf": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
this.mem.setUint8(sp + 24, (loadValue(sp + 8) instanceof loadValue(sp + 16)) ? 1 : 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func copyBytesToGo(dst []byte, src ref) (int, bool)
|
||||||
|
"syscall/js.copyBytesToGo": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
const dst = loadSlice(sp + 8);
|
||||||
|
const src = loadValue(sp + 32);
|
||||||
|
if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) {
|
||||||
|
this.mem.setUint8(sp + 48, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const toCopy = src.subarray(0, dst.length);
|
||||||
|
dst.set(toCopy);
|
||||||
|
setInt64(sp + 40, toCopy.length);
|
||||||
|
this.mem.setUint8(sp + 48, 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func copyBytesToJS(dst ref, src []byte) (int, bool)
|
||||||
|
"syscall/js.copyBytesToJS": (sp) => {
|
||||||
|
sp >>>= 0;
|
||||||
|
const dst = loadValue(sp + 8);
|
||||||
|
const src = loadSlice(sp + 16);
|
||||||
|
if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) {
|
||||||
|
this.mem.setUint8(sp + 48, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const toCopy = src.subarray(0, dst.length);
|
||||||
|
dst.set(toCopy);
|
||||||
|
setInt64(sp + 40, toCopy.length);
|
||||||
|
this.mem.setUint8(sp + 48, 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
"debug": (value) => {
|
||||||
|
console.log(value);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(instance) {
|
||||||
|
if (!(instance instanceof WebAssembly.Instance)) {
|
||||||
|
throw new Error("Go.run: WebAssembly.Instance expected");
|
||||||
|
}
|
||||||
|
this._inst = instance;
|
||||||
|
this.mem = new DataView(this._inst.exports.mem.buffer);
|
||||||
|
this._values = [ // JS values that Go currently has references to, indexed by reference id
|
||||||
|
NaN,
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
globalThis,
|
||||||
|
this,
|
||||||
|
];
|
||||||
|
this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id
|
||||||
|
this._ids = new Map([ // mapping from JS values to reference ids
|
||||||
|
[0, 1],
|
||||||
|
[null, 2],
|
||||||
|
[true, 3],
|
||||||
|
[false, 4],
|
||||||
|
[globalThis, 5],
|
||||||
|
[this, 6],
|
||||||
|
]);
|
||||||
|
this._idPool = []; // unused ids that have been garbage collected
|
||||||
|
this.exited = false; // whether the Go program has exited
|
||||||
|
|
||||||
|
// Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
|
||||||
|
let offset = 4096;
|
||||||
|
|
||||||
|
const strPtr = (str) => {
|
||||||
|
const ptr = offset;
|
||||||
|
const bytes = encoder.encode(str + "\0");
|
||||||
|
new Uint8Array(this.mem.buffer, offset, bytes.length).set(bytes);
|
||||||
|
offset += bytes.length;
|
||||||
|
if (offset % 8 !== 0) {
|
||||||
|
offset += 8 - (offset % 8);
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
const argc = this.argv.length;
|
||||||
|
|
||||||
|
const argvPtrs = [];
|
||||||
|
this.argv.forEach((arg) => {
|
||||||
|
argvPtrs.push(strPtr(arg));
|
||||||
|
});
|
||||||
|
argvPtrs.push(0);
|
||||||
|
|
||||||
|
const keys = Object.keys(this.env).sort();
|
||||||
|
keys.forEach((key) => {
|
||||||
|
argvPtrs.push(strPtr(`${key}=${this.env[key]}`));
|
||||||
|
});
|
||||||
|
argvPtrs.push(0);
|
||||||
|
|
||||||
|
const argv = offset;
|
||||||
|
argvPtrs.forEach((ptr) => {
|
||||||
|
this.mem.setUint32(offset, ptr, true);
|
||||||
|
this.mem.setUint32(offset + 4, 0, true);
|
||||||
|
offset += 8;
|
||||||
|
});
|
||||||
|
|
||||||
|
// The linker guarantees global data starts from at least wasmMinDataAddr.
|
||||||
|
// Keep in sync with cmd/link/internal/ld/data.go:wasmMinDataAddr.
|
||||||
|
const wasmMinDataAddr = 4096 + 8192;
|
||||||
|
if (offset >= wasmMinDataAddr) {
|
||||||
|
throw new Error("total length of command line and environment variables exceeds limit");
|
||||||
|
}
|
||||||
|
|
||||||
|
this._inst.exports.run(argc, argv);
|
||||||
|
if (this.exited) {
|
||||||
|
this._resolveExitPromise();
|
||||||
|
}
|
||||||
|
await this._exitPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
_resume() {
|
||||||
|
if (this.exited) {
|
||||||
|
throw new Error("Go program has already exited");
|
||||||
|
}
|
||||||
|
this._inst.exports.resume();
|
||||||
|
if (this.exited) {
|
||||||
|
this._resolveExitPromise();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_makeFuncWrapper(id) {
|
||||||
|
const go = this;
|
||||||
|
return function () {
|
||||||
|
const event = { id: id, this: this, args: arguments };
|
||||||
|
go._pendingEvent = event;
|
||||||
|
go._resume();
|
||||||
|
return event.result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted } from 'vue';
|
import {onMounted} from 'vue';
|
||||||
import { useConfigStore } from '@/stores/configStore';
|
import {useConfigStore} from '@/stores/configStore';
|
||||||
import { useSystemStore } from '@/stores/systemStore';
|
import {useSystemStore} from '@/stores/systemStore';
|
||||||
import { useKeybindingStore } from '@/stores/keybindingStore';
|
import {useKeybindingStore} from '@/stores/keybindingStore';
|
||||||
import { useThemeStore } from '@/stores/themeStore';
|
import {useThemeStore} from '@/stores/themeStore';
|
||||||
import { useUpdateStore } from '@/stores/updateStore';
|
import {useUpdateStore} from '@/stores/updateStore';
|
||||||
|
import {useBackupStore} from '@/stores/backupStore';
|
||||||
import WindowTitleBar from '@/components/titlebar/WindowTitleBar.vue';
|
import WindowTitleBar from '@/components/titlebar/WindowTitleBar.vue';
|
||||||
|
|
||||||
const configStore = useConfigStore();
|
const configStore = useConfigStore();
|
||||||
@@ -12,6 +13,7 @@ const systemStore = useSystemStore();
|
|||||||
const keybindingStore = useKeybindingStore();
|
const keybindingStore = useKeybindingStore();
|
||||||
const themeStore = useThemeStore();
|
const themeStore = useThemeStore();
|
||||||
const updateStore = useUpdateStore();
|
const updateStore = useUpdateStore();
|
||||||
|
const backupStore = useBackupStore();
|
||||||
|
|
||||||
// 应用启动时加载配置和初始化系统信息
|
// 应用启动时加载配置和初始化系统信息
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
@@ -26,6 +28,9 @@ onMounted(async () => {
|
|||||||
await configStore.initializeLanguage();
|
await configStore.initializeLanguage();
|
||||||
themeStore.initializeTheme();
|
themeStore.initializeTheme();
|
||||||
|
|
||||||
|
// 初始化备份服务
|
||||||
|
await backupStore.initialize();
|
||||||
|
|
||||||
// 启动时检查更新
|
// 启动时检查更新
|
||||||
await updateStore.checkOnStartup();
|
await updateStore.checkOnStartup();
|
||||||
});
|
});
|
||||||
@@ -33,7 +38,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<WindowTitleBar />
|
<WindowTitleBar/>
|
||||||
<div class="app-content">
|
<div class="app-content">
|
||||||
<router-view/>
|
<router-view/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
32
frontend/src/common/prettier/plugins/go/build.bat
Normal file
32
frontend/src/common/prettier/plugins/go/build.bat
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
@echo off
|
||||||
|
rem Build script for Go Prettier Plugin WASM
|
||||||
|
rem This script compiles the Go code to WebAssembly
|
||||||
|
|
||||||
|
echo 🔨 Building Go Prettier Plugin WASM...
|
||||||
|
|
||||||
|
rem Set WASM build environment
|
||||||
|
set GOOS=js
|
||||||
|
set GOARCH=wasm
|
||||||
|
|
||||||
|
rem Build the WASM file
|
||||||
|
echo Compiling main.go to go.wasm...
|
||||||
|
go build -o go.wasm main.go
|
||||||
|
|
||||||
|
if %ERRORLEVEL% EQU 0 (
|
||||||
|
echo ✅ Build successful!
|
||||||
|
|
||||||
|
rem Show file size (Windows version)
|
||||||
|
for %%A in (go.wasm) do echo 📊 WASM file size: %%~zA bytes
|
||||||
|
|
||||||
|
rem Copy to public directory for browser access
|
||||||
|
if exist "..\..\..\..\..\public" (
|
||||||
|
copy go.wasm ..\..\..\..\..\public\go.wasm > nul
|
||||||
|
echo 📋 Copied to public directory
|
||||||
|
)
|
||||||
|
|
||||||
|
echo 🎉 Go Prettier Plugin WASM is ready!
|
||||||
|
) else (
|
||||||
|
echo ❌ Build failed!
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
30
frontend/src/common/prettier/plugins/go/build.sh
Normal file
30
frontend/src/common/prettier/plugins/go/build.sh
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Build script for Go Prettier Plugin WASM
|
||||||
|
# This script compiles the Go code to WebAssembly
|
||||||
|
|
||||||
|
echo "🔨 Building Go Prettier Plugin WASM..."
|
||||||
|
|
||||||
|
# Set WASM build environment
|
||||||
|
export GOOS=js
|
||||||
|
export GOARCH=wasm
|
||||||
|
|
||||||
|
# Build the WASM file
|
||||||
|
echo "Compiling main.go to go.wasm..."
|
||||||
|
go build -o go.wasm main.go
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "✅ Build successful!"
|
||||||
|
echo "📊 WASM file size: $(du -h go.wasm | cut -f1)"
|
||||||
|
|
||||||
|
# Copy to public directory for browser access
|
||||||
|
if [ -d "../../../../../public" ]; then
|
||||||
|
cp go.wasm ../../../../../public/go.wasm
|
||||||
|
echo "📋 Copied to public directory"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "🎉 Go Prettier Plugin WASM is ready!"
|
||||||
|
else
|
||||||
|
echo "❌ Build failed!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
10
frontend/src/common/prettier/plugins/go/go.d.ts
vendored
Normal file
10
frontend/src/common/prettier/plugins/go/go.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Parser, Plugin } from "prettier";
|
||||||
|
|
||||||
|
export declare const languages: Plugin["languages"];
|
||||||
|
export declare const parsers: {
|
||||||
|
go: Parser;
|
||||||
|
};
|
||||||
|
export declare const printers: Plugin["printers"];
|
||||||
|
|
||||||
|
declare const plugin: Plugin;
|
||||||
|
export default plugin;
|
||||||
116
frontend/src/common/prettier/plugins/go/go.mjs
Normal file
116
frontend/src/common/prettier/plugins/go/go.mjs
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/**
|
||||||
|
* Go Prettier Plugin for Vite + Vue3 Environment
|
||||||
|
* WebAssembly-based Go code formatter for Prettier
|
||||||
|
*/
|
||||||
|
|
||||||
|
let initializePromise = null;
|
||||||
|
|
||||||
|
// Load WASM file from public directory
|
||||||
|
const loadWasm = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/go.wasm');
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Failed to load WASM file: ${response.status} ${response.statusText}`);
|
||||||
|
}
|
||||||
|
return await response.arrayBuffer();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('WASM loading failed:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize Go runtime
|
||||||
|
const initGoRuntime = async () => {
|
||||||
|
if (globalThis.Go) return;
|
||||||
|
|
||||||
|
// Auto-load wasm_exec.js if not available
|
||||||
|
try {
|
||||||
|
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = '/wasm_exec.js';
|
||||||
|
document.head.appendChild(script);
|
||||||
|
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
script.onload = resolve;
|
||||||
|
script.onerror = () => reject(new Error('Failed to load wasm_exec.js'));
|
||||||
|
setTimeout(() => reject(new Error('wasm_exec.js loading timeout')), 5000);
|
||||||
|
});
|
||||||
|
if (!globalThis.Go) {
|
||||||
|
throw new Error('Go WASM runtime is not available after loading wasm_exec.js');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to load wasm_exec.js:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const initialize = async () => {
|
||||||
|
if (initializePromise) return initializePromise;
|
||||||
|
|
||||||
|
initializePromise = (async () => {
|
||||||
|
await initGoRuntime();
|
||||||
|
|
||||||
|
const go = new globalThis.Go();
|
||||||
|
const wasmBuffer = await loadWasm();
|
||||||
|
const {instance} = await WebAssembly.instantiate(wasmBuffer, go.importObject);
|
||||||
|
|
||||||
|
// Run Go program
|
||||||
|
go.run(instance).catch(err => {
|
||||||
|
console.error('Go WASM program exit error:', err);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait for initialization to complete
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 200));
|
||||||
|
|
||||||
|
// Check if formatGo function is available
|
||||||
|
if (typeof globalThis.formatGo !== 'function') {
|
||||||
|
throw new Error('Go WASM module not properly initialized - formatGo function not available');
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
return initializePromise;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const languages = [
|
||||||
|
{
|
||||||
|
name: "Go",
|
||||||
|
parsers: ["go"],
|
||||||
|
extensions: [".go"],
|
||||||
|
vscodeLanguageIds: ["go"],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const parsers = {
|
||||||
|
go: {
|
||||||
|
parse: (text) => text,
|
||||||
|
astFormat: "go-format",
|
||||||
|
locStart: (node) => 0,
|
||||||
|
locEnd: (node) => node.length,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const printers = {
|
||||||
|
"go-format": {
|
||||||
|
print: async (path) => {
|
||||||
|
await initialize();
|
||||||
|
const text = path.getValue();
|
||||||
|
|
||||||
|
if (typeof globalThis.formatGo !== 'function') {
|
||||||
|
throw new Error('Go WASM module not properly initialized - formatGo function missing');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return globalThis.formatGo(text);
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Go formatting failed: ${error.message}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Default export for Prettier plugin compatibility
|
||||||
|
export default {
|
||||||
|
languages,
|
||||||
|
parsers,
|
||||||
|
printers
|
||||||
|
};
|
||||||
255
frontend/src/common/prettier/plugins/go/main.go
Normal file
255
frontend/src/common/prettier/plugins/go/main.go
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
//go:build js && wasm
|
||||||
|
|
||||||
|
// Package main implements a WebAssembly module that provides Go code formatting
|
||||||
|
// functionality for the Prettier plugin. This package exposes the formatGo function
|
||||||
|
// to JavaScript, enabling web-based Go code formatting with better error tolerance.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"go/format"
|
||||||
|
"go/parser"
|
||||||
|
"go/token"
|
||||||
|
"strings"
|
||||||
|
"syscall/js"
|
||||||
|
)
|
||||||
|
|
||||||
|
// formatGoCode attempts to format Go source code with better error tolerance
|
||||||
|
func formatGoCode(src string) (string, error) {
|
||||||
|
// Trim input but preserve leading/trailing newlines structure
|
||||||
|
trimmed := strings.TrimSpace(src)
|
||||||
|
if trimmed == "" {
|
||||||
|
return src, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// First try the standard format.Source for complete, valid code
|
||||||
|
if formatted, err := format.Source([]byte(src)); err == nil {
|
||||||
|
return string(formatted), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new file set for parsing
|
||||||
|
fset := token.NewFileSet()
|
||||||
|
|
||||||
|
// Strategy 1: Try as complete Go file
|
||||||
|
if parsed, err := parser.ParseFile(fset, "", src, parser.ParseComments); err == nil {
|
||||||
|
return formatASTNode(fset, parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategy 2: Try wrapping as package-level declarations
|
||||||
|
packageWrapped := fmt.Sprintf("package main\n\n%s", trimmed)
|
||||||
|
if parsed, err := parser.ParseFile(fset, "", packageWrapped, parser.ParseComments); err == nil {
|
||||||
|
if formatted, err := formatASTNode(fset, parsed); err == nil {
|
||||||
|
return extractPackageContent(formatted), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategy 3: Try wrapping in main function
|
||||||
|
funcWrapped := fmt.Sprintf("package main\n\nfunc main() {\n%s\n}", indentLines(trimmed, "\t"))
|
||||||
|
if parsed, err := parser.ParseFile(fset, "", funcWrapped, parser.ParseComments); err == nil {
|
||||||
|
if formatted, err := formatASTNode(fset, parsed); err == nil {
|
||||||
|
return extractFunctionBody(formatted), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategy 4: Try wrapping in anonymous function
|
||||||
|
anonWrapped := fmt.Sprintf("package main\n\nvar _ = func() {\n%s\n}", indentLines(trimmed, "\t"))
|
||||||
|
if parsed, err := parser.ParseFile(fset, "", anonWrapped, parser.ParseComments); err == nil {
|
||||||
|
if formatted, err := formatASTNode(fset, parsed); err == nil {
|
||||||
|
return extractFunctionBody(formatted), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategy 5: Try line-by-line formatting for complex cases
|
||||||
|
return formatLineByLine(trimmed, fset)
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatASTNode formats an AST node using the standard formatter
|
||||||
|
func formatASTNode(fset *token.FileSet, node interface{}) (string, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := format.Node(&buf, fset, node); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return buf.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractPackageContent extracts content after package declaration
|
||||||
|
func extractPackageContent(formatted string) string {
|
||||||
|
lines := strings.Split(formatted, "\n")
|
||||||
|
var contentLines []string
|
||||||
|
skipNext := false
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
if strings.HasPrefix(line, "package ") {
|
||||||
|
skipNext = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if skipNext && strings.TrimSpace(line) == "" {
|
||||||
|
skipNext = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !skipNext {
|
||||||
|
contentLines = append(contentLines, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(contentLines, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractFunctionBody extracts content from within a function body
|
||||||
|
func extractFunctionBody(formatted string) string {
|
||||||
|
lines := strings.Split(formatted, "\n")
|
||||||
|
var bodyLines []string
|
||||||
|
inFunction := false
|
||||||
|
braceCount := 0
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
if strings.Contains(line, "func ") && strings.Contains(line, "{") {
|
||||||
|
inFunction = true
|
||||||
|
braceCount = 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if inFunction {
|
||||||
|
// Count braces to know when function ends
|
||||||
|
braceCount += strings.Count(line, "{")
|
||||||
|
braceCount -= strings.Count(line, "}")
|
||||||
|
|
||||||
|
if braceCount == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove one level of indentation and add the line
|
||||||
|
if strings.HasPrefix(line, "\t") {
|
||||||
|
bodyLines = append(bodyLines, line[1:])
|
||||||
|
} else {
|
||||||
|
bodyLines = append(bodyLines, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove empty lines from start and end
|
||||||
|
for len(bodyLines) > 0 && strings.TrimSpace(bodyLines[0]) == "" {
|
||||||
|
bodyLines = bodyLines[1:]
|
||||||
|
}
|
||||||
|
for len(bodyLines) > 0 && strings.TrimSpace(bodyLines[len(bodyLines)-1]) == "" {
|
||||||
|
bodyLines = bodyLines[:len(bodyLines)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(bodyLines, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// indentLines adds indentation to each non-empty line
|
||||||
|
func indentLines(text, indent string) string {
|
||||||
|
lines := strings.Split(text, "\n")
|
||||||
|
var indentedLines []string
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
if strings.TrimSpace(line) == "" {
|
||||||
|
indentedLines = append(indentedLines, "")
|
||||||
|
} else {
|
||||||
|
indentedLines = append(indentedLines, indent+line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(indentedLines, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatLineByLine attempts to format each statement individually
|
||||||
|
func formatLineByLine(src string, fset *token.FileSet) (string, error) {
|
||||||
|
lines := strings.Split(src, "\n")
|
||||||
|
var formattedLines []string
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
trimmedLine := strings.TrimSpace(line)
|
||||||
|
if trimmedLine == "" {
|
||||||
|
formattedLines = append(formattedLines, "")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try different wrapping strategies for individual lines
|
||||||
|
attempts := []string{
|
||||||
|
fmt.Sprintf("package main\n\nfunc main() {\n\t%s\n}", trimmedLine),
|
||||||
|
fmt.Sprintf("package main\n\n%s", trimmedLine),
|
||||||
|
fmt.Sprintf("package main\n\nvar _ = %s", trimmedLine),
|
||||||
|
}
|
||||||
|
|
||||||
|
formatted := trimmedLine // fallback
|
||||||
|
for _, attempt := range attempts {
|
||||||
|
if parsed, err := parser.ParseFile(fset, "", attempt, parser.ParseComments); err == nil {
|
||||||
|
if result, err := formatASTNode(fset, parsed); err == nil {
|
||||||
|
if extracted := extractSingleStatement(result, trimmedLine); extracted != "" {
|
||||||
|
formatted = extracted
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
formattedLines = append(formattedLines, formatted)
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(formattedLines, "\n"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractSingleStatement tries to extract a single formatted statement
|
||||||
|
func extractSingleStatement(formatted, original string) string {
|
||||||
|
lines := strings.Split(formatted, "\n")
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
trimmed := strings.TrimSpace(line)
|
||||||
|
if trimmed != "" && !strings.HasPrefix(trimmed, "package ") &&
|
||||||
|
!strings.HasPrefix(trimmed, "func ") && !strings.HasPrefix(trimmed, "var _ =") &&
|
||||||
|
trimmed != "{" && trimmed != "}" {
|
||||||
|
// Remove leading tabs/spaces to normalize indentation
|
||||||
|
return strings.TrimLeft(line, " \t")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return original
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatGo is a JavaScript-callable function that formats Go source code.
|
||||||
|
// It attempts multiple strategies to format code, including handling incomplete
|
||||||
|
// or syntactically invalid code fragments.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - this: The JavaScript 'this' context (unused)
|
||||||
|
// - i: JavaScript arguments array where i[0] should contain the Go source code as a string
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - js.Value: The formatted Go source code as a JavaScript string value
|
||||||
|
// - If formatting fails completely, returns the original code unchanged
|
||||||
|
// - If no arguments are provided, returns js.Null() and logs an error
|
||||||
|
func formatGo(this js.Value, i []js.Value) interface{} {
|
||||||
|
if len(i) == 0 {
|
||||||
|
js.Global().Get("console").Call("error", "formatGo: missing code argument")
|
||||||
|
return js.Null()
|
||||||
|
}
|
||||||
|
|
||||||
|
code := i[0].String()
|
||||||
|
if strings.TrimSpace(code) == "" {
|
||||||
|
return js.ValueOf(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
formatted, err := formatGoCode(code)
|
||||||
|
if err != nil {
|
||||||
|
js.Global().Get("console").Call("warn", "Go formatting had issues:", err.Error())
|
||||||
|
return js.ValueOf(code) // Return original code if all attempts fail
|
||||||
|
}
|
||||||
|
|
||||||
|
return js.ValueOf(formatted)
|
||||||
|
}
|
||||||
|
|
||||||
|
// main initializes the WebAssembly module and exposes the formatGo function
|
||||||
|
// to the JavaScript global scope.
|
||||||
|
func main() {
|
||||||
|
// Create a channel to keep the Go program running
|
||||||
|
c := make(chan struct{}, 0)
|
||||||
|
|
||||||
|
// Expose the formatGo function to the JavaScript global scope
|
||||||
|
js.Global().Set("formatGo", js.FuncOf(formatGo))
|
||||||
|
|
||||||
|
// Block forever
|
||||||
|
<-c
|
||||||
|
}
|
||||||
17
frontend/src/common/prettier/plugins/java/comments.d.ts
vendored
Normal file
17
frontend/src/common/prettier/plugins/java/comments.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import type { IToken } from "java-parser";
|
||||||
|
import { type AstPath } from "prettier";
|
||||||
|
import { type JavaNode, type JavaNonTerminal, type JavaParserOptions } from "./printers/helpers.js";
|
||||||
|
export declare function determineFormatterOffOnRanges(cst: JavaNonTerminal): void;
|
||||||
|
export declare function isFullyBetweenFormatterOffOn(path: AstPath<JavaNode>): boolean;
|
||||||
|
export declare function canAttachComment(node: JavaNode): boolean;
|
||||||
|
export declare function handleLineComment(commentNode: JavaComment, _: string, options: JavaParserOptions): boolean;
|
||||||
|
export declare function handleRemainingComment(commentNode: JavaComment): boolean;
|
||||||
|
export type JavaComment = IToken & {
|
||||||
|
value: string;
|
||||||
|
leading: boolean;
|
||||||
|
trailing: boolean;
|
||||||
|
printed: boolean;
|
||||||
|
enclosingNode?: JavaNonTerminal;
|
||||||
|
precedingNode?: JavaNonTerminal;
|
||||||
|
followingNode?: JavaNonTerminal;
|
||||||
|
};
|
||||||
199
frontend/src/common/prettier/plugins/java/comments.js
Normal file
199
frontend/src/common/prettier/plugins/java/comments.js
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
import { util } from "prettier";
|
||||||
|
import parser from "./parser.js";
|
||||||
|
import { isEmptyStatement, isNonTerminal, isTerminal } from "./printers/helpers.js";
|
||||||
|
const formatterOffOnRangesByCst = new WeakMap();
|
||||||
|
export function determineFormatterOffOnRanges(cst) {
|
||||||
|
const { comments } = cst;
|
||||||
|
if (!comments) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const ranges = comments
|
||||||
|
.filter(({ image }) => /^(\/\/\s*@formatter:(off|on)\s*|\/\*\s*@formatter:(off|on)\s*\*\/)$/.test(image))
|
||||||
|
.reduce((ranges, { image, startOffset }) => {
|
||||||
|
const previous = ranges.at(-1);
|
||||||
|
if (image.endsWith("off")) {
|
||||||
|
if ((previous === null || previous === void 0 ? void 0 : previous.on) !== Infinity) {
|
||||||
|
ranges.push({ off: startOffset, on: Infinity });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((previous === null || previous === void 0 ? void 0 : previous.on) === Infinity) {
|
||||||
|
previous.on = startOffset;
|
||||||
|
}
|
||||||
|
return ranges;
|
||||||
|
}, new Array());
|
||||||
|
formatterOffOnRangesByCst.set(cst, ranges);
|
||||||
|
}
|
||||||
|
export function isFullyBetweenFormatterOffOn(path) {
|
||||||
|
var _a;
|
||||||
|
const { node, root } = path;
|
||||||
|
const start = parser.locStart(node);
|
||||||
|
const end = parser.locEnd(node);
|
||||||
|
return (((_a = formatterOffOnRangesByCst
|
||||||
|
.get(root)) === null || _a === void 0 ? void 0 : _a.some(range => range.off < start && end < range.on)) === true);
|
||||||
|
}
|
||||||
|
export function canAttachComment(node) {
|
||||||
|
var _a, _b, _c;
|
||||||
|
if (isTerminal(node)) {
|
||||||
|
const { name, CATEGORIES } = node.tokenType;
|
||||||
|
return (name === "Identifier" ||
|
||||||
|
(CATEGORIES === null || CATEGORIES === void 0 ? void 0 : CATEGORIES.find(({ name }) => name === "BinaryOperator")) !== undefined);
|
||||||
|
}
|
||||||
|
const { children, name } = node;
|
||||||
|
switch (name) {
|
||||||
|
case "argumentList":
|
||||||
|
case "blockStatements":
|
||||||
|
case "emptyStatement":
|
||||||
|
case "enumBodyDeclarations":
|
||||||
|
return false;
|
||||||
|
case "annotationInterfaceMemberDeclaration":
|
||||||
|
case "classMemberDeclaration":
|
||||||
|
case "interfaceMemberDeclaration":
|
||||||
|
case "methodBody":
|
||||||
|
return !children.Semicolon;
|
||||||
|
case "blockStatement":
|
||||||
|
return !children.statement || !isEmptyStatement(children.statement[0]);
|
||||||
|
case "classBodyDeclaration":
|
||||||
|
return !((_a = children.classMemberDeclaration) === null || _a === void 0 ? void 0 : _a[0].children.Semicolon);
|
||||||
|
case "recordBodyDeclaration":
|
||||||
|
return !((_c = (_b = children.classBodyDeclaration) === null || _b === void 0 ? void 0 : _b[0].children.classMemberDeclaration) === null || _c === void 0 ? void 0 : _c[0].children.Semicolon);
|
||||||
|
case "statement":
|
||||||
|
return !isEmptyStatement(node);
|
||||||
|
case "statementWithoutTrailingSubstatement":
|
||||||
|
return !children.emptyStatement;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export function handleLineComment(commentNode, _, options) {
|
||||||
|
return [
|
||||||
|
handleBinaryExpressionComments,
|
||||||
|
handleFqnOrRefTypeComments,
|
||||||
|
handleIfStatementComments,
|
||||||
|
handleJumpStatementComments,
|
||||||
|
handleLabeledStatementComments,
|
||||||
|
handleNameComments
|
||||||
|
].some(fn => fn(commentNode, options));
|
||||||
|
}
|
||||||
|
export function handleRemainingComment(commentNode) {
|
||||||
|
return [
|
||||||
|
handleFqnOrRefTypeComments,
|
||||||
|
handleMethodDeclaratorComments,
|
||||||
|
handleNameComments,
|
||||||
|
handleJumpStatementComments
|
||||||
|
].some(fn => fn(commentNode));
|
||||||
|
}
|
||||||
|
function handleBinaryExpressionComments(commentNode, options) {
|
||||||
|
const { enclosingNode, precedingNode, followingNode } = commentNode;
|
||||||
|
if (enclosingNode &&
|
||||||
|
isNonTerminal(enclosingNode) &&
|
||||||
|
enclosingNode.name === "binaryExpression") {
|
||||||
|
if (isBinaryOperator(followingNode)) {
|
||||||
|
if (options.experimentalOperatorPosition === "start") {
|
||||||
|
util.addLeadingComment(followingNode, commentNode);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
util.addTrailingComment(followingNode, commentNode);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (options.experimentalOperatorPosition === "start" &&
|
||||||
|
isBinaryOperator(precedingNode)) {
|
||||||
|
util.addLeadingComment(precedingNode, commentNode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function handleFqnOrRefTypeComments(commentNode) {
|
||||||
|
const { enclosingNode, followingNode } = commentNode;
|
||||||
|
if (enclosingNode &&
|
||||||
|
isNonTerminal(enclosingNode) &&
|
||||||
|
enclosingNode.name === "fqnOrRefType" &&
|
||||||
|
followingNode) {
|
||||||
|
util.addLeadingComment(followingNode, commentNode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function handleIfStatementComments(commentNode) {
|
||||||
|
const { enclosingNode, precedingNode } = commentNode;
|
||||||
|
if (enclosingNode &&
|
||||||
|
isNonTerminal(enclosingNode) &&
|
||||||
|
enclosingNode.name === "ifStatement" &&
|
||||||
|
precedingNode &&
|
||||||
|
isNonTerminal(precedingNode) &&
|
||||||
|
precedingNode.name === "statement") {
|
||||||
|
util.addDanglingComment(enclosingNode, commentNode, undefined);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function handleJumpStatementComments(commentNode) {
|
||||||
|
const { enclosingNode, precedingNode, followingNode } = commentNode;
|
||||||
|
if (enclosingNode &&
|
||||||
|
!precedingNode &&
|
||||||
|
!followingNode &&
|
||||||
|
isNonTerminal(enclosingNode) &&
|
||||||
|
["breakStatement", "continueStatement", "returnStatement"].includes(enclosingNode.name)) {
|
||||||
|
util.addTrailingComment(enclosingNode, commentNode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function handleLabeledStatementComments(commentNode) {
|
||||||
|
const { enclosingNode, precedingNode } = commentNode;
|
||||||
|
if (enclosingNode &&
|
||||||
|
precedingNode &&
|
||||||
|
isNonTerminal(enclosingNode) &&
|
||||||
|
enclosingNode.name === "labeledStatement" &&
|
||||||
|
isTerminal(precedingNode) &&
|
||||||
|
precedingNode.tokenType.name === "Identifier") {
|
||||||
|
util.addLeadingComment(precedingNode, commentNode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function handleMethodDeclaratorComments(commentNode) {
|
||||||
|
const { enclosingNode } = commentNode;
|
||||||
|
if (enclosingNode &&
|
||||||
|
isNonTerminal(enclosingNode) &&
|
||||||
|
enclosingNode.name === "methodDeclarator" &&
|
||||||
|
!enclosingNode.children.receiverParameter &&
|
||||||
|
!enclosingNode.children.formalParameterList &&
|
||||||
|
enclosingNode.children.LBrace[0].startOffset < commentNode.startOffset &&
|
||||||
|
commentNode.startOffset < enclosingNode.children.RBrace[0].startOffset) {
|
||||||
|
util.addDanglingComment(enclosingNode, commentNode, undefined);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function handleNameComments(commentNode) {
|
||||||
|
const { enclosingNode, precedingNode } = commentNode;
|
||||||
|
if (enclosingNode &&
|
||||||
|
precedingNode &&
|
||||||
|
isNonTerminal(enclosingNode) &&
|
||||||
|
isTerminal(precedingNode) &&
|
||||||
|
precedingNode.tokenType.name === "Identifier" &&
|
||||||
|
[
|
||||||
|
"ambiguousName",
|
||||||
|
"classOrInterfaceTypeToInstantiate",
|
||||||
|
"expressionName",
|
||||||
|
"moduleDeclaration",
|
||||||
|
"moduleName",
|
||||||
|
"packageDeclaration",
|
||||||
|
"packageName",
|
||||||
|
"packageOrTypeName",
|
||||||
|
"typeName"
|
||||||
|
].includes(enclosingNode.name)) {
|
||||||
|
util.addTrailingComment(precedingNode, commentNode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function isBinaryOperator(node) {
|
||||||
|
var _a;
|
||||||
|
return (node !== undefined &&
|
||||||
|
(isNonTerminal(node)
|
||||||
|
? node.name === "shiftOperator"
|
||||||
|
: (_a = node.tokenType.CATEGORIES) === null || _a === void 0 ? void 0 : _a.some(({ name }) => name === "BinaryOperator")));
|
||||||
|
}
|
||||||
563
frontend/src/common/prettier/plugins/java/index.d.ts
vendored
Normal file
563
frontend/src/common/prettier/plugins/java/index.d.ts
vendored
Normal file
@@ -0,0 +1,563 @@
|
|||||||
|
import type { JavaNode } from "./printers/helpers.js";
|
||||||
|
declare const _default: {
|
||||||
|
languages: {
|
||||||
|
name: string;
|
||||||
|
parsers: "java"[];
|
||||||
|
group: string;
|
||||||
|
tmScope: string;
|
||||||
|
aceMode: string;
|
||||||
|
codemirrorMode: string;
|
||||||
|
codemirrorMimeType: string;
|
||||||
|
extensions: string[];
|
||||||
|
linguistLanguageId: number;
|
||||||
|
vscodeLanguageIds: string[];
|
||||||
|
}[];
|
||||||
|
parsers: {
|
||||||
|
java: {
|
||||||
|
parse(text: string, options: import("./printers/helpers.js").JavaParserOptions): import("./printers/helpers.js").JavaNonTerminal;
|
||||||
|
astFormat: string;
|
||||||
|
hasPragma(text: string): boolean;
|
||||||
|
locStart(node: JavaNode): number;
|
||||||
|
locEnd(node: JavaNode): number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
printers: {
|
||||||
|
java: {
|
||||||
|
print(path: import("prettier").AstPath<import("java-parser").ArrayInitializerCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").VariableInitializerListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").BlockCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").BlockStatementsCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").LocalVariableDeclarationStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").LocalVariableDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").LabeledStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ExpressionStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").IfStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").AssertStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").SwitchStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").SwitchBlockCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").SwitchBlockStatementGroupCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").SwitchLabelCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").SwitchRuleCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").WhileStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").DoStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").BasicForStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").StatementExpressionListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").EnhancedForStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").BreakStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ContinueStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ReturnStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ThrowStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").SynchronizedStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TryStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").CatchesCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").CatchClauseCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").CatchFormalParameterCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").CatchTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").FinallyCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TryWithResourcesStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ResourceSpecificationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ResourceListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").YieldStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ForInitCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ForUpdateCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").StatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").StatementWithoutTrailingSubstatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ForStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").BlockStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").CaseConstantCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").CasePatternCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").EmptyStatementCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").StatementExpressionCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").LocalVariableTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ResourceCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").VariableAccessCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ClassDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").NormalClassDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TypeParametersCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TypeParameterListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ClassExtendsCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ClassImplementsCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").InterfaceTypeListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ClassBodyCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ClassMemberDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").FieldDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").VariableDeclaratorListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").VariableDeclaratorCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").VariableDeclaratorIdCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").UnannPrimitiveTypeWithOptionalDimsSuffixCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").UnannReferenceTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").MethodDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").MethodHeaderCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").MethodDeclaratorCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ReceiverParameterCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").FormalParameterListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").VariableParaRegularParameterCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").VariableArityParameterCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ThrowsCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ExceptionTypeListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").StaticInitializerCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ConstructorDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ConstructorDeclaratorCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ConstructorBodyCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").UnqualifiedExplicitConstructorInvocationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").QualifiedExplicitConstructorInvocationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").EnumDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").EnumBodyCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").EnumConstantListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").EnumConstantCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").EnumBodyDeclarationsCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").RecordDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").RecordHeaderCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").RecordComponentListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").RecordComponentCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").VariableArityRecordComponentCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").RecordBodyCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").CompactConstructorDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").UnannTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").VariableInitializerCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").VariableModifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").UnannClassTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ClassBodyDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").InstanceInitializerCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ClassModifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ClassPermitsCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").FieldModifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").MethodModifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").MethodBodyCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ConstructorModifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").SimpleTypeNameCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ExplicitConstructorInvocationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").EnumConstantModifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ExceptionTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").FormalParameterCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ResultCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").RecordBodyDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").RecordComponentModifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").UnannClassOrInterfaceTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").UnannInterfaceTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").UnannPrimitiveTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").UnannTypeVariableCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").LambdaExpressionCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").LambdaParametersCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").LambdaParametersWithBracesCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ConciseLambdaParameterListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").NormalLambdaParameterListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").RegularLambdaParameterCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ConditionalExpressionCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").BinaryExpressionCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").UnaryExpressionCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").UnaryExpressionNotPlusMinusCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").PrimaryCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").PrimarySuffixCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").FqnOrRefTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").FqnOrRefTypePartFirstCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").FqnOrRefTypePartRestCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").FqnOrRefTypePartCommonCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ParenthesisExpressionCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").PrimitiveCastExpressionCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ReferenceTypeCastExpressionCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").UnqualifiedClassInstanceCreationExpressionCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ClassOrInterfaceTypeToInstantiateCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").MethodInvocationSuffixCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ArgumentListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ArrayCreationExpressionCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ArrayCreationExpressionWithoutInitializerSuffixCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ArrayCreationWithInitializerSuffixCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").DimExprsCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").DimExprCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ClassLiteralSuffixCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ArrayAccessSuffixCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").MethodReferenceSuffixCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").StringTemplateCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TextBlockTemplateCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").RecordPatternCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ComponentPatternListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").GuardCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TemplateCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").PatternCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ExpressionCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TypePatternCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").CastExpressionCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TypeArgumentsOrDiamondCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").DiamondCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ComponentPatternCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").MatchAllPatternCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ConciseLambdaParameterCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").EmbeddedExpressionCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").LambdaBodyCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").LambdaParameterListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").NormalLambdaParameterCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").LambdaParameterTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").NewExpressionCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").PrimaryPrefixCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TemplateArgumentCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").InterfaceDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").NormalInterfaceDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").InterfaceExtendsCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").InterfaceBodyCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").InterfaceMemberDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ConstantDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").InterfaceMethodDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").AnnotationInterfaceDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").AnnotationInterfaceBodyCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").AnnotationInterfaceMemberDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").AnnotationInterfaceElementDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").DefaultValueCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").AnnotationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ElementValuePairListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ElementValuePairCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ElementValueArrayInitializerCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ElementValueListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ElementValueCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").AnnotationInterfaceElementModifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ConstantModifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").InterfaceModifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").InterfacePermitsCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").InterfaceMethodModifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").LiteralCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ShiftOperatorCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").BooleanLiteralCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").FloatingPointLiteralCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").IntegerLiteralCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").MethodNameCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").AmbiguousNameCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TypeNameCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TypeIdentifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ExpressionNameCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").PackageNameCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ModuleNameCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").PackageOrTypeNameCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").CompilationUnitCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").OrdinaryCompilationUnitCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ModularCompilationUnitCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").PackageDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ImportDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TypeDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ModuleDeclarationCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").RequiresModuleDirectiveCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ExportsModuleDirectiveCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").OpensModuleDirectiveCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").UsesModuleDirectiveCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ProvidesModuleDirectiveCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ModuleDirectiveCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").RequiresModifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").PackageModifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").PrimitiveTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ReferenceTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TypeVariableCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").DimsCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TypeParameterCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TypeBoundCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").AdditionalBoundCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TypeArgumentsCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TypeArgumentListCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").WildcardCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").WildcardBoundsCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").InterfaceTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ClassTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").NumericTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").ClassOrInterfaceTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").FloatingPointTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").IntegralTypeCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TypeArgumentCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").TypeParameterModifierCstNode & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}> | import("prettier").AstPath<import("java-parser").IToken & {
|
||||||
|
comments?: import("./comments.js").JavaComment[];
|
||||||
|
}>, options: import("prettier").ParserOptions<JavaNode>, print: (path: import("prettier").AstPath<JavaNode>) => import("prettier").Doc, args: unknown): import("prettier/doc.js").builders.Doc;
|
||||||
|
hasPrettierIgnore(path: import("prettier").AstPath<JavaNode>): boolean;
|
||||||
|
canAttachComment: typeof import("./comments.js").canAttachComment;
|
||||||
|
isBlockComment(node: JavaNode): boolean;
|
||||||
|
printComment(commentPath: import("prettier").AstPath<JavaNode>): string | import("prettier/doc.js").builders.Doc[];
|
||||||
|
getCommentChildNodes(node: JavaNode): any[];
|
||||||
|
handleComments: {
|
||||||
|
ownLine: typeof import("./comments.js").handleLineComment;
|
||||||
|
endOfLine: typeof import("./comments.js").handleLineComment;
|
||||||
|
remaining: typeof import("./comments.js").handleRemainingComment;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
options: {
|
||||||
|
entrypoint: {
|
||||||
|
type: "choice";
|
||||||
|
category: string;
|
||||||
|
default: string;
|
||||||
|
choices: {
|
||||||
|
value: string;
|
||||||
|
description: string;
|
||||||
|
}[];
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
arrowParens: {
|
||||||
|
type: "choice";
|
||||||
|
category: string;
|
||||||
|
default: string;
|
||||||
|
choices: {
|
||||||
|
value: string;
|
||||||
|
description: string;
|
||||||
|
}[];
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
trailingComma: {
|
||||||
|
type: "choice";
|
||||||
|
category: string;
|
||||||
|
default: string;
|
||||||
|
choices: {
|
||||||
|
value: string;
|
||||||
|
description: string;
|
||||||
|
}[];
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
experimentalOperatorPosition: {
|
||||||
|
type: "choice";
|
||||||
|
category: string;
|
||||||
|
default: string;
|
||||||
|
choices: {
|
||||||
|
value: string;
|
||||||
|
description: string;
|
||||||
|
}[];
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
defaultOptions: {
|
||||||
|
arrowParens: "avoid";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
29
frontend/src/common/prettier/plugins/java/index.js
Normal file
29
frontend/src/common/prettier/plugins/java/index.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import options from "./options.js";
|
||||||
|
import parser from "./parser.js";
|
||||||
|
import printer from "./printer.js";
|
||||||
|
export default {
|
||||||
|
languages: [
|
||||||
|
{
|
||||||
|
name: "Java",
|
||||||
|
parsers: ["java"],
|
||||||
|
group: "Java",
|
||||||
|
tmScope: "source.java",
|
||||||
|
aceMode: "java",
|
||||||
|
codemirrorMode: "clike",
|
||||||
|
codemirrorMimeType: "text/x-java",
|
||||||
|
extensions: [".java"],
|
||||||
|
linguistLanguageId: 181,
|
||||||
|
vscodeLanguageIds: ["java"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
parsers: {
|
||||||
|
java: parser
|
||||||
|
},
|
||||||
|
printers: {
|
||||||
|
java: printer
|
||||||
|
},
|
||||||
|
options,
|
||||||
|
defaultOptions: {
|
||||||
|
arrowParens: "avoid"
|
||||||
|
}
|
||||||
|
};
|
||||||
43
frontend/src/common/prettier/plugins/java/options.d.ts
vendored
Normal file
43
frontend/src/common/prettier/plugins/java/options.d.ts
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
declare const _default: {
|
||||||
|
entrypoint: {
|
||||||
|
type: "choice";
|
||||||
|
category: string;
|
||||||
|
default: string;
|
||||||
|
choices: {
|
||||||
|
value: string;
|
||||||
|
description: string;
|
||||||
|
}[];
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
arrowParens: {
|
||||||
|
type: "choice";
|
||||||
|
category: string;
|
||||||
|
default: string;
|
||||||
|
choices: {
|
||||||
|
value: string;
|
||||||
|
description: string;
|
||||||
|
}[];
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
trailingComma: {
|
||||||
|
type: "choice";
|
||||||
|
category: string;
|
||||||
|
default: string;
|
||||||
|
choices: {
|
||||||
|
value: string;
|
||||||
|
description: string;
|
||||||
|
}[];
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
experimentalOperatorPosition: {
|
||||||
|
type: "choice";
|
||||||
|
category: string;
|
||||||
|
default: string;
|
||||||
|
choices: {
|
||||||
|
value: string;
|
||||||
|
description: string;
|
||||||
|
}[];
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
284
frontend/src/common/prettier/plugins/java/options.js
Normal file
284
frontend/src/common/prettier/plugins/java/options.js
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
export default {
|
||||||
|
entrypoint: {
|
||||||
|
type: "choice",
|
||||||
|
category: "Global",
|
||||||
|
default: "compilationUnit",
|
||||||
|
// sed -nr 's/.*\.RULE\(([^,]+),.*/\1/p' $(ls path/to/java-parser/rules/folder/*)
|
||||||
|
choices: [
|
||||||
|
{ value: "arrayInitializer", description: "" },
|
||||||
|
{ value: "variableInitializerList", description: "" },
|
||||||
|
{ value: "block", description: "" },
|
||||||
|
{ value: "blockStatements", description: "" },
|
||||||
|
{ value: "blockStatement", description: "" },
|
||||||
|
{ value: "localVariableDeclarationStatement", description: "" },
|
||||||
|
{ value: "localVariableDeclaration", description: "" },
|
||||||
|
{ value: "localVariableType", description: "" },
|
||||||
|
{ value: "statement", description: "" },
|
||||||
|
{ value: "statementWithoutTrailingSubstatement", description: "" },
|
||||||
|
{ value: "emptyStatement", description: "" },
|
||||||
|
{ value: "labeledStatement", description: "" },
|
||||||
|
{ value: "expressionStatement", description: "" },
|
||||||
|
{ value: "statementExpression", description: "" },
|
||||||
|
{ value: "ifStatement", description: "" },
|
||||||
|
{ value: "assertStatement", description: "" },
|
||||||
|
{ value: "switchStatement", description: "" },
|
||||||
|
{ value: "switchBlock", description: "" },
|
||||||
|
{ value: "switchBlockStatementGroup", description: "" },
|
||||||
|
{ value: "switchLabel", description: "" },
|
||||||
|
{ value: "switchRule", description: "" },
|
||||||
|
{ value: "caseConstant", description: "" },
|
||||||
|
{ value: "casePattern", description: "" },
|
||||||
|
{ value: "whileStatement", description: "" },
|
||||||
|
{ value: "doStatement", description: "" },
|
||||||
|
{ value: "forStatement", description: "" },
|
||||||
|
{ value: "basicForStatement", description: "" },
|
||||||
|
{ value: "forInit", description: "" },
|
||||||
|
{ value: "forUpdate", description: "" },
|
||||||
|
{ value: "statementExpressionList", description: "" },
|
||||||
|
{ value: "enhancedForStatement", description: "" },
|
||||||
|
{ value: "breakStatement", description: "" },
|
||||||
|
{ value: "continueStatement", description: "" },
|
||||||
|
{ value: "returnStatement", description: "" },
|
||||||
|
{ value: "throwStatement", description: "" },
|
||||||
|
{ value: "synchronizedStatement", description: "" },
|
||||||
|
{ value: "tryStatement", description: "" },
|
||||||
|
{ value: "catches", description: "" },
|
||||||
|
{ value: "catchClause", description: "" },
|
||||||
|
{ value: "catchFormalParameter", description: "" },
|
||||||
|
{ value: "catchType", description: "" },
|
||||||
|
{ value: "finally", description: "" },
|
||||||
|
{ value: "tryWithResourcesStatement", description: "" },
|
||||||
|
{ value: "resourceSpecification", description: "" },
|
||||||
|
{ value: "resourceList", description: "" },
|
||||||
|
{ value: "resource", description: "" },
|
||||||
|
{ value: "yieldStatement", description: "" },
|
||||||
|
{ value: "variableAccess", description: "" },
|
||||||
|
{ value: "classDeclaration", description: "" },
|
||||||
|
{ value: "normalClassDeclaration", description: "" },
|
||||||
|
{ value: "classModifier", description: "" },
|
||||||
|
{ value: "typeParameters", description: "" },
|
||||||
|
{ value: "typeParameterList", description: "" },
|
||||||
|
{ value: "classExtends", description: "" },
|
||||||
|
{ value: "classImplements", description: "" },
|
||||||
|
{ value: "interfaceTypeList", description: "" },
|
||||||
|
{ value: "classPermits", description: "" },
|
||||||
|
{ value: "classBody", description: "" },
|
||||||
|
{ value: "classBodyDeclaration", description: "" },
|
||||||
|
{ value: "classMemberDeclaration", description: "" },
|
||||||
|
{ value: "fieldDeclaration", description: "" },
|
||||||
|
{ value: "fieldModifier", description: "" },
|
||||||
|
{ value: "variableDeclaratorList", description: "" },
|
||||||
|
{ value: "variableDeclarator", description: "" },
|
||||||
|
{ value: "variableDeclaratorId", description: "" },
|
||||||
|
{ value: "variableInitializer", description: "" },
|
||||||
|
{ value: "unannType", description: "" },
|
||||||
|
{ value: "unannPrimitiveTypeWithOptionalDimsSuffix", description: "" },
|
||||||
|
{ value: "unannPrimitiveType", description: "" },
|
||||||
|
{ value: "unannReferenceType", description: "" },
|
||||||
|
{ value: "unannClassOrInterfaceType", description: "" },
|
||||||
|
{ value: "unannClassType", description: "" },
|
||||||
|
{ value: "unannInterfaceType", description: "" },
|
||||||
|
{ value: "unannTypeVariable", description: "" },
|
||||||
|
{ value: "methodDeclaration", description: "" },
|
||||||
|
{ value: "methodModifier", description: "" },
|
||||||
|
{ value: "methodHeader", description: "" },
|
||||||
|
{ value: "result", description: "" },
|
||||||
|
{ value: "methodDeclarator", description: "" },
|
||||||
|
{ value: "receiverParameter", description: "" },
|
||||||
|
{ value: "formalParameterList", description: "" },
|
||||||
|
{ value: "formalParameter", description: "" },
|
||||||
|
{ value: "variableParaRegularParameter", description: "" },
|
||||||
|
{ value: "variableArityParameter", description: "" },
|
||||||
|
{ value: "variableModifier", description: "" },
|
||||||
|
{ value: "throws", description: "" },
|
||||||
|
{ value: "exceptionTypeList", description: "" },
|
||||||
|
{ value: "exceptionType", description: "" },
|
||||||
|
{ value: "methodBody", description: "" },
|
||||||
|
{ value: "instanceInitializer", description: "" },
|
||||||
|
{ value: "staticInitializer", description: "" },
|
||||||
|
{ value: "constructorDeclaration", description: "" },
|
||||||
|
{ value: "constructorModifier", description: "" },
|
||||||
|
{ value: "constructorDeclarator", description: "" },
|
||||||
|
{ value: "simpleTypeName", description: "" },
|
||||||
|
{ value: "constructorBody", description: "" },
|
||||||
|
{ value: "explicitConstructorInvocation", description: "" },
|
||||||
|
{ value: "unqualifiedExplicitConstructorInvocation", description: "" },
|
||||||
|
{ value: "qualifiedExplicitConstructorInvocation", description: "" },
|
||||||
|
{ value: "enumDeclaration", description: "" },
|
||||||
|
{ value: "enumBody", description: "" },
|
||||||
|
{ value: "enumConstantList", description: "" },
|
||||||
|
{ value: "enumConstant", description: "" },
|
||||||
|
{ value: "enumConstantModifier", description: "" },
|
||||||
|
{ value: "enumBodyDeclarations", description: "" },
|
||||||
|
{ value: "recordDeclaration", description: "" },
|
||||||
|
{ value: "recordHeader", description: "" },
|
||||||
|
{ value: "recordComponentList", description: "" },
|
||||||
|
{ value: "recordComponent", description: "" },
|
||||||
|
{ value: "variableArityRecordComponent", description: "" },
|
||||||
|
{ value: "recordComponentModifier", description: "" },
|
||||||
|
{ value: "recordBody", description: "" },
|
||||||
|
{ value: "recordBodyDeclaration", description: "" },
|
||||||
|
{ value: "compactConstructorDeclaration", description: "" },
|
||||||
|
{ value: "isDims", description: "" },
|
||||||
|
{ value: "expression", description: "" },
|
||||||
|
{ value: "lambdaExpression", description: "" },
|
||||||
|
{ value: "lambdaParameters", description: "" },
|
||||||
|
{ value: "lambdaParametersWithBraces", description: "" },
|
||||||
|
{ value: "lambdaParameterList", description: "" },
|
||||||
|
{ value: "conciseLambdaParameterList", description: "" },
|
||||||
|
{ value: "normalLambdaParameterList", description: "" },
|
||||||
|
{ value: "normalLambdaParameter", description: "" },
|
||||||
|
{ value: "regularLambdaParameter", description: "" },
|
||||||
|
{ value: "lambdaParameterType", description: "" },
|
||||||
|
{ value: "conciseLambdaParameter", description: "" },
|
||||||
|
{ value: "lambdaBody", description: "" },
|
||||||
|
{ value: "conditionalExpression", description: "" },
|
||||||
|
{ value: "binaryExpression", description: "" },
|
||||||
|
{ value: "unaryExpression", description: "" },
|
||||||
|
{ value: "unaryExpressionNotPlusMinus", description: "" },
|
||||||
|
{ value: "primary", description: "" },
|
||||||
|
{ value: "primaryPrefix", description: "" },
|
||||||
|
{ value: "primarySuffix", description: "" },
|
||||||
|
{ value: "fqnOrRefType", description: "" },
|
||||||
|
{ value: "fqnOrRefTypePartRest", description: "" },
|
||||||
|
{ value: "fqnOrRefTypePartCommon", description: "" },
|
||||||
|
{ value: "fqnOrRefTypePartFirst", description: "" },
|
||||||
|
{ value: "parenthesisExpression", description: "" },
|
||||||
|
{ value: "castExpression", description: "" },
|
||||||
|
{ value: "primitiveCastExpression", description: "" },
|
||||||
|
{ value: "referenceTypeCastExpression", description: "" },
|
||||||
|
{ value: "newExpression", description: "" },
|
||||||
|
{ value: "unqualifiedClassInstanceCreationExpression", description: "" },
|
||||||
|
{ value: "classOrInterfaceTypeToInstantiate", description: "" },
|
||||||
|
{ value: "typeArgumentsOrDiamond", description: "" },
|
||||||
|
{ value: "diamond", description: "" },
|
||||||
|
{ value: "methodInvocationSuffix", description: "" },
|
||||||
|
{ value: "argumentList", description: "" },
|
||||||
|
{ value: "arrayCreationExpression", description: "" },
|
||||||
|
{
|
||||||
|
value: "arrayCreationExpressionWithoutInitializerSuffix",
|
||||||
|
description: ""
|
||||||
|
},
|
||||||
|
{ value: "arrayCreationWithInitializerSuffix", description: "" },
|
||||||
|
{ value: "dimExprs", description: "" },
|
||||||
|
{ value: "dimExpr", description: "" },
|
||||||
|
{ value: "classLiteralSuffix", description: "" },
|
||||||
|
{ value: "arrayAccessSuffix", description: "" },
|
||||||
|
{ value: "methodReferenceSuffix", description: "" },
|
||||||
|
{ value: "templateArgument", description: "" },
|
||||||
|
{ value: "template", description: "" },
|
||||||
|
{ value: "stringTemplate", description: "" },
|
||||||
|
{ value: "textBlockTemplate", description: "" },
|
||||||
|
{ value: "embeddedExpression", description: "" },
|
||||||
|
{ value: "pattern", description: "" },
|
||||||
|
{ value: "typePattern", description: "" },
|
||||||
|
{ value: "recordPattern", description: "" },
|
||||||
|
{ value: "componentPatternList", description: "" },
|
||||||
|
{ value: "componentPattern", description: "" },
|
||||||
|
{ value: "matchAllPattern", description: "" },
|
||||||
|
{ value: "guard", description: "" },
|
||||||
|
{ value: "isRefTypeInMethodRef", description: "" },
|
||||||
|
{ value: "interfaceDeclaration", description: "" },
|
||||||
|
{ value: "normalInterfaceDeclaration", description: "" },
|
||||||
|
{ value: "interfaceModifier", description: "" },
|
||||||
|
{ value: "interfaceExtends", description: "" },
|
||||||
|
{ value: "interfacePermits", description: "" },
|
||||||
|
{ value: "interfaceBody", description: "" },
|
||||||
|
{ value: "interfaceMemberDeclaration", description: "" },
|
||||||
|
{ value: "constantDeclaration", description: "" },
|
||||||
|
{ value: "constantModifier", description: "" },
|
||||||
|
{ value: "interfaceMethodDeclaration", description: "" },
|
||||||
|
{ value: "interfaceMethodModifier", description: "" },
|
||||||
|
{ value: "annotationInterfaceDeclaration", description: "" },
|
||||||
|
{ value: "annotationInterfaceBody", description: "" },
|
||||||
|
{ value: "annotationInterfaceMemberDeclaration", description: "" },
|
||||||
|
{ value: "annotationInterfaceElementDeclaration", description: "" },
|
||||||
|
{ value: "annotationInterfaceElementModifier", description: "" },
|
||||||
|
{ value: "defaultValue", description: "" },
|
||||||
|
{ value: "annotation", description: "" },
|
||||||
|
{ value: "elementValuePairList", description: "" },
|
||||||
|
{ value: "elementValuePair", description: "" },
|
||||||
|
{ value: "elementValue", description: "" },
|
||||||
|
{ value: "elementValueArrayInitializer", description: "" },
|
||||||
|
{ value: "elementValueList", description: "" },
|
||||||
|
{ value: "literal", description: "" },
|
||||||
|
{ value: "integerLiteral", description: "" },
|
||||||
|
{ value: "floatingPointLiteral", description: "" },
|
||||||
|
{ value: "booleanLiteral", description: "" },
|
||||||
|
{ value: "shiftOperator", description: "" },
|
||||||
|
{ value: "moduleName", description: "" },
|
||||||
|
{ value: "packageName", description: "" },
|
||||||
|
{ value: "typeName", description: "" },
|
||||||
|
{ value: "expressionName", description: "" },
|
||||||
|
{ value: "methodName", description: "" },
|
||||||
|
{ value: "packageOrTypeName", description: "" },
|
||||||
|
{ value: "ambiguousName", description: "" },
|
||||||
|
{ value: "compilationUnit", description: "" },
|
||||||
|
{ value: "ordinaryCompilationUnit", description: "" },
|
||||||
|
{ value: "modularCompilationUnit", description: "" },
|
||||||
|
{ value: "packageDeclaration", description: "" },
|
||||||
|
{ value: "packageModifier", description: "" },
|
||||||
|
{ value: "importDeclaration", description: "" },
|
||||||
|
{ value: "typeDeclaration", description: "" },
|
||||||
|
{ value: "moduleDeclaration", description: "" },
|
||||||
|
{ value: "moduleDirective", description: "" },
|
||||||
|
{ value: "requiresModuleDirective", description: "" },
|
||||||
|
{ value: "exportsModuleDirective", description: "" },
|
||||||
|
{ value: "opensModuleDirective", description: "" },
|
||||||
|
{ value: "usesModuleDirective", description: "" },
|
||||||
|
{ value: "providesModuleDirective", description: "" },
|
||||||
|
{ value: "requiresModifier", description: "" },
|
||||||
|
{ value: "primitiveType", description: "" },
|
||||||
|
{ value: "numericType", description: "" },
|
||||||
|
{ value: "integralType", description: "" },
|
||||||
|
{ value: "floatingPointType", description: "" },
|
||||||
|
{ value: "referenceType", description: "" },
|
||||||
|
{ value: "classOrInterfaceType", description: "" },
|
||||||
|
{ value: "classType", description: "" },
|
||||||
|
{ value: "interfaceType", description: "" },
|
||||||
|
{ value: "typeVariable", description: "" },
|
||||||
|
{ value: "dims", description: "" },
|
||||||
|
{ value: "typeParameter", description: "" },
|
||||||
|
{ value: "typeParameterModifier", description: "" },
|
||||||
|
{ value: "typeBound", description: "" },
|
||||||
|
{ value: "additionalBound", description: "" },
|
||||||
|
{ value: "typeArguments", description: "" },
|
||||||
|
{ value: "typeArgumentList", description: "" },
|
||||||
|
{ value: "typeArgument", description: "" },
|
||||||
|
{ value: "wildcard", description: "" },
|
||||||
|
{ value: "wildcardBounds", description: "" }
|
||||||
|
],
|
||||||
|
description: "Prettify from the entrypoint, allowing to use prettier on snippet."
|
||||||
|
},
|
||||||
|
arrowParens: {
|
||||||
|
type: "choice",
|
||||||
|
category: "Java",
|
||||||
|
default: "always",
|
||||||
|
choices: [
|
||||||
|
{ value: "always", description: "" },
|
||||||
|
{ value: "avoid", description: "" }
|
||||||
|
],
|
||||||
|
description: "Include parentheses around a sole arrow function parameter."
|
||||||
|
},
|
||||||
|
trailingComma: {
|
||||||
|
type: "choice",
|
||||||
|
category: "Java",
|
||||||
|
default: "all",
|
||||||
|
choices: [
|
||||||
|
{ value: "all", description: "" },
|
||||||
|
{ value: "es5", description: "" },
|
||||||
|
{ value: "none", description: "" }
|
||||||
|
],
|
||||||
|
description: "Print trailing commas wherever possible when multi-line."
|
||||||
|
},
|
||||||
|
experimentalOperatorPosition: {
|
||||||
|
type: "choice",
|
||||||
|
category: "Java",
|
||||||
|
default: "end",
|
||||||
|
choices: [
|
||||||
|
{ value: "start", description: "" },
|
||||||
|
{ value: "end", description: "" }
|
||||||
|
],
|
||||||
|
description: "Where to print operators when binary expressions wrap lines."
|
||||||
|
}
|
||||||
|
};
|
||||||
9
frontend/src/common/prettier/plugins/java/parser.d.ts
vendored
Normal file
9
frontend/src/common/prettier/plugins/java/parser.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { type JavaNode, type JavaNonTerminal, type JavaParserOptions } from "./printers/helpers.js";
|
||||||
|
declare const _default: {
|
||||||
|
parse(text: string, options: JavaParserOptions): JavaNonTerminal;
|
||||||
|
astFormat: string;
|
||||||
|
hasPragma(text: string): boolean;
|
||||||
|
locStart(node: JavaNode): number;
|
||||||
|
locEnd(node: JavaNode): number;
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
24
frontend/src/common/prettier/plugins/java/parser.js
Normal file
24
frontend/src/common/prettier/plugins/java/parser.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { parse } from "java-parser";
|
||||||
|
import { determineFormatterOffOnRanges } from "./comments.js";
|
||||||
|
import { isTerminal } from "./printers/helpers.js";
|
||||||
|
export default {
|
||||||
|
parse(text, options) {
|
||||||
|
var _a;
|
||||||
|
const cst = parse(text, options.entrypoint);
|
||||||
|
(_a = cst.comments) === null || _a === void 0 ? void 0 : _a.forEach(comment => {
|
||||||
|
comment.value = comment.image;
|
||||||
|
});
|
||||||
|
determineFormatterOffOnRanges(cst);
|
||||||
|
return cst;
|
||||||
|
},
|
||||||
|
astFormat: "java",
|
||||||
|
hasPragma(text) {
|
||||||
|
return /^\/\*\*\n\s+\*\s@(format|prettier)\n\s+\*\//.test(text);
|
||||||
|
},
|
||||||
|
locStart(node) {
|
||||||
|
return isTerminal(node) ? node.startOffset : node.location.startOffset;
|
||||||
|
},
|
||||||
|
locEnd(node) {
|
||||||
|
return (isTerminal(node) ? node.endOffset : node.location.endOffset) + 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
18
frontend/src/common/prettier/plugins/java/printer.d.ts
vendored
Normal file
18
frontend/src/common/prettier/plugins/java/printer.d.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import type { AstPath } from "prettier";
|
||||||
|
import { canAttachComment, handleLineComment, handleRemainingComment } from "./comments.js";
|
||||||
|
import { type JavaNode } from "./printers/helpers.js";
|
||||||
|
declare const _default: {
|
||||||
|
print(path: DistributedAstPath<JavaNode>, options: import("prettier").ParserOptions<JavaNode>, print: (path: AstPath<JavaNode>) => import("prettier").Doc, args: unknown): import("prettier/doc.js").builders.Doc;
|
||||||
|
hasPrettierIgnore(path: AstPath<JavaNode>): boolean;
|
||||||
|
canAttachComment: typeof canAttachComment;
|
||||||
|
isBlockComment(node: JavaNode): boolean;
|
||||||
|
printComment(commentPath: AstPath<JavaNode>): string | import("prettier/doc.js").builders.Doc[];
|
||||||
|
getCommentChildNodes(node: JavaNode): any[];
|
||||||
|
handleComments: {
|
||||||
|
ownLine: typeof handleLineComment;
|
||||||
|
endOfLine: typeof handleLineComment;
|
||||||
|
remaining: typeof handleRemainingComment;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
|
type DistributedAstPath<T> = T extends any ? AstPath<T> : never;
|
||||||
40
frontend/src/common/prettier/plugins/java/printer.js
Normal file
40
frontend/src/common/prettier/plugins/java/printer.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { canAttachComment, handleLineComment, handleRemainingComment, isFullyBetweenFormatterOffOn } from "./comments.js";
|
||||||
|
import { isNonTerminal, isTerminal, printComment } from "./printers/helpers.js";
|
||||||
|
import { printerForNodeType } from "./printers/index.js";
|
||||||
|
export default {
|
||||||
|
print(path, options, print, args) {
|
||||||
|
return hasTerminal(path)
|
||||||
|
? path.node.image
|
||||||
|
: printerForNodeType(path.node.name)(path, print, options, args);
|
||||||
|
},
|
||||||
|
hasPrettierIgnore(path) {
|
||||||
|
var _a;
|
||||||
|
const { node } = path;
|
||||||
|
return (((_a = node.comments) === null || _a === void 0 ? void 0 : _a.some(({ image }) => /^(\/\/\s*prettier-ignore|\/\*\s*prettier-ignore\s*\*\/)$/.test(image))) === true ||
|
||||||
|
(canAttachComment(node) && isFullyBetweenFormatterOffOn(path)));
|
||||||
|
},
|
||||||
|
canAttachComment,
|
||||||
|
isBlockComment(node) {
|
||||||
|
return isTerminal(node) && node.tokenType.name === "TraditionalComment";
|
||||||
|
},
|
||||||
|
printComment(commentPath) {
|
||||||
|
const { node } = commentPath;
|
||||||
|
if (isNonTerminal(node) || node.tokenType.GROUP !== "comments") {
|
||||||
|
throw new Error(`Not a comment: ${JSON.stringify(node)}`);
|
||||||
|
}
|
||||||
|
return printComment(node);
|
||||||
|
},
|
||||||
|
getCommentChildNodes(node) {
|
||||||
|
return isNonTerminal(node)
|
||||||
|
? Object.values(node.children).flatMap(child => child)
|
||||||
|
: [];
|
||||||
|
},
|
||||||
|
handleComments: {
|
||||||
|
ownLine: handleLineComment,
|
||||||
|
endOfLine: handleLineComment,
|
||||||
|
remaining: handleRemainingComment
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function hasTerminal(path) {
|
||||||
|
return isTerminal(path.node);
|
||||||
|
}
|
||||||
9
frontend/src/common/prettier/plugins/java/printers/arrays.d.ts
vendored
Normal file
9
frontend/src/common/prettier/plugins/java/printers/arrays.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
declare const _default: {
|
||||||
|
arrayInitializer(path: import("prettier").AstPath<import("java-parser").ArrayInitializerCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn, options: import("./helpers.js").JavaParserOptions): import("prettier/doc.js").builders.Group | "{}";
|
||||||
|
variableInitializerList(path: import("prettier").AstPath<import("java-parser").VariableInitializerListCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): import("prettier/doc.js").builders.Doc[];
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { printArrayInitializer, printList } from "./helpers.js";
|
||||||
|
export default {
|
||||||
|
arrayInitializer(path, print, options) {
|
||||||
|
return printArrayInitializer(path, print, options, "variableInitializerList");
|
||||||
|
},
|
||||||
|
variableInitializerList(path, print) {
|
||||||
|
return printList(path, print, "variableInitializer");
|
||||||
|
}
|
||||||
|
};
|
||||||
117
frontend/src/common/prettier/plugins/java/printers/blocks-and-statements.d.ts
vendored
Normal file
117
frontend/src/common/prettier/plugins/java/printers/blocks-and-statements.d.ts
vendored
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import { printSingle } from "./helpers.js";
|
||||||
|
declare const _default: {
|
||||||
|
block(path: import("prettier").AstPath<import("java-parser").BlockCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Group | "{}" | (string | builders.Indent | builders.Hardline)[];
|
||||||
|
blockStatements(path: import("prettier").AstPath<import("java-parser").BlockStatementsCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
blockStatement: typeof printSingle;
|
||||||
|
localVariableDeclarationStatement(path: import("prettier").AstPath<import("java-parser").LocalVariableDeclarationStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
localVariableDeclaration(path: import("prettier").AstPath<import("java-parser").LocalVariableDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
localVariableType: typeof printSingle;
|
||||||
|
statement: typeof printSingle;
|
||||||
|
statementWithoutTrailingSubstatement: typeof printSingle;
|
||||||
|
emptyStatement(): string;
|
||||||
|
labeledStatement(path: import("prettier").AstPath<import("java-parser").LabeledStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
expressionStatement(path: import("prettier").AstPath<import("java-parser").ExpressionStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
statementExpression: typeof printSingle;
|
||||||
|
ifStatement(path: import("prettier").AstPath<import("java-parser").IfStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
assertStatement(path: import("prettier").AstPath<import("java-parser").AssertStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
switchStatement(path: import("prettier").AstPath<import("java-parser").SwitchStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
switchBlock(path: import("prettier").AstPath<import("java-parser").SwitchBlockCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Group | "{}" | (string | builders.Indent | builders.Hardline)[];
|
||||||
|
switchBlockStatementGroup(path: import("prettier").AstPath<import("java-parser").SwitchBlockStatementGroupCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
switchLabel(path: import("prettier").AstPath<import("java-parser").SwitchLabelCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): "default" | builders.Group | builders.Doc[];
|
||||||
|
switchRule(path: import("prettier").AstPath<import("java-parser").SwitchRuleCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
caseConstant: typeof printSingle;
|
||||||
|
casePattern: typeof printSingle;
|
||||||
|
whileStatement(path: import("prettier").AstPath<import("java-parser").WhileStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
doStatement(path: import("prettier").AstPath<import("java-parser").DoStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): (string | builders.Group | builders.Doc[])[];
|
||||||
|
forStatement: typeof printSingle;
|
||||||
|
basicForStatement(path: import("prettier").AstPath<import("java-parser").BasicForStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
forInit: typeof printSingle;
|
||||||
|
forUpdate: typeof printSingle;
|
||||||
|
statementExpressionList(path: import("prettier").AstPath<import("java-parser").StatementExpressionListCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Group;
|
||||||
|
enhancedForStatement(path: import("prettier").AstPath<import("java-parser").EnhancedForStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Group;
|
||||||
|
breakStatement(path: import("prettier").AstPath<import("java-parser").BreakStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[] | "break;";
|
||||||
|
continueStatement(path: import("prettier").AstPath<import("java-parser").ContinueStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[] | "continue;";
|
||||||
|
returnStatement(path: import("prettier").AstPath<import("java-parser").ReturnStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
throwStatement(path: import("prettier").AstPath<import("java-parser").ThrowStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
synchronizedStatement(path: import("prettier").AstPath<import("java-parser").SynchronizedStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
tryStatement(path: import("prettier").AstPath<import("java-parser").TryStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc;
|
||||||
|
catches(path: import("prettier").AstPath<import("java-parser").CatchesCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
catchClause(path: import("prettier").AstPath<import("java-parser").CatchClauseCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
catchFormalParameter(path: import("prettier").AstPath<import("java-parser").CatchFormalParameterCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
catchType(path: import("prettier").AstPath<import("java-parser").CatchTypeCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
finally(path: import("prettier").AstPath<import("java-parser").FinallyCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
tryWithResourcesStatement(path: import("prettier").AstPath<import("java-parser").TryWithResourcesStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
resourceSpecification(path: import("prettier").AstPath<import("java-parser").ResourceSpecificationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Group | "()";
|
||||||
|
resourceList(path: import("prettier").AstPath<import("java-parser").ResourceListCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
resource: typeof printSingle;
|
||||||
|
yieldStatement(path: import("prettier").AstPath<import("java-parser").YieldStatementCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
variableAccess: typeof printSingle;
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
@@ -0,0 +1,337 @@
|
|||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import { call, definedKeys, indentInParentheses, isBinaryExpression, isEmptyStatement, lineEndWithComments, lineStartWithComments, map, onlyDefinedKey, printBlock, printDanglingComments, printSingle, printWithModifiers } from "./helpers.js";
|
||||||
|
const { group, hardline, ifBreak, indent, join, line, softline } = builders;
|
||||||
|
export default {
|
||||||
|
block(path, print) {
|
||||||
|
const statements = path.node.children.blockStatements
|
||||||
|
? call(path, print, "blockStatements")
|
||||||
|
: [];
|
||||||
|
return printBlock(path, statements.length ? [statements] : []);
|
||||||
|
},
|
||||||
|
blockStatements(path, print) {
|
||||||
|
return join(hardline, map(path, statementPath => {
|
||||||
|
const { node, previous } = statementPath;
|
||||||
|
const statement = print(statementPath);
|
||||||
|
return previous &&
|
||||||
|
lineStartWithComments(node) > lineEndWithComments(previous) + 1
|
||||||
|
? [hardline, statement]
|
||||||
|
: statement;
|
||||||
|
}, "blockStatement").filter(doc => doc !== ""));
|
||||||
|
},
|
||||||
|
blockStatement: printSingle,
|
||||||
|
localVariableDeclarationStatement(path, print) {
|
||||||
|
return [call(path, print, "localVariableDeclaration"), ";"];
|
||||||
|
},
|
||||||
|
localVariableDeclaration(path, print) {
|
||||||
|
const declaration = join(" ", [
|
||||||
|
call(path, print, "localVariableType"),
|
||||||
|
call(path, print, "variableDeclaratorList")
|
||||||
|
]);
|
||||||
|
return printWithModifiers(path, print, "variableModifier", declaration);
|
||||||
|
},
|
||||||
|
localVariableType: printSingle,
|
||||||
|
statement: printSingle,
|
||||||
|
statementWithoutTrailingSubstatement: printSingle,
|
||||||
|
emptyStatement() {
|
||||||
|
return "";
|
||||||
|
},
|
||||||
|
labeledStatement(path, print) {
|
||||||
|
return [
|
||||||
|
call(path, print, "Identifier"),
|
||||||
|
": ",
|
||||||
|
call(path, print, "statement")
|
||||||
|
];
|
||||||
|
},
|
||||||
|
expressionStatement(path, print) {
|
||||||
|
return [call(path, print, "statementExpression"), ";"];
|
||||||
|
},
|
||||||
|
statementExpression: printSingle,
|
||||||
|
ifStatement(path, print) {
|
||||||
|
var _a;
|
||||||
|
const { children } = path.node;
|
||||||
|
const hasEmptyStatement = isEmptyStatement(children.statement[0]);
|
||||||
|
const statements = map(path, print, "statement");
|
||||||
|
const statement = [
|
||||||
|
"if ",
|
||||||
|
indentInParentheses(call(path, print, "expression")),
|
||||||
|
hasEmptyStatement ? ";" : [" ", statements[0]]
|
||||||
|
];
|
||||||
|
if (children.Else) {
|
||||||
|
const danglingComments = printDanglingComments(path);
|
||||||
|
if (danglingComments.length) {
|
||||||
|
statement.push(hardline, ...danglingComments, hardline);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const elseHasBlock = ((_a = children.statement[0].children
|
||||||
|
.statementWithoutTrailingSubstatement) === null || _a === void 0 ? void 0 : _a[0].children.block) !==
|
||||||
|
undefined;
|
||||||
|
statement.push(elseHasBlock ? " " : hardline);
|
||||||
|
}
|
||||||
|
const elseHasEmptyStatement = isEmptyStatement(children.statement[1]);
|
||||||
|
statement.push("else", elseHasEmptyStatement ? ";" : [" ", statements[1]]);
|
||||||
|
}
|
||||||
|
return statement;
|
||||||
|
},
|
||||||
|
assertStatement(path, print) {
|
||||||
|
return ["assert ", ...join([" : "], map(path, print, "expression")), ";"];
|
||||||
|
},
|
||||||
|
switchStatement(path, print) {
|
||||||
|
return join(" ", [
|
||||||
|
"switch",
|
||||||
|
indentInParentheses(call(path, print, "expression")),
|
||||||
|
call(path, print, "switchBlock")
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
switchBlock(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const caseKeys = definedKeys(children, [
|
||||||
|
"switchBlockStatementGroup",
|
||||||
|
"switchRule"
|
||||||
|
]);
|
||||||
|
const cases = caseKeys.length === 1 ? map(path, print, caseKeys[0]) : [];
|
||||||
|
return printBlock(path, cases);
|
||||||
|
},
|
||||||
|
switchBlockStatementGroup(path, print) {
|
||||||
|
var _a, _b;
|
||||||
|
const { children } = path.node;
|
||||||
|
const switchLabel = call(path, print, "switchLabel");
|
||||||
|
if (!children.blockStatements) {
|
||||||
|
return [switchLabel, ":"];
|
||||||
|
}
|
||||||
|
const blockStatements = call(path, print, "blockStatements");
|
||||||
|
const statements = children.blockStatements[0].children.blockStatement;
|
||||||
|
const onlyStatementIsBlock = statements.length === 1 &&
|
||||||
|
((_b = (_a = statements[0].children.statement) === null || _a === void 0 ? void 0 : _a[0].children.statementWithoutTrailingSubstatement) === null || _b === void 0 ? void 0 : _b[0].children.block) !== undefined;
|
||||||
|
return [
|
||||||
|
switchLabel,
|
||||||
|
":",
|
||||||
|
onlyStatementIsBlock
|
||||||
|
? [" ", blockStatements]
|
||||||
|
: indent([hardline, blockStatements])
|
||||||
|
];
|
||||||
|
},
|
||||||
|
switchLabel(path, print) {
|
||||||
|
var _a, _b;
|
||||||
|
const { children } = path.node;
|
||||||
|
if (!((_b = (_a = children.caseConstant) !== null && _a !== void 0 ? _a : children.casePattern) !== null && _b !== void 0 ? _b : children.Null)) {
|
||||||
|
return "default";
|
||||||
|
}
|
||||||
|
const values = [];
|
||||||
|
if (children.Null) {
|
||||||
|
values.push("null");
|
||||||
|
if (children.Default) {
|
||||||
|
values.push("default");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const valuesKey = onlyDefinedKey(children, [
|
||||||
|
"caseConstant",
|
||||||
|
"casePattern"
|
||||||
|
]);
|
||||||
|
values.push(...map(path, print, valuesKey));
|
||||||
|
}
|
||||||
|
const hasMultipleValues = values.length > 1;
|
||||||
|
const label = hasMultipleValues
|
||||||
|
? ["case", indent([line, ...join([",", line], values)])]
|
||||||
|
: ["case ", values[0]];
|
||||||
|
return children.guard
|
||||||
|
? [
|
||||||
|
group([...label, hasMultipleValues ? line : " "]),
|
||||||
|
call(path, print, "guard")
|
||||||
|
]
|
||||||
|
: group(label);
|
||||||
|
},
|
||||||
|
switchRule(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const bodyKey = onlyDefinedKey(children, [
|
||||||
|
"block",
|
||||||
|
"expression",
|
||||||
|
"throwStatement"
|
||||||
|
]);
|
||||||
|
const parts = [
|
||||||
|
call(path, print, "switchLabel"),
|
||||||
|
" -> ",
|
||||||
|
call(path, print, bodyKey)
|
||||||
|
];
|
||||||
|
if (children.Semicolon) {
|
||||||
|
parts.push(";");
|
||||||
|
}
|
||||||
|
return parts;
|
||||||
|
},
|
||||||
|
caseConstant: printSingle,
|
||||||
|
casePattern: printSingle,
|
||||||
|
whileStatement(path, print) {
|
||||||
|
const statement = call(path, print, "statement");
|
||||||
|
const hasEmptyStatement = isEmptyStatement(path.node.children.statement[0]);
|
||||||
|
return [
|
||||||
|
"while ",
|
||||||
|
indentInParentheses(call(path, print, "expression")),
|
||||||
|
...[hasEmptyStatement ? ";" : " ", statement]
|
||||||
|
];
|
||||||
|
},
|
||||||
|
doStatement(path, print) {
|
||||||
|
const hasEmptyStatement = isEmptyStatement(path.node.children.statement[0]);
|
||||||
|
return [
|
||||||
|
"do",
|
||||||
|
hasEmptyStatement ? ";" : [" ", call(path, print, "statement")],
|
||||||
|
" while ",
|
||||||
|
indentInParentheses(call(path, print, "expression")),
|
||||||
|
";"
|
||||||
|
];
|
||||||
|
},
|
||||||
|
forStatement: printSingle,
|
||||||
|
basicForStatement(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const danglingComments = printDanglingComments(path);
|
||||||
|
if (danglingComments.length) {
|
||||||
|
danglingComments.push(hardline);
|
||||||
|
}
|
||||||
|
const expressions = ["forInit", "expression", "forUpdate"].map(expressionKey => expressionKey in children ? call(path, print, expressionKey) : "");
|
||||||
|
const hasEmptyStatement = isEmptyStatement(children.statement[0]);
|
||||||
|
return [
|
||||||
|
...danglingComments,
|
||||||
|
"for ",
|
||||||
|
expressions.some(expression => expression !== "")
|
||||||
|
? indentInParentheses(join([";", line], expressions))
|
||||||
|
: "(;;)",
|
||||||
|
hasEmptyStatement ? ";" : [" ", call(path, print, "statement")]
|
||||||
|
];
|
||||||
|
},
|
||||||
|
forInit: printSingle,
|
||||||
|
forUpdate: printSingle,
|
||||||
|
statementExpressionList(path, print) {
|
||||||
|
return group(map(path, print, "statementExpression").map((expression, index) => index === 0 ? expression : [",", indent([line, expression])]));
|
||||||
|
},
|
||||||
|
enhancedForStatement(path, print) {
|
||||||
|
var _a;
|
||||||
|
const statementNode = path.node.children.statement[0];
|
||||||
|
const forStatement = [
|
||||||
|
printDanglingComments(path),
|
||||||
|
"for ",
|
||||||
|
"(",
|
||||||
|
call(path, print, "localVariableDeclaration"),
|
||||||
|
" : ",
|
||||||
|
call(path, print, "expression"),
|
||||||
|
")"
|
||||||
|
];
|
||||||
|
if (isEmptyStatement(statementNode)) {
|
||||||
|
forStatement.push(";");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const hasStatementBlock = ((_a = statementNode.children.statementWithoutTrailingSubstatement) === null || _a === void 0 ? void 0 : _a[0].children.block) !== undefined;
|
||||||
|
const statement = call(path, print, "statement");
|
||||||
|
forStatement.push(hasStatementBlock ? [" ", statement] : indent([line, statement]));
|
||||||
|
}
|
||||||
|
return group(forStatement);
|
||||||
|
},
|
||||||
|
breakStatement(path, print) {
|
||||||
|
return path.node.children.Identifier
|
||||||
|
? ["break ", call(path, print, "Identifier"), ";"]
|
||||||
|
: "break;";
|
||||||
|
},
|
||||||
|
continueStatement(path, print) {
|
||||||
|
return path.node.children.Identifier
|
||||||
|
? ["continue ", call(path, print, "Identifier"), ";"]
|
||||||
|
: "continue;";
|
||||||
|
},
|
||||||
|
returnStatement(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const statement = ["return"];
|
||||||
|
if (children.expression) {
|
||||||
|
statement.push(" ");
|
||||||
|
const expression = call(path, print, "expression");
|
||||||
|
if (isBinaryExpression(children.expression[0])) {
|
||||||
|
statement.push(group([
|
||||||
|
ifBreak("("),
|
||||||
|
indent([softline, expression]),
|
||||||
|
softline,
|
||||||
|
ifBreak(")")
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
statement.push(expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statement.push(";");
|
||||||
|
return statement;
|
||||||
|
},
|
||||||
|
throwStatement(path, print) {
|
||||||
|
return ["throw ", call(path, print, "expression"), ";"];
|
||||||
|
},
|
||||||
|
synchronizedStatement(path, print) {
|
||||||
|
return [
|
||||||
|
"synchronized ",
|
||||||
|
indentInParentheses(call(path, print, "expression")),
|
||||||
|
" ",
|
||||||
|
call(path, print, "block")
|
||||||
|
];
|
||||||
|
},
|
||||||
|
tryStatement(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
if (children.tryWithResourcesStatement) {
|
||||||
|
return call(path, print, "tryWithResourcesStatement");
|
||||||
|
}
|
||||||
|
const blocks = ["try", call(path, print, "block")];
|
||||||
|
if (children.catches) {
|
||||||
|
blocks.push(call(path, print, "catches"));
|
||||||
|
}
|
||||||
|
if (children.finally) {
|
||||||
|
blocks.push(call(path, print, "finally"));
|
||||||
|
}
|
||||||
|
return join(" ", blocks);
|
||||||
|
},
|
||||||
|
catches(path, print) {
|
||||||
|
return join(" ", map(path, print, "catchClause"));
|
||||||
|
},
|
||||||
|
catchClause(path, print) {
|
||||||
|
return [
|
||||||
|
"catch ",
|
||||||
|
indentInParentheses(call(path, print, "catchFormalParameter")),
|
||||||
|
" ",
|
||||||
|
call(path, print, "block")
|
||||||
|
];
|
||||||
|
},
|
||||||
|
catchFormalParameter(path, print) {
|
||||||
|
return join(" ", [
|
||||||
|
...map(path, print, "variableModifier"),
|
||||||
|
call(path, print, "catchType"),
|
||||||
|
call(path, print, "variableDeclaratorId")
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
catchType(path, print) {
|
||||||
|
return join([line, "| "], [call(path, print, "unannClassType"), ...map(path, print, "classType")]);
|
||||||
|
},
|
||||||
|
finally(path, print) {
|
||||||
|
return ["finally ", call(path, print, "block")];
|
||||||
|
},
|
||||||
|
tryWithResourcesStatement(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const blocks = [
|
||||||
|
"try",
|
||||||
|
call(path, print, "resourceSpecification"),
|
||||||
|
call(path, print, "block")
|
||||||
|
];
|
||||||
|
if (children.catches) {
|
||||||
|
blocks.push(call(path, print, "catches"));
|
||||||
|
}
|
||||||
|
if (children.finally) {
|
||||||
|
blocks.push(call(path, print, "finally"));
|
||||||
|
}
|
||||||
|
return join(" ", blocks);
|
||||||
|
},
|
||||||
|
resourceSpecification(path, print) {
|
||||||
|
const resources = [call(path, print, "resourceList")];
|
||||||
|
if (path.node.children.Semicolon) {
|
||||||
|
resources.push(ifBreak(";"));
|
||||||
|
}
|
||||||
|
return indentInParentheses(resources);
|
||||||
|
},
|
||||||
|
resourceList(path, print) {
|
||||||
|
return join([";", line], map(path, print, "resource"));
|
||||||
|
},
|
||||||
|
resource: printSingle,
|
||||||
|
yieldStatement(path, print) {
|
||||||
|
return ["yield ", call(path, print, "expression"), ";"];
|
||||||
|
},
|
||||||
|
variableAccess: printSingle
|
||||||
|
};
|
||||||
157
frontend/src/common/prettier/plugins/java/printers/classes.d.ts
vendored
Normal file
157
frontend/src/common/prettier/plugins/java/printers/classes.d.ts
vendored
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
import type { ClassBodyCstNode, EnumBodyDeclarationsCstNode } from "java-parser";
|
||||||
|
import type { AstPath } from "prettier";
|
||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import { printClassPermits, printClassType, printSingle, type JavaPrintFn } from "./helpers.js";
|
||||||
|
declare const _default: {
|
||||||
|
classDeclaration(path: AstPath<import("java-parser").ClassDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
normalClassDeclaration(path: AstPath<import("java-parser").NormalClassDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
classModifier: typeof printSingle;
|
||||||
|
typeParameters(path: AstPath<import("java-parser").TypeParametersCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Group;
|
||||||
|
typeParameterList(path: AstPath<import("java-parser").TypeParameterListCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
classExtends(path: AstPath<import("java-parser").ClassExtendsCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
classImplements(path: AstPath<import("java-parser").ClassImplementsCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Group;
|
||||||
|
classPermits: typeof printClassPermits;
|
||||||
|
interfaceTypeList(path: AstPath<import("java-parser").InterfaceTypeListCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Group;
|
||||||
|
classBody(path: AstPath<ClassBodyCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Group | "{}" | (string | builders.Indent | builders.Hardline)[];
|
||||||
|
classBodyDeclaration: typeof printSingle;
|
||||||
|
classMemberDeclaration(path: AstPath<import("java-parser").ClassMemberDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc;
|
||||||
|
fieldDeclaration(path: AstPath<import("java-parser").FieldDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
fieldModifier: typeof printSingle;
|
||||||
|
variableDeclaratorList(path: AstPath<import("java-parser").VariableDeclaratorListCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Group | builders.Doc[];
|
||||||
|
variableDeclarator(path: AstPath<import("java-parser").VariableDeclaratorCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc;
|
||||||
|
variableDeclaratorId(path: AstPath<import("java-parser").VariableDeclaratorIdCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc;
|
||||||
|
variableInitializer: typeof printSingle;
|
||||||
|
unannType: typeof printSingle;
|
||||||
|
unannPrimitiveTypeWithOptionalDimsSuffix(path: AstPath<import("java-parser").UnannPrimitiveTypeWithOptionalDimsSuffixCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc;
|
||||||
|
unannPrimitiveType: typeof printSingle;
|
||||||
|
unannReferenceType(path: AstPath<import("java-parser").UnannReferenceTypeCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc;
|
||||||
|
unannClassOrInterfaceType: typeof printSingle;
|
||||||
|
unannClassType: typeof printClassType;
|
||||||
|
unannInterfaceType: typeof printSingle;
|
||||||
|
unannTypeVariable: typeof printSingle;
|
||||||
|
methodDeclaration(path: AstPath<import("java-parser").MethodDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
methodModifier: typeof printSingle;
|
||||||
|
methodHeader(path: AstPath<import("java-parser").MethodHeaderCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Group;
|
||||||
|
result: typeof printSingle;
|
||||||
|
methodDeclarator(path: AstPath<import("java-parser").MethodDeclaratorCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
receiverParameter(path: AstPath<import("java-parser").ReceiverParameterCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
formalParameterList(path: AstPath<import("java-parser").FormalParameterListCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
formalParameter: typeof printSingle;
|
||||||
|
variableParaRegularParameter(path: AstPath<import("java-parser").VariableParaRegularParameterCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
variableArityParameter(path: AstPath<import("java-parser").VariableArityParameterCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
variableModifier: typeof printSingle;
|
||||||
|
throws(path: AstPath<import("java-parser").ThrowsCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
exceptionTypeList(path: AstPath<import("java-parser").ExceptionTypeListCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
exceptionType: typeof printSingle;
|
||||||
|
methodBody: typeof printSingle;
|
||||||
|
instanceInitializer: typeof printSingle;
|
||||||
|
staticInitializer(path: AstPath<import("java-parser").StaticInitializerCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
constructorDeclaration(path: AstPath<import("java-parser").ConstructorDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
constructorModifier: typeof printSingle;
|
||||||
|
constructorDeclarator(path: AstPath<import("java-parser").ConstructorDeclaratorCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
simpleTypeName: typeof printSingle;
|
||||||
|
constructorBody(path: AstPath<import("java-parser").ConstructorBodyCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Group | "{}" | (string | builders.Indent | builders.Hardline)[];
|
||||||
|
explicitConstructorInvocation: typeof printSingle;
|
||||||
|
unqualifiedExplicitConstructorInvocation(path: AstPath<import("java-parser").UnqualifiedExplicitConstructorInvocationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
qualifiedExplicitConstructorInvocation(path: AstPath<import("java-parser").QualifiedExplicitConstructorInvocationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
enumDeclaration(path: AstPath<import("java-parser").EnumDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
enumBody(path: AstPath<import("java-parser").EnumBodyCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn, options: import("./helpers.js").JavaParserOptions): builders.Group | "{}" | (string | builders.Indent | builders.Hardline)[];
|
||||||
|
enumConstantList(path: AstPath<import("java-parser").EnumConstantListCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
enumConstant(path: AstPath<import("java-parser").EnumConstantCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
enumConstantModifier: typeof printSingle;
|
||||||
|
enumBodyDeclarations(path: AstPath<EnumBodyDeclarationsCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
recordDeclaration(path: AstPath<import("java-parser").RecordDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
recordHeader(path: AstPath<import("java-parser").RecordHeaderCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Group | "()";
|
||||||
|
recordComponentList(path: AstPath<import("java-parser").RecordComponentListCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
recordComponent(path: AstPath<import("java-parser").RecordComponentCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Group;
|
||||||
|
variableArityRecordComponent(path: AstPath<import("java-parser").VariableArityRecordComponentCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
recordComponentModifier: typeof printSingle;
|
||||||
|
recordBody(path: AstPath<import("java-parser").RecordBodyCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Group | "{}" | (string | builders.Indent | builders.Hardline)[];
|
||||||
|
recordBodyDeclaration: typeof printSingle;
|
||||||
|
compactConstructorDeclaration(path: AstPath<import("java-parser").CompactConstructorDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
446
frontend/src/common/prettier/plugins/java/printers/classes.js
Normal file
446
frontend/src/common/prettier/plugins/java/printers/classes.js
Normal file
@@ -0,0 +1,446 @@
|
|||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import { call, each, hasDeclarationAnnotations, hasLeadingComments, indentInParentheses, isBinaryExpression, lineEndWithComments, lineStartWithComments, map, onlyDefinedKey, printBlock, printClassPermits, printClassType, printDanglingComments, printList, printSingle, printWithModifiers } from "./helpers.js";
|
||||||
|
const { group, hardline, indent, indentIfBreak, join, line, softline } = builders;
|
||||||
|
export default {
|
||||||
|
classDeclaration(path, print) {
|
||||||
|
const declarationKey = onlyDefinedKey(path.node.children, [
|
||||||
|
"enumDeclaration",
|
||||||
|
"normalClassDeclaration",
|
||||||
|
"recordDeclaration"
|
||||||
|
]);
|
||||||
|
const declaration = call(path, print, declarationKey);
|
||||||
|
return printWithModifiers(path, print, "classModifier", declaration, true);
|
||||||
|
},
|
||||||
|
normalClassDeclaration(path, print) {
|
||||||
|
const { classExtends, classImplements, classPermits, typeParameters } = path.node.children;
|
||||||
|
const header = ["class ", call(path, print, "typeIdentifier")];
|
||||||
|
if (typeParameters) {
|
||||||
|
header.push(call(path, print, "typeParameters"));
|
||||||
|
}
|
||||||
|
if (classExtends) {
|
||||||
|
header.push(indent([line, call(path, print, "classExtends")]));
|
||||||
|
}
|
||||||
|
if (classImplements) {
|
||||||
|
header.push(indent([line, call(path, print, "classImplements")]));
|
||||||
|
}
|
||||||
|
if (classPermits) {
|
||||||
|
header.push(indent([line, call(path, print, "classPermits")]));
|
||||||
|
}
|
||||||
|
return [group(header), " ", call(path, print, "classBody")];
|
||||||
|
},
|
||||||
|
classModifier: printSingle,
|
||||||
|
typeParameters(path, print) {
|
||||||
|
return group([
|
||||||
|
"<",
|
||||||
|
indent([softline, call(path, print, "typeParameterList")]),
|
||||||
|
softline,
|
||||||
|
">"
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
typeParameterList(path, print) {
|
||||||
|
return printList(path, print, "typeParameter");
|
||||||
|
},
|
||||||
|
classExtends(path, print) {
|
||||||
|
return ["extends ", call(path, print, "classType")];
|
||||||
|
},
|
||||||
|
classImplements(path, print) {
|
||||||
|
return group([
|
||||||
|
"implements",
|
||||||
|
indent([line, call(path, print, "interfaceTypeList")])
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
classPermits: printClassPermits,
|
||||||
|
interfaceTypeList(path, print) {
|
||||||
|
return group(printList(path, print, "interfaceType"));
|
||||||
|
},
|
||||||
|
classBody(path, print) {
|
||||||
|
return printBlock(path, printClassBodyDeclarations(path, print));
|
||||||
|
},
|
||||||
|
classBodyDeclaration: printSingle,
|
||||||
|
classMemberDeclaration(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
return children.Semicolon
|
||||||
|
? ""
|
||||||
|
: call(path, print, onlyDefinedKey(children));
|
||||||
|
},
|
||||||
|
fieldDeclaration(path, print) {
|
||||||
|
const declaration = [
|
||||||
|
call(path, print, "unannType"),
|
||||||
|
" ",
|
||||||
|
call(path, print, "variableDeclaratorList"),
|
||||||
|
";"
|
||||||
|
];
|
||||||
|
return printWithModifiers(path, print, "fieldModifier", declaration);
|
||||||
|
},
|
||||||
|
fieldModifier: printSingle,
|
||||||
|
variableDeclaratorList(path, print) {
|
||||||
|
var _a;
|
||||||
|
const declarators = map(path, print, "variableDeclarator");
|
||||||
|
return declarators.length > 1 &&
|
||||||
|
path.node.children.variableDeclarator.some(({ children }) => children.Equals)
|
||||||
|
? group(indent(join([",", line], declarators)), {
|
||||||
|
shouldBreak: ((_a = path.getNode(4)) === null || _a === void 0 ? void 0 : _a.name) !== "forInit"
|
||||||
|
})
|
||||||
|
: join(", ", declarators);
|
||||||
|
},
|
||||||
|
variableDeclarator(path, print) {
|
||||||
|
var _a, _b;
|
||||||
|
const { children } = path.node;
|
||||||
|
const variableInitializer = (_a = children.variableInitializer) === null || _a === void 0 ? void 0 : _a[0];
|
||||||
|
const declaratorId = call(path, print, "variableDeclaratorId");
|
||||||
|
if (!variableInitializer) {
|
||||||
|
return declaratorId;
|
||||||
|
}
|
||||||
|
const expression = (_b = variableInitializer.children.expression) === null || _b === void 0 ? void 0 : _b[0];
|
||||||
|
const declarator = [declaratorId, " ", call(path, print, "Equals")];
|
||||||
|
const initializer = call(path, print, "variableInitializer");
|
||||||
|
if (hasLeadingComments(variableInitializer) ||
|
||||||
|
(expression && isBinaryExpression(expression))) {
|
||||||
|
declarator.push(group(indent([line, initializer])));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const groupId = Symbol("assignment");
|
||||||
|
declarator.push(group(indent(line), { id: groupId }), indentIfBreak(initializer, { groupId }));
|
||||||
|
}
|
||||||
|
return group(declarator);
|
||||||
|
},
|
||||||
|
variableDeclaratorId(path, print) {
|
||||||
|
const { dims, Underscore } = path.node.children;
|
||||||
|
if (Underscore) {
|
||||||
|
return "_";
|
||||||
|
}
|
||||||
|
const identifier = call(path, print, "Identifier");
|
||||||
|
return dims ? [identifier, call(path, print, "dims")] : identifier;
|
||||||
|
},
|
||||||
|
variableInitializer: printSingle,
|
||||||
|
unannType: printSingle,
|
||||||
|
unannPrimitiveTypeWithOptionalDimsSuffix(path, print) {
|
||||||
|
const type = call(path, print, "unannPrimitiveType");
|
||||||
|
return path.node.children.dims ? [type, call(path, print, "dims")] : type;
|
||||||
|
},
|
||||||
|
unannPrimitiveType: printSingle,
|
||||||
|
unannReferenceType(path, print) {
|
||||||
|
const type = call(path, print, "unannClassOrInterfaceType");
|
||||||
|
return path.node.children.dims ? [type, call(path, print, "dims")] : type;
|
||||||
|
},
|
||||||
|
unannClassOrInterfaceType: printSingle,
|
||||||
|
unannClassType: printClassType,
|
||||||
|
unannInterfaceType: printSingle,
|
||||||
|
unannTypeVariable: printSingle,
|
||||||
|
methodDeclaration(path, print) {
|
||||||
|
const declaration = [
|
||||||
|
call(path, print, "methodHeader"),
|
||||||
|
path.node.children.methodBody[0].children.Semicolon ? "" : " ",
|
||||||
|
call(path, print, "methodBody")
|
||||||
|
];
|
||||||
|
return printWithModifiers(path, print, "methodModifier", declaration);
|
||||||
|
},
|
||||||
|
methodModifier: printSingle,
|
||||||
|
methodHeader(path, print) {
|
||||||
|
const { typeParameters, annotation, throws } = path.node.children;
|
||||||
|
const header = [];
|
||||||
|
if (typeParameters) {
|
||||||
|
header.push(call(path, print, "typeParameters"));
|
||||||
|
}
|
||||||
|
if (annotation) {
|
||||||
|
header.push(join(line, map(path, print, "annotation")));
|
||||||
|
}
|
||||||
|
header.push(call(path, print, "result"), call(path, print, "methodDeclarator"));
|
||||||
|
return throws
|
||||||
|
? group([
|
||||||
|
...join(" ", header),
|
||||||
|
group(indent([line, call(path, print, "throws")]))
|
||||||
|
])
|
||||||
|
: group(join(" ", header));
|
||||||
|
},
|
||||||
|
result: printSingle,
|
||||||
|
methodDeclarator(path, print) {
|
||||||
|
const { dims, formalParameterList, receiverParameter } = path.node.children;
|
||||||
|
const declarator = [call(path, print, "Identifier")];
|
||||||
|
const parameters = [];
|
||||||
|
if (receiverParameter) {
|
||||||
|
parameters.push(call(path, print, "receiverParameter"));
|
||||||
|
}
|
||||||
|
if (formalParameterList) {
|
||||||
|
parameters.push(call(path, print, "formalParameterList"));
|
||||||
|
}
|
||||||
|
const items = parameters.length
|
||||||
|
? join([",", line], parameters)
|
||||||
|
: printDanglingComments(path);
|
||||||
|
declarator.push(items.length ? indentInParentheses(items) : "()");
|
||||||
|
if (dims) {
|
||||||
|
declarator.push(call(path, print, "dims"));
|
||||||
|
}
|
||||||
|
return declarator;
|
||||||
|
},
|
||||||
|
receiverParameter(path, print) {
|
||||||
|
return join(" ", [
|
||||||
|
...map(path, print, "annotation"),
|
||||||
|
call(path, print, "unannType"),
|
||||||
|
path.node.children.Identifier
|
||||||
|
? [call(path, print, "Identifier"), ".this"]
|
||||||
|
: "this"
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
formalParameterList(path, print) {
|
||||||
|
return printList(path, print, "formalParameter");
|
||||||
|
},
|
||||||
|
formalParameter: printSingle,
|
||||||
|
variableParaRegularParameter(path, print) {
|
||||||
|
return join(" ", [
|
||||||
|
...map(path, print, "variableModifier"),
|
||||||
|
call(path, print, "unannType"),
|
||||||
|
call(path, print, "variableDeclaratorId")
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
variableArityParameter(path, print) {
|
||||||
|
const type = join(" ", [
|
||||||
|
...map(path, print, "variableModifier"),
|
||||||
|
call(path, print, "unannType"),
|
||||||
|
...map(path, print, "annotation")
|
||||||
|
]);
|
||||||
|
return [type, "... ", call(path, print, "Identifier")];
|
||||||
|
},
|
||||||
|
variableModifier: printSingle,
|
||||||
|
throws(path, print) {
|
||||||
|
return ["throws ", call(path, print, "exceptionTypeList")];
|
||||||
|
},
|
||||||
|
exceptionTypeList(path, print) {
|
||||||
|
return join(", ", map(path, print, "exceptionType"));
|
||||||
|
},
|
||||||
|
exceptionType: printSingle,
|
||||||
|
methodBody: printSingle,
|
||||||
|
instanceInitializer: printSingle,
|
||||||
|
staticInitializer(path, print) {
|
||||||
|
return ["static ", call(path, print, "block")];
|
||||||
|
},
|
||||||
|
constructorDeclaration(path, print) {
|
||||||
|
const declaration = [call(path, print, "constructorDeclarator")];
|
||||||
|
if (path.node.children.throws) {
|
||||||
|
declaration.push(group(indent([line, call(path, print, "throws")])));
|
||||||
|
}
|
||||||
|
declaration.push(" ", call(path, print, "constructorBody"));
|
||||||
|
return printWithModifiers(path, print, "constructorModifier", declaration, true);
|
||||||
|
},
|
||||||
|
constructorModifier: printSingle,
|
||||||
|
constructorDeclarator(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const parameters = [];
|
||||||
|
if (children.receiverParameter) {
|
||||||
|
parameters.push(call(path, print, "receiverParameter"));
|
||||||
|
}
|
||||||
|
if (children.formalParameterList) {
|
||||||
|
parameters.push(call(path, print, "formalParameterList"));
|
||||||
|
}
|
||||||
|
const header = [call(path, print, "simpleTypeName")];
|
||||||
|
header.push(parameters.length
|
||||||
|
? indentInParentheses(join([",", line], parameters))
|
||||||
|
: "()");
|
||||||
|
return children.typeParameters
|
||||||
|
? [call(path, print, "typeParameters"), " ", ...header]
|
||||||
|
: header;
|
||||||
|
},
|
||||||
|
simpleTypeName: printSingle,
|
||||||
|
constructorBody(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const statements = [];
|
||||||
|
if (children.explicitConstructorInvocation) {
|
||||||
|
statements.push(call(path, print, "explicitConstructorInvocation"));
|
||||||
|
}
|
||||||
|
if (children.blockStatements) {
|
||||||
|
statements.push(call(path, print, "blockStatements"));
|
||||||
|
}
|
||||||
|
return printBlock(path, statements);
|
||||||
|
},
|
||||||
|
explicitConstructorInvocation: printSingle,
|
||||||
|
unqualifiedExplicitConstructorInvocation(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const invocation = [];
|
||||||
|
if (children.typeArguments) {
|
||||||
|
invocation.push(call(path, print, "typeArguments"));
|
||||||
|
}
|
||||||
|
invocation.push(children.Super ? "super" : "this");
|
||||||
|
if (children.argumentList) {
|
||||||
|
invocation.push(group(["(", call(path, print, "argumentList"), ")"]));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
invocation.push(indentInParentheses(printDanglingComments(path), { shouldBreak: true }));
|
||||||
|
}
|
||||||
|
invocation.push(";");
|
||||||
|
return invocation;
|
||||||
|
},
|
||||||
|
qualifiedExplicitConstructorInvocation(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const invocation = [call(path, print, "expressionName"), "."];
|
||||||
|
if (children.typeArguments) {
|
||||||
|
invocation.push(call(path, print, "typeArguments"));
|
||||||
|
}
|
||||||
|
invocation.push("super");
|
||||||
|
if (children.argumentList) {
|
||||||
|
invocation.push(group(["(", call(path, print, "argumentList"), ")"]));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
invocation.push(indentInParentheses(printDanglingComments(path), { shouldBreak: true }));
|
||||||
|
}
|
||||||
|
invocation.push(";");
|
||||||
|
return invocation;
|
||||||
|
},
|
||||||
|
enumDeclaration(path, print) {
|
||||||
|
const header = ["enum", call(path, print, "typeIdentifier")];
|
||||||
|
if (path.node.children.classImplements) {
|
||||||
|
header.push(call(path, print, "classImplements"));
|
||||||
|
}
|
||||||
|
return join(" ", [...header, call(path, print, "enumBody")]);
|
||||||
|
},
|
||||||
|
enumBody(path, print, options) {
|
||||||
|
var _a;
|
||||||
|
const { children } = path.node;
|
||||||
|
const contents = [];
|
||||||
|
const hasNonEmptyDeclaration = ((_a = children.enumBodyDeclarations) !== null && _a !== void 0 ? _a : [])
|
||||||
|
.flatMap(({ children }) => { var _a; return (_a = children.classBodyDeclaration) !== null && _a !== void 0 ? _a : []; })
|
||||||
|
.some(({ children }) => { var _a; return !((_a = children.classMemberDeclaration) === null || _a === void 0 ? void 0 : _a[0].children.Semicolon); });
|
||||||
|
if (children.enumConstantList) {
|
||||||
|
contents.push(call(path, print, "enumConstantList"));
|
||||||
|
if (!hasNonEmptyDeclaration && options.trailingComma !== "none") {
|
||||||
|
contents.push(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasNonEmptyDeclaration) {
|
||||||
|
contents.push(";", hardline, call(path, print, "enumBodyDeclarations"));
|
||||||
|
}
|
||||||
|
return printBlock(path, contents.length ? [contents] : []);
|
||||||
|
},
|
||||||
|
enumConstantList(path, print) {
|
||||||
|
return join([",", hardline], map(path, constantPath => {
|
||||||
|
const constant = print(constantPath);
|
||||||
|
const { node, previous } = constantPath;
|
||||||
|
return !previous ||
|
||||||
|
lineStartWithComments(node) <= lineEndWithComments(previous) + 1
|
||||||
|
? constant
|
||||||
|
: [hardline, constant];
|
||||||
|
}, "enumConstant"));
|
||||||
|
},
|
||||||
|
enumConstant(path, print) {
|
||||||
|
const { argumentList, classBody } = path.node.children;
|
||||||
|
const initializer = [call(path, print, "Identifier")];
|
||||||
|
if (argumentList) {
|
||||||
|
initializer.push(group(["(", call(path, print, "argumentList"), ")"]));
|
||||||
|
}
|
||||||
|
if (classBody) {
|
||||||
|
initializer.push(" ", call(path, print, "classBody"));
|
||||||
|
}
|
||||||
|
return printWithModifiers(path, print, "enumConstantModifier", initializer);
|
||||||
|
},
|
||||||
|
enumConstantModifier: printSingle,
|
||||||
|
enumBodyDeclarations(path, print) {
|
||||||
|
return join(hardline, printClassBodyDeclarations(path, print));
|
||||||
|
},
|
||||||
|
recordDeclaration(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const header = ["record ", call(path, print, "typeIdentifier")];
|
||||||
|
if (children.typeParameters) {
|
||||||
|
header.push(call(path, print, "typeParameters"));
|
||||||
|
}
|
||||||
|
header.push(call(path, print, "recordHeader"));
|
||||||
|
if (children.classImplements) {
|
||||||
|
header.push(" ", call(path, print, "classImplements"));
|
||||||
|
}
|
||||||
|
return [group(header), " ", call(path, print, "recordBody")];
|
||||||
|
},
|
||||||
|
recordHeader(path, print) {
|
||||||
|
return path.node.children.recordComponentList
|
||||||
|
? indentInParentheses(call(path, print, "recordComponentList"))
|
||||||
|
: indentInParentheses(printDanglingComments(path), { shouldBreak: true });
|
||||||
|
},
|
||||||
|
recordComponentList(path, print) {
|
||||||
|
return join([",", line], map(path, componentPath => {
|
||||||
|
const { node, previous } = componentPath;
|
||||||
|
const blankLine = previous &&
|
||||||
|
lineStartWithComments(node) > lineEndWithComments(previous) + 1;
|
||||||
|
const component = print(componentPath);
|
||||||
|
return blankLine ? [softline, component] : component;
|
||||||
|
}, "recordComponent"));
|
||||||
|
},
|
||||||
|
recordComponent(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const component = [call(path, print, "unannType")];
|
||||||
|
if (children.Identifier ||
|
||||||
|
children.variableArityRecordComponent[0].children.annotation) {
|
||||||
|
component.push(" ");
|
||||||
|
}
|
||||||
|
const suffixKey = onlyDefinedKey(children, [
|
||||||
|
"Identifier",
|
||||||
|
"variableArityRecordComponent"
|
||||||
|
]);
|
||||||
|
component.push(call(path, print, suffixKey));
|
||||||
|
return group(join(line, [...map(path, print, "recordComponentModifier"), component]));
|
||||||
|
},
|
||||||
|
variableArityRecordComponent(path, print) {
|
||||||
|
return [
|
||||||
|
...join(" ", map(path, print, "annotation")),
|
||||||
|
"... ",
|
||||||
|
call(path, print, "Identifier")
|
||||||
|
];
|
||||||
|
},
|
||||||
|
recordComponentModifier: printSingle,
|
||||||
|
recordBody(path, print) {
|
||||||
|
const declarations = [];
|
||||||
|
let previousRequiresPadding = false;
|
||||||
|
each(path, declarationPath => {
|
||||||
|
var _a, _b, _c, _d;
|
||||||
|
const declaration = print(declarationPath);
|
||||||
|
if (declaration === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { node, previous } = declarationPath;
|
||||||
|
const fieldDeclaration = (_c = (_b = (_a = node.children.classBodyDeclaration) === null || _a === void 0 ? void 0 : _a[0].children.classMemberDeclaration) === null || _b === void 0 ? void 0 : _b[0].children.fieldDeclaration) === null || _c === void 0 ? void 0 : _c[0].children;
|
||||||
|
const currentRequiresPadding = !fieldDeclaration ||
|
||||||
|
hasDeclarationAnnotations((_d = fieldDeclaration.fieldModifier) !== null && _d !== void 0 ? _d : []);
|
||||||
|
const blankLine = declarations.length > 0 &&
|
||||||
|
(previousRequiresPadding ||
|
||||||
|
currentRequiresPadding ||
|
||||||
|
lineStartWithComments(node) > lineEndWithComments(previous) + 1);
|
||||||
|
declarations.push(blankLine ? [hardline, declaration] : declaration);
|
||||||
|
previousRequiresPadding = currentRequiresPadding;
|
||||||
|
}, "recordBodyDeclaration");
|
||||||
|
return printBlock(path, declarations);
|
||||||
|
},
|
||||||
|
recordBodyDeclaration: printSingle,
|
||||||
|
compactConstructorDeclaration(path, print) {
|
||||||
|
const declaration = [
|
||||||
|
call(path, print, "simpleTypeName"),
|
||||||
|
" ",
|
||||||
|
call(path, print, "constructorBody")
|
||||||
|
];
|
||||||
|
return printWithModifiers(path, print, "constructorModifier", declaration, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function printClassBodyDeclarations(path, print) {
|
||||||
|
var _a;
|
||||||
|
if (!path.node.children.classBodyDeclaration) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const declarations = [];
|
||||||
|
let previousRequiresPadding = path.node.name === "enumBodyDeclarations" ||
|
||||||
|
((_a = path.grandparent) === null || _a === void 0 ? void 0 : _a.name) ===
|
||||||
|
"normalClassDeclaration";
|
||||||
|
each(path, declarationPath => {
|
||||||
|
var _a, _b, _c;
|
||||||
|
const declaration = print(declarationPath);
|
||||||
|
if (declaration === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { node, previous } = declarationPath;
|
||||||
|
const fieldDeclaration = (_b = (_a = node.children.classMemberDeclaration) === null || _a === void 0 ? void 0 : _a[0].children.fieldDeclaration) === null || _b === void 0 ? void 0 : _b[0].children;
|
||||||
|
const currentRequiresPadding = fieldDeclaration
|
||||||
|
? hasDeclarationAnnotations((_c = fieldDeclaration.fieldModifier) !== null && _c !== void 0 ? _c : [])
|
||||||
|
: true;
|
||||||
|
const blankLine = previousRequiresPadding ||
|
||||||
|
(declarations.length > 0 &&
|
||||||
|
(currentRequiresPadding ||
|
||||||
|
lineStartWithComments(node) > lineEndWithComments(previous) + 1));
|
||||||
|
declarations.push(blankLine ? [hardline, declaration] : declaration);
|
||||||
|
previousRequiresPadding = currentRequiresPadding;
|
||||||
|
}, "classBodyDeclaration");
|
||||||
|
return declarations;
|
||||||
|
}
|
||||||
134
frontend/src/common/prettier/plugins/java/printers/expressions.d.ts
vendored
Normal file
134
frontend/src/common/prettier/plugins/java/printers/expressions.d.ts
vendored
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
import type { StringTemplateCstNode, TextBlockTemplateCstNode } from "java-parser";
|
||||||
|
import type { AstPath } from "prettier";
|
||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import type { JavaComment } from "../comments.js";
|
||||||
|
import { printSingle, type JavaPrintFn } from "./helpers.js";
|
||||||
|
declare const _default: {
|
||||||
|
expression: typeof printSingle;
|
||||||
|
lambdaExpression(path: AstPath<import("java-parser").LambdaExpressionCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn, _: import("./helpers.js").JavaParserOptions, args?: unknown): builders.Doc[];
|
||||||
|
lambdaParameters(path: AstPath<import("java-parser").LambdaParametersCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn, options: import("./helpers.js").JavaParserOptions): builders.Doc;
|
||||||
|
lambdaParametersWithBraces(path: AstPath<import("java-parser").LambdaParametersWithBracesCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn, options: import("./helpers.js").JavaParserOptions): builders.Doc;
|
||||||
|
lambdaParameterList: typeof printSingle;
|
||||||
|
conciseLambdaParameterList(path: AstPath<import("java-parser").ConciseLambdaParameterListCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
normalLambdaParameterList(path: AstPath<import("java-parser").NormalLambdaParameterListCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
normalLambdaParameter: typeof printSingle;
|
||||||
|
regularLambdaParameter(path: AstPath<import("java-parser").RegularLambdaParameterCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
lambdaParameterType: typeof printSingle;
|
||||||
|
conciseLambdaParameter: typeof printSingle;
|
||||||
|
lambdaBody: typeof printSingle;
|
||||||
|
conditionalExpression(path: AstPath<import("java-parser").ConditionalExpressionCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc;
|
||||||
|
binaryExpression(path: AstPath<import("java-parser").BinaryExpressionCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn, options: import("./helpers.js").JavaParserOptions): builders.Doc;
|
||||||
|
unaryExpression(path: AstPath<import("java-parser").UnaryExpressionCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
unaryExpressionNotPlusMinus(path: AstPath<import("java-parser").UnaryExpressionNotPlusMinusCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
primary(path: AstPath<import("java-parser").PrimaryCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc;
|
||||||
|
primaryPrefix: typeof printSingle;
|
||||||
|
primarySuffix(path: AstPath<import("java-parser").PrimarySuffixCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc;
|
||||||
|
fqnOrRefType(path: AstPath<import("java-parser").FqnOrRefTypeCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn, _: import("./helpers.js").JavaParserOptions, args: unknown): builders.Doc[];
|
||||||
|
fqnOrRefTypePartFirst(path: AstPath<import("java-parser").FqnOrRefTypePartFirstCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
fqnOrRefTypePartRest(path: AstPath<import("java-parser").FqnOrRefTypePartRestCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
fqnOrRefTypePartCommon(path: AstPath<import("java-parser").FqnOrRefTypePartCommonCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc;
|
||||||
|
parenthesisExpression(path: AstPath<import("java-parser").ParenthesisExpressionCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Group | "()" | (string | builders.Indent)[];
|
||||||
|
castExpression: typeof printSingle;
|
||||||
|
primitiveCastExpression(path: AstPath<import("java-parser").PrimitiveCastExpressionCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
referenceTypeCastExpression(path: AstPath<import("java-parser").ReferenceTypeCastExpressionCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
newExpression: typeof printSingle;
|
||||||
|
unqualifiedClassInstanceCreationExpression(path: AstPath<import("java-parser").UnqualifiedClassInstanceCreationExpressionCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
classOrInterfaceTypeToInstantiate(path: AstPath<import("java-parser").ClassOrInterfaceTypeToInstantiateCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
typeArgumentsOrDiamond: typeof printSingle;
|
||||||
|
diamond(): string;
|
||||||
|
methodInvocationSuffix(path: AstPath<import("java-parser").MethodInvocationSuffixCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Group | "()";
|
||||||
|
argumentList(path: AstPath<import("java-parser").ArgumentListCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Group | (builders.Indent | builders.Softline)[] | (builders.BreakParent | builders.Group)[];
|
||||||
|
arrayCreationExpression(path: AstPath<import("java-parser").ArrayCreationExpressionCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
arrayCreationExpressionWithoutInitializerSuffix(path: AstPath<import("java-parser").ArrayCreationExpressionWithoutInitializerSuffixCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc;
|
||||||
|
arrayCreationWithInitializerSuffix(path: AstPath<import("java-parser").ArrayCreationWithInitializerSuffixCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
dimExprs(path: AstPath<import("java-parser").DimExprsCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
dimExpr(path: AstPath<import("java-parser").DimExprCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
classLiteralSuffix(path: AstPath<import("java-parser").ClassLiteralSuffixCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
arrayAccessSuffix(path: AstPath<import("java-parser").ArrayAccessSuffixCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
methodReferenceSuffix(path: AstPath<import("java-parser").MethodReferenceSuffixCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
templateArgument: typeof printSingle;
|
||||||
|
template: typeof printSingle;
|
||||||
|
stringTemplate(path: AstPath<StringTemplateCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Indent;
|
||||||
|
textBlockTemplate(path: AstPath<TextBlockTemplateCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Indent;
|
||||||
|
embeddedExpression: typeof printSingle;
|
||||||
|
pattern: typeof printSingle;
|
||||||
|
typePattern: typeof printSingle;
|
||||||
|
recordPattern(path: AstPath<import("java-parser").RecordPatternCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
componentPatternList(path: AstPath<import("java-parser").ComponentPatternListCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
componentPattern: typeof printSingle;
|
||||||
|
matchAllPattern: typeof printSingle;
|
||||||
|
guard(path: AstPath<import("java-parser").GuardCstNode & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
@@ -0,0 +1,598 @@
|
|||||||
|
import { builders, utils } from "prettier/doc";
|
||||||
|
import { call, definedKeys, each, findBaseIndent, flatMap, hasLeadingComments, indentInParentheses, isBinaryExpression, isNonTerminal, isTerminal, map, onlyDefinedKey, printDanglingComments, printList, printName, printSingle } from "./helpers.js";
|
||||||
|
const { breakParent, conditionalGroup, group, hardline, ifBreak, indent, indentIfBreak, join, line, lineSuffixBoundary, softline } = builders;
|
||||||
|
const { removeLines, willBreak } = utils;
|
||||||
|
export default {
|
||||||
|
expression: printSingle,
|
||||||
|
lambdaExpression(path, print, _, args = {}) {
|
||||||
|
var _a;
|
||||||
|
const hug = (_a = args.hug) !== null && _a !== void 0 ? _a : false;
|
||||||
|
const parameters = call(path, print, "lambdaParameters");
|
||||||
|
const expression = [hug ? removeLines(parameters) : parameters, " ->"];
|
||||||
|
const lambdaExpression = path.node.children.lambdaBody[0].children.expression;
|
||||||
|
const body = call(path, print, "lambdaBody");
|
||||||
|
if (lambdaExpression) {
|
||||||
|
const suffix = indent([line, body]);
|
||||||
|
expression.push(group(hug ? [suffix, softline] : suffix));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
expression.push(" ", body);
|
||||||
|
}
|
||||||
|
return expression;
|
||||||
|
},
|
||||||
|
lambdaParameters(path, print, options) {
|
||||||
|
const parameters = printSingle(path, print);
|
||||||
|
return !path.node.children.lambdaParametersWithBraces &&
|
||||||
|
options.arrowParens === "always"
|
||||||
|
? ["(", parameters, ")"]
|
||||||
|
: parameters;
|
||||||
|
},
|
||||||
|
lambdaParametersWithBraces(path, print, options) {
|
||||||
|
var _a;
|
||||||
|
const { lambdaParameterList } = path.node.children;
|
||||||
|
if (!lambdaParameterList) {
|
||||||
|
return "()";
|
||||||
|
}
|
||||||
|
const { conciseLambdaParameterList, normalLambdaParameterList } = lambdaParameterList[0].children;
|
||||||
|
const parameterCount = ((_a = conciseLambdaParameterList === null || conciseLambdaParameterList === void 0 ? void 0 : conciseLambdaParameterList[0].children.conciseLambdaParameter) !== null && _a !== void 0 ? _a : normalLambdaParameterList === null || normalLambdaParameterList === void 0 ? void 0 : normalLambdaParameterList[0].children.normalLambdaParameter).length;
|
||||||
|
const parameters = call(path, print, "lambdaParameterList");
|
||||||
|
if (parameterCount > 1) {
|
||||||
|
return indentInParentheses(parameters);
|
||||||
|
}
|
||||||
|
return conciseLambdaParameterList && options.arrowParens === "avoid"
|
||||||
|
? parameters
|
||||||
|
: ["(", parameters, ")"];
|
||||||
|
},
|
||||||
|
lambdaParameterList: printSingle,
|
||||||
|
conciseLambdaParameterList(path, print) {
|
||||||
|
return printList(path, print, "conciseLambdaParameter");
|
||||||
|
},
|
||||||
|
normalLambdaParameterList(path, print) {
|
||||||
|
return printList(path, print, "normalLambdaParameter");
|
||||||
|
},
|
||||||
|
normalLambdaParameter: printSingle,
|
||||||
|
regularLambdaParameter(path, print) {
|
||||||
|
return join(" ", [
|
||||||
|
...map(path, print, "variableModifier"),
|
||||||
|
call(path, print, "lambdaParameterType"),
|
||||||
|
call(path, print, "variableDeclaratorId")
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
lambdaParameterType: printSingle,
|
||||||
|
conciseLambdaParameter: printSingle,
|
||||||
|
lambdaBody: printSingle,
|
||||||
|
conditionalExpression(path, print) {
|
||||||
|
var _a;
|
||||||
|
const binaryExpression = call(path, print, "binaryExpression");
|
||||||
|
if (!path.node.children.QuestionMark) {
|
||||||
|
return binaryExpression;
|
||||||
|
}
|
||||||
|
const expressions = map(path, print, "expression");
|
||||||
|
const contents = indent(join(line, [
|
||||||
|
binaryExpression,
|
||||||
|
["? ", expressions[0]],
|
||||||
|
[": ", expressions[1]]
|
||||||
|
]));
|
||||||
|
const isNestedTernary = ((_a = path.getNode(4)) === null || _a === void 0 ? void 0 : _a.name) ===
|
||||||
|
"conditionalExpression";
|
||||||
|
return isNestedTernary ? contents : group(contents);
|
||||||
|
},
|
||||||
|
binaryExpression(path, print, options) {
|
||||||
|
var _a, _b;
|
||||||
|
const { children } = path.node;
|
||||||
|
const operands = flatMap(path, print, definedKeys(children, [
|
||||||
|
"expression",
|
||||||
|
"pattern",
|
||||||
|
"referenceType",
|
||||||
|
"unaryExpression"
|
||||||
|
]));
|
||||||
|
const operators = flatMap(path, operatorPath => {
|
||||||
|
const { node } = operatorPath;
|
||||||
|
let image;
|
||||||
|
if (isTerminal(node)) {
|
||||||
|
image = node.image;
|
||||||
|
}
|
||||||
|
else if (node.children.Less) {
|
||||||
|
image = "<<";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
image = node.children.Greater.length === 2 ? ">>" : ">>>";
|
||||||
|
}
|
||||||
|
return { image, doc: print(operatorPath) };
|
||||||
|
}, definedKeys(children, [
|
||||||
|
"AssignmentOperator",
|
||||||
|
"BinaryOperator",
|
||||||
|
"Instanceof",
|
||||||
|
"shiftOperator"
|
||||||
|
]));
|
||||||
|
const hasNonAssignmentOperators = (operators.length > 0 && !children.AssignmentOperator) ||
|
||||||
|
(children.expression !== undefined &&
|
||||||
|
isBinaryExpression(children.expression[0]));
|
||||||
|
const isInList = ((_a = path.getNode(4)) === null || _a === void 0 ? void 0 : _a.name) === "elementValue" ||
|
||||||
|
((_b = path.getNode(6)) === null || _b === void 0 ? void 0 : _b.name) === "argumentList";
|
||||||
|
return binary(operands, operators, {
|
||||||
|
hasNonAssignmentOperators,
|
||||||
|
isInList,
|
||||||
|
isRoot: true,
|
||||||
|
operatorPosition: options.experimentalOperatorPosition
|
||||||
|
});
|
||||||
|
},
|
||||||
|
unaryExpression(path, print) {
|
||||||
|
return [
|
||||||
|
...map(path, print, "UnaryPrefixOperator"),
|
||||||
|
call(path, print, "primary"),
|
||||||
|
...map(path, print, "UnarySuffixOperator")
|
||||||
|
];
|
||||||
|
},
|
||||||
|
unaryExpressionNotPlusMinus(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const expression = [];
|
||||||
|
if (children.UnaryPrefixOperatorNotPlusMinus) {
|
||||||
|
expression.push(...map(path, print, "UnaryPrefixOperatorNotPlusMinus"));
|
||||||
|
}
|
||||||
|
expression.push(call(path, print, "primary"));
|
||||||
|
if (children.UnarySuffixOperator) {
|
||||||
|
expression.push(...map(path, print, "UnarySuffixOperator"));
|
||||||
|
}
|
||||||
|
return join(" ", expression);
|
||||||
|
},
|
||||||
|
primary(path, print) {
|
||||||
|
var _a, _b;
|
||||||
|
const { children } = path.node;
|
||||||
|
if (!children.primarySuffix) {
|
||||||
|
return call(path, print, "primaryPrefix");
|
||||||
|
}
|
||||||
|
const methodInvocations = children.primarySuffix
|
||||||
|
.filter(({ children }) => children.methodInvocationSuffix)
|
||||||
|
.map(({ children }) => children.methodInvocationSuffix[0].children);
|
||||||
|
const hasLambdaMethodParameter = methodInvocations.some(({ argumentList }) => argumentList === null || argumentList === void 0 ? void 0 : argumentList[0].children.expression.some(({ children }) => children.lambdaExpression));
|
||||||
|
const prefixIsCallExpression = children.primaryPrefix[0].children.newExpression;
|
||||||
|
const callExpressionCount = methodInvocations.length +
|
||||||
|
(prefixIsCallExpression ? 1 : 0) +
|
||||||
|
children.primarySuffix.filter(({ children }) => children.unqualifiedClassInstanceCreationExpression).length;
|
||||||
|
const fqnOrRefType = (_a = children.primaryPrefix[0].children.fqnOrRefType) === null || _a === void 0 ? void 0 : _a[0].children;
|
||||||
|
const prefixIsMethodInvocation = (fqnOrRefType === null || fqnOrRefType === void 0 ? void 0 : fqnOrRefType.fqnOrRefTypePartRest) !== undefined &&
|
||||||
|
((_b = children.primarySuffix) === null || _b === void 0 ? void 0 : _b[0].children.methodInvocationSuffix) !== undefined;
|
||||||
|
const prefixIsStaticMethodInvocation = prefixIsMethodInvocation && isCapitalizedIdentifier(fqnOrRefType);
|
||||||
|
const prefixIsInstanceMethodInvocation = prefixIsMethodInvocation && !prefixIsStaticMethodInvocation;
|
||||||
|
const mustBreakForCallExpressions = methodInvocations.length > 2 && hasLambdaMethodParameter;
|
||||||
|
const separator = mustBreakForCallExpressions ? hardline : softline;
|
||||||
|
const prefix = [
|
||||||
|
call(path, prefixPath => print(prefixPath, {
|
||||||
|
lastSeparator: prefixIsStaticMethodInvocation ||
|
||||||
|
(prefixIsInstanceMethodInvocation && callExpressionCount === 1)
|
||||||
|
? ""
|
||||||
|
: separator
|
||||||
|
}), "primaryPrefix")
|
||||||
|
];
|
||||||
|
const canBreakForCallExpressions = callExpressionCount > 2 ||
|
||||||
|
(callExpressionCount === 2 && prefixIsInstanceMethodInvocation) ||
|
||||||
|
willBreak(prefix);
|
||||||
|
const suffixes = [];
|
||||||
|
each(path, suffixPath => {
|
||||||
|
const { node, previous } = suffixPath;
|
||||||
|
const suffix = print(suffixPath);
|
||||||
|
if (node.children.Dot) {
|
||||||
|
if ((canBreakForCallExpressions &&
|
||||||
|
((!previous && prefixIsCallExpression) ||
|
||||||
|
(previous === null || previous === void 0 ? void 0 : previous.children.methodInvocationSuffix) ||
|
||||||
|
(previous === null || previous === void 0 ? void 0 : previous.children.unqualifiedClassInstanceCreationExpression))) ||
|
||||||
|
(!node.children.templateArgument && willBreak(suffix))) {
|
||||||
|
suffixes.push(separator);
|
||||||
|
}
|
||||||
|
suffixes.push(suffix);
|
||||||
|
}
|
||||||
|
else if (previous) {
|
||||||
|
suffixes.push(suffix);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prefix.push(prefixIsInstanceMethodInvocation && callExpressionCount >= 2
|
||||||
|
? indent(suffix)
|
||||||
|
: suffix);
|
||||||
|
}
|
||||||
|
}, "primarySuffix");
|
||||||
|
const hasSuffixComments = children.primarySuffix.some(suffix => hasLeadingComments(suffix));
|
||||||
|
return group(canBreakForCallExpressions || hasSuffixComments
|
||||||
|
? [prefix, indent(suffixes)]
|
||||||
|
: [prefix, ...suffixes]);
|
||||||
|
},
|
||||||
|
primaryPrefix: printSingle,
|
||||||
|
primarySuffix(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
if (!children.Dot) {
|
||||||
|
return printSingle(path, print);
|
||||||
|
}
|
||||||
|
const suffix = ["."];
|
||||||
|
if (children.This) {
|
||||||
|
suffix.push("this");
|
||||||
|
}
|
||||||
|
else if (children.Identifier) {
|
||||||
|
if (children.typeArguments) {
|
||||||
|
suffix.push(call(path, print, "typeArguments"));
|
||||||
|
}
|
||||||
|
suffix.push(call(path, print, "Identifier"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const suffixKey = onlyDefinedKey(children, [
|
||||||
|
"templateArgument",
|
||||||
|
"unqualifiedClassInstanceCreationExpression"
|
||||||
|
]);
|
||||||
|
suffix.push(call(path, print, suffixKey));
|
||||||
|
}
|
||||||
|
return suffix;
|
||||||
|
},
|
||||||
|
fqnOrRefType(path, print, _, args) {
|
||||||
|
var _a;
|
||||||
|
const lastSeparator = (_a = args.lastSeparator) !== null && _a !== void 0 ? _a : "";
|
||||||
|
const fqnOrRefType = [
|
||||||
|
call(path, print, "fqnOrRefTypePartFirst"),
|
||||||
|
...map(path, partPath => {
|
||||||
|
const part = print(partPath);
|
||||||
|
return partPath.isLast
|
||||||
|
? [willBreak(part) ? hardline : lastSeparator, part]
|
||||||
|
: part;
|
||||||
|
}, "fqnOrRefTypePartRest")
|
||||||
|
];
|
||||||
|
fqnOrRefType.push(indent(fqnOrRefType.pop()));
|
||||||
|
return path.node.children.dims
|
||||||
|
? [fqnOrRefType, call(path, print, "dims")]
|
||||||
|
: fqnOrRefType;
|
||||||
|
},
|
||||||
|
fqnOrRefTypePartFirst(path, print) {
|
||||||
|
return join(" ", [
|
||||||
|
...map(path, print, "annotation"),
|
||||||
|
call(path, print, "fqnOrRefTypePartCommon")
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
fqnOrRefTypePartRest(path, print) {
|
||||||
|
const common = call(path, print, "fqnOrRefTypePartCommon");
|
||||||
|
const type = path.node.children.typeArguments
|
||||||
|
? [call(path, print, "typeArguments"), common]
|
||||||
|
: common;
|
||||||
|
return [".", ...join(" ", [...map(path, print, "annotation"), type])];
|
||||||
|
},
|
||||||
|
fqnOrRefTypePartCommon(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const keywordKey = onlyDefinedKey(children, ["Identifier", "Super"]);
|
||||||
|
const keyword = call(path, print, keywordKey);
|
||||||
|
return children.typeArguments
|
||||||
|
? [keyword, call(path, print, "typeArguments")]
|
||||||
|
: keyword;
|
||||||
|
},
|
||||||
|
parenthesisExpression(path, print) {
|
||||||
|
var _a;
|
||||||
|
const expression = call(path, print, "expression");
|
||||||
|
const ancestorName = (_a = path.getNode(14)) === null || _a === void 0 ? void 0 : _a.name;
|
||||||
|
const binaryExpression = path.getNode(8);
|
||||||
|
return ancestorName &&
|
||||||
|
["guard", "returnStatement"].includes(ancestorName) &&
|
||||||
|
binaryExpression &&
|
||||||
|
binaryExpression.name === "binaryExpression" &&
|
||||||
|
Object.keys(binaryExpression.children).length === 1
|
||||||
|
? indentInParentheses(expression)
|
||||||
|
: ["(", indent(expression), ")"];
|
||||||
|
},
|
||||||
|
castExpression: printSingle,
|
||||||
|
primitiveCastExpression(path, print) {
|
||||||
|
return [
|
||||||
|
"(",
|
||||||
|
call(path, print, "primitiveType"),
|
||||||
|
") ",
|
||||||
|
call(path, print, "unaryExpression")
|
||||||
|
];
|
||||||
|
},
|
||||||
|
referenceTypeCastExpression(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const type = call(path, print, "referenceType");
|
||||||
|
const cast = children.additionalBound
|
||||||
|
? indentInParentheses(join(line, [type, ...map(path, print, "additionalBound")]))
|
||||||
|
: ["(", type, ")"];
|
||||||
|
const expressionKey = onlyDefinedKey(children, [
|
||||||
|
"lambdaExpression",
|
||||||
|
"unaryExpressionNotPlusMinus"
|
||||||
|
]);
|
||||||
|
return [cast, " ", call(path, print, expressionKey)];
|
||||||
|
},
|
||||||
|
newExpression: printSingle,
|
||||||
|
unqualifiedClassInstanceCreationExpression(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const expression = ["new "];
|
||||||
|
if (children.typeArguments) {
|
||||||
|
expression.push(call(path, print, "typeArguments"));
|
||||||
|
}
|
||||||
|
expression.push(call(path, print, "classOrInterfaceTypeToInstantiate"), children.argumentList
|
||||||
|
? group(["(", call(path, print, "argumentList"), ")"])
|
||||||
|
: "()");
|
||||||
|
if (children.classBody) {
|
||||||
|
expression.push(" ", call(path, print, "classBody"));
|
||||||
|
}
|
||||||
|
return expression;
|
||||||
|
},
|
||||||
|
classOrInterfaceTypeToInstantiate(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const type = children.annotation
|
||||||
|
? flatMap(path, childPath => [
|
||||||
|
print(childPath),
|
||||||
|
isNonTerminal(childPath.node) ? " " : "."
|
||||||
|
], ["annotation", "Identifier"])
|
||||||
|
: printName(path, print);
|
||||||
|
if (children.typeArgumentsOrDiamond) {
|
||||||
|
type.push(call(path, print, "typeArgumentsOrDiamond"));
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
},
|
||||||
|
typeArgumentsOrDiamond: printSingle,
|
||||||
|
diamond() {
|
||||||
|
return "<>";
|
||||||
|
},
|
||||||
|
methodInvocationSuffix(path, print) {
|
||||||
|
return path.node.children.argumentList
|
||||||
|
? group(["(", call(path, print, "argumentList"), ")"])
|
||||||
|
: indentInParentheses(printDanglingComments(path), { shouldBreak: true });
|
||||||
|
},
|
||||||
|
argumentList(path, print) {
|
||||||
|
var _a, _b, _c, _d;
|
||||||
|
const expressions = path.node.children.expression;
|
||||||
|
const lastExpression = expressions.at(-1);
|
||||||
|
const lastExpressionLambdaBodyExpression = (_b = (_a = lastExpression.children.lambdaExpression) === null || _a === void 0 ? void 0 : _a[0].children.lambdaBody[0].children.expression) === null || _b === void 0 ? void 0 : _b[0].children;
|
||||||
|
const lastExpressionLambdaBodyTernaryExpression = (_c = lastExpressionLambdaBodyExpression === null || lastExpressionLambdaBodyExpression === void 0 ? void 0 : lastExpressionLambdaBodyExpression.conditionalExpression) === null || _c === void 0 ? void 0 : _c[0].children;
|
||||||
|
const isHuggable = !lastExpression.comments &&
|
||||||
|
(!lastExpressionLambdaBodyExpression ||
|
||||||
|
(lastExpressionLambdaBodyTernaryExpression === null || lastExpressionLambdaBodyTernaryExpression === void 0 ? void 0 : lastExpressionLambdaBodyTernaryExpression.QuestionMark) !== undefined ||
|
||||||
|
((_d = lastExpressionLambdaBodyTernaryExpression === null || lastExpressionLambdaBodyTernaryExpression === void 0 ? void 0 : lastExpressionLambdaBodyTernaryExpression.binaryExpression) === null || _d === void 0 ? void 0 : _d[0].children.unaryExpression.length) === 1) &&
|
||||||
|
expressions.findIndex(({ children }) => children.lambdaExpression) ===
|
||||||
|
expressions.length - 1;
|
||||||
|
const args = map(path, print, "expression");
|
||||||
|
const allArgsExpandable = [
|
||||||
|
indent([softline, ...join([",", line], args)]),
|
||||||
|
softline
|
||||||
|
];
|
||||||
|
if (!isHuggable || willBreak(args.at(-1)[0])) {
|
||||||
|
return allArgsExpandable;
|
||||||
|
}
|
||||||
|
const headArgs = args.slice(0, -1);
|
||||||
|
const huggedLastArg = path.call(argPath => print(argPath, { hug: true }), "children", "expression", args.length - 1);
|
||||||
|
const lastArgExpanded = join(", ", [
|
||||||
|
...headArgs,
|
||||||
|
group(huggedLastArg, { shouldBreak: true })
|
||||||
|
]);
|
||||||
|
if (willBreak(huggedLastArg)) {
|
||||||
|
return [
|
||||||
|
breakParent,
|
||||||
|
conditionalGroup([lastArgExpanded, allArgsExpandable])
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return conditionalGroup([
|
||||||
|
join(", ", [...headArgs, huggedLastArg]),
|
||||||
|
lastArgExpanded,
|
||||||
|
allArgsExpandable
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
arrayCreationExpression(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const typeKey = onlyDefinedKey(children, [
|
||||||
|
"classOrInterfaceType",
|
||||||
|
"primitiveType"
|
||||||
|
]);
|
||||||
|
const suffixKey = onlyDefinedKey(children, [
|
||||||
|
"arrayCreationExpressionWithoutInitializerSuffix",
|
||||||
|
"arrayCreationWithInitializerSuffix"
|
||||||
|
]);
|
||||||
|
return ["new ", call(path, print, typeKey), call(path, print, suffixKey)];
|
||||||
|
},
|
||||||
|
arrayCreationExpressionWithoutInitializerSuffix(path, print) {
|
||||||
|
const expressions = call(path, print, "dimExprs");
|
||||||
|
return path.node.children.dims
|
||||||
|
? [expressions, call(path, print, "dims")]
|
||||||
|
: expressions;
|
||||||
|
},
|
||||||
|
arrayCreationWithInitializerSuffix(path, print) {
|
||||||
|
return [
|
||||||
|
call(path, print, "dims"),
|
||||||
|
" ",
|
||||||
|
call(path, print, "arrayInitializer")
|
||||||
|
];
|
||||||
|
},
|
||||||
|
dimExprs(path, print) {
|
||||||
|
return map(path, print, "dimExpr");
|
||||||
|
},
|
||||||
|
dimExpr(path, print) {
|
||||||
|
return join(" ", [
|
||||||
|
...map(path, print, "annotation"),
|
||||||
|
["[", call(path, print, "expression"), "]"]
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
classLiteralSuffix(path, print) {
|
||||||
|
const lSquares = map(path, print, "LSquare");
|
||||||
|
const rSquares = map(path, print, "RSquare");
|
||||||
|
return [
|
||||||
|
...lSquares.flatMap((lSquare, index) => [lSquare, rSquares[index]]),
|
||||||
|
".class"
|
||||||
|
];
|
||||||
|
},
|
||||||
|
arrayAccessSuffix(path, print) {
|
||||||
|
return ["[", call(path, print, "expression"), "]"];
|
||||||
|
},
|
||||||
|
methodReferenceSuffix(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const reference = ["::"];
|
||||||
|
if (children.typeArguments) {
|
||||||
|
reference.push(call(path, print, "typeArguments"));
|
||||||
|
}
|
||||||
|
reference.push(call(path, print, onlyDefinedKey(children, ["Identifier", "New"])));
|
||||||
|
return reference;
|
||||||
|
},
|
||||||
|
templateArgument: printSingle,
|
||||||
|
template: printSingle,
|
||||||
|
stringTemplate(path, print) {
|
||||||
|
return printTemplate(path, print, "StringTemplateBegin", "StringTemplateMid", "StringTemplateEnd");
|
||||||
|
},
|
||||||
|
textBlockTemplate(path, print) {
|
||||||
|
return printTemplate(path, print, "TextBlockTemplateBegin", "TextBlockTemplateMid", "TextBlockTemplateEnd");
|
||||||
|
},
|
||||||
|
embeddedExpression: printSingle,
|
||||||
|
pattern: printSingle,
|
||||||
|
typePattern: printSingle,
|
||||||
|
recordPattern(path, print) {
|
||||||
|
const patterns = path.node.children.componentPatternList
|
||||||
|
? indentInParentheses(call(path, print, "componentPatternList"))
|
||||||
|
: "()";
|
||||||
|
return [call(path, print, "referenceType"), patterns];
|
||||||
|
},
|
||||||
|
componentPatternList(path, print) {
|
||||||
|
return printList(path, print, "componentPattern");
|
||||||
|
},
|
||||||
|
componentPattern: printSingle,
|
||||||
|
matchAllPattern: printSingle,
|
||||||
|
guard(path, print) {
|
||||||
|
var _a;
|
||||||
|
const expression = call(path, print, "expression");
|
||||||
|
const hasParentheses = ((_a = path.node.children.expression[0].children.conditionalExpression) === null || _a === void 0 ? void 0 : _a[0].children.binaryExpression[0].children.unaryExpression[0].children.primary[0].children.primaryPrefix[0].children.parenthesisExpression) !==
|
||||||
|
undefined;
|
||||||
|
return [
|
||||||
|
"when ",
|
||||||
|
hasParentheses
|
||||||
|
? expression
|
||||||
|
: group([
|
||||||
|
ifBreak("("),
|
||||||
|
indent([softline, expression]),
|
||||||
|
softline,
|
||||||
|
ifBreak(")")
|
||||||
|
])
|
||||||
|
];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function binary(operands, operators, { hasNonAssignmentOperators = false, isInList = false, isRoot = false, operatorPosition }) {
|
||||||
|
let levelOperator;
|
||||||
|
let levelPrecedence;
|
||||||
|
let level = [];
|
||||||
|
while (operators.length) {
|
||||||
|
const nextOperator = operators[0].image;
|
||||||
|
const nextPrecedence = getOperatorPrecedence(nextOperator);
|
||||||
|
if (levelPrecedence === undefined || nextPrecedence === levelPrecedence) {
|
||||||
|
const { image: operator, doc: operatorDoc } = operators.shift();
|
||||||
|
level.push(operands.shift());
|
||||||
|
if (levelOperator !== undefined &&
|
||||||
|
needsParentheses(levelOperator, operator)) {
|
||||||
|
level = [["(", group(indent(level)), ")"]];
|
||||||
|
}
|
||||||
|
const parts = [" ", operatorDoc, line];
|
||||||
|
if (operatorPosition === "start" && !isAssignmentOperator(operator)) {
|
||||||
|
parts.reverse();
|
||||||
|
}
|
||||||
|
level.push(parts);
|
||||||
|
levelOperator = operator;
|
||||||
|
levelPrecedence = nextPrecedence;
|
||||||
|
}
|
||||||
|
else if (nextPrecedence < levelPrecedence) {
|
||||||
|
if (!isRoot) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
level.push(operands.shift());
|
||||||
|
const content = group(indent(level));
|
||||||
|
operands.unshift(levelOperator !== undefined &&
|
||||||
|
needsParentheses(levelOperator, nextOperator)
|
||||||
|
? ["(", content, ")"]
|
||||||
|
: content);
|
||||||
|
level = [];
|
||||||
|
levelOperator = undefined;
|
||||||
|
levelPrecedence = undefined;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const content = binary(operands, operators, { operatorPosition });
|
||||||
|
operands.unshift(levelOperator !== undefined &&
|
||||||
|
needsParentheses(nextOperator, levelOperator)
|
||||||
|
? ["(", indent(content), ")"]
|
||||||
|
: content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
level.push(operands.shift());
|
||||||
|
if (!levelOperator ||
|
||||||
|
(!isInList &&
|
||||||
|
!isAssignmentOperator(levelOperator) &&
|
||||||
|
levelOperator !== "instanceof")) {
|
||||||
|
return group(level);
|
||||||
|
}
|
||||||
|
if (!isRoot || hasNonAssignmentOperators) {
|
||||||
|
return group(indent(level));
|
||||||
|
}
|
||||||
|
const groupId = Symbol("assignment");
|
||||||
|
return group([
|
||||||
|
level[0],
|
||||||
|
group(indent(level[1]), { id: groupId }),
|
||||||
|
indentIfBreak(level[2], { groupId })
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
const precedencesByOperator = new Map([
|
||||||
|
["||"],
|
||||||
|
["&&"],
|
||||||
|
["|"],
|
||||||
|
["^"],
|
||||||
|
["&"],
|
||||||
|
["==", "!="],
|
||||||
|
["<", ">", "<=", ">=", "instanceof"],
|
||||||
|
["<<", ">>", ">>>"],
|
||||||
|
["+", "-"],
|
||||||
|
["*", "/", "%"]
|
||||||
|
].flatMap((operators, index) => operators.map(operator => [operator, index])));
|
||||||
|
function getOperatorPrecedence(operator) {
|
||||||
|
var _a;
|
||||||
|
return (_a = precedencesByOperator.get(operator)) !== null && _a !== void 0 ? _a : -1;
|
||||||
|
}
|
||||||
|
function needsParentheses(operator, parentOperator) {
|
||||||
|
return ((operator === "&&" && parentOperator === "||") ||
|
||||||
|
(["|", "^", "&", "<<", ">>", ">>>"].includes(parentOperator) &&
|
||||||
|
getOperatorPrecedence(operator) >
|
||||||
|
getOperatorPrecedence(parentOperator)) ||
|
||||||
|
[operator, parentOperator].every(o => ["==", "!="].includes(o)) ||
|
||||||
|
[operator, parentOperator].every(o => ["<<", ">>", ">>>"].includes(o)) ||
|
||||||
|
(operator === "*" && parentOperator === "/") ||
|
||||||
|
(operator === "/" && parentOperator === "*") ||
|
||||||
|
(operator === "%" && ["+", "-", "*", "/"].includes(parentOperator)) ||
|
||||||
|
(["*", "/"].includes(operator) && parentOperator === "%"));
|
||||||
|
}
|
||||||
|
const assignmentOperators = new Set([
|
||||||
|
"=",
|
||||||
|
"*=",
|
||||||
|
"/=",
|
||||||
|
"%=",
|
||||||
|
"+=",
|
||||||
|
"-=",
|
||||||
|
"<<=",
|
||||||
|
">>=",
|
||||||
|
">>>=",
|
||||||
|
"&=",
|
||||||
|
"^=",
|
||||||
|
"|="
|
||||||
|
]);
|
||||||
|
function isAssignmentOperator(operator) {
|
||||||
|
return assignmentOperators.has(operator);
|
||||||
|
}
|
||||||
|
function isCapitalizedIdentifier(fqnOrRefType) {
|
||||||
|
var _a, _b, _c;
|
||||||
|
const nextToLastIdentifier = (_c = (_b = [
|
||||||
|
fqnOrRefType.fqnOrRefTypePartFirst[0],
|
||||||
|
...((_a = fqnOrRefType.fqnOrRefTypePartRest) !== null && _a !== void 0 ? _a : [])
|
||||||
|
].at(-2)) === null || _b === void 0 ? void 0 : _b.children.fqnOrRefTypePartCommon[0].children.Identifier) === null || _c === void 0 ? void 0 : _c[0].image;
|
||||||
|
return /^\p{Uppercase_Letter}/u.test(nextToLastIdentifier !== null && nextToLastIdentifier !== void 0 ? nextToLastIdentifier : "");
|
||||||
|
}
|
||||||
|
function printTemplate(path, print, beginKey, midKey, endKey) {
|
||||||
|
const begin = call(path, ({ node }) => node.image, beginKey);
|
||||||
|
const mids = map(path, ({ node }) => node.image, midKey);
|
||||||
|
const end = call(path, ({ node }) => node.image, endKey);
|
||||||
|
const lines = [begin, ...mids, end].join("").split("\n").slice(1);
|
||||||
|
const baseIndent = findBaseIndent(lines);
|
||||||
|
const prefix = "\n" + " ".repeat(baseIndent);
|
||||||
|
const parts = [begin, ...mids, end].map(image => join(hardline, image.split(prefix)));
|
||||||
|
return indent([
|
||||||
|
parts[0],
|
||||||
|
...map(path, (expressionPath, index) => {
|
||||||
|
const expression = group([
|
||||||
|
indent([softline, print(expressionPath), lineSuffixBoundary]),
|
||||||
|
softline
|
||||||
|
]);
|
||||||
|
return index === 0 ? expression : [parts[index], expression];
|
||||||
|
}, "embeddedExpression"),
|
||||||
|
parts.at(-1)
|
||||||
|
]);
|
||||||
|
}
|
||||||
71
frontend/src/common/prettier/plugins/java/printers/helpers.d.ts
vendored
Normal file
71
frontend/src/common/prettier/plugins/java/printers/helpers.d.ts
vendored
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import type { AnnotationCstNode, ClassPermitsCstNode, ClassTypeCtx, CstElement, CstNode, ExpressionCstNode, InterfacePermitsCstNode, IToken, StatementCstNode } from "java-parser";
|
||||||
|
import type { AstPath, Doc, ParserOptions } from "prettier";
|
||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import type { JavaComment } from "../comments.js";
|
||||||
|
export declare function onlyDefinedKey<T extends Record<string, any>, K extends Key<T> & string>(obj: T, options?: K[]): K;
|
||||||
|
export declare function definedKeys<T extends Record<string, any>, K extends Key<T> & string>(obj: T, options?: K[]): K[];
|
||||||
|
export declare function printWithModifiers<T extends CstNode, P extends IterProperties<T["children"]>>(path: AstPath<T>, print: JavaPrintFn, modifierChild: P, contents: Doc, noTypeAnnotations?: boolean): builders.Doc[];
|
||||||
|
export declare function hasDeclarationAnnotations(modifiers: ModifierNode[]): boolean;
|
||||||
|
export declare function call<T extends CstNode, U, P extends IterProperties<T["children"]>>(path: AstPath<T>, callback: MapCallback<IndexValue<IndexValue<T, "children">, P>, U>, child: P): U;
|
||||||
|
export declare function each<T extends CstNode, P extends IterProperties<T["children"]>>(path: AstPath<T>, callback: MapCallback<IndexValue<IndexValue<T, "children">, P>, void>, child: P): void;
|
||||||
|
export declare function map<T extends CstNode, U, P extends IterProperties<T["children"]>>(path: AstPath<T>, callback: MapCallback<IndexValue<IndexValue<T, "children">, P>, U>, child: P): U[];
|
||||||
|
export declare function flatMap<T extends CstNode, U, P extends IterProperties<T["children"]>>(path: AstPath<T>, callback: MapCallback<IndexValue<IndexValue<T, "children">, P>, U>, children: P[]): U[];
|
||||||
|
export declare function printSingle(path: AstPath<JavaNonTerminal>, print: JavaPrintFn, _?: JavaParserOptions, args?: unknown): builders.Doc;
|
||||||
|
export declare function lineStartWithComments(node: JavaNonTerminal): number;
|
||||||
|
export declare function lineEndWithComments(node: JavaNonTerminal): number;
|
||||||
|
export declare function printDanglingComments(path: AstPath<JavaNonTerminal>): builders.Doc[];
|
||||||
|
export declare function printComment(node: JavaTerminal): string | builders.Doc[];
|
||||||
|
export declare function hasLeadingComments(node: JavaNode): boolean | undefined;
|
||||||
|
export declare function indentInParentheses(contents: Doc, opts?: {
|
||||||
|
shouldBreak?: boolean;
|
||||||
|
}): builders.Group | "()";
|
||||||
|
export declare function printArrayInitializer<T extends JavaNonTerminal, P extends IterProperties<T["children"]>>(path: AstPath<T>, print: JavaPrintFn, options: JavaParserOptions, child: P): builders.Group | "{}";
|
||||||
|
export declare function printBlock(path: AstPath<JavaNonTerminal>, contents: Doc[]): builders.Group | "{}" | (string | builders.Indent | builders.Hardline)[];
|
||||||
|
export declare function printName(path: AstPath<JavaNonTerminal & {
|
||||||
|
children: {
|
||||||
|
Identifier: IToken[];
|
||||||
|
};
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
export declare function printList<T extends JavaNonTerminal, P extends IterProperties<T["children"]>>(path: AstPath<T>, print: JavaPrintFn, child: P): builders.Doc[];
|
||||||
|
export declare function printClassPermits(path: AstPath<ClassPermitsCstNode | InterfacePermitsCstNode>, print: JavaPrintFn): builders.Group;
|
||||||
|
export declare function printClassType(path: AstPath<JavaNonTerminal & {
|
||||||
|
children: ClassTypeCtx;
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
export declare function isBinaryExpression(expression: ExpressionCstNode): boolean;
|
||||||
|
export declare function findBaseIndent(lines: string[]): number;
|
||||||
|
export declare function isEmptyStatement(statement: StatementCstNode): boolean;
|
||||||
|
export declare function isNonTerminal(node: CstElement): node is JavaNonTerminal;
|
||||||
|
export declare function isTerminal(node: CstElement): node is IToken;
|
||||||
|
export type JavaNode = CstElement & {
|
||||||
|
comments?: JavaComment[];
|
||||||
|
};
|
||||||
|
export type JavaNonTerminal = Exclude<JavaNode, IToken>;
|
||||||
|
export type JavaTerminal = Exclude<JavaNode, CstNode>;
|
||||||
|
export type JavaNodePrinters = {
|
||||||
|
[T in JavaNonTerminal["name"]]: JavaNodePrinter<T>;
|
||||||
|
};
|
||||||
|
export type JavaNodePrinter<T> = (path: AstPath<Extract<JavaNonTerminal, {
|
||||||
|
name: T;
|
||||||
|
}>>, print: JavaPrintFn, options: JavaParserOptions, args?: unknown) => Doc;
|
||||||
|
export type JavaPrintFn = (path: AstPath<JavaNode>, args?: unknown) => Doc;
|
||||||
|
export type JavaParserOptions = ParserOptions<JavaNode> & {
|
||||||
|
entrypoint?: string;
|
||||||
|
};
|
||||||
|
export type IterProperties<T> = T extends any[] ? IndexProperties<T> : ArrayProperties<T>;
|
||||||
|
type Key<T> = T extends T ? keyof T : never;
|
||||||
|
type ModifierNode = JavaNonTerminal & {
|
||||||
|
children: {
|
||||||
|
annotation?: AnnotationCstNode[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
type IsTuple<T> = T extends [] ? true : T extends [infer First, ...infer Remain] ? IsTuple<Remain> : false;
|
||||||
|
type IndexProperties<T extends {
|
||||||
|
length: number;
|
||||||
|
}> = IsTuple<T> extends true ? Exclude<Partial<T>["length"], T["length"]> : number;
|
||||||
|
type ArrayProperties<T> = {
|
||||||
|
[K in keyof T]: NonNullable<T[K]> extends readonly any[] ? K : never;
|
||||||
|
}[keyof T];
|
||||||
|
type ArrayElement<T> = T extends Array<infer E> ? E : never;
|
||||||
|
type MapCallback<T, U> = (path: AstPath<ArrayElement<T>>, index: number, value: any) => U;
|
||||||
|
type IndexValue<T, P> = T extends any[] ? P extends number ? T[P] : never : P extends keyof T ? T[P] : never;
|
||||||
|
export {};
|
||||||
239
frontend/src/common/prettier/plugins/java/printers/helpers.js
Normal file
239
frontend/src/common/prettier/plugins/java/printers/helpers.js
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import parser from "../parser.js";
|
||||||
|
const { group, hardline, ifBreak, indent, join, line, softline } = builders;
|
||||||
|
export function onlyDefinedKey(obj, options) {
|
||||||
|
const keys = definedKeys(obj, options);
|
||||||
|
if (keys.length === 1) {
|
||||||
|
return keys[0];
|
||||||
|
}
|
||||||
|
throw new Error(keys.length > 1
|
||||||
|
? `More than one defined key found: ${keys}`
|
||||||
|
: "No defined keys found");
|
||||||
|
}
|
||||||
|
export function definedKeys(obj, options) {
|
||||||
|
return (options !== null && options !== void 0 ? options : Object.keys(obj)).filter(key => obj[key] !== undefined);
|
||||||
|
}
|
||||||
|
const indexByModifier = [
|
||||||
|
"public",
|
||||||
|
"protected",
|
||||||
|
"private",
|
||||||
|
"abstract",
|
||||||
|
"default",
|
||||||
|
"static",
|
||||||
|
"final",
|
||||||
|
"transient",
|
||||||
|
"volatile",
|
||||||
|
"synchronized",
|
||||||
|
"native",
|
||||||
|
"sealed",
|
||||||
|
"non-sealed",
|
||||||
|
"strictfp"
|
||||||
|
].reduce((map, name, index) => map.set(name, index), new Map());
|
||||||
|
export function printWithModifiers(path, print, modifierChild, contents, noTypeAnnotations = false) {
|
||||||
|
const declarationAnnotations = [];
|
||||||
|
const otherModifiers = [];
|
||||||
|
const typeAnnotations = [];
|
||||||
|
each(path, modifierPath => {
|
||||||
|
const { children } = modifierPath.node;
|
||||||
|
const modifier = print(modifierPath);
|
||||||
|
if (children.annotation) {
|
||||||
|
(otherModifiers.length ? typeAnnotations : declarationAnnotations).push(modifier);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
otherModifiers.push(modifier);
|
||||||
|
declarationAnnotations.push(...typeAnnotations);
|
||||||
|
typeAnnotations.length = 0;
|
||||||
|
}
|
||||||
|
}, modifierChild);
|
||||||
|
if (noTypeAnnotations) {
|
||||||
|
declarationAnnotations.push(...typeAnnotations);
|
||||||
|
typeAnnotations.length = 0;
|
||||||
|
}
|
||||||
|
otherModifiers.sort((a, b) => indexByModifier.get(a) - indexByModifier.get(b));
|
||||||
|
return join(hardline, [
|
||||||
|
...declarationAnnotations,
|
||||||
|
join(" ", [...otherModifiers, ...typeAnnotations, contents])
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
export function hasDeclarationAnnotations(modifiers) {
|
||||||
|
let hasAnnotation = false;
|
||||||
|
let hasNonAnnotation = false;
|
||||||
|
for (const modifier of modifiers) {
|
||||||
|
if (modifier.children.annotation) {
|
||||||
|
hasAnnotation = true;
|
||||||
|
}
|
||||||
|
else if (hasAnnotation) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hasNonAnnotation = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hasAnnotation && !hasNonAnnotation;
|
||||||
|
}
|
||||||
|
export function call(path, callback, child) {
|
||||||
|
return path.map(callback, "children", child)[0];
|
||||||
|
}
|
||||||
|
export function each(path, callback, child) {
|
||||||
|
if (path.node.children[child]) {
|
||||||
|
path.each(callback, "children", child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export function map(path, callback, child) {
|
||||||
|
return path.node.children[child] ? path.map(callback, "children", child) : [];
|
||||||
|
}
|
||||||
|
export function flatMap(path, callback, children) {
|
||||||
|
return children
|
||||||
|
.flatMap(child => map(path, callback, child).map((doc, index) => {
|
||||||
|
const node = path.node.children[child][index];
|
||||||
|
return {
|
||||||
|
doc,
|
||||||
|
startOffset: parser.locStart(node)
|
||||||
|
};
|
||||||
|
}))
|
||||||
|
.sort((a, b) => a.startOffset - b.startOffset)
|
||||||
|
.map(({ doc }) => doc);
|
||||||
|
}
|
||||||
|
export function printSingle(path, print, _, args) {
|
||||||
|
return call(path, childPath => print(childPath, args), onlyDefinedKey(path.node.children));
|
||||||
|
}
|
||||||
|
export function lineStartWithComments(node) {
|
||||||
|
const { comments, location } = node;
|
||||||
|
return comments
|
||||||
|
? Math.min(location.startLine, comments[0].startLine)
|
||||||
|
: location.startLine;
|
||||||
|
}
|
||||||
|
export function lineEndWithComments(node) {
|
||||||
|
const { comments, location } = node;
|
||||||
|
return comments
|
||||||
|
? Math.max(location.endLine, comments.at(-1).endLine)
|
||||||
|
: location.endLine;
|
||||||
|
}
|
||||||
|
export function printDanglingComments(path) {
|
||||||
|
if (!path.node.comments) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const comments = [];
|
||||||
|
path.each(commentPath => {
|
||||||
|
const comment = commentPath.node;
|
||||||
|
if (comment.leading || comment.trailing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
comment.printed = true;
|
||||||
|
comments.push(printComment(comment));
|
||||||
|
}, "comments");
|
||||||
|
return join(hardline, comments);
|
||||||
|
}
|
||||||
|
export function printComment(node) {
|
||||||
|
const { image } = node;
|
||||||
|
const lines = image.split("\n").map(line => line.trim());
|
||||||
|
return lines.length > 1 &&
|
||||||
|
lines[0].startsWith("/*") &&
|
||||||
|
lines.slice(1).every(line => line.startsWith("*")) &&
|
||||||
|
lines.at(-1).endsWith("*/")
|
||||||
|
? join(hardline, lines.map((line, index) => (index === 0 ? line : ` ${line}`)))
|
||||||
|
: image;
|
||||||
|
}
|
||||||
|
export function hasLeadingComments(node) {
|
||||||
|
var _a;
|
||||||
|
return (_a = node.comments) === null || _a === void 0 ? void 0 : _a.some(({ leading }) => leading);
|
||||||
|
}
|
||||||
|
export function indentInParentheses(contents, opts) {
|
||||||
|
return !Array.isArray(contents) || contents.length
|
||||||
|
? group(["(", indent([softline, contents]), softline, ")"], opts)
|
||||||
|
: "()";
|
||||||
|
}
|
||||||
|
export function printArrayInitializer(path, print, options, child) {
|
||||||
|
const list = [];
|
||||||
|
if (child && child in path.node.children) {
|
||||||
|
list.push(call(path, print, child));
|
||||||
|
if (options.trailingComma !== "none") {
|
||||||
|
list.push(ifBreak(","));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list.push(...printDanglingComments(path));
|
||||||
|
return list.length ? group(["{", indent([line, ...list]), line, "}"]) : "{}";
|
||||||
|
}
|
||||||
|
export function printBlock(path, contents) {
|
||||||
|
if (!contents.length) {
|
||||||
|
const danglingComments = printDanglingComments(path);
|
||||||
|
return danglingComments.length
|
||||||
|
? ["{", indent([hardline, ...danglingComments]), hardline, "}"]
|
||||||
|
: "{}";
|
||||||
|
}
|
||||||
|
return group([
|
||||||
|
"{",
|
||||||
|
indent([hardline, ...join(hardline, contents)]),
|
||||||
|
hardline,
|
||||||
|
"}"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
export function printName(path, print) {
|
||||||
|
return join(".", map(path, print, "Identifier"));
|
||||||
|
}
|
||||||
|
export function printList(path, print, child) {
|
||||||
|
return join([",", line], map(path, print, child));
|
||||||
|
}
|
||||||
|
export function printClassPermits(path, print) {
|
||||||
|
return group([
|
||||||
|
"permits",
|
||||||
|
indent([line, group(printList(path, print, "typeName"))])
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
export function printClassType(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
return definedKeys(children, ["annotation", "Identifier", "typeArguments"])
|
||||||
|
.flatMap(child => children[child].map((node, index) => ({
|
||||||
|
child,
|
||||||
|
index,
|
||||||
|
startOffset: parser.locStart(node)
|
||||||
|
})))
|
||||||
|
.sort((a, b) => a.startOffset - b.startOffset)
|
||||||
|
.flatMap(({ child, index: childIndex }, index, array) => {
|
||||||
|
const node = children[child][childIndex];
|
||||||
|
const next = array.at(index + 1);
|
||||||
|
const nextNode = next && children[next.child][next.index];
|
||||||
|
const docs = [path.call(print, "children", child, childIndex)];
|
||||||
|
if (nextNode) {
|
||||||
|
if (isNonTerminal(node)) {
|
||||||
|
docs.push(node.name === "annotation" ? " " : ".");
|
||||||
|
}
|
||||||
|
else if (isTerminal(nextNode) || nextNode.name === "annotation") {
|
||||||
|
docs.push(".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return docs;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
export function isBinaryExpression(expression) {
|
||||||
|
var _a;
|
||||||
|
const conditionalExpression = (_a = expression.children.conditionalExpression) === null || _a === void 0 ? void 0 : _a[0].children;
|
||||||
|
if (!conditionalExpression) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const isTernary = conditionalExpression.QuestionMark !== undefined;
|
||||||
|
if (isTernary) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const hasNonAssignmentOperators = Object.values(conditionalExpression.binaryExpression[0].children).some(child => {
|
||||||
|
var _a;
|
||||||
|
return isTerminal(child[0]) &&
|
||||||
|
!((_a = child[0].tokenType.CATEGORIES) === null || _a === void 0 ? void 0 : _a.some(category => category.name === "AssignmentOperator"));
|
||||||
|
});
|
||||||
|
return hasNonAssignmentOperators;
|
||||||
|
}
|
||||||
|
export function findBaseIndent(lines) {
|
||||||
|
return lines.length
|
||||||
|
? Math.min(...lines.map(line => line.search(/\S/)).filter(indent => indent >= 0))
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
export function isEmptyStatement(statement) {
|
||||||
|
var _a;
|
||||||
|
return (((_a = statement.children.statementWithoutTrailingSubstatement) === null || _a === void 0 ? void 0 : _a[0].children.emptyStatement) !== undefined);
|
||||||
|
}
|
||||||
|
export function isNonTerminal(node) {
|
||||||
|
return !isTerminal(node);
|
||||||
|
}
|
||||||
|
export function isTerminal(node) {
|
||||||
|
return "tokenType" in node;
|
||||||
|
}
|
||||||
2
frontend/src/common/prettier/plugins/java/printers/index.d.ts
vendored
Normal file
2
frontend/src/common/prettier/plugins/java/printers/index.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import type { JavaNodePrinter, JavaNodePrinters } from "./helpers.js";
|
||||||
|
export declare function printerForNodeType<T extends keyof JavaNodePrinters>(type: T): JavaNodePrinter<T>;
|
||||||
13
frontend/src/common/prettier/plugins/java/printers/index.js
Normal file
13
frontend/src/common/prettier/plugins/java/printers/index.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import arrays from "./arrays.js";
|
||||||
|
import blocksAndStatements from "./blocks-and-statements.js";
|
||||||
|
import classes from "./classes.js";
|
||||||
|
import expressions from "./expressions.js";
|
||||||
|
import interfaces from "./interfaces.js";
|
||||||
|
import lexicalStructure from "./lexical-structure.js";
|
||||||
|
import names from "./names.js";
|
||||||
|
import packagesAndModules from "./packages-and-modules.js";
|
||||||
|
import typesValuesAndVariables from "./types-values-and-variables.js";
|
||||||
|
const printersByNodeType = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, arrays), blocksAndStatements), classes), expressions), interfaces), lexicalStructure), names), packagesAndModules), typesValuesAndVariables);
|
||||||
|
export function printerForNodeType(type) {
|
||||||
|
return printersByNodeType[type];
|
||||||
|
}
|
||||||
62
frontend/src/common/prettier/plugins/java/printers/interfaces.d.ts
vendored
Normal file
62
frontend/src/common/prettier/plugins/java/printers/interfaces.d.ts
vendored
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import { printClassPermits, printSingle } from "./helpers.js";
|
||||||
|
declare const _default: {
|
||||||
|
interfaceDeclaration(path: import("prettier").AstPath<import("java-parser").InterfaceDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
normalInterfaceDeclaration(path: import("prettier").AstPath<import("java-parser").NormalInterfaceDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
interfaceModifier: typeof printSingle;
|
||||||
|
interfaceExtends(path: import("prettier").AstPath<import("java-parser").InterfaceExtendsCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Group;
|
||||||
|
interfacePermits: typeof printClassPermits;
|
||||||
|
interfaceBody(path: import("prettier").AstPath<import("java-parser").InterfaceBodyCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Group | "{}" | (string | builders.Indent | builders.Hardline)[];
|
||||||
|
interfaceMemberDeclaration(path: import("prettier").AstPath<import("java-parser").InterfaceMemberDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc;
|
||||||
|
constantDeclaration(path: import("prettier").AstPath<import("java-parser").ConstantDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
constantModifier: typeof printSingle;
|
||||||
|
interfaceMethodDeclaration(path: import("prettier").AstPath<import("java-parser").InterfaceMethodDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
interfaceMethodModifier: typeof printSingle;
|
||||||
|
annotationInterfaceDeclaration(path: import("prettier").AstPath<import("java-parser").AnnotationInterfaceDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
annotationInterfaceBody(path: import("prettier").AstPath<import("java-parser").AnnotationInterfaceBodyCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Group | "{}" | (string | builders.Indent | builders.Hardline)[];
|
||||||
|
annotationInterfaceMemberDeclaration(path: import("prettier").AstPath<import("java-parser").AnnotationInterfaceMemberDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc;
|
||||||
|
annotationInterfaceElementDeclaration(path: import("prettier").AstPath<import("java-parser").AnnotationInterfaceElementDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
annotationInterfaceElementModifier: typeof printSingle;
|
||||||
|
defaultValue(path: import("prettier").AstPath<import("java-parser").DefaultValueCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
annotation(path: import("prettier").AstPath<import("java-parser").AnnotationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
elementValuePairList(path: import("prettier").AstPath<import("java-parser").ElementValuePairListCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
elementValuePair(path: import("prettier").AstPath<import("java-parser").ElementValuePairCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
elementValue: typeof printSingle;
|
||||||
|
elementValueArrayInitializer(path: import("prettier").AstPath<import("java-parser").ElementValueArrayInitializerCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn, options: import("./helpers.js").JavaParserOptions): builders.Group | "{}";
|
||||||
|
elementValueList(path: import("prettier").AstPath<import("java-parser").ElementValueListCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Group;
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
157
frontend/src/common/prettier/plugins/java/printers/interfaces.js
Normal file
157
frontend/src/common/prettier/plugins/java/printers/interfaces.js
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import { call, each, hasDeclarationAnnotations, indentInParentheses, lineEndWithComments, lineStartWithComments, onlyDefinedKey, printArrayInitializer, printBlock, printClassPermits, printList, printSingle, printWithModifiers } from "./helpers.js";
|
||||||
|
const { group, hardline, indent, join, line } = builders;
|
||||||
|
export default {
|
||||||
|
interfaceDeclaration(path, print) {
|
||||||
|
const declarationKey = onlyDefinedKey(path.node.children, [
|
||||||
|
"annotationInterfaceDeclaration",
|
||||||
|
"normalInterfaceDeclaration"
|
||||||
|
]);
|
||||||
|
return printWithModifiers(path, print, "interfaceModifier", call(path, print, declarationKey), true);
|
||||||
|
},
|
||||||
|
normalInterfaceDeclaration(path, print) {
|
||||||
|
const { interfaceExtends, interfacePermits, typeParameters } = path.node.children;
|
||||||
|
const header = ["interface ", call(path, print, "typeIdentifier")];
|
||||||
|
if (typeParameters) {
|
||||||
|
header.push(call(path, print, "typeParameters"));
|
||||||
|
}
|
||||||
|
if (interfaceExtends) {
|
||||||
|
header.push(indent([line, call(path, print, "interfaceExtends")]));
|
||||||
|
}
|
||||||
|
if (interfacePermits) {
|
||||||
|
header.push(indent([line, call(path, print, "interfacePermits")]));
|
||||||
|
}
|
||||||
|
return [group(header), " ", call(path, print, "interfaceBody")];
|
||||||
|
},
|
||||||
|
interfaceModifier: printSingle,
|
||||||
|
interfaceExtends(path, print) {
|
||||||
|
return group([
|
||||||
|
"extends",
|
||||||
|
indent([line, call(path, print, "interfaceTypeList")])
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
interfacePermits: printClassPermits,
|
||||||
|
interfaceBody(path, print) {
|
||||||
|
const declarations = [];
|
||||||
|
let previousRequiresPadding = false;
|
||||||
|
each(path, declarationPath => {
|
||||||
|
var _a, _b, _c, _d;
|
||||||
|
const declaration = print(declarationPath);
|
||||||
|
if (declaration === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { node, previous } = declarationPath;
|
||||||
|
const constantDeclaration = (_a = node.children.constantDeclaration) === null || _a === void 0 ? void 0 : _a[0].children;
|
||||||
|
const methodDeclaration = (_b = node.children.interfaceMethodDeclaration) === null || _b === void 0 ? void 0 : _b[0].children;
|
||||||
|
const currentRequiresPadding = (!constantDeclaration && !methodDeclaration) ||
|
||||||
|
(methodDeclaration === null || methodDeclaration === void 0 ? void 0 : methodDeclaration.methodBody[0].children.block) !== undefined ||
|
||||||
|
hasDeclarationAnnotations((_d = (_c = constantDeclaration === null || constantDeclaration === void 0 ? void 0 : constantDeclaration.constantModifier) !== null && _c !== void 0 ? _c : methodDeclaration === null || methodDeclaration === void 0 ? void 0 : methodDeclaration.interfaceMethodModifier) !== null && _d !== void 0 ? _d : []);
|
||||||
|
const blankLine = declarations.length > 0 &&
|
||||||
|
(previousRequiresPadding ||
|
||||||
|
currentRequiresPadding ||
|
||||||
|
lineStartWithComments(node) > lineEndWithComments(previous) + 1);
|
||||||
|
declarations.push(blankLine ? [hardline, declaration] : declaration);
|
||||||
|
previousRequiresPadding = currentRequiresPadding;
|
||||||
|
}, "interfaceMemberDeclaration");
|
||||||
|
return printBlock(path, declarations);
|
||||||
|
},
|
||||||
|
interfaceMemberDeclaration(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
return children.Semicolon
|
||||||
|
? ""
|
||||||
|
: call(path, print, onlyDefinedKey(children));
|
||||||
|
},
|
||||||
|
constantDeclaration(path, print) {
|
||||||
|
const declaration = [
|
||||||
|
call(path, print, "unannType"),
|
||||||
|
" ",
|
||||||
|
call(path, print, "variableDeclaratorList"),
|
||||||
|
";"
|
||||||
|
];
|
||||||
|
return printWithModifiers(path, print, "constantModifier", declaration);
|
||||||
|
},
|
||||||
|
constantModifier: printSingle,
|
||||||
|
interfaceMethodDeclaration(path, print) {
|
||||||
|
const declaration = [
|
||||||
|
call(path, print, "methodHeader"),
|
||||||
|
path.node.children.methodBody[0].children.Semicolon ? "" : " ",
|
||||||
|
call(path, print, "methodBody")
|
||||||
|
];
|
||||||
|
return printWithModifiers(path, print, "interfaceMethodModifier", declaration);
|
||||||
|
},
|
||||||
|
interfaceMethodModifier: printSingle,
|
||||||
|
annotationInterfaceDeclaration(path, print) {
|
||||||
|
return join(" ", [
|
||||||
|
"@interface",
|
||||||
|
call(path, print, "typeIdentifier"),
|
||||||
|
call(path, print, "annotationInterfaceBody")
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
annotationInterfaceBody(path, print) {
|
||||||
|
const declarations = [];
|
||||||
|
each(path, declarationPath => {
|
||||||
|
const declaration = print(declarationPath);
|
||||||
|
if (declaration === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
declarations.push(declarationPath.isFirst ? declaration : [hardline, declaration]);
|
||||||
|
}, "annotationInterfaceMemberDeclaration");
|
||||||
|
return printBlock(path, declarations);
|
||||||
|
},
|
||||||
|
annotationInterfaceMemberDeclaration(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
return children.Semicolon
|
||||||
|
? ""
|
||||||
|
: call(path, print, onlyDefinedKey(children));
|
||||||
|
},
|
||||||
|
annotationInterfaceElementDeclaration(path, print) {
|
||||||
|
const { dims, defaultValue } = path.node.children;
|
||||||
|
const declaration = [
|
||||||
|
call(path, print, "unannType"),
|
||||||
|
" ",
|
||||||
|
call(path, print, "Identifier"),
|
||||||
|
"()"
|
||||||
|
];
|
||||||
|
if (dims) {
|
||||||
|
declaration.push(call(path, print, "dims"));
|
||||||
|
}
|
||||||
|
if (defaultValue) {
|
||||||
|
declaration.push(" ", call(path, print, "defaultValue"));
|
||||||
|
}
|
||||||
|
declaration.push(";");
|
||||||
|
return printWithModifiers(path, print, "annotationInterfaceElementModifier", declaration);
|
||||||
|
},
|
||||||
|
annotationInterfaceElementModifier: printSingle,
|
||||||
|
defaultValue(path, print) {
|
||||||
|
return ["default ", call(path, print, "elementValue")];
|
||||||
|
},
|
||||||
|
annotation(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const annotation = ["@", call(path, print, "typeName")];
|
||||||
|
if (children.elementValue || children.elementValuePairList) {
|
||||||
|
const valuesKey = onlyDefinedKey(children, [
|
||||||
|
"elementValue",
|
||||||
|
"elementValuePairList"
|
||||||
|
]);
|
||||||
|
annotation.push(indentInParentheses(call(path, print, valuesKey)));
|
||||||
|
}
|
||||||
|
return annotation;
|
||||||
|
},
|
||||||
|
elementValuePairList(path, print) {
|
||||||
|
return printList(path, print, "elementValuePair");
|
||||||
|
},
|
||||||
|
elementValuePair(path, print) {
|
||||||
|
return join(" ", [
|
||||||
|
call(path, print, "Identifier"),
|
||||||
|
call(path, print, "Equals"),
|
||||||
|
call(path, print, "elementValue")
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
elementValue: printSingle,
|
||||||
|
elementValueArrayInitializer(path, print, options) {
|
||||||
|
return printArrayInitializer(path, print, options, "elementValueList");
|
||||||
|
},
|
||||||
|
elementValueList(path, print) {
|
||||||
|
return group(printList(path, print, "elementValue"));
|
||||||
|
}
|
||||||
|
};
|
||||||
14
frontend/src/common/prettier/plugins/java/printers/lexical-structure.d.ts
vendored
Normal file
14
frontend/src/common/prettier/plugins/java/printers/lexical-structure.d.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import { printSingle } from "./helpers.js";
|
||||||
|
declare const _default: {
|
||||||
|
literal(path: import("prettier").AstPath<import("java-parser").LiteralCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc;
|
||||||
|
integerLiteral: typeof printSingle;
|
||||||
|
floatingPointLiteral: typeof printSingle;
|
||||||
|
booleanLiteral: typeof printSingle;
|
||||||
|
shiftOperator(path: import("prettier").AstPath<import("java-parser").ShiftOperatorCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import { findBaseIndent, map, onlyDefinedKey, printSingle } from "./helpers.js";
|
||||||
|
const { hardline, indent, join } = builders;
|
||||||
|
export default {
|
||||||
|
literal(path, print) {
|
||||||
|
const { TextBlock } = path.node.children;
|
||||||
|
if (!TextBlock) {
|
||||||
|
return printSingle(path, print);
|
||||||
|
}
|
||||||
|
const [open, ...lines] = TextBlock[0].image.split("\n");
|
||||||
|
const baseIndent = findBaseIndent(lines);
|
||||||
|
const textBlock = join(hardline, [
|
||||||
|
open,
|
||||||
|
...lines.map(line => line.slice(baseIndent))
|
||||||
|
]);
|
||||||
|
const ancestor = path.getNode(14);
|
||||||
|
return (ancestor === null || ancestor === void 0 ? void 0 : ancestor.name) === "variableInitializer" ||
|
||||||
|
((ancestor === null || ancestor === void 0 ? void 0 : ancestor.name) === "binaryExpression" &&
|
||||||
|
ancestor.children.AssignmentOperator)
|
||||||
|
? indent(textBlock)
|
||||||
|
: textBlock;
|
||||||
|
},
|
||||||
|
integerLiteral: printSingle,
|
||||||
|
floatingPointLiteral: printSingle,
|
||||||
|
booleanLiteral: printSingle,
|
||||||
|
shiftOperator(path, print) {
|
||||||
|
return map(path, print, onlyDefinedKey(path.node.children));
|
||||||
|
}
|
||||||
|
};
|
||||||
12
frontend/src/common/prettier/plugins/java/printers/names.d.ts
vendored
Normal file
12
frontend/src/common/prettier/plugins/java/printers/names.d.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { printName, printSingle } from "./helpers.js";
|
||||||
|
declare const _default: {
|
||||||
|
typeIdentifier: typeof printSingle;
|
||||||
|
moduleName: typeof printName;
|
||||||
|
packageName: typeof printName;
|
||||||
|
typeName: typeof printName;
|
||||||
|
expressionName: typeof printName;
|
||||||
|
methodName: typeof printSingle;
|
||||||
|
packageOrTypeName: typeof printName;
|
||||||
|
ambiguousName: typeof printName;
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
11
frontend/src/common/prettier/plugins/java/printers/names.js
Normal file
11
frontend/src/common/prettier/plugins/java/printers/names.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { printName, printSingle } from "./helpers.js";
|
||||||
|
export default {
|
||||||
|
typeIdentifier: printSingle,
|
||||||
|
moduleName: printName,
|
||||||
|
packageName: printName,
|
||||||
|
typeName: printName,
|
||||||
|
expressionName: printName,
|
||||||
|
methodName: printSingle,
|
||||||
|
packageOrTypeName: printName,
|
||||||
|
ambiguousName: printName
|
||||||
|
};
|
||||||
46
frontend/src/common/prettier/plugins/java/printers/packages-and-modules.d.ts
vendored
Normal file
46
frontend/src/common/prettier/plugins/java/printers/packages-and-modules.d.ts
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import type { ExportsModuleDirectiveCstNode, ImportDeclarationCstNode, OpensModuleDirectiveCstNode } from "java-parser";
|
||||||
|
import type { AstPath } from "prettier";
|
||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import { printSingle, type JavaPrintFn } from "./helpers.js";
|
||||||
|
declare const _default: {
|
||||||
|
compilationUnit(path: AstPath<import("java-parser").CompilationUnitCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
ordinaryCompilationUnit(path: AstPath<import("java-parser").OrdinaryCompilationUnitCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
modularCompilationUnit(path: AstPath<import("java-parser").ModularCompilationUnitCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
packageDeclaration(path: AstPath<import("java-parser").PackageDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
packageModifier: typeof printSingle;
|
||||||
|
importDeclaration(path: AstPath<ImportDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc;
|
||||||
|
typeDeclaration(path: AstPath<import("java-parser").TypeDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc;
|
||||||
|
moduleDeclaration(path: AstPath<import("java-parser").ModuleDeclarationCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
moduleDirective: typeof printSingle;
|
||||||
|
requiresModuleDirective(path: AstPath<import("java-parser").RequiresModuleDirectiveCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
exportsModuleDirective(path: AstPath<ExportsModuleDirectiveCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
opensModuleDirective(path: AstPath<OpensModuleDirectiveCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
usesModuleDirective(path: AstPath<import("java-parser").UsesModuleDirectiveCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
providesModuleDirective(path: AstPath<import("java-parser").ProvidesModuleDirectiveCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: JavaPrintFn): builders.Doc[];
|
||||||
|
requiresModifier: typeof printSingle;
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import { call, lineEndWithComments, lineStartWithComments, map, printBlock, printDanglingComments, printName, printSingle } from "./helpers.js";
|
||||||
|
const { group, hardline, indent, join, line } = builders;
|
||||||
|
export default {
|
||||||
|
compilationUnit(path, print) {
|
||||||
|
return [...printDanglingComments(path), printSingle(path, print), hardline];
|
||||||
|
},
|
||||||
|
ordinaryCompilationUnit(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const declarations = [];
|
||||||
|
if (children.packageDeclaration) {
|
||||||
|
declarations.push(call(path, print, "packageDeclaration"));
|
||||||
|
}
|
||||||
|
if (children.importDeclaration) {
|
||||||
|
const staticCount = sortImports(children.importDeclaration);
|
||||||
|
const importDeclarations = map(path, print, "importDeclaration").filter(doc => doc !== "");
|
||||||
|
const staticDeclarations = importDeclarations.slice(0, staticCount);
|
||||||
|
const nonStaticDeclarations = importDeclarations.slice(staticCount);
|
||||||
|
declarations.push(...[staticDeclarations, nonStaticDeclarations]
|
||||||
|
.filter(({ length }) => length)
|
||||||
|
.map(declarations => join(hardline, declarations)));
|
||||||
|
}
|
||||||
|
if (children.typeDeclaration) {
|
||||||
|
declarations.push(...map(path, print, "typeDeclaration").filter(declaration => declaration !== ""));
|
||||||
|
}
|
||||||
|
return join([hardline, hardline], declarations);
|
||||||
|
},
|
||||||
|
modularCompilationUnit(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const declarations = [];
|
||||||
|
if (children.importDeclaration) {
|
||||||
|
const staticCount = sortImports(children.importDeclaration);
|
||||||
|
const importDeclarations = map(path, print, "importDeclaration").filter(doc => doc !== "");
|
||||||
|
const staticDeclarations = importDeclarations.slice(0, staticCount);
|
||||||
|
const nonStaticDeclarations = importDeclarations.slice(staticCount);
|
||||||
|
declarations.push(...[staticDeclarations, nonStaticDeclarations]
|
||||||
|
.filter(({ length }) => length)
|
||||||
|
.map(declarations => join(hardline, declarations)));
|
||||||
|
}
|
||||||
|
declarations.push(call(path, print, "moduleDeclaration"));
|
||||||
|
return join([hardline, hardline], declarations);
|
||||||
|
},
|
||||||
|
packageDeclaration(path, print) {
|
||||||
|
return join(hardline, [
|
||||||
|
...map(path, print, "packageModifier"),
|
||||||
|
["package ", printName(path, print), ";"]
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
packageModifier: printSingle,
|
||||||
|
importDeclaration(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
if (children.emptyStatement) {
|
||||||
|
return call(path, print, "emptyStatement");
|
||||||
|
}
|
||||||
|
const declaration = ["import "];
|
||||||
|
if (children.Static) {
|
||||||
|
declaration.push("static ");
|
||||||
|
}
|
||||||
|
declaration.push(call(path, print, "packageOrTypeName"));
|
||||||
|
if (children.Star) {
|
||||||
|
declaration.push(".*");
|
||||||
|
}
|
||||||
|
declaration.push(";");
|
||||||
|
return declaration;
|
||||||
|
},
|
||||||
|
typeDeclaration(path, print) {
|
||||||
|
return path.node.children.Semicolon ? "" : printSingle(path, print);
|
||||||
|
},
|
||||||
|
moduleDeclaration(path, print) {
|
||||||
|
const { annotation, Open } = path.node.children;
|
||||||
|
const prefix = [];
|
||||||
|
if (annotation) {
|
||||||
|
prefix.push(...map(path, print, "annotation"));
|
||||||
|
}
|
||||||
|
if (Open) {
|
||||||
|
prefix.push("open");
|
||||||
|
}
|
||||||
|
const declarations = map(path, declarationPath => {
|
||||||
|
const declaration = print(declarationPath);
|
||||||
|
const { node, previous } = declarationPath;
|
||||||
|
return !previous ||
|
||||||
|
lineStartWithComments(node) <= lineEndWithComments(previous) + 1
|
||||||
|
? declaration
|
||||||
|
: [hardline, declaration];
|
||||||
|
}, "moduleDirective");
|
||||||
|
return join(" ", [
|
||||||
|
...prefix,
|
||||||
|
"module",
|
||||||
|
printName(path, print),
|
||||||
|
printBlock(path, declarations)
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
moduleDirective: printSingle,
|
||||||
|
requiresModuleDirective(path, print) {
|
||||||
|
return join(" ", [
|
||||||
|
"requires",
|
||||||
|
...map(path, print, "requiresModifier"),
|
||||||
|
[call(path, print, "moduleName"), ";"]
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
exportsModuleDirective(path, print) {
|
||||||
|
return printToModuleNamesDirective(path, print, "exports");
|
||||||
|
},
|
||||||
|
opensModuleDirective(path, print) {
|
||||||
|
return printToModuleNamesDirective(path, print, "opens");
|
||||||
|
},
|
||||||
|
usesModuleDirective(path, print) {
|
||||||
|
return ["uses ", call(path, print, "typeName"), ";"];
|
||||||
|
},
|
||||||
|
providesModuleDirective(path, print) {
|
||||||
|
const [firstTypeName, ...restTypeNames] = map(path, print, "typeName");
|
||||||
|
return [
|
||||||
|
"provides ",
|
||||||
|
firstTypeName,
|
||||||
|
group(indent([
|
||||||
|
line,
|
||||||
|
group(indent(["with", line, ...join([",", line], restTypeNames)]))
|
||||||
|
])),
|
||||||
|
";"
|
||||||
|
];
|
||||||
|
},
|
||||||
|
requiresModifier: printSingle
|
||||||
|
};
|
||||||
|
function sortImports(importDeclarations) {
|
||||||
|
importDeclarations.sort(({ children: a }, { children: b }) => {
|
||||||
|
if (a.Static && !b.Static) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (b.Static && !a.Static) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!b.packageOrTypeName) {
|
||||||
|
if (a.packageOrTypeName) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (!a.packageOrTypeName) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return compareFqn(a.packageOrTypeName[0], b.packageOrTypeName[0]);
|
||||||
|
});
|
||||||
|
return importDeclarations.reduce((staticCount, importDeclaration) => importDeclaration.children.Static ? staticCount + 1 : staticCount, 0);
|
||||||
|
}
|
||||||
|
function compareFqn(a, b) {
|
||||||
|
const identifiersA = a.children.Identifier;
|
||||||
|
const identifiersB = b.children.Identifier;
|
||||||
|
const minParts = Math.min(identifiersA.length, identifiersB.length);
|
||||||
|
for (let i = 0; i < minParts; i++) {
|
||||||
|
const imageA = identifiersA[i].image;
|
||||||
|
const imageB = identifiersB[i].image;
|
||||||
|
if (imageA < imageB) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (imageA > imageB) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return identifiersA.length - identifiersB.length;
|
||||||
|
}
|
||||||
|
function printToModuleNamesDirective(path, print, prefix) {
|
||||||
|
const directive = [prefix, " ", call(path, print, "packageName")];
|
||||||
|
if (path.node.children.moduleName) {
|
||||||
|
const moduleNames = join([",", line], map(path, print, "moduleName"));
|
||||||
|
directive.push(group(indent([line, group(indent(["to", line, ...moduleNames]))])));
|
||||||
|
}
|
||||||
|
directive.push(";");
|
||||||
|
return directive;
|
||||||
|
}
|
||||||
46
frontend/src/common/prettier/plugins/java/printers/types-values-and-variables.d.ts
vendored
Normal file
46
frontend/src/common/prettier/plugins/java/printers/types-values-and-variables.d.ts
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import { printClassType, printSingle } from "./helpers.js";
|
||||||
|
declare const _default: {
|
||||||
|
primitiveType(path: import("prettier").AstPath<import("java-parser").PrimitiveTypeCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
numericType: typeof printSingle;
|
||||||
|
integralType: typeof printSingle;
|
||||||
|
floatingPointType: typeof printSingle;
|
||||||
|
referenceType(path: import("prettier").AstPath<import("java-parser").ReferenceTypeCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
classOrInterfaceType: typeof printSingle;
|
||||||
|
classType: typeof printClassType;
|
||||||
|
interfaceType: typeof printSingle;
|
||||||
|
typeVariable(path: import("prettier").AstPath<import("java-parser").TypeVariableCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
dims(path: import("prettier").AstPath<import("java-parser").DimsCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
typeParameter(path: import("prettier").AstPath<import("java-parser").TypeParameterCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
typeParameterModifier: typeof printSingle;
|
||||||
|
typeBound(path: import("prettier").AstPath<import("java-parser").TypeBoundCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
additionalBound(path: import("prettier").AstPath<import("java-parser").AdditionalBoundCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
typeArguments(path: import("prettier").AstPath<import("java-parser").TypeArgumentsCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Group;
|
||||||
|
typeArgumentList(path: import("prettier").AstPath<import("java-parser").TypeArgumentListCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
typeArgument: typeof printSingle;
|
||||||
|
wildcard(path: import("prettier").AstPath<import("java-parser").WildcardCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
wildcardBounds(path: import("prettier").AstPath<import("java-parser").WildcardBoundsCstNode & {
|
||||||
|
comments?: import("../comments.js").JavaComment[];
|
||||||
|
}>, print: import("./helpers.js").JavaPrintFn): builders.Doc[];
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
import { builders } from "prettier/doc";
|
||||||
|
import { call, definedKeys, flatMap, isNonTerminal, map, onlyDefinedKey, printClassType, printList, printSingle } from "./helpers.js";
|
||||||
|
const { group, indent, join, line, softline } = builders;
|
||||||
|
export default {
|
||||||
|
primitiveType(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const typeKey = onlyDefinedKey(children, ["Boolean", "numericType"]);
|
||||||
|
return join(" ", [
|
||||||
|
...map(path, print, "annotation"),
|
||||||
|
call(path, print, typeKey)
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
numericType: printSingle,
|
||||||
|
integralType: printSingle,
|
||||||
|
floatingPointType: printSingle,
|
||||||
|
referenceType(path, print) {
|
||||||
|
const { children } = path.node;
|
||||||
|
const typeKey = onlyDefinedKey(children, [
|
||||||
|
"primitiveType",
|
||||||
|
"classOrInterfaceType"
|
||||||
|
]);
|
||||||
|
const type = call(path, print, typeKey);
|
||||||
|
return join(" ", [
|
||||||
|
...map(path, print, "annotation"),
|
||||||
|
children.dims ? [type, call(path, print, "dims")] : type
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
classOrInterfaceType: printSingle,
|
||||||
|
classType: printClassType,
|
||||||
|
interfaceType: printSingle,
|
||||||
|
typeVariable(path, print) {
|
||||||
|
return join(" ", [
|
||||||
|
...map(path, print, "annotation"),
|
||||||
|
call(path, print, "Identifier")
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
dims(path, print) {
|
||||||
|
return flatMap(path, childPath => {
|
||||||
|
const child = print(childPath);
|
||||||
|
return isNonTerminal(childPath.node) ? [child, " "] : child;
|
||||||
|
}, definedKeys(path.node.children, ["annotation", "LSquare", "RSquare"]));
|
||||||
|
},
|
||||||
|
typeParameter(path, print) {
|
||||||
|
const parameter = [
|
||||||
|
...map(path, print, "typeParameterModifier"),
|
||||||
|
call(path, print, "typeIdentifier")
|
||||||
|
];
|
||||||
|
if (path.node.children.typeBound) {
|
||||||
|
parameter.push(call(path, print, "typeBound"));
|
||||||
|
}
|
||||||
|
return join(" ", parameter);
|
||||||
|
},
|
||||||
|
typeParameterModifier: printSingle,
|
||||||
|
typeBound(path, print) {
|
||||||
|
const bound = ["extends ", call(path, print, "classOrInterfaceType")];
|
||||||
|
if (path.node.children.additionalBound) {
|
||||||
|
bound.push(group(indent([line, ...join(line, map(path, print, "additionalBound"))])));
|
||||||
|
}
|
||||||
|
return bound;
|
||||||
|
},
|
||||||
|
additionalBound(path, print) {
|
||||||
|
return ["& ", call(path, print, "interfaceType")];
|
||||||
|
},
|
||||||
|
typeArguments(path, print) {
|
||||||
|
return group([
|
||||||
|
"<",
|
||||||
|
indent([softline, call(path, print, "typeArgumentList")]),
|
||||||
|
softline,
|
||||||
|
">"
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
typeArgumentList(path, print) {
|
||||||
|
return printList(path, print, "typeArgument");
|
||||||
|
},
|
||||||
|
typeArgument: printSingle,
|
||||||
|
wildcard(path, print) {
|
||||||
|
const wildcard = [...map(path, print, "annotation"), "?"];
|
||||||
|
if (path.node.children.wildcardBounds) {
|
||||||
|
wildcard.push(call(path, print, "wildcardBounds"));
|
||||||
|
}
|
||||||
|
return join(" ", wildcard);
|
||||||
|
},
|
||||||
|
wildcardBounds(path, print) {
|
||||||
|
return [
|
||||||
|
path.node.children.Extends ? "extends" : "super",
|
||||||
|
" ",
|
||||||
|
call(path, print, "referenceType")
|
||||||
|
];
|
||||||
|
}
|
||||||
|
};
|
||||||
4
frontend/src/common/prettier/plugins/php/index.d.ts
vendored
Normal file
4
frontend/src/common/prettier/plugins/php/index.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import type { Plugin } from "prettier";
|
||||||
|
|
||||||
|
declare const plugin: Plugin;
|
||||||
|
export default plugin;
|
||||||
19
frontend/src/common/prettier/plugins/php/index.mjs
Normal file
19
frontend/src/common/prettier/plugins/php/index.mjs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
export {
|
||||||
|
languages,
|
||||||
|
printers,
|
||||||
|
parsers,
|
||||||
|
options,
|
||||||
|
defaultOptions
|
||||||
|
} from './src/index.mjs';
|
||||||
|
|
||||||
|
import { languages, printers, parsers, options, defaultOptions } from './src/index.mjs';
|
||||||
|
|
||||||
|
const phpPlugin = {
|
||||||
|
languages,
|
||||||
|
printers,
|
||||||
|
parsers,
|
||||||
|
options,
|
||||||
|
defaultOptions
|
||||||
|
};
|
||||||
|
|
||||||
|
export default phpPlugin;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user