Compare commits
20 Commits
v1.3.6
...
0338351680
| Author | SHA1 | Date | |
|---|---|---|---|
| 0338351680 | |||
| e372a0dd7c | |||
| d597f379ff | |||
| 9222a52d91 | |||
| c3670bb8cd | |||
| 2ea3456ff7 | |||
| c9379f0edb | |||
| f72010bd69 | |||
| cd027097f8 | |||
| 9cbbf729c0 | |||
|
|
c26c11e253 | ||
| 338ac358db | |||
| a83c7139c9 | |||
| 42c7d11c09 | |||
| 5ca5aa64c7 | |||
| eda7ef771e | |||
| 593c4d7783 | |||
| d24a522b32 | |||
| 41afb834ae | |||
| b745329e26 |
@@ -18,7 +18,6 @@ import * as ThemeService from "./themeservice.js";
|
||||
import * as TranslationService from "./translationservice.js";
|
||||
import * as TrayService from "./trayservice.js";
|
||||
import * as WindowService from "./windowservice.js";
|
||||
import * as WindowSnapService from "./windowsnapservice.js";
|
||||
export {
|
||||
BackupService,
|
||||
ConfigService,
|
||||
@@ -36,8 +35,7 @@ export {
|
||||
ThemeService,
|
||||
TranslationService,
|
||||
TrayService,
|
||||
WindowService,
|
||||
WindowSnapService
|
||||
WindowService
|
||||
};
|
||||
|
||||
export * from "./models.js";
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
/**
|
||||
* WindowSnapService 窗口吸附服务
|
||||
* @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";
|
||||
|
||||
/**
|
||||
* Cleanup 清理资源
|
||||
*/
|
||||
export function Cleanup(): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2155505498) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* GetCurrentThreshold 获取当前自适应阈值(用于调试或显示)
|
||||
*/
|
||||
export function GetCurrentThreshold(): Promise<number> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(3176419026) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* OnWindowSnapConfigChanged 处理窗口吸附配置变更
|
||||
*/
|
||||
export function OnWindowSnapConfigChanged(enabled: boolean): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(3794787039, enabled) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* RegisterWindow 注册需要吸附管理的窗口
|
||||
*/
|
||||
export function RegisterWindow(documentID: number, window: application$0.WebviewWindow | null, title: string): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(1000222723, documentID, window, title) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* ServiceShutdown 实现服务关闭接口
|
||||
*/
|
||||
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(1172710495) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* SetAppReferences 设置应用和主窗口引用
|
||||
*/
|
||||
export function SetAppReferences(app: application$0.App | null, mainWindow: application$0.WebviewWindow | null): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(1782093351, app, mainWindow) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* SetSnapEnabled 设置是否启用窗口吸附
|
||||
*/
|
||||
export function SetSnapEnabled(enabled: boolean): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2280126835, enabled) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* UnregisterWindow 取消注册窗口
|
||||
*/
|
||||
export function UnregisterWindow(documentID: number): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2844230768, documentID) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
@@ -9,5 +9,6 @@
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
<script src="/math.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
2444
frontend/package-lock.json
generated
2444
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -5,20 +5,20 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --host --mode development",
|
||||
"build:dev": "vue-tsc && vite build --minify false --mode development",
|
||||
"build": "vue-tsc && vite build --mode production",
|
||||
"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": "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",
|
||||
"lint": "eslint",
|
||||
"lint:fix": "eslint --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.18.6",
|
||||
"@codemirror/autocomplete": "^6.18.7",
|
||||
"@codemirror/commands": "^6.8.1",
|
||||
"@codemirror/lang-angular": "^0.1.4",
|
||||
"@codemirror/lang-cpp": "^6.0.3",
|
||||
"@codemirror/lang-css": "^6.3.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-javascript": "^6.2.4",
|
||||
"@codemirror/lang-json": "^6.0.2",
|
||||
@@ -33,7 +33,6 @@
|
||||
"@codemirror/lang-sql": "^6.9.1",
|
||||
"@codemirror/lang-vue": "^0.1.3",
|
||||
"@codemirror/lang-wast": "^6.0.2",
|
||||
"@codemirror/lang-xml": "^6.1.0",
|
||||
"@codemirror/lang-yaml": "^6.1.2",
|
||||
"@codemirror/language": "^6.11.3",
|
||||
"@codemirror/language-data": "^6.5.1",
|
||||
@@ -41,40 +40,52 @@
|
||||
"@codemirror/lint": "^6.8.5",
|
||||
"@codemirror/search": "^6.5.11",
|
||||
"@codemirror/state": "^6.5.2",
|
||||
"@codemirror/view": "^6.38.1",
|
||||
"@codemirror/view": "^6.38.2",
|
||||
"@cospaia/prettier-plugin-clojure": "^0.0.2",
|
||||
"@lezer/highlight": "^1.2.1",
|
||||
"@lezer/lr": "^1.4.2",
|
||||
"@prettier/plugin-xml": "^3.4.2",
|
||||
"@reteps/dockerfmt": "^0.3.6",
|
||||
"@toml-tools/lexer": "^1.0.0",
|
||||
"@toml-tools/parser": "^1.0.0",
|
||||
"codemirror": "^6.0.2",
|
||||
"codemirror-lang-elixir": "^4.0.0",
|
||||
"colors-named": "^1.0.2",
|
||||
"colors-named-hex": "^1.0.2",
|
||||
"franc-min": "^6.2.0",
|
||||
"groovy-beautify": "^0.0.17",
|
||||
"hsl-matcher": "^1.2.4",
|
||||
"lezer": "^0.13.5",
|
||||
"java-parser": "^3.0.1",
|
||||
"jsox": "^1.2.123",
|
||||
"linguist-languages": "^9.0.0",
|
||||
"php-parser": "^3.2.5",
|
||||
"pinia": "^3.0.3",
|
||||
"pinia-plugin-persistedstate": "^4.5.0",
|
||||
"prettier": "^3.6.2",
|
||||
"remarkable": "^2.0.1",
|
||||
"sass": "^1.90.0",
|
||||
"vue": "^3.5.19",
|
||||
"vue-i18n": "^11.1.11",
|
||||
"sass": "^1.92.1",
|
||||
"sh-syntax": "^0.5.8",
|
||||
"vue": "^3.5.21",
|
||||
"vue-i18n": "^11.1.12",
|
||||
"vue-pick-colors": "^1.8.0",
|
||||
"vue-router": "^4.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.34.0",
|
||||
"@eslint/js": "^9.35.0",
|
||||
"@lezer/generator": "^1.8.0",
|
||||
"@types/node": "^24.3.0",
|
||||
"@types/node": "^24.3.1",
|
||||
"@types/remarkable": "^2.0.8",
|
||||
"@vitejs/plugin-vue": "^6.0.1",
|
||||
"@wailsio/runtime": "latest",
|
||||
"eslint": "^9.34.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^9.35.0",
|
||||
"eslint-plugin-vue": "^10.4.0",
|
||||
"globals": "^16.3.0",
|
||||
"globals": "^16.4.0",
|
||||
"typescript": "^5.9.2",
|
||||
"typescript-eslint": "^8.40.0",
|
||||
"typescript-eslint": "^8.43.0",
|
||||
"unplugin-vue-components": "^29.0.0",
|
||||
"vite": "^7.1.3",
|
||||
"vite": "^7.1.5",
|
||||
"vite-plugin-node-polyfills": "^0.24.0",
|
||||
"vue-eslint-parser": "^10.2.0",
|
||||
"vue-tsc": "^3.0.6"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
importScripts("guesslang.min.js")
|
||||
|
||||
const LANGUAGES = ["json", "py", "html", "sql", "md", "java", "php", "css", "xml", "cpp", "rs", "cs", "rb", "sh", "yaml", "toml", "go", "clj", "ex", "erl", "js", "ts", "swift", "kt", "groovy", "ps1", "dart", "scala"]
|
||||
|
||||
const guessLang = new self.GuessLang()
|
||||
|
||||
function sendResult(language, confidence, idx) {
|
||||
@@ -27,20 +25,13 @@ onmessage = (event) => {
|
||||
|
||||
guessLang.runModel(content).then((result) => {
|
||||
if (result.length > 0) {
|
||||
const lang = result[0]
|
||||
if (LANGUAGES.includes(lang.languageId) && lang.confidence > 0.15) {
|
||||
sendResult(lang.languageId, lang.confidence, idx)
|
||||
// 返回置信度最高的结果
|
||||
const bestResult = result[0]
|
||||
if (bestResult.confidence > 0.15) {
|
||||
sendResult(bestResult.languageId, bestResult.confidence, idx)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for (let lang of result) {
|
||||
if (LANGUAGES.includes(lang.languageId) && lang.confidence > 0.5) {
|
||||
sendResult(lang.languageId, lang.confidence, idx)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
sendResult("text", 0.0, idx)
|
||||
}).catch(() => {
|
||||
sendResult("text", 0.0, idx)
|
||||
|
||||
3
frontend/public/math.js
Normal file
3
frontend/public/math.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
frontend/src/common/prettier/plugins/clang/clang-format-cli.wasm
Normal file
BIN
frontend/src/common/prettier/plugins/clang/clang-format-cli.wasm
Normal file
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
import fs from "node:fs/promises";
|
||||
import initAsync from "./clang-format.js";
|
||||
|
||||
const wasm = new URL("./clang-format.wasm", import.meta.url);
|
||||
|
||||
export default function (init = fs.readFile(wasm)) {
|
||||
return initAsync(init);
|
||||
}
|
||||
|
||||
export * from "./clang-format.js";
|
||||
@@ -0,0 +1,8 @@
|
||||
import initAsync from "./clang-format.js";
|
||||
import wasm from "./clang-format.wasm?url";
|
||||
|
||||
export default function (input = wasm) {
|
||||
return initAsync(input);
|
||||
}
|
||||
|
||||
export * from "./clang-format.js";
|
||||
155
frontend/src/common/prettier/plugins/clang/clang-format.js
Normal file
155
frontend/src/common/prettier/plugins/clang/clang-format.js
Normal file
File diff suppressed because one or more lines are too long
BIN
frontend/src/common/prettier/plugins/clang/clang-format.wasm
Normal file
BIN
frontend/src/common/prettier/plugins/clang/clang-format.wasm
Normal file
Binary file not shown.
3
frontend/src/common/prettier/plugins/clang/cli-pre.js
Normal file
3
frontend/src/common/prettier/plugins/clang/cli-pre.js
Normal file
@@ -0,0 +1,3 @@
|
||||
Module.preRun = function customPreRun() {
|
||||
ENV.PWD = process.cwd();
|
||||
}
|
||||
858
frontend/src/common/prettier/plugins/clang/git-clang-format
Normal file
858
frontend/src/common/prettier/plugins/clang/git-clang-format
Normal file
@@ -0,0 +1,858 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# ===- git-clang-format - ClangFormat Git Integration -------*- python -*--=== #
|
||||
#
|
||||
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
# See https://llvm.org/LICENSE.txt for license information.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
#
|
||||
# ===----------------------------------------------------------------------=== #
|
||||
|
||||
r"""
|
||||
clang-format git integration
|
||||
============================
|
||||
|
||||
This file provides a clang-format integration for git. Put it somewhere in your
|
||||
path and ensure that it is executable. Then, "git clang-format" will invoke
|
||||
clang-format on the changes in current files or a specific commit.
|
||||
|
||||
For further details, run:
|
||||
git clang-format -h
|
||||
|
||||
Requires Python version >=3.8
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
import argparse
|
||||
import collections
|
||||
import contextlib
|
||||
import errno
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
usage = "git clang-format [OPTIONS] [<commit>] [<commit>|--staged] [--] [<file>...]"
|
||||
|
||||
desc = """
|
||||
If zero or one commits are given, run clang-format on all lines that differ
|
||||
between the working directory and <commit>, which defaults to HEAD. Changes are
|
||||
only applied to the working directory, or in the stage/index.
|
||||
|
||||
Examples:
|
||||
To format staged changes, i.e everything that's been `git add`ed:
|
||||
git clang-format
|
||||
|
||||
To also format everything touched in the most recent commit:
|
||||
git clang-format HEAD~1
|
||||
|
||||
If you're on a branch off main, to format everything touched on your branch:
|
||||
git clang-format main
|
||||
|
||||
If two commits are given (requires --diff), run clang-format on all lines in the
|
||||
second <commit> that differ from the first <commit>.
|
||||
|
||||
The following git-config settings set the default of the corresponding option:
|
||||
clangFormat.binary
|
||||
clangFormat.commit
|
||||
clangFormat.extensions
|
||||
clangFormat.style
|
||||
"""
|
||||
|
||||
# Name of the temporary index file in which save the output of clang-format.
|
||||
# This file is created within the .git directory.
|
||||
temp_index_basename = "clang-format-index"
|
||||
|
||||
|
||||
Range = collections.namedtuple("Range", "start, count")
|
||||
|
||||
|
||||
def main():
|
||||
config = load_git_config()
|
||||
|
||||
# In order to keep '--' yet allow options after positionals, we need to
|
||||
# check for '--' ourselves. (Setting nargs='*' throws away the '--', while
|
||||
# nargs=argparse.REMAINDER disallows options after positionals.)
|
||||
argv = sys.argv[1:]
|
||||
try:
|
||||
idx = argv.index("--")
|
||||
except ValueError:
|
||||
dash_dash = []
|
||||
else:
|
||||
dash_dash = argv[idx:]
|
||||
argv = argv[:idx]
|
||||
|
||||
default_extensions = ",".join(
|
||||
[
|
||||
# From clang/lib/Frontend/FrontendOptions.cpp, all lower case
|
||||
"c",
|
||||
"h", # C
|
||||
"m", # ObjC
|
||||
"mm", # ObjC++
|
||||
"cc",
|
||||
"cp",
|
||||
"cpp",
|
||||
"c++",
|
||||
"cxx",
|
||||
"hh",
|
||||
"hpp",
|
||||
"hxx",
|
||||
"inc", # C++
|
||||
"ccm",
|
||||
"cppm",
|
||||
"cxxm",
|
||||
"c++m", # C++ Modules
|
||||
"cu",
|
||||
"cuh", # CUDA
|
||||
"cl", # OpenCL
|
||||
# Other languages that clang-format supports
|
||||
"proto",
|
||||
"protodevel", # Protocol Buffers
|
||||
"java", # Java
|
||||
"js",
|
||||
"mjs",
|
||||
"cjs", # JavaScript
|
||||
"ts", # TypeScript
|
||||
"cs", # C Sharp
|
||||
"json",
|
||||
"ipynb", # Json
|
||||
"sv",
|
||||
"svh",
|
||||
"v",
|
||||
"vh", # Verilog
|
||||
"td", # TableGen
|
||||
"txtpb",
|
||||
"textpb",
|
||||
"pb.txt",
|
||||
"textproto",
|
||||
"asciipb", # TextProto
|
||||
]
|
||||
)
|
||||
|
||||
p = argparse.ArgumentParser(
|
||||
usage=usage,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description=desc,
|
||||
)
|
||||
p.add_argument(
|
||||
"--binary",
|
||||
default=config.get("clangformat.binary", "clang-format"),
|
||||
help="path to clang-format",
|
||||
),
|
||||
p.add_argument(
|
||||
"--commit",
|
||||
default=config.get("clangformat.commit", "HEAD"),
|
||||
help="default commit to use if none is specified",
|
||||
),
|
||||
p.add_argument(
|
||||
"--diff",
|
||||
action="store_true",
|
||||
help="print a diff instead of applying the changes",
|
||||
)
|
||||
p.add_argument(
|
||||
"--diffstat",
|
||||
action="store_true",
|
||||
help="print a diffstat instead of applying the changes",
|
||||
)
|
||||
p.add_argument(
|
||||
"--extensions",
|
||||
default=config.get("clangformat.extensions", default_extensions),
|
||||
help=(
|
||||
"comma-separated list of file extensions to format, "
|
||||
"excluding the period and case-insensitive"
|
||||
),
|
||||
),
|
||||
p.add_argument(
|
||||
"-f",
|
||||
"--force",
|
||||
action="store_true",
|
||||
help="allow changes to unstaged files",
|
||||
)
|
||||
p.add_argument(
|
||||
"-p", "--patch", action="store_true", help="select hunks interactively"
|
||||
)
|
||||
p.add_argument(
|
||||
"-q",
|
||||
"--quiet",
|
||||
action="count",
|
||||
default=0,
|
||||
help="print less information",
|
||||
)
|
||||
p.add_argument(
|
||||
"--staged",
|
||||
"--cached",
|
||||
action="store_true",
|
||||
help="format lines in the stage instead of the working dir",
|
||||
)
|
||||
p.add_argument(
|
||||
"--style",
|
||||
default=config.get("clangformat.style", None),
|
||||
help="passed to clang-format",
|
||||
),
|
||||
p.add_argument(
|
||||
"-v",
|
||||
"--verbose",
|
||||
action="count",
|
||||
default=0,
|
||||
help="print extra information",
|
||||
)
|
||||
p.add_argument(
|
||||
"--diff_from_common_commit",
|
||||
action="store_true",
|
||||
help=(
|
||||
"diff from the last common commit for commits in "
|
||||
"separate branches rather than the exact point of the "
|
||||
"commits"
|
||||
),
|
||||
)
|
||||
# We gather all the remaining positional arguments into 'args' since we need
|
||||
# to use some heuristics to determine whether or not <commit> was present.
|
||||
# However, to print pretty messages, we make use of metavar and help.
|
||||
p.add_argument(
|
||||
"args",
|
||||
nargs="*",
|
||||
metavar="<commit>",
|
||||
help="revision from which to compute the diff",
|
||||
)
|
||||
p.add_argument(
|
||||
"ignored",
|
||||
nargs="*",
|
||||
metavar="<file>...",
|
||||
help="if specified, only consider differences in these files",
|
||||
)
|
||||
opts = p.parse_args(argv)
|
||||
|
||||
opts.verbose -= opts.quiet
|
||||
del opts.quiet
|
||||
|
||||
commits, files = interpret_args(opts.args, dash_dash, opts.commit)
|
||||
if len(commits) > 2:
|
||||
die("at most two commits allowed; %d given" % len(commits))
|
||||
if len(commits) == 2:
|
||||
if opts.staged:
|
||||
die("--staged is not allowed when two commits are given")
|
||||
if not opts.diff:
|
||||
die("--diff is required when two commits are given")
|
||||
elif opts.diff_from_common_commit:
|
||||
die("--diff_from_common_commit is only allowed when two commits are given")
|
||||
|
||||
if os.path.dirname(opts.binary):
|
||||
opts.binary = os.path.abspath(opts.binary)
|
||||
|
||||
changed_lines = compute_diff_and_extract_lines(
|
||||
commits, files, opts.staged, opts.diff_from_common_commit
|
||||
)
|
||||
if opts.verbose >= 1:
|
||||
ignored_files = set(changed_lines)
|
||||
filter_by_extension(changed_lines, opts.extensions.lower().split(","))
|
||||
# The computed diff outputs absolute paths, so we must cd before accessing
|
||||
# those files.
|
||||
cd_to_toplevel()
|
||||
filter_symlinks(changed_lines)
|
||||
filter_ignored_files(changed_lines, binary=opts.binary)
|
||||
if opts.verbose >= 1:
|
||||
ignored_files.difference_update(changed_lines)
|
||||
if ignored_files:
|
||||
print(
|
||||
"Ignoring the following files (wrong extension, symlink, or "
|
||||
"ignored by clang-format):"
|
||||
)
|
||||
for filename in ignored_files:
|
||||
print(" %s" % filename)
|
||||
if changed_lines:
|
||||
print("Running clang-format on the following files:")
|
||||
for filename in changed_lines:
|
||||
print(" %s" % filename)
|
||||
|
||||
if not changed_lines:
|
||||
if opts.verbose >= 0:
|
||||
print("no modified files to format")
|
||||
return 0
|
||||
|
||||
if len(commits) > 1:
|
||||
old_tree = commits[1]
|
||||
revision = old_tree
|
||||
elif opts.staged:
|
||||
old_tree = create_tree_from_index(changed_lines)
|
||||
revision = ""
|
||||
else:
|
||||
old_tree = create_tree_from_workdir(changed_lines)
|
||||
revision = None
|
||||
new_tree = run_clang_format_and_save_to_tree(
|
||||
changed_lines, revision, binary=opts.binary, style=opts.style
|
||||
)
|
||||
if opts.verbose >= 1:
|
||||
print("old tree: %s" % old_tree)
|
||||
print("new tree: %s" % new_tree)
|
||||
|
||||
if old_tree == new_tree:
|
||||
if opts.verbose >= 0:
|
||||
print("clang-format did not modify any files")
|
||||
return 0
|
||||
|
||||
if opts.diff:
|
||||
return print_diff(old_tree, new_tree)
|
||||
if opts.diffstat:
|
||||
return print_diffstat(old_tree, new_tree)
|
||||
|
||||
changed_files = apply_changes(
|
||||
old_tree, new_tree, force=opts.force, patch_mode=opts.patch
|
||||
)
|
||||
if (opts.verbose >= 0 and not opts.patch) or opts.verbose >= 1:
|
||||
print("changed files:")
|
||||
for filename in changed_files:
|
||||
print(" %s" % filename)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
def load_git_config(non_string_options=None):
|
||||
"""Return the git configuration as a dictionary.
|
||||
|
||||
All options are assumed to be strings unless in `non_string_options`, in
|
||||
which is a dictionary mapping option name (in lower case) to either "--bool"
|
||||
or "--int"."""
|
||||
if non_string_options is None:
|
||||
non_string_options = {}
|
||||
out = {}
|
||||
for entry in run("git", "config", "--list", "--null").split("\0"):
|
||||
if entry:
|
||||
if "\n" in entry:
|
||||
name, value = entry.split("\n", 1)
|
||||
else:
|
||||
# A setting with no '=' ('\n' with --null) is implicitly 'true'
|
||||
name = entry
|
||||
value = "true"
|
||||
if name in non_string_options:
|
||||
value = run("git", "config", non_string_options[name], name)
|
||||
out[name] = value
|
||||
return out
|
||||
|
||||
|
||||
def interpret_args(args, dash_dash, default_commit):
|
||||
"""Interpret `args` as "[commits] [--] [files]" and return (commits, files).
|
||||
|
||||
It is assumed that "--" and everything that follows has been removed from
|
||||
args and placed in `dash_dash`.
|
||||
|
||||
If "--" is present (i.e., `dash_dash` is non-empty), the arguments to its
|
||||
left (if present) are taken as commits. Otherwise, the arguments are
|
||||
checked from left to right if they are commits or files. If commits are not
|
||||
given, a list with `default_commit` is used."""
|
||||
if dash_dash:
|
||||
if len(args) == 0:
|
||||
commits = [default_commit]
|
||||
else:
|
||||
commits = args
|
||||
for commit in commits:
|
||||
object_type = get_object_type(commit)
|
||||
if object_type not in ("commit", "tag"):
|
||||
if object_type is None:
|
||||
die("'%s' is not a commit" % commit)
|
||||
else:
|
||||
die(
|
||||
"'%s' is a %s, but a commit was expected"
|
||||
% (commit, object_type)
|
||||
)
|
||||
files = dash_dash[1:]
|
||||
elif args:
|
||||
commits = []
|
||||
while args:
|
||||
if not disambiguate_revision(args[0]):
|
||||
break
|
||||
commits.append(args.pop(0))
|
||||
if not commits:
|
||||
commits = [default_commit]
|
||||
files = args
|
||||
else:
|
||||
commits = [default_commit]
|
||||
files = []
|
||||
return commits, files
|
||||
|
||||
|
||||
def disambiguate_revision(value):
|
||||
"""Returns True if `value` is a revision, False if it is a file, or dies."""
|
||||
# If `value` is ambiguous (neither a commit nor a file), the following
|
||||
# command will die with an appropriate error message.
|
||||
run("git", "rev-parse", value, verbose=False)
|
||||
object_type = get_object_type(value)
|
||||
if object_type is None:
|
||||
return False
|
||||
if object_type in ("commit", "tag"):
|
||||
return True
|
||||
die("`%s` is a %s, but a commit or filename was expected" % (value, object_type))
|
||||
|
||||
|
||||
def get_object_type(value):
|
||||
"""Returns a string description of an object's type, or None if it is not
|
||||
a valid git object."""
|
||||
cmd = ["git", "cat-file", "-t", value]
|
||||
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
stdout, stderr = p.communicate()
|
||||
if p.returncode != 0:
|
||||
return None
|
||||
return convert_string(stdout.strip())
|
||||
|
||||
|
||||
def compute_diff_and_extract_lines(commits, files, staged, diff_common_commit):
|
||||
"""Calls compute_diff() followed by extract_lines()."""
|
||||
diff_process = compute_diff(commits, files, staged, diff_common_commit)
|
||||
changed_lines = extract_lines(diff_process.stdout)
|
||||
diff_process.stdout.close()
|
||||
diff_process.wait()
|
||||
if diff_process.returncode != 0:
|
||||
# Assume error was already printed to stderr.
|
||||
sys.exit(2)
|
||||
return changed_lines
|
||||
|
||||
|
||||
def compute_diff(commits, files, staged, diff_common_commit):
|
||||
"""Return a subprocess object producing the diff from `commits`.
|
||||
|
||||
The return value's `stdin` file object will produce a patch with the
|
||||
differences between the working directory (or stage if --staged is used) and
|
||||
the first commit if a single one was specified, or the difference between
|
||||
both specified commits, filtered on `files` (if non-empty).
|
||||
Zero context lines are used in the patch."""
|
||||
git_tool = "diff-index"
|
||||
extra_args = []
|
||||
if len(commits) == 2:
|
||||
git_tool = "diff-tree"
|
||||
if diff_common_commit:
|
||||
commits = [f"{commits[0]}...{commits[1]}"]
|
||||
elif staged:
|
||||
extra_args += ["--cached"]
|
||||
|
||||
cmd = ["git", git_tool, "-p", "-U0"] + extra_args + commits + ["--"]
|
||||
cmd.extend(files)
|
||||
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
p.stdin.close()
|
||||
return p
|
||||
|
||||
|
||||
def extract_lines(patch_file):
|
||||
"""Extract the changed lines in `patch_file`.
|
||||
|
||||
The return value is a dictionary mapping filename to a list of (start_line,
|
||||
line_count) pairs.
|
||||
|
||||
The input must have been produced with ``-U0``, meaning unidiff format with
|
||||
zero lines of context. The return value is a dict mapping filename to a
|
||||
list of line `Range`s."""
|
||||
matches = {}
|
||||
for line in patch_file:
|
||||
line = convert_string(line)
|
||||
match = re.search(r"^\+\+\+\ [^/]+/(.*)", line)
|
||||
if match:
|
||||
filename = match.group(1).rstrip("\r\n\t")
|
||||
match = re.search(r"^@@ -[0-9,]+ \+(\d+)(,(\d+))?", line)
|
||||
if match:
|
||||
start_line = int(match.group(1))
|
||||
line_count = 1
|
||||
if match.group(3):
|
||||
line_count = int(match.group(3))
|
||||
if line_count == 0:
|
||||
line_count = 1
|
||||
if start_line == 0:
|
||||
continue
|
||||
matches.setdefault(filename, []).append(Range(start_line, line_count))
|
||||
return matches
|
||||
|
||||
|
||||
def filter_by_extension(dictionary, allowed_extensions):
|
||||
"""Delete every key in `dictionary` that doesn't have an allowed extension.
|
||||
|
||||
`allowed_extensions` must be a collection of lowercase file extensions,
|
||||
excluding the period."""
|
||||
allowed_extensions = frozenset(allowed_extensions)
|
||||
for filename in list(dictionary.keys()):
|
||||
base_ext = filename.rsplit(".", 1)
|
||||
if len(base_ext) == 1 and "" in allowed_extensions:
|
||||
continue
|
||||
if len(base_ext) == 1 or base_ext[1].lower() not in allowed_extensions:
|
||||
del dictionary[filename]
|
||||
|
||||
|
||||
def filter_symlinks(dictionary):
|
||||
"""Delete every key in `dictionary` that is a symlink."""
|
||||
for filename in list(dictionary.keys()):
|
||||
if os.path.islink(filename):
|
||||
del dictionary[filename]
|
||||
|
||||
|
||||
def filter_ignored_files(dictionary, binary):
|
||||
"""Delete every key in `dictionary` that is ignored by clang-format."""
|
||||
ignored_files = run(binary, "-list-ignored", *dictionary.keys())
|
||||
if not ignored_files:
|
||||
return
|
||||
ignored_files = ignored_files.split("\n")
|
||||
for filename in ignored_files:
|
||||
del dictionary[filename]
|
||||
|
||||
|
||||
def cd_to_toplevel():
|
||||
"""Change to the top level of the git repository."""
|
||||
toplevel = run("git", "rev-parse", "--show-toplevel")
|
||||
os.chdir(toplevel)
|
||||
|
||||
|
||||
def create_tree_from_workdir(filenames):
|
||||
"""Create a new git tree with the given files from the working directory.
|
||||
|
||||
Returns the object ID (SHA-1) of the created tree."""
|
||||
return create_tree(filenames, "--stdin")
|
||||
|
||||
|
||||
def create_tree_from_index(filenames):
|
||||
# Copy the environment, because the files have to be read from the original
|
||||
# index.
|
||||
env = os.environ.copy()
|
||||
|
||||
def index_contents_generator():
|
||||
for filename in filenames:
|
||||
git_ls_files_cmd = [
|
||||
"git",
|
||||
"ls-files",
|
||||
"--stage",
|
||||
"-z",
|
||||
"--",
|
||||
filename,
|
||||
]
|
||||
git_ls_files = subprocess.Popen(
|
||||
git_ls_files_cmd,
|
||||
env=env,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
stdout = git_ls_files.communicate()[0]
|
||||
yield convert_string(stdout.split(b"\0")[0])
|
||||
|
||||
return create_tree(index_contents_generator(), "--index-info")
|
||||
|
||||
|
||||
def run_clang_format_and_save_to_tree(
|
||||
changed_lines, revision=None, binary="clang-format", style=None
|
||||
):
|
||||
"""Run clang-format on each file and save the result to a git tree.
|
||||
|
||||
Returns the object ID (SHA-1) of the created tree."""
|
||||
# Copy the environment when formatting the files in the index, because the
|
||||
# files have to be read from the original index.
|
||||
env = os.environ.copy() if revision == "" else None
|
||||
|
||||
def iteritems(container):
|
||||
try:
|
||||
return container.iteritems() # Python 2
|
||||
except AttributeError:
|
||||
return container.items() # Python 3
|
||||
|
||||
def index_info_generator():
|
||||
for filename, line_ranges in iteritems(changed_lines):
|
||||
if revision is not None:
|
||||
if len(revision) > 0:
|
||||
git_metadata_cmd = [
|
||||
"git",
|
||||
"ls-tree",
|
||||
"%s:%s" % (revision, os.path.dirname(filename)),
|
||||
os.path.basename(filename),
|
||||
]
|
||||
else:
|
||||
git_metadata_cmd = [
|
||||
"git",
|
||||
"ls-files",
|
||||
"--stage",
|
||||
"--",
|
||||
filename,
|
||||
]
|
||||
git_metadata = subprocess.Popen(
|
||||
git_metadata_cmd,
|
||||
env=env,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
stdout = git_metadata.communicate()[0]
|
||||
mode = oct(int(stdout.split()[0], 8))
|
||||
else:
|
||||
mode = oct(os.stat(filename).st_mode)
|
||||
# Adjust python3 octal format so that it matches what git expects
|
||||
if mode.startswith("0o"):
|
||||
mode = "0" + mode[2:]
|
||||
blob_id = clang_format_to_blob(
|
||||
filename,
|
||||
line_ranges,
|
||||
revision=revision,
|
||||
binary=binary,
|
||||
style=style,
|
||||
env=env,
|
||||
)
|
||||
yield "%s %s\t%s" % (mode, blob_id, filename)
|
||||
|
||||
return create_tree(index_info_generator(), "--index-info")
|
||||
|
||||
|
||||
def create_tree(input_lines, mode):
|
||||
"""Create a tree object from the given input.
|
||||
|
||||
If mode is '--stdin', it must be a list of filenames. If mode is
|
||||
'--index-info' is must be a list of values suitable for "git update-index
|
||||
--index-info", such as "<mode> <SP> <sha1> <TAB> <filename>". Any other
|
||||
mode is invalid."""
|
||||
assert mode in ("--stdin", "--index-info")
|
||||
cmd = ["git", "update-index", "--add", "-z", mode]
|
||||
with temporary_index_file():
|
||||
p = subprocess.Popen(cmd, stdin=subprocess.PIPE)
|
||||
for line in input_lines:
|
||||
p.stdin.write(to_bytes("%s\0" % line))
|
||||
p.stdin.close()
|
||||
if p.wait() != 0:
|
||||
die("`%s` failed" % " ".join(cmd))
|
||||
tree_id = run("git", "write-tree")
|
||||
return tree_id
|
||||
|
||||
|
||||
def clang_format_to_blob(
|
||||
filename,
|
||||
line_ranges,
|
||||
revision=None,
|
||||
binary="clang-format",
|
||||
style=None,
|
||||
env=None,
|
||||
):
|
||||
"""Run clang-format on the given file and save the result to a git blob.
|
||||
|
||||
Runs on the file in `revision` if not None, or on the file in the working
|
||||
directory if `revision` is None. Revision can be set to an empty string to
|
||||
run clang-format on the file in the index.
|
||||
|
||||
Returns the object ID (SHA-1) of the created blob."""
|
||||
clang_format_cmd = [binary]
|
||||
if style:
|
||||
clang_format_cmd.extend(["--style=" + style])
|
||||
clang_format_cmd.extend(
|
||||
[
|
||||
"--lines=%s:%s" % (start_line, start_line + line_count - 1)
|
||||
for start_line, line_count in line_ranges
|
||||
]
|
||||
)
|
||||
if revision is not None:
|
||||
clang_format_cmd.extend(["--assume-filename=" + filename])
|
||||
git_show_cmd = [
|
||||
"git",
|
||||
"cat-file",
|
||||
"blob",
|
||||
"%s:%s" % (revision, filename),
|
||||
]
|
||||
git_show = subprocess.Popen(
|
||||
git_show_cmd, env=env, stdin=subprocess.PIPE, stdout=subprocess.PIPE
|
||||
)
|
||||
git_show.stdin.close()
|
||||
clang_format_stdin = git_show.stdout
|
||||
else:
|
||||
clang_format_cmd.extend([filename])
|
||||
git_show = None
|
||||
clang_format_stdin = subprocess.PIPE
|
||||
try:
|
||||
clang_format = subprocess.Popen(
|
||||
clang_format_cmd, stdin=clang_format_stdin, stdout=subprocess.PIPE
|
||||
)
|
||||
if clang_format_stdin == subprocess.PIPE:
|
||||
clang_format_stdin = clang_format.stdin
|
||||
except OSError as e:
|
||||
if e.errno == errno.ENOENT:
|
||||
die('cannot find executable "%s"' % binary)
|
||||
else:
|
||||
raise
|
||||
clang_format_stdin.close()
|
||||
hash_object_cmd = [
|
||||
"git",
|
||||
"hash-object",
|
||||
"-w",
|
||||
"--path=" + filename,
|
||||
"--stdin",
|
||||
]
|
||||
hash_object = subprocess.Popen(
|
||||
hash_object_cmd, stdin=clang_format.stdout, stdout=subprocess.PIPE
|
||||
)
|
||||
clang_format.stdout.close()
|
||||
stdout = hash_object.communicate()[0]
|
||||
if hash_object.returncode != 0:
|
||||
die("`%s` failed" % " ".join(hash_object_cmd))
|
||||
if clang_format.wait() != 0:
|
||||
die("`%s` failed" % " ".join(clang_format_cmd))
|
||||
if git_show and git_show.wait() != 0:
|
||||
die("`%s` failed" % " ".join(git_show_cmd))
|
||||
return convert_string(stdout).rstrip("\r\n")
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def temporary_index_file(tree=None):
|
||||
"""Context manager for setting GIT_INDEX_FILE to a temporary file and
|
||||
deleting the file afterward."""
|
||||
index_path = create_temporary_index(tree)
|
||||
old_index_path = os.environ.get("GIT_INDEX_FILE")
|
||||
os.environ["GIT_INDEX_FILE"] = index_path
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if old_index_path is None:
|
||||
del os.environ["GIT_INDEX_FILE"]
|
||||
else:
|
||||
os.environ["GIT_INDEX_FILE"] = old_index_path
|
||||
os.remove(index_path)
|
||||
|
||||
|
||||
def create_temporary_index(tree=None):
|
||||
"""Create a temporary index file and return the created file's path.
|
||||
|
||||
If `tree` is not None, use that as the tree to read in. Otherwise, an
|
||||
empty index is created."""
|
||||
gitdir = run("git", "rev-parse", "--git-dir")
|
||||
path = os.path.join(gitdir, temp_index_basename)
|
||||
if tree is None:
|
||||
tree = "--empty"
|
||||
run("git", "read-tree", "--index-output=" + path, tree)
|
||||
return path
|
||||
|
||||
|
||||
def print_diff(old_tree, new_tree):
|
||||
"""Print the diff between the two trees to stdout."""
|
||||
# We use the porcelain 'diff' and not plumbing 'diff-tree' because the
|
||||
# output is expected to be viewed by the user, and only the former does nice
|
||||
# things like color and pagination.
|
||||
#
|
||||
# We also only print modified files since `new_tree` only contains the files
|
||||
# that were modified, so unmodified files would show as deleted without the
|
||||
# filter.
|
||||
return subprocess.run(
|
||||
["git", "diff", "--diff-filter=M", "--exit-code", old_tree, new_tree]
|
||||
).returncode
|
||||
|
||||
|
||||
def print_diffstat(old_tree, new_tree):
|
||||
"""Print the diffstat between the two trees to stdout."""
|
||||
# We use the porcelain 'diff' and not plumbing 'diff-tree' because the
|
||||
# output is expected to be viewed by the user, and only the former does nice
|
||||
# things like color and pagination.
|
||||
#
|
||||
# We also only print modified files since `new_tree` only contains the files
|
||||
# that were modified, so unmodified files would show as deleted without the
|
||||
# filter.
|
||||
return subprocess.run(
|
||||
[
|
||||
"git",
|
||||
"diff",
|
||||
"--diff-filter=M",
|
||||
"--exit-code",
|
||||
"--stat",
|
||||
old_tree,
|
||||
new_tree,
|
||||
]
|
||||
).returncode
|
||||
|
||||
|
||||
def apply_changes(old_tree, new_tree, force=False, patch_mode=False):
|
||||
"""Apply the changes in `new_tree` to the working directory.
|
||||
|
||||
Bails if there are local changes in those files and not `force`. If
|
||||
`patch_mode`, runs `git checkout --patch` to select hunks interactively."""
|
||||
changed_files = (
|
||||
run(
|
||||
"git",
|
||||
"diff-tree",
|
||||
"--diff-filter=M",
|
||||
"-r",
|
||||
"-z",
|
||||
"--name-only",
|
||||
old_tree,
|
||||
new_tree,
|
||||
)
|
||||
.rstrip("\0")
|
||||
.split("\0")
|
||||
)
|
||||
if not force:
|
||||
unstaged_files = run("git", "diff-files", "--name-status", *changed_files)
|
||||
if unstaged_files:
|
||||
print(
|
||||
"The following files would be modified but have unstaged changes:",
|
||||
file=sys.stderr,
|
||||
)
|
||||
print(unstaged_files, file=sys.stderr)
|
||||
print("Please commit, stage, or stash them first.", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
if patch_mode:
|
||||
# In patch mode, we could just as well create an index from the new tree
|
||||
# and checkout from that, but then the user will be presented with a
|
||||
# message saying "Discard ... from worktree". Instead, we use the old
|
||||
# tree as the index and checkout from new_tree, which gives the slightly
|
||||
# better message, "Apply ... to index and worktree". This is not quite
|
||||
# right, since it won't be applied to the user's index, but oh well.
|
||||
with temporary_index_file(old_tree):
|
||||
subprocess.run(["git", "checkout", "--patch", new_tree], check=True)
|
||||
index_tree = old_tree
|
||||
else:
|
||||
with temporary_index_file(new_tree):
|
||||
run("git", "checkout-index", "-f", "--", *changed_files)
|
||||
return changed_files
|
||||
|
||||
|
||||
def run(*args, **kwargs):
|
||||
stdin = kwargs.pop("stdin", "")
|
||||
verbose = kwargs.pop("verbose", True)
|
||||
strip = kwargs.pop("strip", True)
|
||||
for name in kwargs:
|
||||
raise TypeError("run() got an unexpected keyword argument '%s'" % name)
|
||||
p = subprocess.Popen(
|
||||
args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
stdin=subprocess.PIPE,
|
||||
)
|
||||
stdout, stderr = p.communicate(input=stdin)
|
||||
|
||||
stdout = convert_string(stdout)
|
||||
stderr = convert_string(stderr)
|
||||
|
||||
if p.returncode == 0:
|
||||
if stderr:
|
||||
if verbose:
|
||||
print("`%s` printed to stderr:" % " ".join(args), file=sys.stderr)
|
||||
print(stderr.rstrip(), file=sys.stderr)
|
||||
if strip:
|
||||
stdout = stdout.rstrip("\r\n")
|
||||
return stdout
|
||||
if verbose:
|
||||
print("`%s` returned %s" % (" ".join(args), p.returncode), file=sys.stderr)
|
||||
if stderr:
|
||||
print(stderr.rstrip(), file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
def die(message):
|
||||
print("error:", message, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
def to_bytes(str_input):
|
||||
# Encode to UTF-8 to get binary data.
|
||||
if isinstance(str_input, bytes):
|
||||
return str_input
|
||||
return str_input.encode("utf-8")
|
||||
|
||||
|
||||
def to_string(bytes_input):
|
||||
if isinstance(bytes_input, str):
|
||||
return bytes_input
|
||||
return bytes_input.encode("utf-8")
|
||||
|
||||
|
||||
def convert_string(bytes_input):
|
||||
try:
|
||||
return to_string(bytes_input.decode("utf-8"))
|
||||
except AttributeError: # 'str' object has no attribute 'decode'.
|
||||
return str(bytes_input)
|
||||
except UnicodeError:
|
||||
return str(bytes_input)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
216
frontend/src/common/prettier/plugins/clang/index.ts
Normal file
216
frontend/src/common/prettier/plugins/clang/index.ts
Normal file
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
* Prettier Plugin for C/C++/C#/Java/Protobuf formatting using clang-format WebAssembly
|
||||
*
|
||||
* This plugin provides support for formatting multiple languages using the clang-format WASM implementation.
|
||||
* Supported languages:
|
||||
* - C / C++
|
||||
* - Objective-C / Objective-C++
|
||||
* - C#
|
||||
* - Java
|
||||
* - Protocol Buffer (Protobuf)
|
||||
*
|
||||
* It supports various file extensions and common clang-format styles.
|
||||
*/
|
||||
import type { Plugin, Parser, Printer } from 'prettier';
|
||||
|
||||
// Import the clang-format WASM module
|
||||
import clangFormatInit, { format } from './clang-format-vite.js';
|
||||
|
||||
const parserName = 'clang-format';
|
||||
|
||||
// Language configuration
|
||||
const languages = [
|
||||
{
|
||||
name: 'C',
|
||||
aliases: ['c'],
|
||||
parsers: ['c'],
|
||||
extensions: ['.c', '.h'],
|
||||
filenames: ['*.c', '*.h'],
|
||||
aceMode: 'c_cpp',
|
||||
tmScope: 'source.c',
|
||||
linguistLanguageId: 50,
|
||||
vscodeLanguageIds: ['c']
|
||||
},
|
||||
{
|
||||
name: 'C++',
|
||||
aliases: ['cpp', 'cxx', 'cc'],
|
||||
parsers: ['cpp'],
|
||||
extensions: ['.cpp', '.cxx', '.cc', '.hpp', '.hxx', '.hh', '.C', '.H'],
|
||||
filenames: ['*.cpp', '*.cxx', '*.cc', '*.hpp', '*.hxx', '*.hh', '*.C', '*.H'],
|
||||
aceMode: 'c_cpp',
|
||||
tmScope: 'source.cpp',
|
||||
linguistLanguageId: 43,
|
||||
vscodeLanguageIds: ['cpp']
|
||||
},
|
||||
{
|
||||
name: 'Objective-C',
|
||||
aliases: ['objc', 'objectivec'],
|
||||
parsers: ['objective-c'],
|
||||
extensions: ['.m'],
|
||||
filenames: ['*.m'],
|
||||
aceMode: 'objectivec',
|
||||
tmScope: 'source.objc',
|
||||
linguistLanguageId: 259,
|
||||
vscodeLanguageIds: ['objective-c']
|
||||
},
|
||||
{
|
||||
name: 'Objective-C++',
|
||||
aliases: ['objcpp', 'objectivecpp'],
|
||||
parsers: ['objective-cpp'],
|
||||
extensions: ['.mm'],
|
||||
filenames: ['*.mm'],
|
||||
aceMode: 'objectivec',
|
||||
tmScope: 'source.objcpp',
|
||||
linguistLanguageId: 260,
|
||||
vscodeLanguageIds: ['objective-cpp']
|
||||
},
|
||||
{
|
||||
name: 'C#',
|
||||
aliases: ['csharp', 'cs'],
|
||||
parsers: ['cs'],
|
||||
extensions: ['.cs'],
|
||||
filenames: ['*.cs'],
|
||||
aceMode: 'csharp',
|
||||
tmScope: 'source.cs',
|
||||
linguistLanguageId: 42,
|
||||
vscodeLanguageIds: ['csharp']
|
||||
},
|
||||
{
|
||||
name: 'Java',
|
||||
aliases: ['java'],
|
||||
parsers: ['java'],
|
||||
extensions: ['.java'],
|
||||
filenames: ['*.java'],
|
||||
aceMode: 'java',
|
||||
tmScope: 'source.java',
|
||||
linguistLanguageId: 181,
|
||||
vscodeLanguageIds: ['java']
|
||||
},
|
||||
{
|
||||
name: 'Protocol Buffer',
|
||||
aliases: ['protobuf', 'proto'],
|
||||
parsers: ['proto'],
|
||||
extensions: ['.proto'],
|
||||
filenames: ['*.proto'],
|
||||
aceMode: 'protobuf',
|
||||
tmScope: 'source.proto',
|
||||
linguistLanguageId: 297,
|
||||
vscodeLanguageIds: ['proto']
|
||||
}
|
||||
];
|
||||
|
||||
// Parser configuration
|
||||
const clangParser: Parser<string> = {
|
||||
astFormat: parserName,
|
||||
parse: (text: string) => text,
|
||||
locStart: () => 0,
|
||||
locEnd: (node: string) => node.length,
|
||||
};
|
||||
|
||||
// Lazy initialize clang-format WASM module
|
||||
let initPromise: Promise<void> | null = null;
|
||||
let isInitialized = false;
|
||||
|
||||
function initClangFormat(): Promise<void> {
|
||||
if (isInitialized) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (!initPromise) {
|
||||
initPromise = (async () => {
|
||||
try {
|
||||
await clangFormatInit();
|
||||
isInitialized = true;
|
||||
} catch (error) {
|
||||
console.warn('Failed to initialize clang-format WASM module:', error);
|
||||
initPromise = null;
|
||||
throw error;
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
return initPromise;
|
||||
}
|
||||
|
||||
// Printer configuration
|
||||
const clangPrinter: Printer<string> = {
|
||||
// @ts-expect-error -- Support async printer like shell plugin
|
||||
async print(path, options) {
|
||||
try {
|
||||
// Wait for initialization to complete
|
||||
await initClangFormat();
|
||||
|
||||
const text = (path as any).getValue ? (path as any).getValue() : path.node;
|
||||
const style = getClangStyle(options);
|
||||
|
||||
// Format using clang-format (synchronous call)
|
||||
const formatted = format(text, options.filename, style);
|
||||
|
||||
return formatted.trim();
|
||||
} catch (error) {
|
||||
console.warn('clang-format failed:', error);
|
||||
// Return original text if formatting fails
|
||||
return (path as any).getValue ? (path as any).getValue() : path.node;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
// Helper function to determine clang-format style
|
||||
function getClangStyle(options: any): string {
|
||||
// You can extend this to support more options
|
||||
const style = options.clangStyle || 'LLVM';
|
||||
|
||||
// Support common styles
|
||||
const validStyles = ['LLVM', 'Google', 'Chromium', 'Mozilla', 'WebKit', 'Microsoft', 'GNU'];
|
||||
if (validStyles.includes(style)) {
|
||||
return style;
|
||||
}
|
||||
|
||||
// Default to LLVM style
|
||||
return 'LLVM';
|
||||
}
|
||||
|
||||
// Plugin options
|
||||
const options = {
|
||||
clangStyle: {
|
||||
since: '0.0.1',
|
||||
category: 'Format' as const,
|
||||
type: 'choice' as const,
|
||||
default: 'LLVM',
|
||||
description: 'The clang-format style to use',
|
||||
choices: [
|
||||
{ value: 'LLVM', description: 'LLVM coding standards' },
|
||||
{ value: 'Google', description: "Google's C++ style guide" },
|
||||
{ value: 'Chromium', description: "Chromium's style guide" },
|
||||
{ value: 'Mozilla', description: "Mozilla's style guide" },
|
||||
{ value: 'WebKit', description: "WebKit's style guide" },
|
||||
{ value: 'Microsoft', description: "Microsoft's style guide" },
|
||||
{ value: 'GNU', description: 'GNU coding standards' }
|
||||
]
|
||||
},
|
||||
filename: {
|
||||
// since: '0.1.0',
|
||||
category: 'Config',
|
||||
type: 'string',
|
||||
default: undefined,
|
||||
description: 'Custom filename to use for web_fmt processing (affects language detection)',
|
||||
}
|
||||
};
|
||||
|
||||
// Plugin object
|
||||
const clangPlugin: Plugin = {
|
||||
languages,
|
||||
parsers: {
|
||||
[parserName]: clangParser,
|
||||
},
|
||||
printers: {
|
||||
[parserName]: clangPrinter,
|
||||
},
|
||||
...options,
|
||||
};
|
||||
|
||||
export default clangPlugin;
|
||||
export { languages };
|
||||
export const parsers = clangPlugin.parsers;
|
||||
export const printers = clangPlugin.printers;
|
||||
105
frontend/src/common/prettier/plugins/clang/src/CMakeLists.txt
Normal file
105
frontend/src/common/prettier/plugins/clang/src/CMakeLists.txt
Normal file
@@ -0,0 +1,105 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
project(clang-format-wasm)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Set Emscripten flags for WASM
|
||||
if(EMSCRIPTEN)
|
||||
set(CMAKE_EXECUTABLE_SUFFIX ".js")
|
||||
|
||||
# Common Emscripten flags
|
||||
set(EMSCRIPTEN_FLAGS
|
||||
-O3
|
||||
-sWASM=1
|
||||
-sEXPORTED_RUNTIME_METHODS=['ccall','cwrap']
|
||||
-sALLOW_MEMORY_GROWTH=1
|
||||
-sMODULARIZE=1
|
||||
-sEXPORT_NAME='Module'
|
||||
-sENVIRONMENT=web,webview,worker
|
||||
-sUSE_ES6_IMPORT_META=0
|
||||
--no-entry
|
||||
)
|
||||
|
||||
# Library-specific flags
|
||||
set(LIB_EMSCRIPTEN_FLAGS
|
||||
${EMSCRIPTEN_FLAGS}
|
||||
-sEXPORTED_FUNCTIONS=['_malloc','_free']
|
||||
--bind
|
||||
)
|
||||
|
||||
# CLI-specific flags
|
||||
set(CLI_EMSCRIPTEN_FLAGS
|
||||
${EMSCRIPTEN_FLAGS}
|
||||
-sEXPORTED_FUNCTIONS=['_main']
|
||||
-sINVOKE_RUN=0
|
||||
-sNODERAWFS=1
|
||||
)
|
||||
endif()
|
||||
|
||||
# Find LLVM
|
||||
find_package(LLVM REQUIRED CONFIG)
|
||||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
|
||||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
||||
|
||||
# Include LLVM headers
|
||||
include_directories(${LLVM_INCLUDE_DIRS})
|
||||
add_definitions(${LLVM_DEFINITIONS})
|
||||
|
||||
# Find Clang
|
||||
find_package(Clang REQUIRED CONFIG)
|
||||
|
||||
# Get LLVM components
|
||||
llvm_map_components_to_libnames(llvm_libs support core)
|
||||
|
||||
# Define source files
|
||||
set(LIB_SOURCES
|
||||
lib.cc
|
||||
lib.h
|
||||
binding.cc
|
||||
)
|
||||
|
||||
set(CLI_SOURCES
|
||||
cli.cc
|
||||
)
|
||||
|
||||
# Create library target
|
||||
add_executable(clang-format-wasm ${LIB_SOURCES})
|
||||
|
||||
# Link against Clang and LLVM libraries
|
||||
target_link_libraries(clang-format-wasm
|
||||
clangFormat
|
||||
clangToolingCore
|
||||
clangBasic
|
||||
clangRewrite
|
||||
${llvm_libs}
|
||||
)
|
||||
|
||||
# Create CLI target
|
||||
add_executable(clang-format-cli ${CLI_SOURCES})
|
||||
|
||||
target_link_libraries(clang-format-cli
|
||||
clangFormat
|
||||
clangToolingCore
|
||||
clangBasic
|
||||
clangRewrite
|
||||
${llvm_libs}
|
||||
)
|
||||
|
||||
# Set Emscripten flags
|
||||
if(EMSCRIPTEN)
|
||||
# Configure library target
|
||||
set_target_properties(clang-format-wasm PROPERTIES
|
||||
COMPILE_FLAGS "${LIB_EMSCRIPTEN_FLAGS}"
|
||||
LINK_FLAGS "${LIB_EMSCRIPTEN_FLAGS}"
|
||||
OUTPUT_NAME "clang-format-esm"
|
||||
)
|
||||
|
||||
# Configure CLI target
|
||||
set_target_properties(clang-format-cli PROPERTIES
|
||||
COMPILE_FLAGS "${CLI_EMSCRIPTEN_FLAGS}"
|
||||
LINK_FLAGS "${CLI_EMSCRIPTEN_FLAGS}"
|
||||
OUTPUT_NAME "clang-format-cli"
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,117 @@
|
||||
#include "CustomFileSystem.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include <emscripten.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::vfs;
|
||||
|
||||
namespace {
|
||||
|
||||
bool isRunningOnWindows() {
|
||||
return EM_ASM_INT({return process.platform == 'win32' ? 1 : 0}) == 1;
|
||||
}
|
||||
|
||||
std::error_code current_path(SmallVectorImpl<char> &result) {
|
||||
result.clear();
|
||||
|
||||
const char *pwd = ::getenv("PWD");
|
||||
result.append(pwd, pwd + strlen(pwd));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace llvm {
|
||||
namespace vfs {
|
||||
|
||||
sys::path::Style getPathStyle() {
|
||||
static sys::path::Style cachedStyle = sys::path::Style::native;
|
||||
|
||||
if (cachedStyle == sys::path::Style::native) {
|
||||
cachedStyle = isRunningOnWindows() ? sys::path::Style::windows
|
||||
: sys::path::Style::posix;
|
||||
}
|
||||
|
||||
return cachedStyle;
|
||||
}
|
||||
|
||||
void make_absolute(const Twine ¤t_directory,
|
||||
SmallVectorImpl<char> &path) {
|
||||
StringRef p(path.data(), path.size());
|
||||
|
||||
auto pathStyle = getPathStyle();
|
||||
|
||||
bool rootDirectory = sys::path::has_root_directory(p, pathStyle);
|
||||
bool rootName = sys::path::has_root_name(p, pathStyle);
|
||||
|
||||
// Already absolute.
|
||||
if ((rootName || is_style_posix(pathStyle)) && rootDirectory)
|
||||
return;
|
||||
|
||||
// All of the following conditions will need the current directory.
|
||||
SmallString<128> current_dir;
|
||||
current_directory.toVector(current_dir);
|
||||
|
||||
// Relative path. Prepend the current directory.
|
||||
if (!rootName && !rootDirectory) {
|
||||
// Append path to the current directory.
|
||||
sys::path::append(current_dir, pathStyle, p);
|
||||
// Set path to the result.
|
||||
path.swap(current_dir);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rootName && rootDirectory) {
|
||||
StringRef cdrn = sys::path::root_name(current_dir, pathStyle);
|
||||
SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
|
||||
sys::path::append(curDirRootName, pathStyle, p);
|
||||
// Set path to the result.
|
||||
path.swap(curDirRootName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rootName && !rootDirectory) {
|
||||
StringRef pRootName = sys::path::root_name(p, pathStyle);
|
||||
StringRef bRootDirectory =
|
||||
sys::path::root_directory(current_dir, pathStyle);
|
||||
StringRef bRelativePath = sys::path::relative_path(current_dir, pathStyle);
|
||||
StringRef pRelativePath = sys::path::relative_path(p, pathStyle);
|
||||
|
||||
SmallString<128> res;
|
||||
sys::path::append(res, pathStyle, pRootName, bRootDirectory, bRelativePath,
|
||||
pRelativePath);
|
||||
path.swap(res);
|
||||
return;
|
||||
}
|
||||
|
||||
llvm_unreachable("All rootName and rootDirectory combinations should have "
|
||||
"occurred above!");
|
||||
}
|
||||
|
||||
std::error_code make_absolute(SmallVectorImpl<char> &path) {
|
||||
if (sys::path::is_absolute(path, getPathStyle()))
|
||||
return {};
|
||||
|
||||
SmallString<128> current_dir;
|
||||
if (std::error_code ec = current_path(current_dir))
|
||||
return ec;
|
||||
|
||||
make_absolute(current_dir, path);
|
||||
return {};
|
||||
}
|
||||
|
||||
CustomFileSystem::CustomFileSystem(IntrusiveRefCntPtr<FileSystem> FS)
|
||||
: ProxyFileSystem(std::move(FS)) {}
|
||||
|
||||
std::error_code
|
||||
CustomFileSystem::makeAbsolute(SmallVectorImpl<char> &Path) const {
|
||||
return make_absolute(Path);
|
||||
}
|
||||
|
||||
} // namespace vfs
|
||||
} // namespace llvm
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef CUSTOM_FILE_SYSTEM_H
|
||||
#define CUSTOM_FILE_SYSTEM_H
|
||||
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/ErrorOr.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/VirtualFileSystem.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace vfs {
|
||||
|
||||
sys::path::Style getPathStyle();
|
||||
std::error_code make_absolute(SmallVectorImpl<char> &path);
|
||||
|
||||
class CustomFileSystem : public ProxyFileSystem {
|
||||
public:
|
||||
CustomFileSystem(IntrusiveRefCntPtr<FileSystem> FS);
|
||||
|
||||
std::error_code makeAbsolute(SmallVectorImpl<char> &Path) const override;
|
||||
};
|
||||
|
||||
} // namespace vfs
|
||||
} // namespace llvm
|
||||
|
||||
#endif // CUSTOM_FILE_SYSTEM_H
|
||||
100
frontend/src/common/prettier/plugins/clang/src/README.md
Normal file
100
frontend/src/common/prettier/plugins/clang/src/README.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Clang Format WASM Plugin
|
||||
|
||||
这是一个基于 clang-format WebAssembly 的 Prettier 插件,支持格式化 C/C++/C#/Java/Protobuf 代码。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
clang/
|
||||
├── src/ # 源码目录
|
||||
│ ├── scripts/ # 构建和工具脚本
|
||||
│ │ ├── build.sh # 主构建脚本
|
||||
│ │ ├── gen_patch.sh # 补丁生成脚本
|
||||
│ │ └── cli.patch # CLI 修改补丁
|
||||
│ ├── *.cc # C++ 源文件
|
||||
│ ├── *.h # C++ 头文件
|
||||
│ ├── CMakeLists.txt # CMake 构建配置
|
||||
│ ├── package.json # NPM 包配置
|
||||
│ ├── clang-format.d.ts # TypeScript 类型定义
|
||||
│ ├── template.js # JavaScript 模板
|
||||
│ └── clang-format-diff.py # Python 差异工具
|
||||
├── *.js # 编译后的 JavaScript 文件
|
||||
├── *.wasm # 编译后的 WebAssembly 文件
|
||||
├── *.cjs # CommonJS 格式的 CLI 工具
|
||||
├── git-clang-format # Git 集成工具
|
||||
└── index.ts # 插件入口文件
|
||||
```
|
||||
|
||||
## 构建说明
|
||||
|
||||
### 前提条件
|
||||
|
||||
- Install LLVM and Clang (version 18 or later)
|
||||
- Install CMake (version 3.27 or later)
|
||||
- Install Ninja (version 1.11 or later)
|
||||
|
||||
### 构建步骤
|
||||
|
||||
1. Clone this repository
|
||||
|
||||
2. 进入源码目录:
|
||||
```bash
|
||||
cd src
|
||||
```
|
||||
|
||||
3. 运行构建脚本:
|
||||
```bash
|
||||
./scripts/build.sh
|
||||
```
|
||||
|
||||
构建脚本会:
|
||||
- 创建 `build` 目录并编译源码
|
||||
- 将编译结果复制到上级目录(插件目录)
|
||||
- 生成 WebAssembly 文件和 JavaScript 绑定
|
||||
- 复制必要的工具和类型定义文件
|
||||
|
||||
### 输出文件
|
||||
|
||||
构建完成后,插件目录下会包含:
|
||||
- `clang-format.wasm` - WebAssembly 库文件
|
||||
- `clang-format.js` - JavaScript 绑定文件
|
||||
- `clang-format-cli.cjs` - CLI 工具
|
||||
- `clang-format-cli.wasm` - CLI WebAssembly 文件
|
||||
- `git-clang-format` - Git 集成工具
|
||||
- `clang-format-diff.py` - 差异工具
|
||||
|
||||
## 开发说明
|
||||
|
||||
### 修改源码
|
||||
|
||||
- C++ 源文件位于 `src/` 目录下
|
||||
- 修改后运行 `./scripts/build.sh` 重新构建
|
||||
- 类型定义文件 `src/clang-format.d.ts` 需要与实际 API 保持同步
|
||||
|
||||
### 生成补丁
|
||||
|
||||
如果修改了 CLI 相关代码,可以使用:
|
||||
```bash
|
||||
./scripts/gen_patch.sh
|
||||
```
|
||||
|
||||
生成补丁文件 `scripts/cli.patch`。
|
||||
|
||||
## 使用说明
|
||||
|
||||
插件会自动加载编译后的 WebAssembly 文件,支持以下语言:
|
||||
- C/C++
|
||||
- Objective-C/C++
|
||||
- C#
|
||||
- Java
|
||||
- Protocol Buffer
|
||||
|
||||
支持的 clang-format 样式:
|
||||
- LLVM
|
||||
- Google
|
||||
- Chromium
|
||||
- Mozilla
|
||||
- WebKit
|
||||
- Microsoft
|
||||
- GNU
|
||||
- 自定义样式
|
||||
26
frontend/src/common/prettier/plugins/clang/src/binding.cc
Normal file
26
frontend/src/common/prettier/plugins/clang/src/binding.cc
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "lib.h"
|
||||
#include <emscripten/bind.h>
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
register_vector<unsigned>("RangeList");
|
||||
|
||||
value_object<Result>("Result")
|
||||
.field("error", &Result::error)
|
||||
.field("content", &Result::content);
|
||||
|
||||
function<std::string>("version", &version);
|
||||
function<Result, const std::string, const std::string, const std::string>(
|
||||
"format", &format);
|
||||
function<Result, const std::string, const std::string, const std::string,
|
||||
const std::vector<unsigned>>("format_byte", &format_byte);
|
||||
function<Result, const std::string, const std::string, const std::string,
|
||||
const std::vector<unsigned>>("format_line", &format_line);
|
||||
function<void, const std::string>("set_fallback_style", &set_fallback_style);
|
||||
function<void, bool>("set_sort_includes", &set_sort_includes);
|
||||
function<Result, const std::string, const std::string, const std::string>(
|
||||
"dump_config", &dump_config);
|
||||
}
|
||||
|
||||
int main(void) {}
|
||||
@@ -0,0 +1,197 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# ===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===#
|
||||
#
|
||||
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
# See https://llvm.org/LICENSE.txt for license information.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
#
|
||||
# ===------------------------------------------------------------------------===#
|
||||
|
||||
"""
|
||||
This script reads input from a unified diff and reformats all the changed
|
||||
lines. This is useful to reformat all the lines touched by a specific patch.
|
||||
Example usage for git/svn users:
|
||||
|
||||
git diff -U0 --no-color --relative HEAD^ | {clang_format_diff} -p1 -i
|
||||
svn diff --diff-cmd=diff -x-U0 | {clang_format_diff} -i
|
||||
|
||||
It should be noted that the filename contained in the diff is used unmodified
|
||||
to determine the source file to update. Users calling this script directly
|
||||
should be careful to ensure that the path in the diff is correct relative to the
|
||||
current working directory.
|
||||
"""
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import argparse
|
||||
import difflib
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
if sys.version_info.major >= 3:
|
||||
from io import StringIO
|
||||
else:
|
||||
from io import BytesIO as StringIO
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description=__doc__.format(clang_format_diff="%(prog)s"),
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
)
|
||||
parser.add_argument(
|
||||
"-i",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="apply edits to files instead of displaying a diff",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
metavar="NUM",
|
||||
default=0,
|
||||
help="strip the smallest prefix containing P slashes",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-regex",
|
||||
metavar="PATTERN",
|
||||
default=None,
|
||||
help="custom pattern selecting file paths to reformat "
|
||||
"(case sensitive, overrides -iregex)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-iregex",
|
||||
metavar="PATTERN",
|
||||
default=r".*\.(?:cpp|cc|c\+\+|cxx|cppm|ccm|cxxm|c\+\+m|c|cl|h|hh|hpp"
|
||||
r"|hxx|m|mm|inc|js|ts|proto|protodevel|java|cs|json|ipynb|s?vh?)",
|
||||
help="custom pattern selecting file paths to reformat "
|
||||
"(case insensitive, overridden by -regex)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-sort-includes",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="let clang-format sort include blocks",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--verbose",
|
||||
action="store_true",
|
||||
help="be more verbose, ineffective without -i",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-style",
|
||||
help="formatting style to apply (LLVM, GNU, Google, Chromium, "
|
||||
"Microsoft, Mozilla, WebKit)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-fallback-style",
|
||||
help="The name of the predefined style used as a"
|
||||
"fallback in case clang-format is invoked with"
|
||||
"-style=file, but can not find the .clang-format"
|
||||
"file to use.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-binary",
|
||||
default="clang-format",
|
||||
help="location of binary to use for clang-format",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
# Extract changed lines for each file.
|
||||
filename = None
|
||||
lines_by_file = {}
|
||||
for line in sys.stdin:
|
||||
match = re.search(r"^\+\+\+\ (.*?/){%s}(.+)" % args.p, line.rstrip())
|
||||
if match:
|
||||
filename = match.group(2)
|
||||
if filename is None:
|
||||
continue
|
||||
|
||||
if args.regex is not None:
|
||||
if not re.match("^%s$" % args.regex, filename):
|
||||
continue
|
||||
else:
|
||||
if not re.match("^%s$" % args.iregex, filename, re.IGNORECASE):
|
||||
continue
|
||||
|
||||
match = re.search(r"^@@.*\+(\d+)(?:,(\d+))?", line)
|
||||
if match:
|
||||
start_line = int(match.group(1))
|
||||
line_count = 1
|
||||
if match.group(2):
|
||||
line_count = int(match.group(2))
|
||||
# The input is something like
|
||||
#
|
||||
# @@ -1, +0,0 @@
|
||||
#
|
||||
# which means no lines were added.
|
||||
if line_count == 0:
|
||||
continue
|
||||
# Also format lines range if line_count is 0 in case of deleting
|
||||
# surrounding statements.
|
||||
end_line = start_line
|
||||
if line_count != 0:
|
||||
end_line += line_count - 1
|
||||
lines_by_file.setdefault(filename, []).extend(
|
||||
["--lines", str(start_line) + ":" + str(end_line)]
|
||||
)
|
||||
|
||||
# Reformat files containing changes in place.
|
||||
has_diff = False
|
||||
for filename, lines in lines_by_file.items():
|
||||
if args.i and args.verbose:
|
||||
print("Formatting {}".format(filename))
|
||||
command = [args.binary, filename]
|
||||
if args.i:
|
||||
command.append("-i")
|
||||
if args.sort_includes:
|
||||
command.append("--sort-includes")
|
||||
command.extend(lines)
|
||||
if args.style:
|
||||
command.extend(["--style", args.style])
|
||||
if args.fallback_style:
|
||||
command.extend(["--fallback-style", args.fallback_style])
|
||||
|
||||
try:
|
||||
p = subprocess.Popen(
|
||||
command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=None,
|
||||
stdin=subprocess.PIPE,
|
||||
universal_newlines=True,
|
||||
)
|
||||
except OSError as e:
|
||||
# Give the user more context when clang-format isn't
|
||||
# found/isn't executable, etc.
|
||||
raise RuntimeError(
|
||||
'Failed to run "%s" - %s"' % (" ".join(command), e.strerror)
|
||||
)
|
||||
|
||||
stdout, _stderr = p.communicate()
|
||||
if p.returncode != 0:
|
||||
return p.returncode
|
||||
|
||||
if not args.i:
|
||||
with open(filename) as f:
|
||||
code = f.readlines()
|
||||
formatted_code = StringIO(stdout).readlines()
|
||||
diff = difflib.unified_diff(
|
||||
code,
|
||||
formatted_code,
|
||||
filename,
|
||||
filename,
|
||||
"(before formatting)",
|
||||
"(after formatting)",
|
||||
)
|
||||
diff_string = "".join(diff)
|
||||
if len(diff_string) > 0:
|
||||
has_diff = True
|
||||
sys.stdout.write(diff_string)
|
||||
|
||||
if has_diff:
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
175
frontend/src/common/prettier/plugins/clang/src/clang-format.d.ts
vendored
Normal file
175
frontend/src/common/prettier/plugins/clang/src/clang-format.d.ts
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
export type InitInput =
|
||||
| RequestInfo
|
||||
| URL
|
||||
| Response
|
||||
| BufferSource
|
||||
| WebAssembly.Module;
|
||||
|
||||
export default function init(input?: InitInput): Promise<void>;
|
||||
|
||||
/**
|
||||
* The style to use for formatting.
|
||||
* Supported style values are:
|
||||
* - `LLVM` - A style complying with the LLVM coding standards.
|
||||
* - `Google` - A style complying with Google’s C++ style guide.
|
||||
* - `Chromium` - A style complying with Chromium’s style guide.
|
||||
* - `Mozilla` - A style complying with Mozilla’s style guide.
|
||||
* - `WebKit` - A style complying with WebKit’s style guide.
|
||||
* - `Microsoft` - A style complying with Microsoft’s style guide.
|
||||
* - `GNU` - A style complying with the GNU coding standards.
|
||||
* - A string starting with `{`, for example: `{BasedOnStyle: Chromium, IndentWidth: 4, ...}`.
|
||||
* - A string which represents `.clang-format` content.
|
||||
*
|
||||
*/
|
||||
export type Style =
|
||||
| "LLVM"
|
||||
| "Google"
|
||||
| "Chromium"
|
||||
| "Mozilla"
|
||||
| "WebKit"
|
||||
| "Microsoft"
|
||||
| "GNU"
|
||||
| (string & {});
|
||||
|
||||
/**
|
||||
* The filename to use for determining the language.
|
||||
*/
|
||||
export type Filename =
|
||||
| "main.c"
|
||||
| "main.cc"
|
||||
| "main.cxx"
|
||||
| "main.cpp"
|
||||
| "main.java"
|
||||
| "main.js"
|
||||
| "main.mjs"
|
||||
| "main.ts"
|
||||
| "main.json"
|
||||
| "main.m"
|
||||
| "main.mm"
|
||||
| "main.proto"
|
||||
| "main.cs"
|
||||
| (string & {});
|
||||
|
||||
/**
|
||||
* Formats the given content using the specified style.
|
||||
*
|
||||
* @param {string} content - The content to format.
|
||||
* @param {Filename} filename - The filename to use for determining the language.
|
||||
* @param {Style} style - The style to use for formatting.
|
||||
* Supported style values are:
|
||||
* - `LLVM` - A style complying with the LLVM coding standards.
|
||||
* - `Google` - A style complying with Google’s C++ style guide.
|
||||
* - `Chromium` - A style complying with Chromium’s style guide.
|
||||
* - `Mozilla` - A style complying with Mozilla’s style guide.
|
||||
* - `WebKit` - A style complying with WebKit’s style guide.
|
||||
* - `Microsoft` - A style complying with Microsoft’s style guide.
|
||||
* - `GNU` - A style complying with the GNU coding standards.
|
||||
* - A string starting with `{`, for example: `{BasedOnStyle: Chromium, IndentWidth: 4, ...}`.
|
||||
* - A string which represents `.clang-format` content.
|
||||
*
|
||||
* @returns {string} The formatted content.
|
||||
* @throws {Error}
|
||||
*
|
||||
* @see {@link https://clang.llvm.org/docs/ClangFormatStyleOptions.html}
|
||||
*/
|
||||
export declare function format(
|
||||
content: string,
|
||||
filename?: Filename,
|
||||
style?: Style,
|
||||
): string;
|
||||
|
||||
/**
|
||||
* Both the startLine and endLine are 1-based.
|
||||
*/
|
||||
export type LineRange = [startLine: number, endLine: number];
|
||||
|
||||
/**
|
||||
* Both the offset and length are measured in bytes.
|
||||
*/
|
||||
export type ByteRange = [offset: number, length: number];
|
||||
|
||||
/**
|
||||
* Formats the specified range of lines in the given content using the specified style.
|
||||
*
|
||||
* @param {string} content - The content to format.
|
||||
* @param {LineRange[]} range - Array<[startLine, endLine]> - The range of lines to format.
|
||||
* Both startLine and endLine are 1-based.
|
||||
* Multiple ranges can be formatted by specifying several lines arguments.
|
||||
* @param {Filename} filename - The filename to use for determining the language.
|
||||
* @param {Style} style - The style to use for formatting.
|
||||
* Supported style values are:
|
||||
* - `LLVM` - A style complying with the LLVM coding standards.
|
||||
* - `Google` - A style complying with Google’s C++ style guide.
|
||||
* - `Chromium` - A style complying with Chromium’s style guide.
|
||||
* - `Mozilla` - A style complying with Mozilla’s style guide.
|
||||
* - `WebKit` - A style complying with WebKit’s style guide.
|
||||
* - `Microsoft` - A style complying with Microsoft’s style guide.
|
||||
* - `GNU` - A style complying with the GNU coding standards.
|
||||
* - A string starting with `{`, for example: `{BasedOnStyle: Chromium, IndentWidth: 4, ...}`.
|
||||
* - A string which represents `.clang-format` content.
|
||||
*
|
||||
* @returns {string} The formatted content.
|
||||
* @throws {Error}
|
||||
*
|
||||
* @see {@link https://clang.llvm.org/docs/ClangFormatStyleOptions.html}
|
||||
*/
|
||||
export declare function format_line_range(
|
||||
content: string,
|
||||
range: ByteRange[] | [[offset: number]],
|
||||
filename?: Filename,
|
||||
style?: Style,
|
||||
): string;
|
||||
|
||||
/**
|
||||
* @deprecated Use `format_line_range` instead.
|
||||
*/
|
||||
export declare function formatLineRange(
|
||||
content: string,
|
||||
range: ByteRange[] | [[offset: number]],
|
||||
filename?: Filename,
|
||||
style?: Style,
|
||||
): string;
|
||||
|
||||
/**
|
||||
* Formats the specified range of bytes in the given content using the specified style.
|
||||
*
|
||||
* @param {string} content - The content to format.
|
||||
* @param {ByteRange[]} range - Array<[offset, length]> - The range of bytes to format.
|
||||
* @param {Filename} filename - The filename to use for determining the language.
|
||||
* @param {Style} style - The style to use for formatting.
|
||||
* Supported style values are:
|
||||
* - `LLVM` - A style complying with the LLVM coding standards.
|
||||
* - `Google` - A style complying with Google’s C++ style guide.
|
||||
* - `Chromium` - A style complying with Chromium’s style guide.
|
||||
* - `Mozilla` - A style complying with Mozilla’s style guide.
|
||||
* - `WebKit` - A style complying with WebKit’s style guide.
|
||||
* - `Microsoft` - A style complying with Microsoft’s style guide.
|
||||
* - `GNU` - A style complying with the GNU coding standards.
|
||||
* - A string starting with `{`, for example: `{BasedOnStyle: Chromium, IndentWidth: 4, ...}`.
|
||||
* - A string which represents `.clang-format` content.
|
||||
*
|
||||
* @returns {string} The formatted content.
|
||||
* @throws {Error}
|
||||
*
|
||||
* @see {@link https://clang.llvm.org/docs/ClangFormatStyleOptions.html}
|
||||
*/
|
||||
export declare function format_byte_range(
|
||||
content: string,
|
||||
range: LineRange[],
|
||||
filename?: Filename,
|
||||
style?: Style,
|
||||
): string;
|
||||
|
||||
/**
|
||||
* @deprecated Use `format_byte_range` instead.
|
||||
*/
|
||||
export declare function formatByteRange(
|
||||
content: string,
|
||||
range: LineRange[],
|
||||
filename?: Filename,
|
||||
style?: Style,
|
||||
): string;
|
||||
|
||||
export declare function version(): string;
|
||||
|
||||
export declare function set_fallback_style(style: Style): void;
|
||||
748
frontend/src/common/prettier/plugins/clang/src/cli.cc
Normal file
748
frontend/src/common/prettier/plugins/clang/src/cli.cc
Normal file
@@ -0,0 +1,748 @@
|
||||
//===-- clang-format/ClangFormat.cpp - Clang format tool ------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// This file implements a clang-format tool that automatically formats
|
||||
/// (fragments of) C++ code.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/../../lib/Format/MatchFilePath.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/DiagnosticOptions.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "clang/Format/Format.h"
|
||||
#include "clang/Rewrite/Core/Rewriter.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/InitLLVM.h"
|
||||
#include "llvm/Support/Process.h"
|
||||
#include <fstream>
|
||||
|
||||
#include "CustomFileSystem.h"
|
||||
|
||||
using namespace llvm;
|
||||
using clang::tooling::Replacements;
|
||||
|
||||
static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);
|
||||
|
||||
// Mark all our options with this category, everything else (except for -version
|
||||
// and -help) will be hidden.
|
||||
static cl::OptionCategory ClangFormatCategory("Clang-format options");
|
||||
|
||||
static cl::list<unsigned>
|
||||
Offsets("offset",
|
||||
cl::desc("Format a range starting at this byte offset.\n"
|
||||
"Multiple ranges can be formatted by specifying\n"
|
||||
"several -offset and -length pairs.\n"
|
||||
"Can only be used with one input file."),
|
||||
cl::cat(ClangFormatCategory));
|
||||
static cl::list<unsigned>
|
||||
Lengths("length",
|
||||
cl::desc("Format a range of this length (in bytes).\n"
|
||||
"Multiple ranges can be formatted by specifying\n"
|
||||
"several -offset and -length pairs.\n"
|
||||
"When only a single -offset is specified without\n"
|
||||
"-length, clang-format will format up to the end\n"
|
||||
"of the file.\n"
|
||||
"Can only be used with one input file."),
|
||||
cl::cat(ClangFormatCategory));
|
||||
static cl::list<std::string>
|
||||
LineRanges("lines",
|
||||
cl::desc("<start line>:<end line> - format a range of\n"
|
||||
"lines (both 1-based).\n"
|
||||
"Multiple ranges can be formatted by specifying\n"
|
||||
"several -lines arguments.\n"
|
||||
"Can't be used with -offset and -length.\n"
|
||||
"Can only be used with one input file."),
|
||||
cl::cat(ClangFormatCategory));
|
||||
static cl::opt<std::string>
|
||||
Style("style", cl::desc(clang::format::StyleOptionHelpDescription),
|
||||
cl::init(clang::format::DefaultFormatStyle),
|
||||
cl::cat(ClangFormatCategory));
|
||||
static cl::opt<std::string>
|
||||
FallbackStyle("fallback-style",
|
||||
cl::desc("The name of the predefined style used as a\n"
|
||||
"fallback in case clang-format is invoked with\n"
|
||||
"-style=file, but can not find the .clang-format\n"
|
||||
"file to use. Defaults to 'LLVM'.\n"
|
||||
"Use -fallback-style=none to skip formatting."),
|
||||
cl::init(clang::format::DefaultFallbackStyle),
|
||||
cl::cat(ClangFormatCategory));
|
||||
|
||||
static cl::opt<std::string> AssumeFileName(
|
||||
"assume-filename",
|
||||
cl::desc("Set filename used to determine the language and to find\n"
|
||||
".clang-format file.\n"
|
||||
"Only used when reading from stdin.\n"
|
||||
"If this is not passed, the .clang-format file is searched\n"
|
||||
"relative to the current working directory when reading stdin.\n"
|
||||
"Unrecognized filenames are treated as C++.\n"
|
||||
"supported:\n"
|
||||
" CSharp: .cs\n"
|
||||
" Java: .java\n"
|
||||
" JavaScript: .js .mjs .cjs .ts\n"
|
||||
" Json: .json .ipynb\n"
|
||||
" Objective-C: .m .mm\n"
|
||||
" Proto: .proto .protodevel\n"
|
||||
" TableGen: .td\n"
|
||||
" TextProto: .txtpb .textpb .pb.txt .textproto .asciipb\n"
|
||||
" Verilog: .sv .svh .v .vh"),
|
||||
cl::init("<stdin>"), cl::cat(ClangFormatCategory));
|
||||
|
||||
static cl::opt<bool> Inplace("i",
|
||||
cl::desc("Inplace edit <file>s, if specified."),
|
||||
cl::cat(ClangFormatCategory));
|
||||
|
||||
static cl::opt<bool> OutputXML("output-replacements-xml",
|
||||
cl::desc("Output replacements as XML."),
|
||||
cl::cat(ClangFormatCategory));
|
||||
static cl::opt<bool>
|
||||
DumpConfig("dump-config",
|
||||
cl::desc("Dump configuration options to stdout and exit.\n"
|
||||
"Can be used with -style option."),
|
||||
cl::cat(ClangFormatCategory));
|
||||
static cl::opt<unsigned>
|
||||
Cursor("cursor",
|
||||
cl::desc("The position of the cursor when invoking\n"
|
||||
"clang-format from an editor integration"),
|
||||
cl::init(0), cl::cat(ClangFormatCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
SortIncludes("sort-includes",
|
||||
cl::desc("If set, overrides the include sorting behavior\n"
|
||||
"determined by the SortIncludes style flag"),
|
||||
cl::cat(ClangFormatCategory));
|
||||
|
||||
static cl::opt<std::string> QualifierAlignment(
|
||||
"qualifier-alignment",
|
||||
cl::desc("If set, overrides the qualifier alignment style\n"
|
||||
"determined by the QualifierAlignment style flag"),
|
||||
cl::init(""), cl::cat(ClangFormatCategory));
|
||||
|
||||
static cl::opt<std::string> Files(
|
||||
"files",
|
||||
cl::desc("A file containing a list of files to process, one per line."),
|
||||
cl::value_desc("filename"), cl::init(""), cl::cat(ClangFormatCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
Verbose("verbose", cl::desc("If set, shows the list of processed files"),
|
||||
cl::cat(ClangFormatCategory));
|
||||
|
||||
// Use --dry-run to match other LLVM tools when you mean do it but don't
|
||||
// actually do it
|
||||
static cl::opt<bool>
|
||||
DryRun("dry-run",
|
||||
cl::desc("If set, do not actually make the formatting changes"),
|
||||
cl::cat(ClangFormatCategory));
|
||||
|
||||
// Use -n as a common command as an alias for --dry-run. (git and make use -n)
|
||||
static cl::alias DryRunShort("n", cl::desc("Alias for --dry-run"),
|
||||
cl::cat(ClangFormatCategory), cl::aliasopt(DryRun),
|
||||
cl::NotHidden);
|
||||
|
||||
// Emulate being able to turn on/off the warning.
|
||||
static cl::opt<bool>
|
||||
WarnFormat("Wclang-format-violations",
|
||||
cl::desc("Warnings about individual formatting changes needed. "
|
||||
"Used only with --dry-run or -n"),
|
||||
cl::init(true), cl::cat(ClangFormatCategory), cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
NoWarnFormat("Wno-clang-format-violations",
|
||||
cl::desc("Do not warn about individual formatting changes "
|
||||
"needed. Used only with --dry-run or -n"),
|
||||
cl::init(false), cl::cat(ClangFormatCategory), cl::Hidden);
|
||||
|
||||
static cl::opt<unsigned> ErrorLimit(
|
||||
"ferror-limit",
|
||||
cl::desc("Set the maximum number of clang-format errors to emit\n"
|
||||
"before stopping (0 = no limit).\n"
|
||||
"Used only with --dry-run or -n"),
|
||||
cl::init(0), cl::cat(ClangFormatCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
WarningsAsErrors("Werror",
|
||||
cl::desc("If set, changes formatting warnings to errors"),
|
||||
cl::cat(ClangFormatCategory));
|
||||
|
||||
namespace {
|
||||
enum class WNoError { Unknown };
|
||||
}
|
||||
|
||||
static cl::bits<WNoError> WNoErrorList(
|
||||
"Wno-error",
|
||||
cl::desc("If set, don't error out on the specified warning type."),
|
||||
cl::values(
|
||||
clEnumValN(WNoError::Unknown, "unknown",
|
||||
"If set, unknown format options are only warned about.\n"
|
||||
"This can be used to enable formatting, even if the\n"
|
||||
"configuration contains unknown (newer) options.\n"
|
||||
"Use with caution, as this might lead to dramatically\n"
|
||||
"differing format depending on an option being\n"
|
||||
"supported or not.")),
|
||||
cl::cat(ClangFormatCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
ShowColors("fcolor-diagnostics",
|
||||
cl::desc("If set, and on a color-capable terminal controls "
|
||||
"whether or not to print diagnostics in color"),
|
||||
cl::init(true), cl::cat(ClangFormatCategory), cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
NoShowColors("fno-color-diagnostics",
|
||||
cl::desc("If set, and on a color-capable terminal controls "
|
||||
"whether or not to print diagnostics in color"),
|
||||
cl::init(false), cl::cat(ClangFormatCategory), cl::Hidden);
|
||||
|
||||
static cl::list<std::string> FileNames(cl::Positional,
|
||||
cl::desc("[@<file>] [<file> ...]"),
|
||||
cl::cat(ClangFormatCategory));
|
||||
|
||||
static cl::opt<bool> FailOnIncompleteFormat(
|
||||
"fail-on-incomplete-format",
|
||||
cl::desc("If set, fail with exit code 1 on incomplete format."),
|
||||
cl::init(false), cl::cat(ClangFormatCategory));
|
||||
|
||||
static cl::opt<bool> ListIgnored("list-ignored",
|
||||
cl::desc("List ignored files."),
|
||||
cl::cat(ClangFormatCategory), cl::Hidden);
|
||||
|
||||
namespace clang {
|
||||
namespace format {
|
||||
|
||||
static FileID createInMemoryFile(StringRef FileName, MemoryBufferRef Source,
|
||||
SourceManager &Sources, FileManager &Files,
|
||||
llvm::vfs::InMemoryFileSystem *MemFS) {
|
||||
MemFS->addFileNoOwn(FileName, 0, Source);
|
||||
auto File = Files.getOptionalFileRef(FileName);
|
||||
assert(File && "File not added to MemFS?");
|
||||
return Sources.createFileID(*File, SourceLocation(), SrcMgr::C_User);
|
||||
}
|
||||
|
||||
// Parses <start line>:<end line> input to a pair of line numbers.
|
||||
// Returns true on error.
|
||||
static bool parseLineRange(StringRef Input, unsigned &FromLine,
|
||||
unsigned &ToLine) {
|
||||
std::pair<StringRef, StringRef> LineRange = Input.split(':');
|
||||
return LineRange.first.getAsInteger(0, FromLine) ||
|
||||
LineRange.second.getAsInteger(0, ToLine);
|
||||
}
|
||||
|
||||
static bool fillRanges(MemoryBuffer *Code,
|
||||
std::vector<tooling::Range> &Ranges) {
|
||||
IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
|
||||
new llvm::vfs::InMemoryFileSystem);
|
||||
FileManager Files(FileSystemOptions(), InMemoryFileSystem);
|
||||
DiagnosticOptions DiagOpts;
|
||||
DiagnosticsEngine Diagnostics(
|
||||
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), DiagOpts);
|
||||
SourceManager Sources(Diagnostics, Files);
|
||||
const auto ID = createInMemoryFile("<irrelevant>", *Code, Sources, Files,
|
||||
InMemoryFileSystem.get());
|
||||
if (!LineRanges.empty()) {
|
||||
if (!Offsets.empty() || !Lengths.empty()) {
|
||||
errs() << "error: cannot use -lines with -offset/-length\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto &LineRange : LineRanges) {
|
||||
unsigned FromLine, ToLine;
|
||||
if (parseLineRange(LineRange, FromLine, ToLine)) {
|
||||
errs() << "error: invalid <start line>:<end line> pair\n";
|
||||
return true;
|
||||
}
|
||||
if (FromLine < 1) {
|
||||
errs() << "error: start line should be at least 1\n";
|
||||
return true;
|
||||
}
|
||||
if (FromLine > ToLine) {
|
||||
errs() << "error: start line should not exceed end line\n";
|
||||
return true;
|
||||
}
|
||||
const auto Start = Sources.translateLineCol(ID, FromLine, 1);
|
||||
const auto End = Sources.translateLineCol(ID, ToLine, UINT_MAX);
|
||||
if (Start.isInvalid() || End.isInvalid())
|
||||
return true;
|
||||
const auto Offset = Sources.getFileOffset(Start);
|
||||
const auto Length = Sources.getFileOffset(End) - Offset;
|
||||
Ranges.push_back(tooling::Range(Offset, Length));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Offsets.empty())
|
||||
Offsets.push_back(0);
|
||||
const bool EmptyLengths = Lengths.empty();
|
||||
unsigned Length = 0;
|
||||
if (Offsets.size() == 1 && EmptyLengths) {
|
||||
Length = Sources.getFileOffset(Sources.getLocForEndOfFile(ID)) - Offsets[0];
|
||||
} else if (Offsets.size() != Lengths.size()) {
|
||||
errs() << "error: number of -offset and -length arguments must match.\n";
|
||||
return true;
|
||||
}
|
||||
for (unsigned I = 0, E = Offsets.size(), CodeSize = Code->getBufferSize();
|
||||
I < E; ++I) {
|
||||
const auto Offset = Offsets[I];
|
||||
if (Offset >= CodeSize) {
|
||||
errs() << "error: offset " << Offset << " is outside the file\n";
|
||||
return true;
|
||||
}
|
||||
if (!EmptyLengths)
|
||||
Length = Lengths[I];
|
||||
if (Offset + Length > CodeSize) {
|
||||
errs() << "error: invalid length " << Length << ", offset + length ("
|
||||
<< Offset + Length << ") is outside the file.\n";
|
||||
return true;
|
||||
}
|
||||
Ranges.push_back(tooling::Range(Offset, Length));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void outputReplacementXML(StringRef Text) {
|
||||
// FIXME: When we sort includes, we need to make sure the stream is correct
|
||||
// utf-8.
|
||||
size_t From = 0;
|
||||
size_t Index;
|
||||
while ((Index = Text.find_first_of("\n\r<&", From)) != StringRef::npos) {
|
||||
outs() << Text.substr(From, Index - From);
|
||||
switch (Text[Index]) {
|
||||
case '\n':
|
||||
outs() << " ";
|
||||
break;
|
||||
case '\r':
|
||||
outs() << " ";
|
||||
break;
|
||||
case '<':
|
||||
outs() << "<";
|
||||
break;
|
||||
case '&':
|
||||
outs() << "&";
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unexpected character encountered!");
|
||||
}
|
||||
From = Index + 1;
|
||||
}
|
||||
outs() << Text.substr(From);
|
||||
}
|
||||
|
||||
static void outputReplacementsXML(const Replacements &Replaces) {
|
||||
for (const auto &R : Replaces) {
|
||||
outs() << "<replacement "
|
||||
<< "offset='" << R.getOffset() << "' "
|
||||
<< "length='" << R.getLength() << "'>";
|
||||
outputReplacementXML(R.getReplacementText());
|
||||
outs() << "</replacement>\n";
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
emitReplacementWarnings(const Replacements &Replaces, StringRef AssumedFileName,
|
||||
const std::unique_ptr<llvm::MemoryBuffer> &Code) {
|
||||
unsigned Errors = 0;
|
||||
if (WarnFormat && !NoWarnFormat) {
|
||||
SourceMgr Mgr;
|
||||
const char *StartBuf = Code->getBufferStart();
|
||||
|
||||
Mgr.AddNewSourceBuffer(
|
||||
MemoryBuffer::getMemBuffer(StartBuf, AssumedFileName), SMLoc());
|
||||
for (const auto &R : Replaces) {
|
||||
SMDiagnostic Diag = Mgr.GetMessage(
|
||||
SMLoc::getFromPointer(StartBuf + R.getOffset()),
|
||||
WarningsAsErrors ? SourceMgr::DiagKind::DK_Error
|
||||
: SourceMgr::DiagKind::DK_Warning,
|
||||
"code should be clang-formatted [-Wclang-format-violations]");
|
||||
|
||||
Diag.print(nullptr, llvm::errs(), ShowColors && !NoShowColors);
|
||||
if (ErrorLimit && ++Errors >= ErrorLimit)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return WarningsAsErrors;
|
||||
}
|
||||
|
||||
static void outputXML(const Replacements &Replaces,
|
||||
const Replacements &FormatChanges,
|
||||
const FormattingAttemptStatus &Status,
|
||||
const cl::opt<unsigned> &Cursor,
|
||||
unsigned CursorPosition) {
|
||||
outs() << "<?xml version='1.0'?>\n<replacements "
|
||||
"xml:space='preserve' incomplete_format='"
|
||||
<< (Status.FormatComplete ? "false" : "true") << "'";
|
||||
if (!Status.FormatComplete)
|
||||
outs() << " line='" << Status.Line << "'";
|
||||
outs() << ">\n";
|
||||
if (Cursor.getNumOccurrences() != 0) {
|
||||
outs() << "<cursor>" << FormatChanges.getShiftedCodePosition(CursorPosition)
|
||||
<< "</cursor>\n";
|
||||
}
|
||||
|
||||
outputReplacementsXML(Replaces);
|
||||
outs() << "</replacements>\n";
|
||||
}
|
||||
|
||||
class ClangFormatDiagConsumer : public DiagnosticConsumer {
|
||||
virtual void anchor() {}
|
||||
|
||||
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
|
||||
const Diagnostic &Info) override {
|
||||
|
||||
SmallVector<char, 16> vec;
|
||||
Info.FormatDiagnostic(vec);
|
||||
errs() << "clang-format error:" << vec << "\n";
|
||||
}
|
||||
};
|
||||
|
||||
// Returns true on error.
|
||||
static bool format(StringRef FileName, bool ErrorOnIncompleteFormat = false) {
|
||||
const bool IsSTDIN = FileName == "-";
|
||||
if (!OutputXML && Inplace && IsSTDIN) {
|
||||
errs() << "error: cannot use -i when reading from stdin.\n";
|
||||
return true;
|
||||
}
|
||||
// On Windows, overwriting a file with an open file mapping doesn't work,
|
||||
// so read the whole file into memory when formatting in-place.
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
|
||||
!OutputXML && Inplace
|
||||
? MemoryBuffer::getFileAsStream(FileName)
|
||||
: MemoryBuffer::getFileOrSTDIN(FileName, /*IsText=*/true);
|
||||
if (std::error_code EC = CodeOrErr.getError()) {
|
||||
errs() << FileName << ": " << EC.message() << "\n";
|
||||
return true;
|
||||
}
|
||||
std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get());
|
||||
if (Code->getBufferSize() == 0)
|
||||
return false; // Empty files are formatted correctly.
|
||||
|
||||
StringRef BufStr = Code->getBuffer();
|
||||
|
||||
const char *InvalidBOM = SrcMgr::ContentCache::getInvalidBOM(BufStr);
|
||||
|
||||
if (InvalidBOM) {
|
||||
errs() << "error: encoding with unsupported byte order mark \""
|
||||
<< InvalidBOM << "\" detected";
|
||||
if (!IsSTDIN)
|
||||
errs() << " in file '" << FileName << "'";
|
||||
errs() << ".\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<tooling::Range> Ranges;
|
||||
if (fillRanges(Code.get(), Ranges))
|
||||
return true;
|
||||
StringRef AssumedFileName = IsSTDIN ? AssumeFileName : FileName;
|
||||
if (AssumedFileName.empty()) {
|
||||
llvm::errs() << "error: empty filenames are not allowed\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
auto RealFS = vfs::getRealFileSystem();
|
||||
auto CustomFS = new vfs::CustomFileSystem(RealFS);
|
||||
IntrusiveRefCntPtr<vfs::FileSystem> CustomFSPtr(CustomFS);
|
||||
Expected<FormatStyle> FormatStyle =
|
||||
getStyle(Style, AssumedFileName, FallbackStyle, Code->getBuffer(),
|
||||
CustomFSPtr.get(), WNoErrorList.isSet(WNoError::Unknown));
|
||||
if (!FormatStyle) {
|
||||
llvm::errs() << toString(FormatStyle.takeError()) << "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
StringRef QualifierAlignmentOrder = QualifierAlignment;
|
||||
|
||||
FormatStyle->QualifierAlignment =
|
||||
StringSwitch<FormatStyle::QualifierAlignmentStyle>(
|
||||
QualifierAlignmentOrder.lower())
|
||||
.Case("right", FormatStyle::QAS_Right)
|
||||
.Case("left", FormatStyle::QAS_Left)
|
||||
.Default(FormatStyle->QualifierAlignment);
|
||||
|
||||
if (FormatStyle->QualifierAlignment == FormatStyle::QAS_Left) {
|
||||
FormatStyle->QualifierOrder = {"const", "volatile", "type"};
|
||||
} else if (FormatStyle->QualifierAlignment == FormatStyle::QAS_Right) {
|
||||
FormatStyle->QualifierOrder = {"type", "const", "volatile"};
|
||||
} else if (QualifierAlignmentOrder.contains("type")) {
|
||||
FormatStyle->QualifierAlignment = FormatStyle::QAS_Custom;
|
||||
SmallVector<StringRef> Qualifiers;
|
||||
QualifierAlignmentOrder.split(Qualifiers, " ", /*MaxSplit=*/-1,
|
||||
/*KeepEmpty=*/false);
|
||||
FormatStyle->QualifierOrder = {Qualifiers.begin(), Qualifiers.end()};
|
||||
}
|
||||
|
||||
if (SortIncludes.getNumOccurrences() != 0) {
|
||||
FormatStyle->SortIncludes = {};
|
||||
if (SortIncludes)
|
||||
FormatStyle->SortIncludes.Enabled = true;
|
||||
}
|
||||
unsigned CursorPosition = Cursor;
|
||||
Replacements Replaces = sortIncludes(*FormatStyle, Code->getBuffer(), Ranges,
|
||||
AssumedFileName, &CursorPosition);
|
||||
|
||||
const bool IsJson = FormatStyle->isJson();
|
||||
|
||||
// To format JSON insert a variable to trick the code into thinking its
|
||||
// JavaScript.
|
||||
if (IsJson && !FormatStyle->DisableFormat) {
|
||||
auto Err =
|
||||
Replaces.add(tooling::Replacement(AssumedFileName, 0, 0, "x = "));
|
||||
if (Err)
|
||||
llvm::errs() << "Bad Json variable insertion\n";
|
||||
}
|
||||
|
||||
auto ChangedCode = tooling::applyAllReplacements(Code->getBuffer(), Replaces);
|
||||
if (!ChangedCode) {
|
||||
llvm::errs() << toString(ChangedCode.takeError()) << "\n";
|
||||
return true;
|
||||
}
|
||||
// Get new affected ranges after sorting `#includes`.
|
||||
Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges);
|
||||
FormattingAttemptStatus Status;
|
||||
Replacements FormatChanges =
|
||||
reformat(*FormatStyle, *ChangedCode, Ranges, AssumedFileName, &Status);
|
||||
Replaces = Replaces.merge(FormatChanges);
|
||||
if (DryRun) {
|
||||
return Replaces.size() > (IsJson ? 1u : 0u) &&
|
||||
emitReplacementWarnings(Replaces, AssumedFileName, Code);
|
||||
}
|
||||
if (OutputXML) {
|
||||
outputXML(Replaces, FormatChanges, Status, Cursor, CursorPosition);
|
||||
} else {
|
||||
IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
|
||||
new llvm::vfs::InMemoryFileSystem);
|
||||
FileManager Files(FileSystemOptions(), InMemoryFileSystem);
|
||||
|
||||
DiagnosticOptions DiagOpts;
|
||||
ClangFormatDiagConsumer IgnoreDiagnostics;
|
||||
DiagnosticsEngine Diagnostics(
|
||||
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), DiagOpts,
|
||||
&IgnoreDiagnostics, false);
|
||||
SourceManager Sources(Diagnostics, Files);
|
||||
FileID ID = createInMemoryFile(AssumedFileName, *Code, Sources, Files,
|
||||
InMemoryFileSystem.get());
|
||||
Rewriter Rewrite(Sources, LangOptions());
|
||||
tooling::applyAllReplacements(Replaces, Rewrite);
|
||||
if (Inplace) {
|
||||
if (Rewrite.overwriteChangedFiles())
|
||||
return true;
|
||||
} else {
|
||||
if (Cursor.getNumOccurrences() != 0) {
|
||||
outs() << "{ \"Cursor\": "
|
||||
<< FormatChanges.getShiftedCodePosition(CursorPosition)
|
||||
<< ", \"IncompleteFormat\": "
|
||||
<< (Status.FormatComplete ? "false" : "true");
|
||||
if (!Status.FormatComplete)
|
||||
outs() << ", \"Line\": " << Status.Line;
|
||||
outs() << " }\n";
|
||||
}
|
||||
Rewrite.getEditBuffer(ID).write(outs());
|
||||
}
|
||||
}
|
||||
return ErrorOnIncompleteFormat && !Status.FormatComplete;
|
||||
}
|
||||
|
||||
} // namespace format
|
||||
} // namespace clang
|
||||
|
||||
static void PrintVersion(raw_ostream &OS) {
|
||||
OS << clang::getClangToolFullVersion("clang-format") << '\n';
|
||||
}
|
||||
|
||||
// Dump the configuration.
|
||||
static int dumpConfig() {
|
||||
std::unique_ptr<llvm::MemoryBuffer> Code;
|
||||
// We can't read the code to detect the language if there's no file name.
|
||||
if (!FileNames.empty()) {
|
||||
// Read in the code in case the filename alone isn't enough to detect the
|
||||
// language.
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
|
||||
MemoryBuffer::getFileOrSTDIN(FileNames[0], /*IsText=*/true);
|
||||
if (std::error_code EC = CodeOrErr.getError()) {
|
||||
llvm::errs() << EC.message() << "\n";
|
||||
return 1;
|
||||
}
|
||||
Code = std::move(CodeOrErr.get());
|
||||
}
|
||||
|
||||
auto RealFS = vfs::getRealFileSystem();
|
||||
auto CustomFS = new vfs::CustomFileSystem(RealFS);
|
||||
IntrusiveRefCntPtr<vfs::FileSystem> CustomFSPtr(CustomFS);
|
||||
|
||||
Expected<clang::format::FormatStyle> FormatStyle = clang::format::getStyle(
|
||||
Style,
|
||||
FileNames.empty() || FileNames[0] == "-" ? AssumeFileName : FileNames[0],
|
||||
FallbackStyle, Code ? Code->getBuffer() : "", CustomFSPtr.get());
|
||||
if (!FormatStyle) {
|
||||
llvm::errs() << toString(FormatStyle.takeError()) << "\n";
|
||||
return 1;
|
||||
}
|
||||
std::string Config = clang::format::configurationAsText(*FormatStyle);
|
||||
outs() << Config << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
using String = SmallString<128>;
|
||||
static String IgnoreDir; // Directory of .clang-format-ignore file.
|
||||
static String PrevDir; // Directory of previous `FilePath`.
|
||||
static SmallVector<String> Patterns; // Patterns in .clang-format-ignore file.
|
||||
|
||||
// Check whether `FilePath` is ignored according to the nearest
|
||||
// .clang-format-ignore file based on the rules below:
|
||||
// - A blank line is skipped.
|
||||
// - Leading and trailing spaces of a line are trimmed.
|
||||
// - A line starting with a hash (`#`) is a comment.
|
||||
// - A non-comment line is a single pattern.
|
||||
// - The slash (`/`) is used as the directory separator.
|
||||
// - A pattern is relative to the directory of the .clang-format-ignore file (or
|
||||
// the root directory if the pattern starts with a slash).
|
||||
// - A pattern is negated if it starts with a bang (`!`).
|
||||
static bool isIgnored(StringRef FilePath) {
|
||||
using namespace llvm::sys::fs;
|
||||
if (!is_regular_file(FilePath))
|
||||
return false;
|
||||
|
||||
String Path;
|
||||
String AbsPath{FilePath};
|
||||
|
||||
auto PathStyle = vfs::getPathStyle();
|
||||
|
||||
using namespace llvm::sys::path;
|
||||
vfs::make_absolute(AbsPath);
|
||||
remove_dots(AbsPath, /*remove_dot_dot=*/true, PathStyle);
|
||||
|
||||
if (StringRef Dir{parent_path(AbsPath, PathStyle)}; PrevDir != Dir) {
|
||||
PrevDir = Dir;
|
||||
|
||||
for (;;) {
|
||||
Path = Dir;
|
||||
append(Path, PathStyle, ".clang-format-ignore");
|
||||
if (is_regular_file(Path))
|
||||
break;
|
||||
Dir = parent_path(Dir, PathStyle);
|
||||
if (Dir.empty())
|
||||
return false;
|
||||
}
|
||||
|
||||
IgnoreDir = convert_to_slash(Dir, PathStyle);
|
||||
|
||||
std::ifstream IgnoreFile{Path.c_str()};
|
||||
if (!IgnoreFile.good())
|
||||
return false;
|
||||
|
||||
Patterns.clear();
|
||||
|
||||
for (std::string Line; std::getline(IgnoreFile, Line);) {
|
||||
if (const auto Pattern{StringRef{Line}.trim()};
|
||||
// Skip empty and comment lines.
|
||||
!Pattern.empty() && Pattern[0] != '#') {
|
||||
Patterns.push_back(Pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IgnoreDir.empty())
|
||||
return false;
|
||||
|
||||
const auto Pathname{convert_to_slash(AbsPath, PathStyle)};
|
||||
for (const auto &Pat : Patterns) {
|
||||
const bool IsNegated = Pat[0] == '!';
|
||||
StringRef Pattern{Pat};
|
||||
if (IsNegated)
|
||||
Pattern = Pattern.drop_front();
|
||||
|
||||
if (Pattern.empty())
|
||||
continue;
|
||||
|
||||
Pattern = Pattern.ltrim();
|
||||
|
||||
// `Pattern` is relative to `IgnoreDir` unless it starts with a slash.
|
||||
// This doesn't support patterns containing drive names (e.g. `C:`).
|
||||
if (Pattern[0] != '/') {
|
||||
Path = IgnoreDir;
|
||||
append(Path, Style::posix, Pattern);
|
||||
remove_dots(Path, /*remove_dot_dot=*/true, Style::posix);
|
||||
Pattern = Path;
|
||||
}
|
||||
|
||||
if (clang::format::matchFilePath(Pattern, Pathname) == !IsNegated)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
InitLLVM X(argc, argv);
|
||||
|
||||
cl::HideUnrelatedOptions(ClangFormatCategory);
|
||||
|
||||
cl::SetVersionPrinter(PrintVersion);
|
||||
cl::ParseCommandLineOptions(
|
||||
argc, argv,
|
||||
"A tool to format C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# "
|
||||
"code.\n\n"
|
||||
"If no arguments are specified, it formats the code from standard input\n"
|
||||
"and writes the result to the standard output.\n"
|
||||
"If <file>s are given, it reformats the files. If -i is specified\n"
|
||||
"together with <file>s, the files are edited in-place. Otherwise, the\n"
|
||||
"result is written to the standard output.\n");
|
||||
|
||||
if (Help) {
|
||||
cl::PrintHelpMessage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (DumpConfig)
|
||||
return dumpConfig();
|
||||
|
||||
if (!Files.empty()) {
|
||||
std::ifstream ExternalFileOfFiles{std::string(Files)};
|
||||
std::string Line;
|
||||
unsigned LineNo = 1;
|
||||
while (std::getline(ExternalFileOfFiles, Line)) {
|
||||
FileNames.push_back(Line);
|
||||
LineNo++;
|
||||
}
|
||||
errs() << "Clang-formatting " << LineNo << " files\n";
|
||||
}
|
||||
|
||||
if (FileNames.empty()) {
|
||||
if (isIgnored(AssumeFileName))
|
||||
return 0;
|
||||
return clang::format::format("-", FailOnIncompleteFormat);
|
||||
}
|
||||
|
||||
if (FileNames.size() > 1 &&
|
||||
(!Offsets.empty() || !Lengths.empty() || !LineRanges.empty())) {
|
||||
errs() << "error: -offset, -length and -lines can only be used for "
|
||||
"single file.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned FileNo = 1;
|
||||
bool Error = false;
|
||||
for (const auto &FileName : FileNames) {
|
||||
const bool Ignored = isIgnored(FileName);
|
||||
if (ListIgnored) {
|
||||
if (Ignored)
|
||||
outs() << FileName << '\n';
|
||||
continue;
|
||||
}
|
||||
if (Ignored)
|
||||
continue;
|
||||
if (Verbose) {
|
||||
errs() << "Formatting [" << FileNo++ << "/" << FileNames.size() << "] "
|
||||
<< FileName << "\n";
|
||||
}
|
||||
Error |= clang::format::format(FileName, FailOnIncompleteFormat);
|
||||
}
|
||||
return Error ? 1 : 0;
|
||||
}
|
||||
323
frontend/src/common/prettier/plugins/clang/src/lib.cc
Normal file
323
frontend/src/common/prettier/plugins/clang/src/lib.cc
Normal file
@@ -0,0 +1,323 @@
|
||||
//===-- clang-format/ClangFormat.cpp - Clang format tool ------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// This file implements a clang-format tool that automatically formats
|
||||
/// (fragments of) C++ code.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lib.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "clang/Format/Format.h"
|
||||
#include "clang/Rewrite/Core/Rewriter.h"
|
||||
|
||||
using namespace llvm;
|
||||
using clang::tooling::Replacements;
|
||||
|
||||
static std::string FallbackStyle{clang::format::DefaultFallbackStyle};
|
||||
|
||||
static unsigned Cursor{0};
|
||||
|
||||
static bool SortIncludes{false};
|
||||
|
||||
static std::string QualifierAlignment{""};
|
||||
|
||||
static auto Ok(const std::string content) -> Result {
|
||||
return {false, std::move(content)};
|
||||
}
|
||||
|
||||
static auto Err(const std::string content) -> Result {
|
||||
return {true, std::move(content)};
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
namespace format {
|
||||
|
||||
static FileID createInMemoryFile(StringRef FileName, MemoryBufferRef Source,
|
||||
SourceManager &Sources, FileManager &Files,
|
||||
llvm::vfs::InMemoryFileSystem *MemFS) {
|
||||
MemFS->addFileNoOwn(FileName, 0, Source);
|
||||
auto File = Files.getOptionalFileRef(FileName);
|
||||
assert(File && "File not added to MemFS?");
|
||||
return Sources.createFileID(*File, SourceLocation(), SrcMgr::C_User);
|
||||
}
|
||||
|
||||
static auto fillRanges(MemoryBuffer *Code, std::vector<tooling::Range> &Ranges)
|
||||
-> void {
|
||||
Ranges.push_back(tooling::Range(0, Code->getBuffer().size()));
|
||||
}
|
||||
|
||||
static auto isPredefinedStyle(StringRef style) -> bool {
|
||||
return StringSwitch<bool>(style.lower())
|
||||
.Cases("llvm", "chromium", "mozilla", "google", "webkit", "gnu",
|
||||
"microsoft", "none", "file", true)
|
||||
.Default(false);
|
||||
}
|
||||
|
||||
static auto format_range(const std::unique_ptr<llvm::MemoryBuffer> code,
|
||||
const std::string assumedFileName,
|
||||
const std::string style,
|
||||
std::vector<tooling::Range> ranges) -> Result {
|
||||
StringRef BufStr = code->getBuffer();
|
||||
|
||||
const char *InvalidBOM = SrcMgr::ContentCache::getInvalidBOM(BufStr);
|
||||
|
||||
if (InvalidBOM) {
|
||||
std::stringstream err;
|
||||
err << "encoding with unsupported byte order mark \"" << InvalidBOM
|
||||
<< "\" detected.";
|
||||
|
||||
return Err(err.str());
|
||||
}
|
||||
|
||||
StringRef AssumedFileName = assumedFileName;
|
||||
if (AssumedFileName.empty())
|
||||
AssumedFileName = "<stdin>";
|
||||
|
||||
IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
|
||||
new llvm::vfs::InMemoryFileSystem);
|
||||
FileManager Files(FileSystemOptions(), InMemoryFileSystem);
|
||||
|
||||
DiagnosticOptions DiagOpts;
|
||||
DiagnosticsEngine Diagnostics(
|
||||
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), DiagOpts);
|
||||
SourceManager Sources(Diagnostics, Files);
|
||||
|
||||
StringRef _style = style;
|
||||
|
||||
if (!_style.starts_with("{") && !isPredefinedStyle(_style)) {
|
||||
std::unique_ptr<llvm::MemoryBuffer> DotClangFormat =
|
||||
MemoryBuffer::getMemBuffer(style);
|
||||
|
||||
createInMemoryFile(".clang-format", *DotClangFormat.get(), Sources, Files,
|
||||
InMemoryFileSystem.get());
|
||||
_style = "file:.clang-format";
|
||||
}
|
||||
|
||||
llvm::Expected<FormatStyle> FormatStyle =
|
||||
getStyle(_style, AssumedFileName, FallbackStyle, code->getBuffer(),
|
||||
InMemoryFileSystem.get(), false);
|
||||
|
||||
InMemoryFileSystem.reset();
|
||||
|
||||
if (!FormatStyle) {
|
||||
std::string err = llvm::toString(FormatStyle.takeError());
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
StringRef QualifierAlignmentOrder = QualifierAlignment;
|
||||
|
||||
FormatStyle->QualifierAlignment =
|
||||
StringSwitch<FormatStyle::QualifierAlignmentStyle>(
|
||||
QualifierAlignmentOrder.lower())
|
||||
.Case("right", FormatStyle::QAS_Right)
|
||||
.Case("left", FormatStyle::QAS_Left)
|
||||
.Default(FormatStyle->QualifierAlignment);
|
||||
|
||||
if (FormatStyle->QualifierAlignment == FormatStyle::QAS_Left) {
|
||||
FormatStyle->QualifierOrder = {"const", "volatile", "type"};
|
||||
} else if (FormatStyle->QualifierAlignment == FormatStyle::QAS_Right) {
|
||||
FormatStyle->QualifierOrder = {"type", "const", "volatile"};
|
||||
} else if (QualifierAlignmentOrder.contains("type")) {
|
||||
FormatStyle->QualifierAlignment = FormatStyle::QAS_Custom;
|
||||
SmallVector<StringRef> Qualifiers;
|
||||
QualifierAlignmentOrder.split(Qualifiers, " ", /*MaxSplit=*/-1,
|
||||
/*KeepEmpty=*/false);
|
||||
FormatStyle->QualifierOrder = {Qualifiers.begin(), Qualifiers.end()};
|
||||
}
|
||||
|
||||
if (SortIncludes) {
|
||||
FormatStyle->SortIncludes = {};
|
||||
FormatStyle->SortIncludes.Enabled = true;
|
||||
}
|
||||
|
||||
unsigned CursorPosition = Cursor;
|
||||
Replacements Replaces = sortIncludes(*FormatStyle, code->getBuffer(), ranges,
|
||||
AssumedFileName, &CursorPosition);
|
||||
|
||||
// To format JSON insert a variable to trick the code into thinking its
|
||||
// JavaScript.
|
||||
if (FormatStyle->isJson() && !FormatStyle->DisableFormat) {
|
||||
auto err =
|
||||
Replaces.add(tooling::Replacement(AssumedFileName, 0, 0, "x = "));
|
||||
if (err)
|
||||
return Err("Bad Json variable insertion");
|
||||
}
|
||||
|
||||
auto ChangedCode =
|
||||
cantFail(tooling::applyAllReplacements(code->getBuffer(), Replaces));
|
||||
|
||||
// Get new affected ranges after sorting `#includes`.
|
||||
ranges = tooling::calculateRangesAfterReplacements(Replaces, ranges);
|
||||
FormattingAttemptStatus Status;
|
||||
Replacements FormatChanges =
|
||||
reformat(*FormatStyle, ChangedCode, ranges, AssumedFileName, &Status);
|
||||
Replaces = Replaces.merge(FormatChanges);
|
||||
|
||||
return Ok(
|
||||
cantFail(tooling::applyAllReplacements(code->getBuffer(), Replaces)));
|
||||
}
|
||||
|
||||
static auto format_range(const std::string str,
|
||||
const std::string assumedFileName,
|
||||
const std::string style, const bool is_line_range,
|
||||
const std::vector<unsigned> ranges) -> Result {
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
|
||||
MemoryBuffer::getMemBuffer(str);
|
||||
|
||||
if (std::error_code EC = CodeOrErr.getError())
|
||||
return Err(EC.message());
|
||||
std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get());
|
||||
if (Code->getBufferSize() == 0)
|
||||
return Ok(""); // Empty files are formatted correctly.
|
||||
|
||||
std::vector<tooling::Range> Ranges;
|
||||
|
||||
if (ranges.empty()) {
|
||||
fillRanges(Code.get(), Ranges);
|
||||
return format_range(std::move(Code), assumedFileName, style,
|
||||
std::move(Ranges));
|
||||
}
|
||||
|
||||
IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
|
||||
new llvm::vfs::InMemoryFileSystem);
|
||||
FileManager Files(FileSystemOptions(), InMemoryFileSystem);
|
||||
DiagnosticOptions DiagOpts;
|
||||
DiagnosticsEngine Diagnostics(
|
||||
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), DiagOpts);
|
||||
SourceManager Sources(Diagnostics, Files);
|
||||
FileID ID = createInMemoryFile("<irrelevant>", *Code, Sources, Files,
|
||||
InMemoryFileSystem.get());
|
||||
|
||||
if (is_line_range) {
|
||||
for (auto FromLine = begin(ranges); FromLine < end(ranges); FromLine += 2) {
|
||||
auto ToLine = FromLine + 1;
|
||||
|
||||
SourceLocation Start = Sources.translateLineCol(ID, *FromLine, 1);
|
||||
SourceLocation End = Sources.translateLineCol(ID, *ToLine, UINT_MAX);
|
||||
if (Start.isInvalid() || End.isInvalid())
|
||||
return Err("invalid line number");
|
||||
unsigned Offset = Sources.getFileOffset(Start);
|
||||
unsigned Length = Sources.getFileOffset(End) - Offset;
|
||||
Ranges.push_back(tooling::Range(Offset, Length));
|
||||
}
|
||||
} else {
|
||||
if (ranges.size() > 2 && ranges.size() % 2 != 0)
|
||||
return Err("number of -offset and -length arguments must match");
|
||||
|
||||
if (ranges.size() == 1) {
|
||||
auto offset = begin(ranges);
|
||||
if (*offset >= Code->getBufferSize()) {
|
||||
std::stringstream err;
|
||||
err << "offset " << *offset << " is outside the file";
|
||||
return Err(err.str());
|
||||
}
|
||||
SourceLocation Start =
|
||||
Sources.getLocForStartOfFile(ID).getLocWithOffset(*offset);
|
||||
SourceLocation End = Sources.getLocForEndOfFile(ID);
|
||||
|
||||
unsigned Offset = Sources.getFileOffset(Start);
|
||||
unsigned Length = Sources.getFileOffset(End) - Offset;
|
||||
|
||||
Ranges.push_back(tooling::Range(Offset, Length));
|
||||
} else {
|
||||
for (auto offset = begin(ranges); offset < end(ranges); offset += 2) {
|
||||
auto length = offset + 1;
|
||||
|
||||
if (*offset >= Code->getBufferSize()) {
|
||||
std::stringstream err;
|
||||
err << "offset " << *offset << " is outside the file";
|
||||
return Err(err.str());
|
||||
}
|
||||
|
||||
unsigned end = *offset + *length;
|
||||
if (end > Code->getBufferSize()) {
|
||||
std::stringstream err;
|
||||
err << "invalid length " << *length << ", offset + length (" << end
|
||||
<< ") is outside the file.";
|
||||
return Err(err.str());
|
||||
}
|
||||
|
||||
SourceLocation Start =
|
||||
Sources.getLocForStartOfFile(ID).getLocWithOffset(*offset);
|
||||
SourceLocation End = Start.getLocWithOffset(*length);
|
||||
|
||||
unsigned Offset = Sources.getFileOffset(Start);
|
||||
unsigned Length = Sources.getFileOffset(End) - Offset;
|
||||
|
||||
Ranges.push_back(tooling::Range(Offset, Length));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return format_range(std::move(Code), assumedFileName, style,
|
||||
std::move(Ranges));
|
||||
}
|
||||
|
||||
static auto format(const std::string str, const std::string assumedFileName,
|
||||
const std::string style) -> Result {
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
|
||||
MemoryBuffer::getMemBuffer(str);
|
||||
|
||||
if (std::error_code EC = CodeOrErr.getError())
|
||||
return Err(EC.message());
|
||||
std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get());
|
||||
if (Code->getBufferSize() == 0)
|
||||
return Ok(""); // Empty files are formatted correctly.
|
||||
|
||||
std::vector<tooling::Range> Ranges;
|
||||
fillRanges(Code.get(), Ranges);
|
||||
|
||||
return format_range(std::move(Code), assumedFileName, style,
|
||||
std::move(Ranges));
|
||||
}
|
||||
|
||||
} // namespace format
|
||||
} // namespace clang
|
||||
|
||||
auto version() -> std::string {
|
||||
return clang::getClangToolFullVersion("clang-format");
|
||||
}
|
||||
|
||||
auto format(const std::string str, const std::string assumedFileName,
|
||||
const std::string style) -> Result {
|
||||
return clang::format::format(str, assumedFileName, style);
|
||||
}
|
||||
|
||||
auto format_byte(const std::string str, const std::string assumedFileName,
|
||||
const std::string style, const std::vector<unsigned> ranges)
|
||||
-> Result {
|
||||
return clang::format::format_range(str, assumedFileName, style, false,
|
||||
std::move(ranges));
|
||||
}
|
||||
|
||||
auto format_line(const std::string str, const std::string assumedFileName,
|
||||
const std::string style, const std::vector<unsigned> ranges)
|
||||
-> Result {
|
||||
return clang::format::format_range(str, assumedFileName, style, true,
|
||||
std::move(ranges));
|
||||
}
|
||||
|
||||
auto set_fallback_style(const std::string style) -> void {
|
||||
FallbackStyle = style;
|
||||
}
|
||||
|
||||
auto set_sort_includes(const bool sort) -> void { SortIncludes = sort; }
|
||||
|
||||
auto dump_config(const std::string style, const std::string FileName,
|
||||
const std::string code) -> Result {
|
||||
llvm::Expected<clang::format::FormatStyle> FormatStyle =
|
||||
clang::format::getStyle(style, FileName, FallbackStyle, code);
|
||||
if (!FormatStyle)
|
||||
return Err(llvm::toString(FormatStyle.takeError()));
|
||||
std::string Config = clang::format::configurationAsText(*FormatStyle);
|
||||
return Ok(Config);
|
||||
}
|
||||
24
frontend/src/common/prettier/plugins/clang/src/lib.h
Normal file
24
frontend/src/common/prettier/plugins/clang/src/lib.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef CLANG_FORMAT_WASM_LIB_H_
|
||||
#define CLANG_FORMAT_WASM_LIB_H_
|
||||
#include <sstream>
|
||||
|
||||
struct Result {
|
||||
bool error;
|
||||
std::string content;
|
||||
};
|
||||
|
||||
auto version() -> std::string;
|
||||
auto format(const std::string str, const std::string assumedFileName, const std::string style) -> Result;
|
||||
auto format_byte(const std::string str,
|
||||
const std::string assumedFileName,
|
||||
const std::string style,
|
||||
const std::vector<unsigned> ranges) -> Result;
|
||||
auto format_line(const std::string str,
|
||||
const std::string assumedFileName,
|
||||
const std::string style,
|
||||
const std::vector<unsigned> ranges) -> Result;
|
||||
auto set_fallback_style(const std::string style) -> void;
|
||||
auto set_sort_includes(const bool sort) -> void;
|
||||
auto dump_config(const std::string style, const std::string FileName, const std::string code) -> Result;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
set -Eeo pipefail
|
||||
|
||||
cd $(dirname $0)/..
|
||||
project_root=$(pwd)
|
||||
|
||||
rm -rf pkg
|
||||
mkdir -p pkg build
|
||||
cd build
|
||||
|
||||
export CC=$(which clang)
|
||||
export CXX=$(which clang++)
|
||||
|
||||
emcmake cmake -G Ninja ..
|
||||
ninja clang-format-wasm
|
||||
|
||||
cd $project_root
|
||||
|
||||
if [[ ! -z "${WASM_OPT}" ]]; then
|
||||
wasm-opt -Os build/clang-format-esm.wasm -o build/clang-format-esm-Os.wasm
|
||||
wasm-opt -Oz build/clang-format-esm.wasm -o build/clang-format-esm-Oz.wasm
|
||||
fi
|
||||
|
||||
SMALLEST_WASM=$(ls -Sr build/clang-format-e*.wasm | head -1)
|
||||
|
||||
cp $SMALLEST_WASM pkg/clang-format.wasm
|
||||
cat src/template.js build/clang-format-esm.js >pkg/clang-format.js
|
||||
|
||||
# add shebang
|
||||
echo '#!/usr/bin/env node' | cat - ./build/clang-format-cli.js >./pkg/clang-format-cli.cjs
|
||||
cp ./build/clang-format-cli.wasm ./pkg/
|
||||
|
||||
cp ./src/clang-format.d.ts src/clang-format-*.js ./pkg/
|
||||
cp ./package.json LICENSE README.md .npmignore ./pkg/
|
||||
|
||||
# copy git-clang-format and clang-format-diff.py
|
||||
cp ./build/_deps/llvm_project-src/clang/tools/clang-format/git-clang-format ./pkg/
|
||||
cp ./build/_deps/llvm_project-src/clang/tools/clang-format/clang-format-diff.py ./pkg/
|
||||
|
||||
ls -lh ./pkg
|
||||
|
||||
# make sure repo is clean
|
||||
# git diff --exit-code
|
||||
@@ -0,0 +1,95 @@
|
||||
diff --git a/src/cli.cc b/src/cli.cc
|
||||
index 2861005..69ec009 100644
|
||||
--- a/src/cli.cc
|
||||
+++ b/src/cli.cc
|
||||
@@ -12,7 +12,7 @@
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
-#include "../../lib/Format/MatchFilePath.h"
|
||||
+#include "clang/../../lib/Format/MatchFilePath.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/DiagnosticOptions.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "llvm/Support/Process.h"
|
||||
#include <fstream>
|
||||
|
||||
+#include "CustomFileSystem.h"
|
||||
+
|
||||
using namespace llvm;
|
||||
using clang::tooling::Replacements;
|
||||
|
||||
@@ -448,9 +450,12 @@ static bool format(StringRef FileName, bool ErrorOnIncompleteFormat = false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+ auto RealFS = vfs::getRealFileSystem();
|
||||
+ auto CustomFS = new vfs::CustomFileSystem(RealFS);
|
||||
+ IntrusiveRefCntPtr<vfs::FileSystem> CustomFSPtr(CustomFS);
|
||||
Expected<FormatStyle> FormatStyle =
|
||||
getStyle(Style, AssumedFileName, FallbackStyle, Code->getBuffer(),
|
||||
- nullptr, WNoErrorList.isSet(WNoError::Unknown));
|
||||
+ CustomFSPtr.get(), WNoErrorList.isSet(WNoError::Unknown));
|
||||
if (!FormatStyle) {
|
||||
llvm::errs() << toString(FormatStyle.takeError()) << "\n";
|
||||
return true;
|
||||
@@ -571,10 +576,15 @@ static int dumpConfig() {
|
||||
}
|
||||
Code = std::move(CodeOrErr.get());
|
||||
}
|
||||
+
|
||||
+ auto RealFS = vfs::getRealFileSystem();
|
||||
+ auto CustomFS = new vfs::CustomFileSystem(RealFS);
|
||||
+ IntrusiveRefCntPtr<vfs::FileSystem> CustomFSPtr(CustomFS);
|
||||
+
|
||||
Expected<clang::format::FormatStyle> FormatStyle = clang::format::getStyle(
|
||||
Style,
|
||||
FileNames.empty() || FileNames[0] == "-" ? AssumeFileName : FileNames[0],
|
||||
- FallbackStyle, Code ? Code->getBuffer() : "");
|
||||
+ FallbackStyle, Code ? Code->getBuffer() : "", CustomFSPtr.get());
|
||||
if (!FormatStyle) {
|
||||
llvm::errs() << toString(FormatStyle.takeError()) << "\n";
|
||||
return 1;
|
||||
@@ -607,24 +617,26 @@ static bool isIgnored(StringRef FilePath) {
|
||||
String Path;
|
||||
String AbsPath{FilePath};
|
||||
|
||||
+ auto PathStyle = vfs::getPathStyle();
|
||||
+
|
||||
using namespace llvm::sys::path;
|
||||
- make_absolute(AbsPath);
|
||||
- remove_dots(AbsPath, /*remove_dot_dot=*/true);
|
||||
+ vfs::make_absolute(AbsPath);
|
||||
+ remove_dots(AbsPath, /*remove_dot_dot=*/true, PathStyle);
|
||||
|
||||
- if (StringRef Dir{parent_path(AbsPath)}; PrevDir != Dir) {
|
||||
+ if (StringRef Dir{parent_path(AbsPath, PathStyle)}; PrevDir != Dir) {
|
||||
PrevDir = Dir;
|
||||
|
||||
for (;;) {
|
||||
Path = Dir;
|
||||
- append(Path, ".clang-format-ignore");
|
||||
+ append(Path, PathStyle, ".clang-format-ignore");
|
||||
if (is_regular_file(Path))
|
||||
break;
|
||||
- Dir = parent_path(Dir);
|
||||
+ Dir = parent_path(Dir, PathStyle);
|
||||
if (Dir.empty())
|
||||
return false;
|
||||
}
|
||||
|
||||
- IgnoreDir = convert_to_slash(Dir);
|
||||
+ IgnoreDir = convert_to_slash(Dir, PathStyle);
|
||||
|
||||
std::ifstream IgnoreFile{Path.c_str()};
|
||||
if (!IgnoreFile.good())
|
||||
@@ -644,7 +656,7 @@ static bool isIgnored(StringRef FilePath) {
|
||||
if (IgnoreDir.empty())
|
||||
return false;
|
||||
|
||||
- const auto Pathname{convert_to_slash(AbsPath)};
|
||||
+ const auto Pathname{convert_to_slash(AbsPath, PathStyle)};
|
||||
for (const auto &Pat : Patterns) {
|
||||
const bool IsNegated = Pat[0] == '!';
|
||||
StringRef Pattern{Pat};
|
||||
@@ -0,0 +1,26 @@
|
||||
current_dir=$(pwd)
|
||||
tmp_dir=$(mktemp -d)
|
||||
|
||||
cd $tmp_dir
|
||||
|
||||
git init
|
||||
|
||||
cp $current_dir/build/_deps/llvm_project-src/clang/tools/clang-format/ClangFormat.cpp ./cli.cc
|
||||
|
||||
git add -f .
|
||||
git commit -m "init"
|
||||
|
||||
cp $current_dir/src/cli.cc ./cli.cc
|
||||
|
||||
git add -f .
|
||||
git diff \
|
||||
--cached \
|
||||
--no-color \
|
||||
--ignore-space-at-eol \
|
||||
--no-ext-diff \
|
||||
--src-prefix=a/src/ \
|
||||
--dst-prefix=b/src/ \
|
||||
>$current_dir/scripts/cli.patch || true
|
||||
|
||||
rm -rf $tmp_dir
|
||||
|
||||
146
frontend/src/common/prettier/plugins/clang/src/template.js
Normal file
146
frontend/src/common/prettier/plugins/clang/src/template.js
Normal file
@@ -0,0 +1,146 @@
|
||||
/* @ts-self-types="./clang-format.d.ts" */
|
||||
async function load(module) {
|
||||
if (typeof Response === "function" && module instanceof Response) {
|
||||
if ("compileStreaming" in WebAssembly) {
|
||||
try {
|
||||
return await WebAssembly.compileStreaming(module);
|
||||
} catch (e) {
|
||||
if (module.headers.get("Content-Type") !== "application/wasm") {
|
||||
console.warn(
|
||||
"`WebAssembly.compileStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",
|
||||
e,
|
||||
);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return module.arrayBuffer();
|
||||
}
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
let wasm;
|
||||
export default async function initAsync(input) {
|
||||
if (wasm !== undefined) {
|
||||
return wasm;
|
||||
}
|
||||
|
||||
if (typeof input === "undefined") {
|
||||
input = new URL("clang-format.wasm", import.meta.url);
|
||||
}
|
||||
|
||||
if (
|
||||
typeof input === "string" ||
|
||||
(typeof Request === "function" && input instanceof Request) ||
|
||||
(typeof URL === "function" && input instanceof URL)
|
||||
) {
|
||||
input = fetch(input);
|
||||
}
|
||||
|
||||
wasm = await load(await input).then((wasm) => Module({ wasm }));
|
||||
assert_init = () => {};
|
||||
}
|
||||
|
||||
function assert_init() {
|
||||
throw new Error("uninit");
|
||||
}
|
||||
|
||||
export function version() {
|
||||
assert_init();
|
||||
return wasm.version();
|
||||
}
|
||||
|
||||
export function set_fallback_style(style) {
|
||||
assert_init();
|
||||
wasm.set_fallback_style(style);
|
||||
}
|
||||
|
||||
export function set_sort_includes(sort) {
|
||||
assert_init();
|
||||
wasm.set_sort_includes(sort);
|
||||
}
|
||||
|
||||
function unwrap(result) {
|
||||
const { error, content } = result;
|
||||
if (error) {
|
||||
throw Error(content);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
export function format(content, filename = "<stdin>", style = "LLVM") {
|
||||
assert_init();
|
||||
const result = wasm.format(content, filename, style);
|
||||
return unwrap(result);
|
||||
}
|
||||
|
||||
export function format_line_range(
|
||||
content,
|
||||
range,
|
||||
filename = "<stdin>",
|
||||
style = "LLVM",
|
||||
) {
|
||||
assert_init();
|
||||
const rangeList = new wasm.RangeList();
|
||||
for (const [fromLine, toLine] of range) {
|
||||
if (fromLine < 1) {
|
||||
throw Error("start line should be at least 1");
|
||||
}
|
||||
if (fromLine > toLine) {
|
||||
throw Error("start line should not exceed end line");
|
||||
}
|
||||
rangeList.push_back(fromLine);
|
||||
rangeList.push_back(toLine);
|
||||
}
|
||||
|
||||
const result = wasm.format_line(content, filename, style, rangeList);
|
||||
rangeList.delete();
|
||||
return unwrap(result);
|
||||
}
|
||||
|
||||
export function format_byte_range(
|
||||
content,
|
||||
range,
|
||||
filename = "<stdin>",
|
||||
style = "LLVM",
|
||||
) {
|
||||
assert_init();
|
||||
const rangeList = new wasm.RangeList();
|
||||
|
||||
if (range.length === 1 && range[0].length === 1) {
|
||||
rangeList.push_back(range[0][0]);
|
||||
} else {
|
||||
for (const [offset, length] of range) {
|
||||
if (offset < 0) {
|
||||
throw Error("start offset should be at least 0");
|
||||
}
|
||||
if (length < 0) {
|
||||
throw Error("length should be at least 0");
|
||||
}
|
||||
rangeList.push_back(offset);
|
||||
rangeList.push_back(length);
|
||||
}
|
||||
}
|
||||
|
||||
const result = wasm.format_byte(content, filename, style, rangeList);
|
||||
rangeList.delete();
|
||||
return unwrap(result);
|
||||
}
|
||||
|
||||
export function dump_config({
|
||||
style = "file",
|
||||
filename = "<stdin>",
|
||||
code = "",
|
||||
} = {}) {
|
||||
assert_init();
|
||||
const result = wasm.dump_config(style, filename, code);
|
||||
return unwrap(result);
|
||||
}
|
||||
|
||||
export {
|
||||
format_byte_range as formatByteRange,
|
||||
format_line_range as formatLineRange,
|
||||
};
|
||||
32
frontend/src/common/prettier/plugins/dart/dart_fmt.d.ts
vendored
Normal file
32
frontend/src/common/prettier/plugins/dart/dart_fmt.d.ts
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
export function format(input: string, filename: string, config?: LayoutConfig): string;
|
||||
|
||||
interface LayoutConfig {
|
||||
line_width?: number;
|
||||
line_ending?: "lf" | "crlf";
|
||||
language_version?: string;
|
||||
}
|
||||
|
||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
export type InitOutput = unknown;
|
||||
|
||||
// export type SyncInitInput = BufferSource | WebAssembly.Module;
|
||||
// /**
|
||||
// * Instantiates the given `module`, which can either be bytes or
|
||||
// * a precompiled `WebAssembly.Module`.
|
||||
// *
|
||||
// * @param {SyncInitInput} module
|
||||
// *
|
||||
// * @returns {InitOutput}
|
||||
// */
|
||||
// export function initSync(module: SyncInitInput): InitOutput;
|
||||
|
||||
/**
|
||||
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
||||
* for everything else, calls `WebAssembly.instantiate` directly.
|
||||
*
|
||||
* @param {InitInput | Promise<InitInput>} module_or_path
|
||||
*
|
||||
* @returns {Promise<InitOutput>}
|
||||
*/
|
||||
export default function init(module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;
|
||||
84
frontend/src/common/prettier/plugins/dart/dart_fmt.js
Normal file
84
frontend/src/common/prettier/plugins/dart/dart_fmt.js
Normal file
@@ -0,0 +1,84 @@
|
||||
import { format as dart_fmt, instantiate, invoke } from "./dart_fmt.mjs";
|
||||
|
||||
let wasm;
|
||||
|
||||
function get_imports() {}
|
||||
function init_memory() {}
|
||||
|
||||
function normalize(module) {
|
||||
if (!(module instanceof WebAssembly.Module)) {
|
||||
return new WebAssembly.Module(module);
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
export default async function (input) {
|
||||
if (wasm !== undefined) return wasm;
|
||||
|
||||
if (typeof input === "undefined") {
|
||||
input = new URL("dart_fmt.wasm", import.meta.url);
|
||||
}
|
||||
const imports = get_imports();
|
||||
|
||||
if (
|
||||
typeof input === "string" ||
|
||||
(typeof Request === "function" && input instanceof Request) ||
|
||||
(typeof URL === "function" && input instanceof URL)
|
||||
) {
|
||||
input = fetch(input);
|
||||
}
|
||||
|
||||
init_memory(imports);
|
||||
|
||||
wasm = await load(await input)
|
||||
.then(normalize)
|
||||
.then(instantiate);
|
||||
|
||||
invoke(wasm);
|
||||
|
||||
return wasm;
|
||||
}
|
||||
|
||||
async function load(module) {
|
||||
if (typeof Response === "function" && module instanceof Response) {
|
||||
if ("compileStreaming" in WebAssembly) {
|
||||
try {
|
||||
return await WebAssembly.compileStreaming(module);
|
||||
} catch (e) {
|
||||
if (module.headers.get("Content-Type") != "application/wasm") {
|
||||
console.warn(
|
||||
"`WebAssembly.compileStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",
|
||||
e,
|
||||
);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return module.arrayBuffer();
|
||||
}
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
export function format(source, filename = "stdin.dart", config = {}) {
|
||||
const options = { lineEnding: "\n" };
|
||||
if (config.line_width) {
|
||||
options.pageWidth = config.line_width;
|
||||
}
|
||||
if (options.line_ending === "crlf") {
|
||||
options.lineEnding = "\r\n";
|
||||
}
|
||||
if(options.language_version) {
|
||||
options.languageVersion = options.language_version;
|
||||
}
|
||||
|
||||
const result = dart_fmt(source, filename, JSON.stringify(options));
|
||||
const err = result[0] === "x";
|
||||
const output = result.slice(1);
|
||||
if (err) {
|
||||
throw new Error(output);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
350
frontend/src/common/prettier/plugins/dart/dart_fmt.mjs
Normal file
350
frontend/src/common/prettier/plugins/dart/dart_fmt.mjs
Normal file
@@ -0,0 +1,350 @@
|
||||
|
||||
// `modulePromise` is a promise to the `WebAssembly.module` object to be
|
||||
// instantiated.
|
||||
// `importObjectPromise` is a promise to an object that contains any additional
|
||||
// imports needed by the module that aren't provided by the standard runtime.
|
||||
// The fields on this object will be merged into the importObject with which
|
||||
// the module will be instantiated.
|
||||
// This function returns a promise to the instantiated module.
|
||||
export const instantiate = async (modulePromise, importObjectPromise) => {
|
||||
let dartInstance;
|
||||
|
||||
// Prints to the console
|
||||
function printToConsole(value) {
|
||||
if (typeof dartPrint == "function") {
|
||||
dartPrint(value);
|
||||
return;
|
||||
}
|
||||
if (typeof console == "object" && typeof console.log != "undefined") {
|
||||
console.log(value);
|
||||
return;
|
||||
}
|
||||
if (typeof print == "function") {
|
||||
print(value);
|
||||
return;
|
||||
}
|
||||
|
||||
throw "Unable to print message: " + js;
|
||||
}
|
||||
|
||||
// Converts a Dart List to a JS array. Any Dart objects will be converted, but
|
||||
// this will be cheap for JSValues.
|
||||
function arrayFromDartList(constructor, list) {
|
||||
const exports = dartInstance.exports;
|
||||
const read = exports.$listRead;
|
||||
const length = exports.$listLength(list);
|
||||
const array = new constructor(length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
array[i] = read(list, i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
// A special symbol attached to functions that wrap Dart functions.
|
||||
const jsWrappedDartFunctionSymbol = Symbol("JSWrappedDartFunction");
|
||||
|
||||
function finalizeWrapper(dartFunction, wrapped) {
|
||||
wrapped.dartFunction = dartFunction;
|
||||
wrapped[jsWrappedDartFunctionSymbol] = true;
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
// Imports
|
||||
const dart2wasm = {
|
||||
|
||||
_49: v => v.toString(),
|
||||
_64: s => {
|
||||
if (!/^\s*[+-]?(?:Infinity|NaN|(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(s)) {
|
||||
return NaN;
|
||||
}
|
||||
return parseFloat(s);
|
||||
},
|
||||
_65: () => {
|
||||
let stackString = new Error().stack.toString();
|
||||
let frames = stackString.split('\n');
|
||||
let drop = 2;
|
||||
if (frames[0] === 'Error') {
|
||||
drop += 1;
|
||||
}
|
||||
return frames.slice(drop).join('\n');
|
||||
},
|
||||
_69: () => {
|
||||
// On browsers return `globalThis.location.href`
|
||||
if (globalThis.location != null) {
|
||||
return globalThis.location.href;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
_70: () => {
|
||||
return typeof process != "undefined" &&
|
||||
Object.prototype.toString.call(process) == "[object process]" &&
|
||||
process.platform == "win32"
|
||||
},
|
||||
_85: s => JSON.stringify(s),
|
||||
_86: s => printToConsole(s),
|
||||
_87: a => a.join(''),
|
||||
_90: (s, t) => s.split(t),
|
||||
_91: s => s.toLowerCase(),
|
||||
_92: s => s.toUpperCase(),
|
||||
_93: s => s.trim(),
|
||||
_97: (s, p, i) => s.indexOf(p, i),
|
||||
_98: (s, p, i) => s.lastIndexOf(p, i),
|
||||
_100: Object.is,
|
||||
_101: s => s.toUpperCase(),
|
||||
_102: s => s.toLowerCase(),
|
||||
_103: (a, i) => a.push(i),
|
||||
_113: (a, b) => a == b ? 0 : (a > b ? 1 : -1),
|
||||
_114: a => a.length,
|
||||
_116: (a, i) => a[i],
|
||||
_117: (a, i, v) => a[i] = v,
|
||||
_120: (o, start, length) => new Uint8Array(o.buffer, o.byteOffset + start, length),
|
||||
_121: (o, start, length) => new Int8Array(o.buffer, o.byteOffset + start, length),
|
||||
_122: (o, start, length) => new Uint8ClampedArray(o.buffer, o.byteOffset + start, length),
|
||||
_123: (o, start, length) => new Uint16Array(o.buffer, o.byteOffset + start, length),
|
||||
_124: (o, start, length) => new Int16Array(o.buffer, o.byteOffset + start, length),
|
||||
_125: (o, start, length) => new Uint32Array(o.buffer, o.byteOffset + start, length),
|
||||
_126: (o, start, length) => new Int32Array(o.buffer, o.byteOffset + start, length),
|
||||
_129: (o, start, length) => new Float32Array(o.buffer, o.byteOffset + start, length),
|
||||
_130: (o, start, length) => new Float64Array(o.buffer, o.byteOffset + start, length),
|
||||
_133: (o) => new DataView(o.buffer, o.byteOffset, o.byteLength),
|
||||
_137: Function.prototype.call.bind(Object.getOwnPropertyDescriptor(DataView.prototype, 'byteLength').get),
|
||||
_138: (b, o) => new DataView(b, o),
|
||||
_140: Function.prototype.call.bind(DataView.prototype.getUint8),
|
||||
_141: Function.prototype.call.bind(DataView.prototype.setUint8),
|
||||
_142: Function.prototype.call.bind(DataView.prototype.getInt8),
|
||||
_143: Function.prototype.call.bind(DataView.prototype.setInt8),
|
||||
_144: Function.prototype.call.bind(DataView.prototype.getUint16),
|
||||
_145: Function.prototype.call.bind(DataView.prototype.setUint16),
|
||||
_146: Function.prototype.call.bind(DataView.prototype.getInt16),
|
||||
_147: Function.prototype.call.bind(DataView.prototype.setInt16),
|
||||
_148: Function.prototype.call.bind(DataView.prototype.getUint32),
|
||||
_149: Function.prototype.call.bind(DataView.prototype.setUint32),
|
||||
_150: Function.prototype.call.bind(DataView.prototype.getInt32),
|
||||
_151: Function.prototype.call.bind(DataView.prototype.setInt32),
|
||||
_156: Function.prototype.call.bind(DataView.prototype.getFloat32),
|
||||
_157: Function.prototype.call.bind(DataView.prototype.setFloat32),
|
||||
_158: Function.prototype.call.bind(DataView.prototype.getFloat64),
|
||||
_159: Function.prototype.call.bind(DataView.prototype.setFloat64),
|
||||
_165: x0 => format = x0,
|
||||
_166: f => finalizeWrapper(f, function(x0,x1,x2) { return dartInstance.exports._166(f,arguments.length,x0,x1,x2) }),
|
||||
_184: (c) =>
|
||||
queueMicrotask(() => dartInstance.exports.$invokeCallback(c)),
|
||||
_187: (s, m) => {
|
||||
try {
|
||||
return new RegExp(s, m);
|
||||
} catch (e) {
|
||||
return String(e);
|
||||
}
|
||||
},
|
||||
_188: (x0,x1) => x0.exec(x1),
|
||||
_189: (x0,x1) => x0.test(x1),
|
||||
_190: (x0,x1) => x0.exec(x1),
|
||||
_191: (x0,x1) => x0.exec(x1),
|
||||
_192: x0 => x0.pop(),
|
||||
_198: o => o === undefined,
|
||||
_199: o => typeof o === 'boolean',
|
||||
_200: o => typeof o === 'number',
|
||||
_202: o => typeof o === 'string',
|
||||
_205: o => o instanceof Int8Array,
|
||||
_206: o => o instanceof Uint8Array,
|
||||
_207: o => o instanceof Uint8ClampedArray,
|
||||
_208: o => o instanceof Int16Array,
|
||||
_209: o => o instanceof Uint16Array,
|
||||
_210: o => o instanceof Int32Array,
|
||||
_211: o => o instanceof Uint32Array,
|
||||
_212: o => o instanceof Float32Array,
|
||||
_213: o => o instanceof Float64Array,
|
||||
_214: o => o instanceof ArrayBuffer,
|
||||
_215: o => o instanceof DataView,
|
||||
_216: o => o instanceof Array,
|
||||
_217: o => typeof o === 'function' && o[jsWrappedDartFunctionSymbol] === true,
|
||||
_220: o => o instanceof RegExp,
|
||||
_221: (l, r) => l === r,
|
||||
_222: o => o,
|
||||
_223: o => o,
|
||||
_224: o => o,
|
||||
_225: b => !!b,
|
||||
_226: o => o.length,
|
||||
_229: (o, i) => o[i],
|
||||
_230: f => f.dartFunction,
|
||||
_231: l => arrayFromDartList(Int8Array, l),
|
||||
_232: (data, length) => {
|
||||
const jsBytes = new Uint8Array(length);
|
||||
const getByte = dartInstance.exports.$uint8ListGet;
|
||||
for (let i = 0; i < length; i++) {
|
||||
jsBytes[i] = getByte(data, i);
|
||||
}
|
||||
return jsBytes;
|
||||
},
|
||||
_233: l => arrayFromDartList(Uint8ClampedArray, l),
|
||||
_234: l => arrayFromDartList(Int16Array, l),
|
||||
_235: l => arrayFromDartList(Uint16Array, l),
|
||||
_236: l => arrayFromDartList(Int32Array, l),
|
||||
_237: l => arrayFromDartList(Uint32Array, l),
|
||||
_238: l => arrayFromDartList(Float32Array, l),
|
||||
_239: l => arrayFromDartList(Float64Array, l),
|
||||
_240: (data, length) => {
|
||||
const read = dartInstance.exports.$byteDataGetUint8;
|
||||
const view = new DataView(new ArrayBuffer(length));
|
||||
for (let i = 0; i < length; i++) {
|
||||
view.setUint8(i, read(data, i));
|
||||
}
|
||||
return view;
|
||||
},
|
||||
_241: l => arrayFromDartList(Array, l),
|
||||
_242: (s, length) => {
|
||||
if (length == 0) return '';
|
||||
|
||||
const read = dartInstance.exports.$stringRead1;
|
||||
let result = '';
|
||||
let index = 0;
|
||||
const chunkLength = Math.min(length - index, 500);
|
||||
let array = new Array(chunkLength);
|
||||
while (index < length) {
|
||||
const newChunkLength = Math.min(length - index, 500);
|
||||
for (let i = 0; i < newChunkLength; i++) {
|
||||
array[i] = read(s, index++);
|
||||
}
|
||||
if (newChunkLength < chunkLength) {
|
||||
array = array.slice(0, newChunkLength);
|
||||
}
|
||||
result += String.fromCharCode(...array);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
,
|
||||
_243: (s, length) => {
|
||||
if (length == 0) return '';
|
||||
|
||||
const read = dartInstance.exports.$stringRead2;
|
||||
let result = '';
|
||||
let index = 0;
|
||||
const chunkLength = Math.min(length - index, 500);
|
||||
let array = new Array(chunkLength);
|
||||
while (index < length) {
|
||||
const newChunkLength = Math.min(length - index, 500);
|
||||
for (let i = 0; i < newChunkLength; i++) {
|
||||
array[i] = read(s, index++);
|
||||
}
|
||||
if (newChunkLength < chunkLength) {
|
||||
array = array.slice(0, newChunkLength);
|
||||
}
|
||||
result += String.fromCharCode(...array);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
,
|
||||
_244: (s) => {
|
||||
let length = s.length;
|
||||
let range = 0;
|
||||
for (let i = 0; i < length; i++) {
|
||||
range |= s.codePointAt(i);
|
||||
}
|
||||
const exports = dartInstance.exports;
|
||||
if (range < 256) {
|
||||
if (length <= 10) {
|
||||
if (length == 1) {
|
||||
return exports.$stringAllocate1_1(s.codePointAt(0));
|
||||
}
|
||||
if (length == 2) {
|
||||
return exports.$stringAllocate1_2(s.codePointAt(0), s.codePointAt(1));
|
||||
}
|
||||
if (length == 3) {
|
||||
return exports.$stringAllocate1_3(s.codePointAt(0), s.codePointAt(1), s.codePointAt(2));
|
||||
}
|
||||
if (length == 4) {
|
||||
return exports.$stringAllocate1_4(s.codePointAt(0), s.codePointAt(1), s.codePointAt(2), s.codePointAt(3));
|
||||
}
|
||||
if (length == 5) {
|
||||
return exports.$stringAllocate1_5(s.codePointAt(0), s.codePointAt(1), s.codePointAt(2), s.codePointAt(3), s.codePointAt(4));
|
||||
}
|
||||
if (length == 6) {
|
||||
return exports.$stringAllocate1_6(s.codePointAt(0), s.codePointAt(1), s.codePointAt(2), s.codePointAt(3), s.codePointAt(4), s.codePointAt(5));
|
||||
}
|
||||
if (length == 7) {
|
||||
return exports.$stringAllocate1_7(s.codePointAt(0), s.codePointAt(1), s.codePointAt(2), s.codePointAt(3), s.codePointAt(4), s.codePointAt(5), s.codePointAt(6));
|
||||
}
|
||||
if (length == 8) {
|
||||
return exports.$stringAllocate1_8(s.codePointAt(0), s.codePointAt(1), s.codePointAt(2), s.codePointAt(3), s.codePointAt(4), s.codePointAt(5), s.codePointAt(6), s.codePointAt(7));
|
||||
}
|
||||
if (length == 9) {
|
||||
return exports.$stringAllocate1_9(s.codePointAt(0), s.codePointAt(1), s.codePointAt(2), s.codePointAt(3), s.codePointAt(4), s.codePointAt(5), s.codePointAt(6), s.codePointAt(7), s.codePointAt(8));
|
||||
}
|
||||
if (length == 10) {
|
||||
return exports.$stringAllocate1_10(s.codePointAt(0), s.codePointAt(1), s.codePointAt(2), s.codePointAt(3), s.codePointAt(4), s.codePointAt(5), s.codePointAt(6), s.codePointAt(7), s.codePointAt(8), s.codePointAt(9));
|
||||
}
|
||||
}
|
||||
const dartString = exports.$stringAllocate1(length);
|
||||
const write = exports.$stringWrite1;
|
||||
for (let i = 0; i < length; i++) {
|
||||
write(dartString, i, s.codePointAt(i));
|
||||
}
|
||||
return dartString;
|
||||
} else {
|
||||
const dartString = exports.$stringAllocate2(length);
|
||||
const write = exports.$stringWrite2;
|
||||
for (let i = 0; i < length; i++) {
|
||||
write(dartString, i, s.charCodeAt(i));
|
||||
}
|
||||
return dartString;
|
||||
}
|
||||
}
|
||||
,
|
||||
_247: l => new Array(l),
|
||||
_251: (o, p) => o[p],
|
||||
_255: o => String(o),
|
||||
_260: x0 => x0.index,
|
||||
_262: x0 => x0.length,
|
||||
_264: (x0,x1) => x0[x1],
|
||||
_265: (x0,x1) => x0.exec(x1),
|
||||
_267: x0 => x0.flags,
|
||||
_268: x0 => x0.multiline,
|
||||
_269: x0 => x0.ignoreCase,
|
||||
_270: x0 => x0.unicode,
|
||||
_271: x0 => x0.dotAll,
|
||||
_272: (x0,x1) => x0.lastIndex = x1
|
||||
};
|
||||
|
||||
const baseImports = {
|
||||
dart2wasm: dart2wasm,
|
||||
|
||||
|
||||
Math: Math,
|
||||
Date: Date,
|
||||
Object: Object,
|
||||
Array: Array,
|
||||
Reflect: Reflect,
|
||||
};
|
||||
|
||||
const jsStringPolyfill = {
|
||||
"charCodeAt": (s, i) => s.charCodeAt(i),
|
||||
"compare": (s1, s2) => {
|
||||
if (s1 < s2) return -1;
|
||||
if (s1 > s2) return 1;
|
||||
return 0;
|
||||
},
|
||||
"concat": (s1, s2) => s1 + s2,
|
||||
"equals": (s1, s2) => s1 === s2,
|
||||
"fromCharCode": (i) => String.fromCharCode(i),
|
||||
"length": (s) => s?.length||0,
|
||||
"substring": (s, a, b) => s.substring(a, b),
|
||||
};
|
||||
|
||||
dartInstance = await WebAssembly.instantiate(await modulePromise, {
|
||||
...baseImports,
|
||||
...(await importObjectPromise),
|
||||
"wasm:js-string": jsStringPolyfill,
|
||||
});
|
||||
|
||||
return dartInstance;
|
||||
}
|
||||
|
||||
// Call the main function for the instantiated module
|
||||
// `moduleInstance` is the instantiated dart2wasm module
|
||||
// `args` are any arguments that should be passed into the main function.
|
||||
export const invoke = (moduleInstance, ...args) => {
|
||||
moduleInstance.exports.$invokeMain(args);
|
||||
}
|
||||
|
||||
|
||||
export let format;
|
||||
BIN
frontend/src/common/prettier/plugins/dart/dart_fmt.unopt.wasm
Normal file
BIN
frontend/src/common/prettier/plugins/dart/dart_fmt.unopt.wasm
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
frontend/src/common/prettier/plugins/dart/dart_fmt.wasm
Normal file
BIN
frontend/src/common/prettier/plugins/dart/dart_fmt.wasm
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
10
frontend/src/common/prettier/plugins/dart/dart_fmt_node.js
Normal file
10
frontend/src/common/prettier/plugins/dart/dart_fmt_node.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import fs from "node:fs/promises";
|
||||
import initAsync from "./dart_fmt.js";
|
||||
|
||||
const wasm = new URL("./dart_fmt.wasm", import.meta.url);
|
||||
|
||||
export default function __wbg_init(init = fs.readFile(wasm)) {
|
||||
return initAsync(init);
|
||||
}
|
||||
|
||||
export * from "./dart_fmt.js";
|
||||
@@ -0,0 +1,8 @@
|
||||
import initAsync from "./dart_fmt.js";
|
||||
import wasm from "./dart_fmt.wasm?url";
|
||||
|
||||
export default function __wbg_init(input = wasm) {
|
||||
return initAsync(input);
|
||||
}
|
||||
|
||||
export * from "./dart_fmt.js";
|
||||
132
frontend/src/common/prettier/plugins/dart/index.ts
Normal file
132
frontend/src/common/prettier/plugins/dart/index.ts
Normal file
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* Prettier Plugin for Dart formatting using dart_fmt WebAssembly
|
||||
*
|
||||
* This plugin provides support for formatting Dart files using the dart_fmt WASM implementation.
|
||||
* dart_fmt is the official Dart code formatter integrated into the Dart SDK.
|
||||
*/
|
||||
import type { Plugin, Parser, Printer } from 'prettier';
|
||||
|
||||
// Import the Dart formatter WASM module
|
||||
import dartInit, { format } from './dart_fmt_vite.js';
|
||||
|
||||
const parserName = 'dart';
|
||||
|
||||
// Language configuration
|
||||
const languages = [
|
||||
{
|
||||
name: 'Dart',
|
||||
aliases: ['dart'],
|
||||
parsers: [parserName],
|
||||
extensions: ['.dart'],
|
||||
aceMode: 'dart',
|
||||
tmScope: 'source.dart',
|
||||
linguistLanguageId: 103,
|
||||
vscodeLanguageIds: ['dart']
|
||||
}
|
||||
];
|
||||
|
||||
// Parser configuration
|
||||
const dartParser: Parser<string> = {
|
||||
astFormat: parserName,
|
||||
parse: (text: string) => text,
|
||||
locStart: () => 0,
|
||||
locEnd: (node: string) => node.length,
|
||||
};
|
||||
|
||||
// Lazy initialize Dart WASM module
|
||||
let initPromise: Promise<void> | null = null;
|
||||
let isInitialized = false;
|
||||
|
||||
function initDart(): Promise<void> {
|
||||
if (isInitialized) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (!initPromise) {
|
||||
initPromise = (async () => {
|
||||
try {
|
||||
await dartInit();
|
||||
isInitialized = true;
|
||||
} catch (error) {
|
||||
console.warn('Failed to initialize Dart WASM module:', error);
|
||||
initPromise = null;
|
||||
throw error;
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
return initPromise;
|
||||
}
|
||||
|
||||
// Printer configuration
|
||||
const dartPrinter: Printer<string> = {
|
||||
// @ts-expect-error -- Support async printer like shell plugin
|
||||
async print(path, options) {
|
||||
try {
|
||||
// Wait for initialization to complete
|
||||
await initDart();
|
||||
|
||||
const text = (path as any).getValue ? (path as any).getValue() : path.node;
|
||||
const config = getDartConfig(options);
|
||||
|
||||
// Format using dart_fmt (synchronous call)
|
||||
const formatted = format(text, undefined, config);
|
||||
|
||||
return formatted.trim();
|
||||
} catch (error) {
|
||||
console.warn('Dart formatting failed:', error);
|
||||
// Return original text if formatting fails
|
||||
return (path as any).getValue ? (path as any).getValue() : path.node;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
// Helper function to create Dart config from Prettier options
|
||||
function getDartConfig(options: any): any {
|
||||
const config: any = {};
|
||||
|
||||
// Map Prettier options to Dart formatter config
|
||||
if (options.printWidth !== undefined) {
|
||||
config.line_width = options.printWidth;
|
||||
}
|
||||
|
||||
if (options.endOfLine !== undefined) {
|
||||
config.line_ending = options.endOfLine === 'crlf' ? 'crlf' : 'lf';
|
||||
}
|
||||
|
||||
// Dart language version (if specified)
|
||||
if (options.dartLanguageVersion !== undefined) {
|
||||
config.language_version = options.dartLanguageVersion;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
// Plugin options
|
||||
const options = {
|
||||
dartLanguageVersion: {
|
||||
since: '0.0.1',
|
||||
category: 'Format' as const,
|
||||
type: 'string' as const,
|
||||
default: undefined,
|
||||
description: 'Dart language version (e.g., "3.0", "2.17")'
|
||||
}
|
||||
};
|
||||
|
||||
// Plugin object
|
||||
const dartPlugin: Plugin = {
|
||||
languages,
|
||||
parsers: {
|
||||
[parserName]: dartParser,
|
||||
},
|
||||
printers: {
|
||||
[parserName]: dartPrinter,
|
||||
},
|
||||
options,
|
||||
};
|
||||
|
||||
export default dartPlugin;
|
||||
export { languages };
|
||||
export const parsers = dartPlugin.parsers;
|
||||
export const printers = dartPlugin.printers;
|
||||
31
frontend/src/common/prettier/plugins/dart/lib/binding.dart
Normal file
31
frontend/src/common/prettier/plugins/dart/lib/binding.dart
Normal file
@@ -0,0 +1,31 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:js_interop';
|
||||
import 'package:dart_fmt/dart_fmt.dart';
|
||||
|
||||
class Options {
|
||||
final int? pageWidth;
|
||||
final String? lineEnding;
|
||||
final String? languageVersion;
|
||||
|
||||
Options.fromJson(Map<String, dynamic> json)
|
||||
: pageWidth = json['pageWidth'] as int?,
|
||||
lineEnding = json['lineEnding'] as String?,
|
||||
languageVersion = json['languageVersion'] as String?;
|
||||
}
|
||||
|
||||
String formatWrapper(String source, String filename, String options) {
|
||||
final config = Options.fromJson(jsonDecode(options));
|
||||
|
||||
try {
|
||||
return "o${format(source, filename, pageWidth: config.pageWidth, lineEnding: config.lineEnding, version: config.languageVersion)}";
|
||||
} catch (e) {
|
||||
return "x$e";
|
||||
}
|
||||
}
|
||||
|
||||
@JS('format')
|
||||
external set formatExport(JSFunction handler);
|
||||
|
||||
void main(List<String> arguments) {
|
||||
formatExport = formatWrapper.toJS;
|
||||
}
|
||||
5
frontend/src/common/prettier/plugins/dart/lib/build.sh
Normal file
5
frontend/src/common/prettier/plugins/dart/lib/build.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
cd $(dirname $0)/..
|
||||
|
||||
dart compile wasm ./lib/binding.dart -o ./build/dart_fmt.wasm
|
||||
|
||||
|
||||
14
frontend/src/common/prettier/plugins/dart/lib/dart_fmt.dart
Normal file
14
frontend/src/common/prettier/plugins/dart/lib/dart_fmt.dart
Normal file
@@ -0,0 +1,14 @@
|
||||
import 'package:dart_style/dart_style.dart';
|
||||
import 'package:pub_semver/pub_semver.dart';
|
||||
|
||||
String format(String source, String filename,
|
||||
{int? pageWidth, String? lineEnding, String? version}) {
|
||||
final languageVersion = version != null
|
||||
? Version.parse(version)
|
||||
: DartFormatter.latestLanguageVersion;
|
||||
final formatter = DartFormatter(
|
||||
pageWidth: pageWidth,
|
||||
lineEnding: lineEnding,
|
||||
languageVersion: languageVersion);
|
||||
return formatter.format(source, uri: filename);
|
||||
}
|
||||
10
frontend/src/common/prettier/plugins/go/gofmt.d.ts
vendored
Normal file
10
frontend/src/common/prettier/plugins/go/gofmt.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
export type InitInput =
|
||||
| RequestInfo
|
||||
| URL
|
||||
| Response
|
||||
| BufferSource
|
||||
| WebAssembly.Module;
|
||||
|
||||
export default function initAsync(wasm_url?: InitInput): Promise<void>;
|
||||
export declare function initSync(module: BufferSource | WebAssembly.Module): void;
|
||||
export declare function format(input: string): string;
|
||||
355
frontend/src/common/prettier/plugins/go/gofmt.js
Normal file
355
frontend/src/common/prettier/plugins/go/gofmt.js
Normal file
@@ -0,0 +1,355 @@
|
||||
// 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.
|
||||
//
|
||||
// This file has been modified for use by the TinyGo compiler.
|
||||
|
||||
const encoder = new TextEncoder("utf-8");
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
let reinterpretBuf = new DataView(new ArrayBuffer(8));
|
||||
var logLine = [];
|
||||
|
||||
class TinyGo {
|
||||
constructor() {
|
||||
this._callbackTimeouts = new Map();
|
||||
this._nextCallbackTimeoutID = 1;
|
||||
|
||||
const mem = () => {
|
||||
// The buffer may change when requesting more memory.
|
||||
return new DataView(this._inst.exports.memory.buffer);
|
||||
}
|
||||
|
||||
const unboxValue = (v_ref) => {
|
||||
reinterpretBuf.setBigInt64(0, v_ref, true);
|
||||
const f = reinterpretBuf.getFloat64(0, true);
|
||||
if (f === 0) {
|
||||
return undefined;
|
||||
}
|
||||
if (!isNaN(f)) {
|
||||
return f;
|
||||
}
|
||||
|
||||
const id = v_ref & 0xffffffffn;
|
||||
return this._values[id];
|
||||
}
|
||||
|
||||
|
||||
const loadValue = (addr) => {
|
||||
let v_ref = mem().getBigUint64(addr, true);
|
||||
return unboxValue(v_ref);
|
||||
}
|
||||
|
||||
const boxValue = (v) => {
|
||||
const nanHead = 0x7FF80000n;
|
||||
|
||||
if (typeof v === "number") {
|
||||
if (isNaN(v)) {
|
||||
return nanHead << 32n;
|
||||
}
|
||||
if (v === 0) {
|
||||
return (nanHead << 32n) | 1n;
|
||||
}
|
||||
reinterpretBuf.setFloat64(0, v, true);
|
||||
return reinterpretBuf.getBigInt64(0, true);
|
||||
}
|
||||
|
||||
switch (v) {
|
||||
case undefined:
|
||||
return 0n;
|
||||
case null:
|
||||
return (nanHead << 32n) | 2n;
|
||||
case true:
|
||||
return (nanHead << 32n) | 3n;
|
||||
case false:
|
||||
return (nanHead << 32n) | 4n;
|
||||
}
|
||||
|
||||
let id = this._ids.get(v);
|
||||
if (id === undefined) {
|
||||
id = this._idPool.pop();
|
||||
if (id === undefined) {
|
||||
id = BigInt(this._values.length);
|
||||
}
|
||||
this._values[id] = v;
|
||||
this._goRefCounts[id] = 0;
|
||||
this._ids.set(v, id);
|
||||
}
|
||||
this._goRefCounts[id]++;
|
||||
let typeFlag = 1n;
|
||||
switch (typeof v) {
|
||||
case "string":
|
||||
typeFlag = 2n;
|
||||
break;
|
||||
case "symbol":
|
||||
typeFlag = 3n;
|
||||
break;
|
||||
case "function":
|
||||
typeFlag = 4n;
|
||||
break;
|
||||
}
|
||||
return id | ((nanHead | typeFlag) << 32n);
|
||||
}
|
||||
|
||||
const storeValue = (addr, v) => {
|
||||
let v_ref = boxValue(v);
|
||||
mem().setBigUint64(addr, v_ref, true);
|
||||
}
|
||||
|
||||
const loadSlice = (array, len, cap) => {
|
||||
return new Uint8Array(this._inst.exports.memory.buffer, array, len);
|
||||
}
|
||||
|
||||
const loadSliceOfValues = (array, len, cap) => {
|
||||
const a = new Array(len);
|
||||
for (let i = 0; i < len; i++) {
|
||||
a[i] = loadValue(array + i * 8);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
const loadString = (ptr, len) => {
|
||||
return decoder.decode(new DataView(this._inst.exports.memory.buffer, ptr, len));
|
||||
}
|
||||
|
||||
const timeOrigin = Date.now() - performance.now();
|
||||
this.importObject = {
|
||||
wasi_snapshot_preview1: {
|
||||
// https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#fd_write
|
||||
fd_write: () => 0, // dummy
|
||||
},
|
||||
gojs: {
|
||||
// func ticks() float64
|
||||
"runtime.ticks": () => {
|
||||
return timeOrigin + performance.now();
|
||||
},
|
||||
|
||||
// func finalizeRef(v ref)
|
||||
"syscall/js.finalizeRef": (v_ref) => {
|
||||
reinterpretBuf.setBigInt64(0, v_ref, true);
|
||||
const f = reinterpretBuf.getFloat64(0, true);
|
||||
if (f === 0 || !isNaN(f)) {
|
||||
return;
|
||||
}
|
||||
const id = v_ref & 0xffffffffn;
|
||||
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": (value_ptr, value_len) => {
|
||||
const s = loadString(value_ptr, value_len);
|
||||
return boxValue(s);
|
||||
},
|
||||
|
||||
// func valueGet(v ref, p string) ref
|
||||
"syscall/js.valueGet": (v_ref, p_ptr, p_len) => {
|
||||
let prop = loadString(p_ptr, p_len);
|
||||
let v = unboxValue(v_ref);
|
||||
let result = Reflect.get(v, prop);
|
||||
return boxValue(result);
|
||||
},
|
||||
|
||||
// func valueSet(v ref, p string, x ref)
|
||||
"syscall/js.valueSet": (v_ref, p_ptr, p_len, x_ref) => {
|
||||
const v = unboxValue(v_ref);
|
||||
const p = loadString(p_ptr, p_len);
|
||||
const x = unboxValue(x_ref);
|
||||
Reflect.set(v, p, x);
|
||||
},
|
||||
|
||||
// func valueIndex(v ref, i int) ref
|
||||
"syscall/js.valueIndex": (v_ref, i) => {
|
||||
return boxValue(Reflect.get(unboxValue(v_ref), i));
|
||||
},
|
||||
|
||||
// valueSetIndex(v ref, i int, x ref)
|
||||
"syscall/js.valueSetIndex": (v_ref, i, x_ref) => {
|
||||
Reflect.set(unboxValue(v_ref), i, unboxValue(x_ref));
|
||||
},
|
||||
|
||||
// func valueCall(v ref, m string, args []ref) (ref, bool)
|
||||
"syscall/js.valueCall": (ret_addr, v_ref, m_ptr, m_len, args_ptr, args_len, args_cap) => {
|
||||
const v = unboxValue(v_ref);
|
||||
const name = loadString(m_ptr, m_len);
|
||||
const args = loadSliceOfValues(args_ptr, args_len, args_cap);
|
||||
try {
|
||||
const m = Reflect.get(v, name);
|
||||
storeValue(ret_addr, Reflect.apply(m, v, args));
|
||||
mem().setUint8(ret_addr + 8, 1);
|
||||
} catch (err) {
|
||||
storeValue(ret_addr, err);
|
||||
mem().setUint8(ret_addr + 8, 0);
|
||||
}
|
||||
},
|
||||
|
||||
// func valueNew(v ref, args []ref) (ref, bool)
|
||||
"syscall/js.valueNew": (ret_addr, v_ref, args_ptr, args_len, args_cap) => {
|
||||
const v = unboxValue(v_ref);
|
||||
const args = loadSliceOfValues(args_ptr, args_len, args_cap);
|
||||
try {
|
||||
storeValue(ret_addr, Reflect.construct(v, args));
|
||||
mem().setUint8(ret_addr + 8, 1);
|
||||
} catch (err) {
|
||||
storeValue(ret_addr, err);
|
||||
mem().setUint8(ret_addr+ 8, 0);
|
||||
}
|
||||
},
|
||||
|
||||
// func valueLength(v ref) int
|
||||
"syscall/js.valueLength": (v_ref) => {
|
||||
return unboxValue(v_ref).length;
|
||||
},
|
||||
|
||||
// valuePrepareString(v ref) (ref, int)
|
||||
"syscall/js.valuePrepareString": (ret_addr, v_ref) => {
|
||||
const s = String(unboxValue(v_ref));
|
||||
const str = encoder.encode(s);
|
||||
storeValue(ret_addr, str);
|
||||
mem().setInt32(ret_addr + 8, str.length, true);
|
||||
},
|
||||
|
||||
// valueLoadString(v ref, b []byte)
|
||||
"syscall/js.valueLoadString": (v_ref, slice_ptr, slice_len, slice_cap) => {
|
||||
const str = unboxValue(v_ref);
|
||||
loadSlice(slice_ptr, slice_len, slice_cap).set(str);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
// Go 1.20 uses 'env'. Go 1.21 uses 'gojs'.
|
||||
// For compatibility, we use both as long as Go 1.20 is supported.
|
||||
this.importObject.env = this.importObject.gojs;
|
||||
}
|
||||
|
||||
async run(instance) {
|
||||
this._inst = instance;
|
||||
this._values = [ // JS values that Go currently has references to, indexed by reference id
|
||||
NaN,
|
||||
0,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
// fake global
|
||||
{
|
||||
set format(fn){ instance.format = fn; },
|
||||
Array,
|
||||
Object,
|
||||
},
|
||||
this,
|
||||
];
|
||||
this._goRefCounts = []; // 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
|
||||
this._idPool = []; // unused ids that have been garbage collected
|
||||
this.exited = false; // whether the Go program has exited
|
||||
|
||||
while (true) {
|
||||
const callbackPromise = new Promise((resolve) => {
|
||||
this._resolveCallbackPromise = () => {
|
||||
if (this.exited) {
|
||||
throw new Error("bad callback: Go program has already exited");
|
||||
}
|
||||
setTimeout(resolve, 0); // make sure it is asynchronous
|
||||
};
|
||||
});
|
||||
this._inst.exports._start();
|
||||
if (this.exited) {
|
||||
break;
|
||||
}
|
||||
await callbackPromise;
|
||||
}
|
||||
}
|
||||
|
||||
_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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ================== End of wasm_exec.js ==================
|
||||
*/
|
||||
/**/let wasm;
|
||||
/**/async function __load(module, imports) {
|
||||
/**/ if (typeof Response === 'function' && module instanceof Response) {
|
||||
/**/ if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
/**/ try { return await WebAssembly.instantiateStreaming(module, imports); }
|
||||
/**/ catch (e) {
|
||||
/**/ if (module.headers.get('Content-Type') != 'application/wasm') {
|
||||
/**/ console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
|
||||
/**/ } else { throw e; }
|
||||
/**/ }
|
||||
/**/ }
|
||||
/**/ const bytes = await module.arrayBuffer();
|
||||
/**/ return await WebAssembly.instantiate(bytes, imports);
|
||||
/**/ } else {
|
||||
/**/ const instance = await WebAssembly.instantiate(module, imports);
|
||||
/**/ if (instance instanceof WebAssembly.Instance) return { instance, module };
|
||||
/**/ else return instance;
|
||||
/**/ }
|
||||
/**/}
|
||||
/**/function __finalize_init(instance) {
|
||||
/**/ return wasm = instance;
|
||||
/**/}
|
||||
/**/function __init_memory(imports, maybe_memory) { }
|
||||
/**/export function initSync(module) {
|
||||
/**/ if (wasm !== undefined) return wasm;
|
||||
/**/
|
||||
/**/ const go = new TinyGo();
|
||||
/**/ const imports = go.importObject;
|
||||
/**/
|
||||
/**/ __init_memory(imports);
|
||||
/**/
|
||||
/**/ if (!(module instanceof WebAssembly.Module)) module = new WebAssembly.Module(module);
|
||||
/**/
|
||||
/**/ const instance = new WebAssembly.Instance(module, imports);
|
||||
/**/
|
||||
/**/ go.run(instance);
|
||||
/**/ return __finalize_init(instance, module);
|
||||
/**/}
|
||||
/**/export default async function initAsync(input) {
|
||||
/**/ if (wasm !== undefined) return wasm;
|
||||
/**/
|
||||
/**/ if (typeof input === 'undefined') input = new URL('gofmt.wasm', import.meta.url);
|
||||
/**/
|
||||
/**/ const go = new TinyGo();
|
||||
/**/ const imports = go.importObject;
|
||||
/**/
|
||||
/**/ if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
|
||||
/**/ input = fetch(input);
|
||||
/**/ }
|
||||
/**/
|
||||
/**/ __init_memory(imports);
|
||||
/**/
|
||||
/**/ const { instance, module } = await __load(await input, imports);
|
||||
/**/
|
||||
/**/ go.run(instance);
|
||||
/**/ return __finalize_init(instance, module);
|
||||
/**/}
|
||||
/**/export function format(input) {
|
||||
/**/ const [err, result] = wasm.format(input);
|
||||
/**/ if (err) {
|
||||
/**/ throw new Error(result);
|
||||
/**/ }
|
||||
/**/ return result;
|
||||
/**/}
|
||||
/**/
|
||||
BIN
frontend/src/common/prettier/plugins/go/gofmt.wasm
Normal file
BIN
frontend/src/common/prettier/plugins/go/gofmt.wasm
Normal file
Binary file not shown.
10
frontend/src/common/prettier/plugins/go/gofmt_node.js
Normal file
10
frontend/src/common/prettier/plugins/go/gofmt_node.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import fs from "node:fs/promises";
|
||||
import initAsync from "./gofmt.js";
|
||||
|
||||
const wasm = new URL("./gofmt.wasm", import.meta.url);
|
||||
|
||||
export default function (init = fs.readFile(wasm)) {
|
||||
return initAsync(init);
|
||||
}
|
||||
|
||||
export * from "./gofmt.js";
|
||||
8
frontend/src/common/prettier/plugins/go/gofmt_vite.js
Normal file
8
frontend/src/common/prettier/plugins/go/gofmt_vite.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import initAsync from "./gofmt.js";
|
||||
import wasm_url from "./gofmt.wasm?url";
|
||||
|
||||
export default function (input = wasm_url) {
|
||||
return initAsync(input);
|
||||
}
|
||||
|
||||
export * from "./gofmt.js";
|
||||
101
frontend/src/common/prettier/plugins/go/index.ts
Normal file
101
frontend/src/common/prettier/plugins/go/index.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* Prettier Plugin for Go formatting using gofmt WebAssembly
|
||||
*
|
||||
* This plugin provides support for formatting Go files using the gofmt WASM implementation.
|
||||
*/
|
||||
import type { Plugin, Parser, Printer } from 'prettier';
|
||||
|
||||
// Import the gofmt WASM module
|
||||
import gofmtInit, { format } from './gofmt_vite.js';
|
||||
|
||||
const parserName = 'go';
|
||||
|
||||
// Language configuration
|
||||
const languages = [
|
||||
{
|
||||
name: 'Go',
|
||||
aliases: ['go', 'golang'],
|
||||
parsers: [parserName],
|
||||
extensions: ['.go'],
|
||||
aceMode: 'golang',
|
||||
tmScope: 'source.go',
|
||||
linguistLanguageId: 132,
|
||||
vscodeLanguageIds: ['go']
|
||||
}
|
||||
];
|
||||
|
||||
// Parser configuration
|
||||
const goParser: Parser<string> = {
|
||||
astFormat: parserName,
|
||||
parse: (text: string) => text,
|
||||
locStart: () => 0,
|
||||
locEnd: (node: string) => node.length,
|
||||
};
|
||||
|
||||
// Lazy initialize gofmt WASM module
|
||||
let initPromise: Promise<void> | null = null;
|
||||
let isInitialized = false;
|
||||
|
||||
function initGofmt(): Promise<void> {
|
||||
if (isInitialized) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (!initPromise) {
|
||||
initPromise = (async () => {
|
||||
try {
|
||||
await gofmtInit();
|
||||
isInitialized = true;
|
||||
} catch (error) {
|
||||
console.warn('Failed to initialize gofmt WASM module:', error);
|
||||
initPromise = null;
|
||||
throw error;
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
return initPromise;
|
||||
}
|
||||
|
||||
// Printer configuration
|
||||
const goPrinter: Printer<string> = {
|
||||
// @ts-expect-error -- Support async printer like shell plugin
|
||||
async print(path, options) {
|
||||
try {
|
||||
// Wait for initialization to complete
|
||||
await initGofmt();
|
||||
|
||||
const text = (path as any).getValue ? (path as any).getValue() : path.node;
|
||||
|
||||
// Format using gofmt (synchronous call)
|
||||
const formatted = format(text);
|
||||
|
||||
return formatted.trim();
|
||||
} catch (error) {
|
||||
console.warn('Go formatting failed:', error);
|
||||
// Return original text if formatting fails
|
||||
return (path as any).getValue ? (path as any).getValue() : path.node;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Plugin options (Go doesn't need additional config options)
|
||||
const options = {};
|
||||
|
||||
// Plugin definition
|
||||
const goPlugin: Plugin = {
|
||||
languages,
|
||||
parsers: {
|
||||
[parserName]: goParser,
|
||||
},
|
||||
printers: {
|
||||
[parserName]: goPrinter,
|
||||
},
|
||||
options,
|
||||
};
|
||||
|
||||
// Export plugin without auto-initialization
|
||||
export default goPlugin;
|
||||
export { languages, initGofmt as initialize };
|
||||
export const parsers = goPlugin.parsers;
|
||||
export const printers = goPlugin.printers;
|
||||
9
frontend/src/common/prettier/plugins/go/src/build.sh
Normal file
9
frontend/src/common/prettier/plugins/go/src/build.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
set -Eeo pipefail
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
echo "Building..."
|
||||
tinygo build -o=../gofmt.wasm -target=wasm -no-debug ./lib.go
|
||||
|
||||
echo "Generating JS..."
|
||||
cp $(tinygo env TINYGOROOT)/targets/wasm_exec.js ../gofmt.js
|
||||
23
frontend/src/common/prettier/plugins/go/src/lib.go
Normal file
23
frontend/src/common/prettier/plugins/go/src/lib.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"go/format"
|
||||
"syscall/js"
|
||||
)
|
||||
|
||||
func Format(this js.Value, args []js.Value) any {
|
||||
input := ([]byte)(args[0].String())
|
||||
|
||||
output, err := format.Source(input)
|
||||
if err != nil {
|
||||
return []any{true, err.Error()}
|
||||
}
|
||||
|
||||
return []any{false, string(output)}
|
||||
}
|
||||
|
||||
func main() {
|
||||
done := make(chan bool)
|
||||
js.Global().Set("format", js.FuncOf(Format))
|
||||
<-done
|
||||
}
|
||||
67
frontend/src/common/prettier/plugins/groovy/index.ts
Normal file
67
frontend/src/common/prettier/plugins/groovy/index.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Prettier Plugin for Groovy/Jenkins file formatting
|
||||
*
|
||||
* This plugin provides support for formatting Groovy and Jenkins files using the groovy-beautify library.
|
||||
* It supports .groovy files and Jenkins-related files like Jenkinsfile.
|
||||
*/
|
||||
import type { Plugin, Parser, Printer } from 'prettier';
|
||||
import groovyBeautify from 'groovy-beautify';
|
||||
|
||||
const parserName = 'groovy';
|
||||
|
||||
// 语言配置
|
||||
const languages = [
|
||||
{
|
||||
name: 'Groovy',
|
||||
aliases: ['groovy'],
|
||||
parsers: [parserName],
|
||||
filenames: ['jenkinsfile', 'Jenkinsfile'],
|
||||
extensions: ['.jenkinsfile', '.Jenkinsfile', '.groovy'],
|
||||
aceMode: 'groovy',
|
||||
tmScope: 'source.groovy',
|
||||
linguistLanguageId: 142,
|
||||
vscodeLanguageIds: ['groovy']
|
||||
},
|
||||
];
|
||||
|
||||
// 解析器配置
|
||||
const groovyParser: Parser<string> = {
|
||||
astFormat: parserName,
|
||||
parse: (text: string) => text,
|
||||
locStart: () => 0,
|
||||
locEnd: (node: string) => node.length,
|
||||
};
|
||||
|
||||
// 打印器配置
|
||||
const groovyPrinter: Printer<string> = {
|
||||
print: (path, options) => {
|
||||
try {
|
||||
return groovyBeautify(path.node, {
|
||||
width: options.printWidth || 80,
|
||||
}).trim();
|
||||
} catch (error) {
|
||||
return path.node;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const options = {
|
||||
|
||||
};
|
||||
|
||||
// 插件对象
|
||||
const groovyPlugin: Plugin = {
|
||||
languages,
|
||||
parsers: {
|
||||
[parserName]: groovyParser,
|
||||
},
|
||||
printers: {
|
||||
[parserName]: groovyPrinter,
|
||||
},
|
||||
options,
|
||||
};
|
||||
|
||||
export default groovyPlugin;
|
||||
export { languages };
|
||||
export const parsers = groovyPlugin.parsers;
|
||||
export const printers = groovyPlugin.printers;
|
||||
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")
|
||||
];
|
||||
}
|
||||
};
|
||||
178
frontend/src/common/prettier/plugins/lua/index.ts
Normal file
178
frontend/src/common/prettier/plugins/lua/index.ts
Normal file
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* Prettier Plugin for Lua formatting using StyLua WebAssembly
|
||||
*
|
||||
* This plugin provides support for formatting Lua files using the StyLua WASM implementation.
|
||||
* StyLua is a fast Lua code formatter written in Rust.
|
||||
*/
|
||||
import type { Plugin, Parser, Printer } from 'prettier';
|
||||
|
||||
// Import the StyLua WASM module
|
||||
import luaInit, { format, type Config } from './lua_fmt_vite.js';
|
||||
|
||||
const parserName = 'lua';
|
||||
|
||||
// Language configuration
|
||||
const languages = [
|
||||
{
|
||||
name: 'Lua',
|
||||
aliases: ['lua'],
|
||||
parsers: [parserName],
|
||||
extensions: ['.lua'],
|
||||
aceMode: 'lua',
|
||||
tmScope: 'source.lua',
|
||||
linguistLanguageId: 213,
|
||||
vscodeLanguageIds: ['lua']
|
||||
}
|
||||
];
|
||||
|
||||
// Parser configuration
|
||||
const luaParser: Parser<string> = {
|
||||
astFormat: parserName,
|
||||
parse: (text: string) => text,
|
||||
locStart: () => 0,
|
||||
locEnd: (node: string) => node.length,
|
||||
};
|
||||
|
||||
// Lazy initialize StyLua WASM module
|
||||
let initPromise: Promise<void> | null = null;
|
||||
let isInitialized = false;
|
||||
|
||||
function initStyLua(): Promise<void> {
|
||||
if (isInitialized) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (!initPromise) {
|
||||
initPromise = (async () => {
|
||||
try {
|
||||
await luaInit();
|
||||
isInitialized = true;
|
||||
} catch (error) {
|
||||
console.warn('Failed to initialize StyLua WASM module:', error);
|
||||
initPromise = null;
|
||||
throw error;
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
return initPromise;
|
||||
}
|
||||
|
||||
// Printer configuration
|
||||
const luaPrinter: Printer<string> = {
|
||||
// @ts-expect-error -- Support async printer like shell plugin
|
||||
async print(path, options) {
|
||||
try {
|
||||
// Wait for initialization to complete
|
||||
await initStyLua();
|
||||
|
||||
const text = (path as any).getValue ? (path as any).getValue() : path.node;
|
||||
const config = getStyLuaConfig(options);
|
||||
|
||||
// Format using StyLua (synchronous call)
|
||||
const formatted = format(text, "input.lua", config);
|
||||
|
||||
return formatted.trim();
|
||||
} catch (error) {
|
||||
console.warn('StyLua formatting failed:', error);
|
||||
// Return original text if formatting fails
|
||||
return (path as any).getValue ? (path as any).getValue() : path.node;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Helper function to create StyLua config from Prettier options
|
||||
function getStyLuaConfig(options: any): Config {
|
||||
const config: Config = {};
|
||||
|
||||
// Map Prettier options to StyLua config
|
||||
if (options.useTabs !== undefined) {
|
||||
config.indent_style = options.useTabs ? 'tab' : 'space';
|
||||
}
|
||||
|
||||
if (options.tabWidth !== undefined) {
|
||||
config.indent_width = options.tabWidth;
|
||||
}
|
||||
|
||||
if (options.printWidth !== undefined) {
|
||||
config.line_width = options.printWidth;
|
||||
}
|
||||
|
||||
if (options.endOfLine !== undefined) {
|
||||
config.line_ending = options.endOfLine === 'crlf' ? 'crlf' : 'lf';
|
||||
}
|
||||
|
||||
if (options.singleQuote !== undefined) {
|
||||
config.quote_style = options.singleQuote ? 'AutoPreferSingle' : 'AutoPreferDouble';
|
||||
}
|
||||
|
||||
// StyLua specific options
|
||||
if (options.luaCallParentheses !== undefined) {
|
||||
config.call_parentheses = options.luaCallParentheses;
|
||||
}
|
||||
|
||||
if (options.luaCollapseSimpleStatement !== undefined) {
|
||||
config.collapse_simple_statement = options.luaCollapseSimpleStatement;
|
||||
}
|
||||
|
||||
if (options.luaSortRequires !== undefined) {
|
||||
config.sort_requires = options.luaSortRequires;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
// Plugin options
|
||||
const options = {
|
||||
luaCallParentheses: {
|
||||
since: '0.0.1',
|
||||
category: 'Format' as const,
|
||||
type: 'choice' as const,
|
||||
default: 'Always',
|
||||
description: 'How to handle function call parentheses',
|
||||
choices: [
|
||||
{ value: 'Always', description: 'Always use parentheses' },
|
||||
{ value: 'NoSingleString', description: 'Remove parentheses for single string argument' },
|
||||
{ value: 'NoSingleTable', description: 'Remove parentheses for single table argument' },
|
||||
{ value: 'None', description: 'Remove parentheses when possible' },
|
||||
{ value: 'Input', description: 'Keep input formatting' }
|
||||
]
|
||||
},
|
||||
luaCollapseSimpleStatement: {
|
||||
since: '0.0.1',
|
||||
category: 'Format' as const,
|
||||
type: 'choice' as const,
|
||||
default: 'Never',
|
||||
description: 'How to handle simple statement collapsing',
|
||||
choices: [
|
||||
{ value: 'Never', description: 'Never collapse simple statements' },
|
||||
{ value: 'FunctionOnly', description: 'Collapse function statements only' },
|
||||
{ value: 'ConditionalOnly', description: 'Collapse conditional statements only' },
|
||||
{ value: 'Always', description: 'Always collapse simple statements' }
|
||||
]
|
||||
},
|
||||
luaSortRequires: {
|
||||
since: '0.0.1',
|
||||
category: 'Format' as const,
|
||||
type: 'boolean' as const,
|
||||
default: false,
|
||||
description: 'Sort require statements alphabetically'
|
||||
}
|
||||
};
|
||||
|
||||
// Plugin object
|
||||
const luaPlugin: Plugin = {
|
||||
languages,
|
||||
parsers: {
|
||||
[parserName]: luaParser,
|
||||
},
|
||||
printers: {
|
||||
[parserName]: luaPrinter,
|
||||
},
|
||||
options,
|
||||
};
|
||||
|
||||
export default luaPlugin;
|
||||
export { languages };
|
||||
export const parsers = luaPlugin.parsers;
|
||||
export const printers = luaPlugin.printers;
|
||||
52
frontend/src/common/prettier/plugins/lua/lua_fmt.d.ts
vendored
Normal file
52
frontend/src/common/prettier/plugins/lua/lua_fmt.d.ts
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export function format(input: string, filename: string, config?: Config): string;
|
||||
|
||||
interface LayoutConfig {
|
||||
indent_style?: "tab" | "space";
|
||||
indent_width?: number;
|
||||
line_width?: number;
|
||||
line_ending?: "lf" | "crlf";
|
||||
}
|
||||
|
||||
|
||||
export interface Config extends LayoutConfig {
|
||||
quote_style?: "AutoPreferDouble" | "AutoPreferSingle" | "ForceDouble" | "ForceSingle";
|
||||
call_parentheses?: "Always" | "NoSingleString" | "NoSingleTable" | "None" | "Input";
|
||||
collapse_simple_statement?: | "Never" | "FunctionOnly" | "ConditionalOnly" | "Always";
|
||||
sort_requires?: boolean;
|
||||
}
|
||||
|
||||
|
||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
export interface InitOutput {
|
||||
readonly memory: WebAssembly.Memory;
|
||||
readonly format: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
||||
readonly __wbindgen_export_0: (a: number, b: number) => number;
|
||||
readonly __wbindgen_export_1: (a: number, b: number, c: number, d: number) => number;
|
||||
readonly __wbindgen_export_2: (a: number) => void;
|
||||
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
|
||||
readonly __wbindgen_export_3: (a: number, b: number, c: number) => void;
|
||||
}
|
||||
|
||||
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
||||
/**
|
||||
* Instantiates the given `module`, which can either be bytes or
|
||||
* a precompiled `WebAssembly.Module`.
|
||||
*
|
||||
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
||||
*
|
||||
* @returns {InitOutput}
|
||||
*/
|
||||
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
||||
|
||||
/**
|
||||
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
||||
* for everything else, calls `WebAssembly.instantiate` directly.
|
||||
*
|
||||
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
||||
*
|
||||
* @returns {Promise<InitOutput>}
|
||||
*/
|
||||
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|
||||
524
frontend/src/common/prettier/plugins/lua/lua_fmt.js
Normal file
524
frontend/src/common/prettier/plugins/lua/lua_fmt.js
Normal file
@@ -0,0 +1,524 @@
|
||||
let wasm;
|
||||
|
||||
const heap = new Array(128).fill(undefined);
|
||||
|
||||
heap.push(undefined, null, true, false);
|
||||
|
||||
function getObject(idx) { return heap[idx]; }
|
||||
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
|
||||
let cachedUint8ArrayMemory0 = null;
|
||||
|
||||
function getUint8ArrayMemory0() {
|
||||
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
||||
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachedUint8ArrayMemory0;
|
||||
}
|
||||
|
||||
const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } );
|
||||
|
||||
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
|
||||
? function (arg, view) {
|
||||
return cachedTextEncoder.encodeInto(arg, view);
|
||||
}
|
||||
: function (arg, view) {
|
||||
const buf = cachedTextEncoder.encode(arg);
|
||||
view.set(buf);
|
||||
return {
|
||||
read: arg.length,
|
||||
written: buf.length
|
||||
};
|
||||
});
|
||||
|
||||
function passStringToWasm0(arg, malloc, realloc) {
|
||||
|
||||
if (realloc === undefined) {
|
||||
const buf = cachedTextEncoder.encode(arg);
|
||||
const ptr = malloc(buf.length, 1) >>> 0;
|
||||
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
|
||||
WASM_VECTOR_LEN = buf.length;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let len = arg.length;
|
||||
let ptr = malloc(len, 1) >>> 0;
|
||||
|
||||
const mem = getUint8ArrayMemory0();
|
||||
|
||||
let offset = 0;
|
||||
|
||||
for (; offset < len; offset++) {
|
||||
const code = arg.charCodeAt(offset);
|
||||
if (code > 0x7F) break;
|
||||
mem[ptr + offset] = code;
|
||||
}
|
||||
|
||||
if (offset !== len) {
|
||||
if (offset !== 0) {
|
||||
arg = arg.slice(offset);
|
||||
}
|
||||
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
||||
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
|
||||
const ret = encodeString(arg, view);
|
||||
|
||||
offset += ret.written;
|
||||
ptr = realloc(ptr, len, offset, 1) >>> 0;
|
||||
}
|
||||
|
||||
WASM_VECTOR_LEN = offset;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let cachedDataViewMemory0 = null;
|
||||
|
||||
function getDataViewMemory0() {
|
||||
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
|
||||
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
|
||||
}
|
||||
return cachedDataViewMemory0;
|
||||
}
|
||||
|
||||
let heap_next = heap.length;
|
||||
|
||||
function addHeapObject(obj) {
|
||||
if (heap_next === heap.length) heap.push(heap.length + 1);
|
||||
const idx = heap_next;
|
||||
heap_next = heap[idx];
|
||||
|
||||
heap[idx] = obj;
|
||||
return idx;
|
||||
}
|
||||
|
||||
function handleError(f, args) {
|
||||
try {
|
||||
return f.apply(this, args);
|
||||
} catch (e) {
|
||||
wasm.__wbindgen_export_2(addHeapObject(e));
|
||||
}
|
||||
}
|
||||
|
||||
function isLikeNone(x) {
|
||||
return x === undefined || x === null;
|
||||
}
|
||||
|
||||
function debugString(val) {
|
||||
// primitive types
|
||||
const type = typeof val;
|
||||
if (type == 'number' || type == 'boolean' || val == null) {
|
||||
return `${val}`;
|
||||
}
|
||||
if (type == 'string') {
|
||||
return `"${val}"`;
|
||||
}
|
||||
if (type == 'symbol') {
|
||||
const description = val.description;
|
||||
if (description == null) {
|
||||
return 'Symbol';
|
||||
} else {
|
||||
return `Symbol(${description})`;
|
||||
}
|
||||
}
|
||||
if (type == 'function') {
|
||||
const name = val.name;
|
||||
if (typeof name == 'string' && name.length > 0) {
|
||||
return `Function(${name})`;
|
||||
} else {
|
||||
return 'Function';
|
||||
}
|
||||
}
|
||||
// objects
|
||||
if (Array.isArray(val)) {
|
||||
const length = val.length;
|
||||
let debug = '[';
|
||||
if (length > 0) {
|
||||
debug += debugString(val[0]);
|
||||
}
|
||||
for(let i = 1; i < length; i++) {
|
||||
debug += ', ' + debugString(val[i]);
|
||||
}
|
||||
debug += ']';
|
||||
return debug;
|
||||
}
|
||||
// Test for built-in
|
||||
const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
|
||||
let className;
|
||||
if (builtInMatches && builtInMatches.length > 1) {
|
||||
className = builtInMatches[1];
|
||||
} else {
|
||||
// Failed to match the standard '[object ClassName]'
|
||||
return toString.call(val);
|
||||
}
|
||||
if (className == 'Object') {
|
||||
// we're a user defined class or Object
|
||||
// JSON.stringify avoids problems with cycles, and is generally much
|
||||
// easier than looping through ownProperties of `val`.
|
||||
try {
|
||||
return 'Object(' + JSON.stringify(val) + ')';
|
||||
} catch (_) {
|
||||
return 'Object';
|
||||
}
|
||||
}
|
||||
// errors
|
||||
if (val instanceof Error) {
|
||||
return `${val.name}: ${val.message}\n${val.stack}`;
|
||||
}
|
||||
// TODO we could test for more things here, like `Set`s and `Map`s.
|
||||
return className;
|
||||
}
|
||||
|
||||
const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
|
||||
|
||||
if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); };
|
||||
|
||||
function getStringFromWasm0(ptr, len) {
|
||||
ptr = ptr >>> 0;
|
||||
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
||||
}
|
||||
|
||||
function dropObject(idx) {
|
||||
if (idx < 132) return;
|
||||
heap[idx] = heap_next;
|
||||
heap_next = idx;
|
||||
}
|
||||
|
||||
function takeObject(idx) {
|
||||
const ret = getObject(idx);
|
||||
dropObject(idx);
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {string} filename
|
||||
* @param {Config | undefined} [config]
|
||||
* @returns {string}
|
||||
*/
|
||||
export function format(input, filename, config) {
|
||||
let deferred4_0;
|
||||
let deferred4_1;
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
const ptr0 = passStringToWasm0(input, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
const ptr1 = passStringToWasm0(filename, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
wasm.format(retptr, ptr0, len0, ptr1, len1, isLikeNone(config) ? 0 : addHeapObject(config));
|
||||
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
||||
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
||||
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
||||
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
||||
var ptr3 = r0;
|
||||
var len3 = r1;
|
||||
if (r3) {
|
||||
ptr3 = 0; len3 = 0;
|
||||
throw takeObject(r2);
|
||||
}
|
||||
deferred4_0 = ptr3;
|
||||
deferred4_1 = len3;
|
||||
return getStringFromWasm0(ptr3, len3);
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
wasm.__wbindgen_export_3(deferred4_0, deferred4_1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
async function __wbg_load(module, imports) {
|
||||
if (typeof Response === 'function' && module instanceof Response) {
|
||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
try {
|
||||
return await WebAssembly.instantiateStreaming(module, imports);
|
||||
|
||||
} catch (e) {
|
||||
if (module.headers.get('Content-Type') != 'application/wasm') {
|
||||
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
|
||||
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bytes = await module.arrayBuffer();
|
||||
return await WebAssembly.instantiate(bytes, imports);
|
||||
|
||||
} else {
|
||||
const instance = await WebAssembly.instantiate(module, imports);
|
||||
|
||||
if (instance instanceof WebAssembly.Instance) {
|
||||
return { instance, module };
|
||||
|
||||
} else {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function __wbg_get_imports() {
|
||||
const imports = {};
|
||||
imports.wbg = {};
|
||||
imports.wbg.__wbg_String_8f0eb39a4a4c2f66 = function(arg0, arg1) {
|
||||
const ret = String(getObject(arg1));
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
||||
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
||||
};
|
||||
imports.wbg.__wbg_buffer_71667b1101df19da = function(arg0) {
|
||||
const ret = getObject(arg0).buffer;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_call_d68488931693e6ee = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg0).call(getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_done_3ca5b09e8598078d = function(arg0) {
|
||||
const ret = getObject(arg0).done;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_entries_d873dde863e50b8c = function(arg0) {
|
||||
const ret = Object.entries(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_get_c122b1d576cf1fdb = function(arg0, arg1) {
|
||||
const ret = getObject(arg0)[arg1 >>> 0];
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_get_ddd82e34e6366fb9 = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = Reflect.get(getObject(arg0), getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_instanceof_ArrayBuffer_36214dbc6ea8dd3d = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof ArrayBuffer;
|
||||
} catch (_) {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_instanceof_Map_52afb7722e323e8b = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof Map;
|
||||
} catch (_) {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_instanceof_Uint8Array_0d898f7981fe0a2d = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof Uint8Array;
|
||||
} catch (_) {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_isArray_435f9cb9abc7eccc = function(arg0) {
|
||||
const ret = Array.isArray(getObject(arg0));
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_isSafeInteger_2817b2c8ebdd29d2 = function(arg0) {
|
||||
const ret = Number.isSafeInteger(getObject(arg0));
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_iterator_2a6b115668862130 = function() {
|
||||
const ret = Symbol.iterator;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_length_b52c3d528b88468e = function(arg0) {
|
||||
const ret = getObject(arg0).length;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_length_e9123d1e4db12534 = function(arg0) {
|
||||
const ret = getObject(arg0).length;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_new_9ed4506807911440 = function(arg0) {
|
||||
const ret = new Uint8Array(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_next_86c8f7dfb19a94eb = function() { return handleError(function (arg0) {
|
||||
const ret = getObject(arg0).next();
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_next_b39104aeda52ac60 = function(arg0) {
|
||||
const ret = getObject(arg0).next;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_set_e8d9380e866a1e41 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).set(getObject(arg1), arg2 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_value_f82ca5432417c8ff = function(arg0) {
|
||||
const ret = getObject(arg0).value;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_bigint_from_i64 = function(arg0) {
|
||||
const ret = arg0;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_bigint_from_u64 = function(arg0) {
|
||||
const ret = BigInt.asUintN(64, arg0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_bigint_get_as_i64 = function(arg0, arg1) {
|
||||
const v = getObject(arg1);
|
||||
const ret = typeof(v) === 'bigint' ? v : undefined;
|
||||
getDataViewMemory0().setBigInt64(arg0 + 8 * 1, isLikeNone(ret) ? BigInt(0) : ret, true);
|
||||
getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
|
||||
};
|
||||
imports.wbg.__wbindgen_boolean_get = function(arg0) {
|
||||
const v = getObject(arg0);
|
||||
const ret = typeof(v) === 'boolean' ? (v ? 1 : 0) : 2;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
|
||||
const ret = debugString(getObject(arg1));
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
||||
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
||||
};
|
||||
imports.wbg.__wbindgen_error_new = function(arg0, arg1) {
|
||||
const ret = new Error(getStringFromWasm0(arg0, arg1));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_in = function(arg0, arg1) {
|
||||
const ret = getObject(arg0) in getObject(arg1);
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_is_bigint = function(arg0) {
|
||||
const ret = typeof(getObject(arg0)) === 'bigint';
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_is_function = function(arg0) {
|
||||
const ret = typeof(getObject(arg0)) === 'function';
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_is_object = function(arg0) {
|
||||
const val = getObject(arg0);
|
||||
const ret = typeof(val) === 'object' && val !== null;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_is_string = function(arg0) {
|
||||
const ret = typeof(getObject(arg0)) === 'string';
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_jsval_eq = function(arg0, arg1) {
|
||||
const ret = getObject(arg0) === getObject(arg1);
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_jsval_loose_eq = function(arg0, arg1) {
|
||||
const ret = getObject(arg0) == getObject(arg1);
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_memory = function() {
|
||||
const ret = wasm.memory;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_number_get = function(arg0, arg1) {
|
||||
const obj = getObject(arg1);
|
||||
const ret = typeof(obj) === 'number' ? obj : undefined;
|
||||
getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);
|
||||
getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
|
||||
};
|
||||
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
|
||||
const ret = getObject(arg0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
|
||||
takeObject(arg0);
|
||||
};
|
||||
imports.wbg.__wbindgen_string_get = function(arg0, arg1) {
|
||||
const obj = getObject(arg1);
|
||||
const ret = typeof(obj) === 'string' ? obj : undefined;
|
||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||
var len1 = WASM_VECTOR_LEN;
|
||||
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
||||
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
||||
};
|
||||
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
|
||||
const ret = getStringFromWasm0(arg0, arg1);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||
};
|
||||
|
||||
return imports;
|
||||
}
|
||||
|
||||
function __wbg_init_memory(imports, memory) {
|
||||
|
||||
}
|
||||
|
||||
function __wbg_finalize_init(instance, module) {
|
||||
wasm = instance.exports;
|
||||
__wbg_init.__wbindgen_wasm_module = module;
|
||||
cachedDataViewMemory0 = null;
|
||||
cachedUint8ArrayMemory0 = null;
|
||||
|
||||
|
||||
|
||||
return wasm;
|
||||
}
|
||||
|
||||
function initSync(module) {
|
||||
if (wasm !== undefined) return wasm;
|
||||
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
if (Object.getPrototypeOf(module) === Object.prototype) {
|
||||
({module} = module)
|
||||
} else {
|
||||
console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
|
||||
}
|
||||
}
|
||||
|
||||
const imports = __wbg_get_imports();
|
||||
|
||||
__wbg_init_memory(imports);
|
||||
|
||||
if (!(module instanceof WebAssembly.Module)) {
|
||||
module = new WebAssembly.Module(module);
|
||||
}
|
||||
|
||||
const instance = new WebAssembly.Instance(module, imports);
|
||||
|
||||
return __wbg_finalize_init(instance, module);
|
||||
}
|
||||
|
||||
async function __wbg_init(module_or_path) {
|
||||
if (wasm !== undefined) return wasm;
|
||||
|
||||
|
||||
if (typeof module_or_path !== 'undefined') {
|
||||
if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
|
||||
({module_or_path} = module_or_path)
|
||||
} else {
|
||||
console.warn('using deprecated parameters for the initialization function; pass a single object instead')
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof module_or_path === 'undefined') {
|
||||
module_or_path = new URL('lua_fmt_bg.wasm', import.meta.url);
|
||||
}
|
||||
const imports = __wbg_get_imports();
|
||||
|
||||
if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {
|
||||
module_or_path = fetch(module_or_path);
|
||||
}
|
||||
|
||||
__wbg_init_memory(imports);
|
||||
|
||||
const { instance, module } = await __wbg_load(await module_or_path, imports);
|
||||
|
||||
return __wbg_finalize_init(instance, module);
|
||||
}
|
||||
|
||||
export { initSync };
|
||||
export default __wbg_init;
|
||||
BIN
frontend/src/common/prettier/plugins/lua/lua_fmt_bg.wasm
Normal file
BIN
frontend/src/common/prettier/plugins/lua/lua_fmt_bg.wasm
Normal file
Binary file not shown.
9
frontend/src/common/prettier/plugins/lua/lua_fmt_bg.wasm.d.ts
vendored
Normal file
9
frontend/src/common/prettier/plugins/lua/lua_fmt_bg.wasm.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export const memory: WebAssembly.Memory;
|
||||
export const format: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
||||
export const __wbindgen_export_0: (a: number, b: number) => number;
|
||||
export const __wbindgen_export_1: (a: number, b: number, c: number, d: number) => number;
|
||||
export const __wbindgen_export_2: (a: number) => void;
|
||||
export const __wbindgen_add_to_stack_pointer: (a: number) => number;
|
||||
export const __wbindgen_export_3: (a: number, b: number, c: number) => void;
|
||||
10
frontend/src/common/prettier/plugins/lua/lua_fmt_node.js
Normal file
10
frontend/src/common/prettier/plugins/lua/lua_fmt_node.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import fs from "node:fs/promises";
|
||||
import initAsync from "./lua_fmt.js";
|
||||
|
||||
const wasm = new URL("./lua_fmt_bg.wasm", import.meta.url);
|
||||
|
||||
export default function __wbg_init(init = { module_or_path: fs.readFile(wasm) }) {
|
||||
return initAsync(init);
|
||||
}
|
||||
|
||||
export * from "./lua_fmt.js";
|
||||
8
frontend/src/common/prettier/plugins/lua/lua_fmt_vite.js
Normal file
8
frontend/src/common/prettier/plugins/lua/lua_fmt_vite.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import initAsync from "./lua_fmt.js";
|
||||
import wasm from "./lua_fmt_bg.wasm?url";
|
||||
|
||||
export default function __wbg_init(input = { module_or_path: wasm }) {
|
||||
return initAsync(input);
|
||||
}
|
||||
|
||||
export * from "./lua_fmt.js";
|
||||
25
frontend/src/common/prettier/plugins/lua/src/Cargo.toml
Normal file
25
frontend/src/common/prettier/plugins/lua/src/Cargo.toml
Normal file
@@ -0,0 +1,25 @@
|
||||
[package]
|
||||
name = "lua"
|
||||
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
edition.workspace = true
|
||||
homepage.workspace = true
|
||||
keywords.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[package.metadata.wasm-pack.profile.release]
|
||||
wasm-opt = ["-Os"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde-wasm-bindgen = { workspace = true }
|
||||
serde_json = { workspace = true, features = ["preserve_order"] }
|
||||
stylua = { workspace = true, features = ["lua52", "lua53", "lua54"] }
|
||||
wasm-bindgen = { workspace = true }
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
5
frontend/src/common/prettier/plugins/lua/src/build.sh
Normal file
5
frontend/src/common/prettier/plugins/lua/src/build.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
cd $(dirname $0)
|
||||
project_dir=$(pwd)
|
||||
|
||||
wasm-pack build --target=web --scope=wasm-fmt .
|
||||
|
||||
151
frontend/src/common/prettier/plugins/lua/src/lib.rs
Normal file
151
frontend/src/common/prettier/plugins/lua/src/lib.rs
Normal file
@@ -0,0 +1,151 @@
|
||||
use serde::Deserialize;
|
||||
use stylua_lib::{
|
||||
format_code, CallParenType, CollapseSimpleStatement, Config as StyluaConfig, IndentType,
|
||||
LineEndings, OutputVerification, QuoteStyle, SortRequiresConfig,
|
||||
};
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn format(input: &str, filename: &str, config: Option<Config>) -> Result<String, String> {
|
||||
let _ = filename;
|
||||
|
||||
let config = config
|
||||
.map(|x| serde_wasm_bindgen::from_value::<LuaConfig>(x.clone()))
|
||||
.transpose()
|
||||
.map_err(|op| op.to_string())?
|
||||
.unwrap_or_default();
|
||||
|
||||
format_code(input, config.into(), None, OutputVerification::None).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
#[wasm_bindgen(typescript_custom_section)]
|
||||
const TS_Config: &'static str = r#"
|
||||
interface LayoutConfig {
|
||||
indent_style?: "tab" | "space";
|
||||
indent_width?: number;
|
||||
line_width?: number;
|
||||
line_ending?: "lf" | "crlf";
|
||||
}"#;
|
||||
|
||||
#[wasm_bindgen(typescript_custom_section)]
|
||||
const TS_Config: &'static str = r#"
|
||||
export interface Config extends LayoutConfig {
|
||||
quote_style?: "AutoPreferDouble" | "AutoPreferSingle" | "ForceDouble" | "ForceSingle";
|
||||
call_parentheses?: "Always" | "NoSingleString" | "NoSingleTable" | "None" | "Input";
|
||||
collapse_simple_statement?: | "Never" | "FunctionOnly" | "ConditionalOnly" | "Always";
|
||||
sort_requires?: boolean;
|
||||
}"#;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(typescript_type = "Config")]
|
||||
pub type Config;
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Default)]
|
||||
struct LayoutConfig {
|
||||
#[serde(alias = "indentStyle")]
|
||||
indent_style: Option<IndentStyle>,
|
||||
#[serde(alias = "indentWidth")]
|
||||
indent_width: Option<u8>,
|
||||
#[serde(alias = "lineWidth")]
|
||||
line_width: Option<u16>,
|
||||
#[serde(alias = "lineEnding")]
|
||||
line_ending: Option<LineEnding>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Default)]
|
||||
struct LuaConfig {
|
||||
#[serde(flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
#[serde(alias = "quoteStyle")]
|
||||
quote_style: Option<QuoteStyle>,
|
||||
|
||||
#[serde(alias = "callParentheses")]
|
||||
call_parentheses: Option<CallParenType>,
|
||||
|
||||
#[serde(alias = "collapseSimpleStatement")]
|
||||
collapse_simple_statement: Option<CollapseSimpleStatement>,
|
||||
|
||||
#[serde(alias = "sortRequires")]
|
||||
sort_requires: Option<bool>,
|
||||
}
|
||||
|
||||
impl From<LuaConfig> for StyluaConfig {
|
||||
fn from(val: LuaConfig) -> Self {
|
||||
let mut config = StyluaConfig::default();
|
||||
|
||||
if let Some(indent_style) = val.layout.indent_style {
|
||||
config.indent_type = indent_style.into();
|
||||
}
|
||||
|
||||
if let Some(indent_width) = val.layout.indent_width {
|
||||
config.indent_width = indent_width as usize;
|
||||
}
|
||||
|
||||
if let Some(line_width) = val.layout.line_width {
|
||||
config.column_width = line_width as usize;
|
||||
}
|
||||
|
||||
if let Some(line_ending) = val.layout.line_ending {
|
||||
config.line_endings = line_ending.into();
|
||||
}
|
||||
|
||||
if let Some(quote_style) = val.quote_style {
|
||||
config.quote_style = quote_style;
|
||||
}
|
||||
|
||||
if let Some(call_parentheses) = val.call_parentheses {
|
||||
config.call_parentheses = call_parentheses;
|
||||
}
|
||||
|
||||
if let Some(collapse_simple_statement) = val.collapse_simple_statement {
|
||||
config.collapse_simple_statement = collapse_simple_statement;
|
||||
}
|
||||
|
||||
if let Some(enabled) = val.sort_requires {
|
||||
let mut sort_requires = SortRequiresConfig::default();
|
||||
sort_requires.enabled = enabled;
|
||||
config.sort_requires = sort_requires;
|
||||
}
|
||||
|
||||
config
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
enum IndentStyle {
|
||||
Tab,
|
||||
#[default]
|
||||
Space,
|
||||
}
|
||||
|
||||
impl From<IndentStyle> for IndentType {
|
||||
fn from(val: IndentStyle) -> Self {
|
||||
match val {
|
||||
IndentStyle::Tab => Self::Tabs,
|
||||
IndentStyle::Space => Self::Spaces,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
enum LineEnding {
|
||||
#[default]
|
||||
Lf,
|
||||
Crlf,
|
||||
}
|
||||
|
||||
impl From<LineEnding> for LineEndings {
|
||||
fn from(val: LineEnding) -> Self {
|
||||
match val {
|
||||
LineEnding::Lf => Self::Unix,
|
||||
LineEnding::Crlf => Self::Windows,
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
111
frontend/src/common/prettier/plugins/php/src/clean.mjs
Normal file
111
frontend/src/common/prettier/plugins/php/src/clean.mjs
Normal file
@@ -0,0 +1,111 @@
|
||||
import { printNumber, normalizeMagicMethodName } from "./util.mjs";
|
||||
|
||||
const ignoredProperties = new Set([
|
||||
"loc",
|
||||
"range",
|
||||
"raw",
|
||||
"comments",
|
||||
"leadingComments",
|
||||
"trailingComments",
|
||||
"parenthesizedExpression",
|
||||
"parent",
|
||||
"prev",
|
||||
"start",
|
||||
"end",
|
||||
"tokens",
|
||||
"errors",
|
||||
"extra",
|
||||
]);
|
||||
|
||||
/**
|
||||
* This function takes the existing ast node and a copy, by reference
|
||||
* We use it for testing, so that we can compare pre-post versions of the AST,
|
||||
* excluding things we don't care about (like node location, case that will be
|
||||
* changed by the printer, etc.)
|
||||
*/
|
||||
function clean(node, newObj) {
|
||||
if (node.kind === "string") {
|
||||
// TODO if options are available in this method, replace with
|
||||
// newObj.isDoubleQuote = !useSingleQuote(node, options);
|
||||
delete newObj.isDoubleQuote;
|
||||
}
|
||||
|
||||
if (["array", "list"].includes(node.kind)) {
|
||||
// TODO if options are available in this method, assign instead of delete
|
||||
delete newObj.shortForm;
|
||||
}
|
||||
|
||||
if (node.kind === "inline") {
|
||||
if (node.value.includes("___PSEUDO_INLINE_PLACEHOLDER___")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
newObj.value = newObj.value.replace(/\n/g, "");
|
||||
}
|
||||
|
||||
// continue ((2)); -> continue 2;
|
||||
// continue 1; -> continue;
|
||||
if ((node.kind === "continue" || node.kind === "break") && node.level) {
|
||||
const { level } = newObj;
|
||||
|
||||
if (level.kind === "number") {
|
||||
newObj.level = level.value === "1" ? null : level;
|
||||
}
|
||||
}
|
||||
|
||||
// if () {{ }} -> if () {}
|
||||
if (node.kind === "block") {
|
||||
if (node.children.length === 1 && node.children[0].kind === "block") {
|
||||
while (newObj.children[0].kind === "block") {
|
||||
newObj.children = newObj.children[0].children;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize numbers
|
||||
if (node.kind === "number") {
|
||||
newObj.value = printNumber(node.value);
|
||||
}
|
||||
|
||||
const statements = ["foreach", "for", "if", "while", "do"];
|
||||
|
||||
if (statements.includes(node.kind)) {
|
||||
if (node.body && node.body.kind !== "block") {
|
||||
newObj.body = {
|
||||
kind: "block",
|
||||
children: [newObj.body],
|
||||
};
|
||||
} else {
|
||||
newObj.body = newObj.body ? newObj.body : null;
|
||||
}
|
||||
|
||||
if (node.alternate && node.alternate.kind !== "block") {
|
||||
newObj.alternate = {
|
||||
kind: "block",
|
||||
children: [newObj.alternate],
|
||||
};
|
||||
} else {
|
||||
newObj.alternate = newObj.alternate ? newObj.alternate : null;
|
||||
}
|
||||
}
|
||||
|
||||
if (node.kind === "usegroup" && typeof node.name === "string") {
|
||||
newObj.name = newObj.name.replace(/^\\/, "");
|
||||
}
|
||||
|
||||
if (node.kind === "useitem") {
|
||||
newObj.name = newObj.name.replace(/^\\/, "");
|
||||
}
|
||||
|
||||
if (node.kind === "method" && node.name.kind === "identifier") {
|
||||
newObj.name.name = normalizeMagicMethodName(newObj.name.name);
|
||||
}
|
||||
|
||||
if (node.kind === "noop") {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
clean.ignoredProperties = ignoredProperties;
|
||||
|
||||
export default clean;
|
||||
1044
frontend/src/common/prettier/plugins/php/src/comments.mjs
Normal file
1044
frontend/src/common/prettier/plugins/php/src/comments.mjs
Normal file
File diff suppressed because it is too large
Load Diff
173
frontend/src/common/prettier/plugins/php/src/index.mjs
Normal file
173
frontend/src/common/prettier/plugins/php/src/index.mjs
Normal file
@@ -0,0 +1,173 @@
|
||||
import { doc } from "prettier";
|
||||
import LINGUIST_LANGUAGES_PHP from "linguist-languages/data/PHP";
|
||||
import LINGUIST_LANGUAGES_HTML_PHP from "linguist-languages/data/HTML_2b_PHP";
|
||||
import parse from "./parser.mjs";
|
||||
import print from "./printer.mjs";
|
||||
import clean from "./clean.mjs";
|
||||
import options from "./options.mjs";
|
||||
import {
|
||||
handleOwnLineComment,
|
||||
handleEndOfLineComment,
|
||||
handleRemainingComment,
|
||||
getCommentChildNodes,
|
||||
canAttachComment,
|
||||
isBlockComment,
|
||||
} from "./comments.mjs";
|
||||
import { hasPragma, insertPragma } from "./pragma.mjs";
|
||||
import { locStart, locEnd } from "./loc.mjs";
|
||||
|
||||
const { join, hardline } = doc.builders;
|
||||
|
||||
function createLanguage(linguistData, { extend, override }) {
|
||||
const language = {};
|
||||
|
||||
for (const key in linguistData) {
|
||||
const newKey = key === "languageId" ? "linguistLanguageId" : key;
|
||||
language[newKey] = linguistData[key];
|
||||
}
|
||||
|
||||
if (extend) {
|
||||
for (const key in extend) {
|
||||
language[key] = (language[key] || []).concat(extend[key]);
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in override) {
|
||||
language[key] = override[key];
|
||||
}
|
||||
|
||||
return language;
|
||||
}
|
||||
|
||||
const languages = [
|
||||
createLanguage(LINGUIST_LANGUAGES_PHP, {
|
||||
override: {
|
||||
parsers: ["php"],
|
||||
vscodeLanguageIds: ["php"],
|
||||
},
|
||||
}),
|
||||
createLanguage(LINGUIST_LANGUAGES_HTML_PHP, {
|
||||
override: {
|
||||
parsers: ["php"],
|
||||
vscodeLanguageIds: ["php"],
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
const parsers = {
|
||||
php: {
|
||||
parse,
|
||||
astFormat: "php",
|
||||
locStart,
|
||||
locEnd,
|
||||
hasPragma,
|
||||
},
|
||||
};
|
||||
|
||||
const ignoredKeys = new Set([
|
||||
"kind",
|
||||
"loc",
|
||||
"errors",
|
||||
"extra",
|
||||
"comments",
|
||||
"leadingComments",
|
||||
"enclosingNode",
|
||||
"precedingNode",
|
||||
"followingNode",
|
||||
]);
|
||||
function getVisitorKeys(node, nonTraversableKeys) {
|
||||
return Object.keys(node).filter(
|
||||
(key) => !nonTraversableKeys.has(key) && !ignoredKeys.has(key)
|
||||
);
|
||||
}
|
||||
|
||||
const printers = {
|
||||
php: {
|
||||
print,
|
||||
getVisitorKeys,
|
||||
insertPragma,
|
||||
massageAstNode: clean,
|
||||
getCommentChildNodes,
|
||||
canAttachComment,
|
||||
isBlockComment,
|
||||
handleComments: {
|
||||
ownLine: handleOwnLineComment,
|
||||
endOfLine: handleEndOfLineComment,
|
||||
remaining: handleRemainingComment,
|
||||
},
|
||||
willPrintOwnComments(path) {
|
||||
const { node } = path;
|
||||
|
||||
return node && node.kind === "noop";
|
||||
},
|
||||
printComment(path) {
|
||||
const comment = path.node;
|
||||
|
||||
switch (comment.kind) {
|
||||
case "commentblock": {
|
||||
// for now, don't touch single line block comments
|
||||
if (!comment.value.includes("\n")) {
|
||||
return comment.value;
|
||||
}
|
||||
|
||||
const lines = comment.value.split("\n");
|
||||
// if this is a block comment, handle indentation
|
||||
if (
|
||||
lines
|
||||
.slice(1, lines.length - 1)
|
||||
.every((line) => line.trim()[0] === "*")
|
||||
) {
|
||||
return join(
|
||||
hardline,
|
||||
lines.map(
|
||||
(line, index) =>
|
||||
(index > 0 ? " " : "") +
|
||||
(index < lines.length - 1 ? line.trim() : line.trimLeft())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// otherwise we can't be sure about indentation, so just print as is
|
||||
return comment.value;
|
||||
}
|
||||
case "commentline": {
|
||||
return comment.value.trimRight();
|
||||
}
|
||||
/* c8 ignore next 2 */
|
||||
default:
|
||||
throw new Error(`Not a comment: ${JSON.stringify(comment)}`);
|
||||
}
|
||||
},
|
||||
hasPrettierIgnore(path) {
|
||||
const isSimpleIgnore = (comment) =>
|
||||
comment.value.includes("prettier-ignore") &&
|
||||
!comment.value.includes("prettier-ignore-start") &&
|
||||
!comment.value.includes("prettier-ignore-end");
|
||||
|
||||
const { node, parent: parentNode } = path;
|
||||
|
||||
return (
|
||||
(node &&
|
||||
node.kind !== "classconstant" &&
|
||||
node.comments &&
|
||||
node.comments.length > 0 &&
|
||||
node.comments.some(isSimpleIgnore)) ||
|
||||
// For proper formatting, the classconstant ignore formatting should
|
||||
// run on the "constant" child
|
||||
(node &&
|
||||
node.kind === "constant" &&
|
||||
parentNode &&
|
||||
parentNode.kind === "classconstant" &&
|
||||
parentNode.comments &&
|
||||
parentNode.comments.length > 0 &&
|
||||
parentNode.comments.some(isSimpleIgnore))
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const defaultOptions = {
|
||||
tabWidth: 4,
|
||||
};
|
||||
|
||||
export { languages, printers, parsers, options, defaultOptions };
|
||||
4
frontend/src/common/prettier/plugins/php/src/loc.mjs
Normal file
4
frontend/src/common/prettier/plugins/php/src/loc.mjs
Normal file
@@ -0,0 +1,4 @@
|
||||
const loc = (prop) => (node) => node.loc?.[prop]?.offset;
|
||||
|
||||
export const locStart = loc("start");
|
||||
export const locEnd = loc("end");
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user