-
Notifications
You must be signed in to change notification settings - Fork 127
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
47 changed files
with
750 additions
and
6 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
//! [kclvm_tools::format] module mainly contains some functions of language formatting, | ||
//! the main API function is `format`, which accepts a path to be formatted and | ||
//! formatted options. | ||
//! | ||
//! The basic principle is to call the [kclvm_parser::parse_file] function to parse the | ||
//! AST Module, and then use the AST printer [kclvm_tools::printer::print_ast_module] | ||
//! to print it as source code string. | ||
use anyhow::{anyhow, Result}; | ||
use std::path::Path; | ||
|
||
use crate::{printer::print_ast_module, util::get_kcl_files}; | ||
use kclvm_parser::parse_file; | ||
|
||
#[cfg(test)] | ||
mod tests; | ||
|
||
/// FormatOptions contains two options: | ||
/// - is_stdout: whether to output the formatted result to stdout. | ||
/// - recursively: whether to recursively traverse a folder and format all KCL files in it. | ||
#[derive(Debug, Default)] | ||
pub struct FormatOptions { | ||
pub is_stdout: bool, | ||
pub recursively: bool, | ||
} | ||
|
||
/// Formats kcl file or directory path contains kcl files and | ||
/// returns the changed file paths. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ```no_run | ||
/// use kclvm_tools::format::{format, FormatOptions}; | ||
/// | ||
/// // Format a single file. | ||
/// format("path_to_a_single_file.k", &FormatOptions::default()).unwrap(); | ||
/// // Format a folder contains kcl files | ||
/// format("path_to_a_folder", &FormatOptions::default()).unwrap(); | ||
/// ``` | ||
pub fn format<P: AsRef<Path>>(path: P, opts: &FormatOptions) -> Result<Vec<String>> { | ||
let mut changed_paths: Vec<String> = vec![]; | ||
let path_ref = path.as_ref(); | ||
if path_ref.is_dir() { | ||
for file in &get_kcl_files(path, opts.recursively)? { | ||
if format_file(file, opts)? { | ||
changed_paths.push(file.clone()) | ||
} | ||
} | ||
} else if path_ref.is_file() { | ||
let file = path_ref.to_str().unwrap().to_string(); | ||
if format_file(&file, opts)? { | ||
changed_paths.push(file) | ||
} | ||
} | ||
if !opts.is_stdout { | ||
let n = changed_paths.len(); | ||
println!( | ||
"KCL format done and {} {} formatted:", | ||
n, | ||
if n <= 1 { "file was" } else { "files were" } | ||
); | ||
for p in &changed_paths { | ||
println!("{}", p); | ||
} | ||
} | ||
Ok(changed_paths) | ||
} | ||
|
||
/// Format a file and returns whether the file has been formatted and modified. | ||
fn format_file(file: &str, opts: &FormatOptions) -> Result<bool> { | ||
let src = std::fs::read_to_string(file)?; | ||
let (source, is_formatted) = format_source(&src)?; | ||
if opts.is_stdout { | ||
println!("{}", source); | ||
} else { | ||
std::fs::write(file, &source)? | ||
} | ||
Ok(is_formatted) | ||
} | ||
|
||
/// Format a code source and return the formatted source and | ||
/// whether the source is changed. | ||
fn format_source(src: &str) -> Result<(String, bool)> { | ||
let module = match parse_file("", Some(src.to_string())) { | ||
Ok(module) => module, | ||
Err(err) => return Err(anyhow!("{}", err)), | ||
}; | ||
let formatted_src = print_ast_module(&module); | ||
let is_formatted = src != formatted_src; | ||
Ok((formatted_src, is_formatted)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
assert True if True, "message" | ||
# Comment | ||
assert False if data, "message" | ||
assert 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
assert True if True, "message" | ||
assert False if data , "message" # Comment | ||
assert 1 |
4 changes: 4 additions & 0 deletions
4
kclvm/tools/src/format/test_data/format_data/blankline.golden
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
a = 1 | ||
b = 2 | ||
c = 3 | ||
d = 4 |
12 changes: 12 additions & 0 deletions
12
kclvm/tools/src/format/test_data/format_data/blankline.input
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
|
||
a=1 | ||
|
||
|
||
b= 2 | ||
|
||
|
||
c =3 | ||
|
||
|
||
|
||
d = 4 |
9 changes: 9 additions & 0 deletions
9
kclvm/tools/src/format/test_data/format_data/breakline.golden
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import math | ||
schema Base: | ||
name: str | ||
|
||
schema Person(Base): | ||
age: int | ||
|
||
person = Person {} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import math | ||
schema Base: | ||
name: str | ||
schema Person(Base): | ||
age: int | ||
person = Person{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
schema Person: | ||
firstName: str = "John" | ||
lastName: str | ||
times: int | ||
|
||
check: | ||
len(lastName) > 0 if times > 5 | ||
|
||
JohnDoe = Person { | ||
"lastName": "Doe" | ||
"times": 10 | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
|
||
schema Person: | ||
firstName: str = "John" | ||
lastName: str | ||
times: int | ||
check: | ||
len(lastName) > 0 if times > 5 | ||
|
||
JohnDoe = Person { | ||
"lastName": "Doe" | ||
"times":10 | ||
} |
80 changes: 80 additions & 0 deletions
80
kclvm/tools/src/format/test_data/format_data/codelayout.golden
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import math as alias_math | ||
schema Person(Base): | ||
# inline comment | ||
name: str | ||
age: int | ||
|
||
check: | ||
age > 0 if age, "age must > 0" | ||
|
||
person = Person { | ||
name: "Alice" | ||
age: 18 | ||
} | ||
|
||
if True: | ||
a = 1 | ||
elif True: | ||
b = 2 | ||
else: | ||
c = 3 | ||
d = 1 + 2 | ||
e = (1 + 2) | ||
f = [1, 2, 3] | ||
g = {"key": "value"} | ||
# block comment | ||
print(1) | ||
dct = {"key": "value"} | ||
lst = [1, 2, 3] | ||
h = dct['key'] | ||
i = lst[1] | ||
x = 1 | ||
y = 2 | ||
long_variable = 3 | ||
i = i + 1 | ||
submitted += 1 | ||
x = x * 2 - 1 | ||
hypot2 = x * x + y * y | ||
_c = (a + b) * (a - b) | ||
_b = 2 | ||
_c = 3 | ||
_d = 4 | ||
_value = (1 + 2 * 3) | ||
_value = (1 + 2 * 3) | ||
_value = 1 + -2 * ~3 | ||
_list = [1, 2, 3] | ||
_list = [*_list, [4, 5, 6]] | ||
_list = [*_list, [4, 5, 6]] | ||
_dict = {**{"k": "v"}, **{"k": "v"}} | ||
a = [1, 2, 3] | ||
b = [ | ||
1 | ||
2 | ||
3 | ||
4 | ||
5 | ||
6 | ||
] | ||
_dict = { | ||
"k1": "v1" | ||
"k2": "v2" | ||
"k3": "v3" | ||
"k4": "v4" | ||
"k5": "v5" | ||
} | ||
foo = 1 | ||
if foo is not None: | ||
_a = 1 | ||
_dict |= {} | ||
hello = "world{}".format(1)[2:4:].lower() | ||
range_int = [i for i in range(10) if i > 1] | ||
|
||
op = 1 + 2 - -3 + (3 - 1) // 3 | ||
op += 1 | ||
op -= 12 + 23 | ||
print(" ", end='') | ||
log = math.log(12) | ||
aa = 1 | ||
assert aa == 1 if aa, "message" | ||
aaaa = (1 + 2 / 2) if _a == 2 + +134.3 else ("a" * 3) | ||
bbbb = "{}".format(a) |
Oops, something went wrong.