mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
Merge branch 'main' into fix-deprecated-interpolated-formatting
This commit is contained in:
commit
ca037c5d0e
44 changed files with 4321 additions and 127 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -30,6 +30,7 @@ zig-cache
|
||||||
.envrc
|
.envrc
|
||||||
*.rs.bk
|
*.rs.bk
|
||||||
*.o
|
*.o
|
||||||
|
*.a
|
||||||
*.so
|
*.so
|
||||||
*.so.*
|
*.so.*
|
||||||
*.obj
|
*.obj
|
||||||
|
|
1
crates/compiler/builtins/bitcode/.gitignore
vendored
Normal file
1
crates/compiler/builtins/bitcode/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
.fuzz_data
|
42
crates/compiler/builtins/bitcode/fuzz_in_tmux.sh
Executable file
42
crates/compiler/builtins/bitcode/fuzz_in_tmux.sh
Executable file
|
@ -0,0 +1,42 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
# Run from this directory.
|
||||||
|
SCRIPT_RELATIVE_DIR=`dirname "${BASH_SOURCE[0]}"`
|
||||||
|
cd $SCRIPT_RELATIVE_DIR
|
||||||
|
|
||||||
|
# First compile the fuzz target.
|
||||||
|
zig build-lib -static -fcompiler-rt -flto -fPIC src/fuzz_sort.zig
|
||||||
|
afl-clang-lto -o fuzz libfuzz_sort.a
|
||||||
|
AFL_LLVM_CMPLOG=1 afl-clang-lto -o fuzz-cmplog libfuzz_sort.a
|
||||||
|
AFL_LLVM_LAF_ALL=1 afl-clang-lto -o fuzz-cmpcov libfuzz_sort.a
|
||||||
|
|
||||||
|
# Setup fuzz directory with dummy input.
|
||||||
|
INPUT_DIR='.fuzz_data/input'
|
||||||
|
OUTPUT_DIR='.fuzz_data/output'
|
||||||
|
if [ ! -d .fuzz_data ]; then
|
||||||
|
mkdir -p $INPUT_DIR
|
||||||
|
echo '1234567887654321' > $INPUT_DIR/dummy_input
|
||||||
|
else
|
||||||
|
# Resuming from existing run.
|
||||||
|
INPUT_DIR='-'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Just hardcoding to 7 fuzzers (this avoids overwhelming 8 core machines).
|
||||||
|
BASE_CMD="AFL_TESTCACHE_SIZE=250 AFL_IMPORT_FIRST=1 afl-fuzz -i $INPUT_DIR -o $OUTPUT_DIR"
|
||||||
|
|
||||||
|
# I'm trying to follow the guide around secondary fuzzers, but I don't quite follow the wording.
|
||||||
|
# So I feel this may be correct, but it may also be more random then they expect.
|
||||||
|
# Overkill anyway...so this is fine.
|
||||||
|
tmux new-session -d -s "fuzz" "AFL_FINAL_SYNC=1 $BASE_CMD -M fuzzer01 ./fuzz"
|
||||||
|
tmux split-window -h "$BASE_CMD -S fuzzer02 -c ./fuzz-cmplog -m none -l 2AT -p explore ./fuzz"
|
||||||
|
tmux split-window -v -t 0.0 "$BASE_CMD -S fuzzer03 -c ./fuzz-cmplog -m none -L 0 -p exploit ./fuzz"
|
||||||
|
tmux split-window -v -t 0.2 "$BASE_CMD -S fuzzer04 -p explore ./fuzz-cmpcov"
|
||||||
|
tmux new-window "$BASE_CMD -S fuzzer05 -Z -p coe ./fuzz-cmpcov"
|
||||||
|
tmux split-window -h "$BASE_CMD -S fuzzer06 -P exploit ./fuzz"
|
||||||
|
tmux split-window -v -t 1.0 "AFL_DISABLE_TRIM=1 $BASE_CMD -S fuzzer07 -p explore ./fuzz"
|
||||||
|
tmux split-window -v -t 1.2 "htop"
|
||||||
|
tmux new-window "watch -c -n 30 afl-whatsup -s .fuzz_data/output"
|
||||||
|
tmux select-window -t 1
|
||||||
|
tmux select-window -t 0
|
||||||
|
tmux -2 a -t "fuzz"
|
101
crates/compiler/builtins/bitcode/src/fuzz_sort.zig
Normal file
101
crates/compiler/builtins/bitcode/src/fuzz_sort.zig
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const sort = @import("sort.zig");
|
||||||
|
|
||||||
|
extern fn malloc(size: usize) callconv(.C) ?*anyopaque;
|
||||||
|
extern fn free(c_ptr: *anyopaque) callconv(.C) void;
|
||||||
|
|
||||||
|
fn cMain() callconv(.C) i32 {
|
||||||
|
fuzz_main() catch unreachable;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
@export(cMain, .{ .name = "main", .linkage = .Strong });
|
||||||
|
}
|
||||||
|
|
||||||
|
const DEBUG = false;
|
||||||
|
|
||||||
|
var allocator: std.mem.Allocator = undefined;
|
||||||
|
|
||||||
|
pub fn fuzz_main() !void {
|
||||||
|
// Setup an allocator that will detect leaks/use-after-free/etc
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
// this will check for leaks and crash the program if it finds any
|
||||||
|
defer std.debug.assert(gpa.deinit() == .ok);
|
||||||
|
allocator = gpa.allocator();
|
||||||
|
|
||||||
|
// Read the data from stdin
|
||||||
|
const stdin = std.io.getStdIn();
|
||||||
|
const data = try stdin.readToEndAlloc(allocator, std.math.maxInt(usize));
|
||||||
|
defer allocator.free(data);
|
||||||
|
|
||||||
|
const len = data.len / @sizeOf(i64);
|
||||||
|
const arr_ptr: [*]i64 = @alignCast(@ptrCast(data.ptr));
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
std.debug.print("Input: [{d}]{d}\n", .{ len, arr_ptr[0..len] });
|
||||||
|
}
|
||||||
|
|
||||||
|
var test_count: i64 = 0;
|
||||||
|
sort.fluxsort(@ptrCast(arr_ptr), len, &test_i64_compare_refcounted, @ptrCast(&test_count), true, &test_inc_n_data, @sizeOf(i64), @alignOf(i64), &test_i64_copy);
|
||||||
|
|
||||||
|
const sorted = std.sort.isSorted(i64, arr_ptr[0..len], {}, std.sort.asc(i64));
|
||||||
|
if (DEBUG) {
|
||||||
|
std.debug.print("Output: [{d}]{d}\nSorted: {}\nFinal RC: {}\n", .{ len, arr_ptr[0..len], sorted, test_count });
|
||||||
|
}
|
||||||
|
std.debug.assert(sorted);
|
||||||
|
std.debug.assert(test_count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Opaque = ?[*]u8;
|
||||||
|
fn test_i64_compare_refcounted(count_ptr: Opaque, a_ptr: Opaque, b_ptr: Opaque) callconv(.C) u8 {
|
||||||
|
const a = @as(*i64, @alignCast(@ptrCast(a_ptr))).*;
|
||||||
|
const b = @as(*i64, @alignCast(@ptrCast(b_ptr))).*;
|
||||||
|
|
||||||
|
const gt = @as(u8, @intFromBool(a > b));
|
||||||
|
const lt = @as(u8, @intFromBool(a < b));
|
||||||
|
|
||||||
|
std.debug.assert(@as(*isize, @ptrCast(@alignCast(count_ptr))).* > 0);
|
||||||
|
@as(*isize, @ptrCast(@alignCast(count_ptr))).* -= 1;
|
||||||
|
// Eq = 0
|
||||||
|
// GT = 1
|
||||||
|
// LT = 2
|
||||||
|
return lt + lt + gt;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_i64_copy(dst_ptr: Opaque, src_ptr: Opaque) callconv(.C) void {
|
||||||
|
@as(*i64, @alignCast(@ptrCast(dst_ptr))).* = @as(*i64, @alignCast(@ptrCast(src_ptr))).*;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_inc_n_data(count_ptr: Opaque, n: usize) callconv(.C) void {
|
||||||
|
@as(*isize, @ptrCast(@alignCast(count_ptr))).* += @intCast(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
@export(testing_roc_alloc, .{ .name = "roc_alloc", .linkage = .Strong });
|
||||||
|
@export(testing_roc_dealloc, .{ .name = "roc_dealloc", .linkage = .Strong });
|
||||||
|
@export(testing_roc_panic, .{ .name = "roc_panic", .linkage = .Strong });
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testing_roc_alloc(size: usize, _: u32) callconv(.C) ?*anyopaque {
|
||||||
|
// We store an extra usize which is the size of the full allocation.
|
||||||
|
const full_size = size + @sizeOf(usize);
|
||||||
|
var raw_ptr = (allocator.alloc(u8, full_size) catch unreachable).ptr;
|
||||||
|
@as([*]usize, @alignCast(@ptrCast(raw_ptr)))[0] = full_size;
|
||||||
|
raw_ptr += @sizeOf(usize);
|
||||||
|
return @as(?*anyopaque, @ptrCast(raw_ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testing_roc_dealloc(c_ptr: *anyopaque, _: u32) callconv(.C) void {
|
||||||
|
const raw_ptr = @as([*]u8, @ptrCast(c_ptr)) - @sizeOf(usize);
|
||||||
|
const full_size = @as([*]usize, @alignCast(@ptrCast(raw_ptr)))[0];
|
||||||
|
const slice = raw_ptr[0..full_size];
|
||||||
|
allocator.free(slice);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testing_roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||||
|
_ = c_ptr;
|
||||||
|
_ = tag_id;
|
||||||
|
|
||||||
|
@panic("Roc panicked");
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const utils = @import("utils.zig");
|
const utils = @import("utils.zig");
|
||||||
const str = @import("str.zig");
|
const str = @import("str.zig");
|
||||||
|
const sort = @import("sort.zig");
|
||||||
const UpdateMode = utils.UpdateMode;
|
const UpdateMode = utils.UpdateMode;
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const math = std.math;
|
const math = std.math;
|
||||||
|
@ -690,60 +691,10 @@ pub fn listDropAt(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn partition(
|
|
||||||
source_ptr: [*]u8,
|
|
||||||
transform: Opaque,
|
|
||||||
wrapper: CompareFn,
|
|
||||||
element_width: usize,
|
|
||||||
low: isize,
|
|
||||||
high: isize,
|
|
||||||
copy: CopyFn,
|
|
||||||
) isize {
|
|
||||||
const pivot = source_ptr + (@as(usize, @intCast(high)) * element_width);
|
|
||||||
var i = (low - 1); // Index of smaller element and indicates the right position of pivot found so far
|
|
||||||
var j = low;
|
|
||||||
|
|
||||||
while (j <= high - 1) : (j += 1) {
|
|
||||||
const current_elem = source_ptr + (@as(usize, @intCast(j)) * element_width);
|
|
||||||
|
|
||||||
const ordering = wrapper(transform, current_elem, pivot);
|
|
||||||
const order = @as(utils.Ordering, @enumFromInt(ordering));
|
|
||||||
|
|
||||||
switch (order) {
|
|
||||||
utils.Ordering.LT => {
|
|
||||||
// the current element is smaller than the pivot; swap it
|
|
||||||
i += 1;
|
|
||||||
swapElements(source_ptr, element_width, @as(usize, @intCast(i)), @as(usize, @intCast(j)), copy);
|
|
||||||
},
|
|
||||||
utils.Ordering.EQ, utils.Ordering.GT => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
swapElements(source_ptr, element_width, @as(usize, @intCast(i + 1)), @as(usize, @intCast(high)), copy);
|
|
||||||
return (i + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn quicksort(
|
|
||||||
source_ptr: [*]u8,
|
|
||||||
transform: Opaque,
|
|
||||||
wrapper: CompareFn,
|
|
||||||
element_width: usize,
|
|
||||||
low: isize,
|
|
||||||
high: isize,
|
|
||||||
copy: CopyFn,
|
|
||||||
) void {
|
|
||||||
if (low < high) {
|
|
||||||
// partition index
|
|
||||||
const pi = partition(source_ptr, transform, wrapper, element_width, low, high, copy);
|
|
||||||
|
|
||||||
_ = quicksort(source_ptr, transform, wrapper, element_width, low, pi - 1, copy); // before pi
|
|
||||||
_ = quicksort(source_ptr, transform, wrapper, element_width, pi + 1, high, copy); // after pi
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn listSortWith(
|
pub fn listSortWith(
|
||||||
input: RocList,
|
input: RocList,
|
||||||
caller: CompareFn,
|
cmp: CompareFn,
|
||||||
data: Opaque,
|
cmp_data: Opaque,
|
||||||
inc_n_data: IncN,
|
inc_n_data: IncN,
|
||||||
data_is_owned: bool,
|
data_is_owned: bool,
|
||||||
alignment: u32,
|
alignment: u32,
|
||||||
|
@ -753,16 +704,13 @@ pub fn listSortWith(
|
||||||
dec: Dec,
|
dec: Dec,
|
||||||
copy: CopyFn,
|
copy: CopyFn,
|
||||||
) callconv(.C) RocList {
|
) callconv(.C) RocList {
|
||||||
|
if (input.len() < 2) {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
var list = input.makeUnique(alignment, element_width, elements_refcounted, inc, dec);
|
var list = input.makeUnique(alignment, element_width, elements_refcounted, inc, dec);
|
||||||
|
|
||||||
if (data_is_owned) {
|
|
||||||
inc_n_data(data, list.len());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list.bytes) |source_ptr| {
|
if (list.bytes) |source_ptr| {
|
||||||
const low = 0;
|
sort.fluxsort(source_ptr, list.len(), cmp, cmp_data, data_is_owned, inc_n_data, element_width, alignment, copy);
|
||||||
const high: isize = @as(isize, @intCast(list.len())) - 1;
|
|
||||||
quicksort(source_ptr, data, caller, element_width, low, high, copy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
|
|
|
@ -394,11 +394,13 @@ fn exportUtilsFn(comptime func: anytype, comptime func_name: []const u8) void {
|
||||||
|
|
||||||
// Custom panic function, as builtin Zig version errors during LLVM verification
|
// Custom panic function, as builtin Zig version errors during LLVM verification
|
||||||
pub fn panic(message: []const u8, stacktrace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
|
pub fn panic(message: []const u8, stacktrace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
|
||||||
if (builtin.is_test) {
|
if (builtin.target.cpu.arch != .wasm32) {
|
||||||
std.debug.print("{s}: {?}", .{ message, stacktrace });
|
std.debug.print("\nSomehow in unreachable zig panic!\nThis is a roc standard libarry bug\n{s}: {?}", .{ message, stacktrace });
|
||||||
|
std.process.abort();
|
||||||
|
} else {
|
||||||
|
// Can't call abort or print from wasm. Just leave it as unreachable.
|
||||||
|
unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
unreachable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run all tests in imported modules
|
// Run all tests in imported modules
|
||||||
|
|
3929
crates/compiler/builtins/bitcode/src/sort.zig
Normal file
3929
crates/compiler/builtins/bitcode/src/sort.zig
Normal file
File diff suppressed because it is too large
Load diff
|
@ -2969,7 +2969,7 @@ fn to_pending_value_def<'a>(
|
||||||
AnnotatedBody {
|
AnnotatedBody {
|
||||||
ann_pattern,
|
ann_pattern,
|
||||||
ann_type,
|
ann_type,
|
||||||
comment: _,
|
lines_between: _,
|
||||||
body_pattern,
|
body_pattern,
|
||||||
body_expr,
|
body_expr,
|
||||||
} => {
|
} => {
|
||||||
|
|
|
@ -86,13 +86,13 @@ fn desugar_value_def<'a>(
|
||||||
AnnotatedBody {
|
AnnotatedBody {
|
||||||
ann_pattern,
|
ann_pattern,
|
||||||
ann_type,
|
ann_type,
|
||||||
comment,
|
lines_between,
|
||||||
body_pattern,
|
body_pattern,
|
||||||
body_expr,
|
body_expr,
|
||||||
} => AnnotatedBody {
|
} => AnnotatedBody {
|
||||||
ann_pattern,
|
ann_pattern,
|
||||||
ann_type,
|
ann_type,
|
||||||
comment: *comment,
|
lines_between,
|
||||||
body_pattern: desugar_loc_pattern(arena, body_pattern, src, line_info, module_path),
|
body_pattern: desugar_loc_pattern(arena, body_pattern, src, line_info, module_path),
|
||||||
body_expr: desugar_expr(arena, body_expr, src, line_info, module_path),
|
body_expr: desugar_expr(arena, body_expr, src, line_info, module_path),
|
||||||
},
|
},
|
||||||
|
@ -170,7 +170,7 @@ fn desugar_value_def<'a>(
|
||||||
ext: None,
|
ext: None,
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
comment: None,
|
lines_between: &[],
|
||||||
body_pattern: new_pat,
|
body_pattern: new_pat,
|
||||||
body_expr: desugar_expr(arena, stmt_expr, src, line_info, module_path),
|
body_expr: desugar_expr(arena, stmt_expr, src, line_info, module_path),
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,7 @@ pub fn desugar_value_def_suffixed<'a>(arena: &'a Bump, value_def: ValueDef<'a>)
|
||||||
AnnotatedBody {
|
AnnotatedBody {
|
||||||
ann_pattern,
|
ann_pattern,
|
||||||
ann_type,
|
ann_type,
|
||||||
comment,
|
lines_between,
|
||||||
body_pattern,
|
body_pattern,
|
||||||
body_expr,
|
body_expr,
|
||||||
} => {
|
} => {
|
||||||
|
@ -244,7 +244,7 @@ pub fn desugar_value_def_suffixed<'a>(arena: &'a Bump, value_def: ValueDef<'a>)
|
||||||
Ok(new_expr) => AnnotatedBody {
|
Ok(new_expr) => AnnotatedBody {
|
||||||
ann_pattern,
|
ann_pattern,
|
||||||
ann_type,
|
ann_type,
|
||||||
comment,
|
lines_between,
|
||||||
body_pattern,
|
body_pattern,
|
||||||
body_expr: new_expr,
|
body_expr: new_expr,
|
||||||
},
|
},
|
||||||
|
@ -257,7 +257,7 @@ pub fn desugar_value_def_suffixed<'a>(arena: &'a Bump, value_def: ValueDef<'a>)
|
||||||
AnnotatedBody {
|
AnnotatedBody {
|
||||||
ann_pattern,
|
ann_pattern,
|
||||||
ann_type,
|
ann_type,
|
||||||
comment,
|
lines_between,
|
||||||
body_pattern,
|
body_pattern,
|
||||||
body_expr: apply_task_await(
|
body_expr: apply_task_await(
|
||||||
arena,
|
arena,
|
||||||
|
@ -272,7 +272,7 @@ pub fn desugar_value_def_suffixed<'a>(arena: &'a Bump, value_def: ValueDef<'a>)
|
||||||
Err(..) => AnnotatedBody {
|
Err(..) => AnnotatedBody {
|
||||||
ann_pattern,
|
ann_pattern,
|
||||||
ann_type,
|
ann_type,
|
||||||
comment,
|
lines_between,
|
||||||
body_pattern,
|
body_pattern,
|
||||||
body_expr: arena.alloc(Loc::at(body_expr.region, MalformedSuffixed(body_expr))),
|
body_expr: arena.alloc(Loc::at(body_expr.region, MalformedSuffixed(body_expr))),
|
||||||
},
|
},
|
||||||
|
|
|
@ -900,7 +900,7 @@ pub fn apply_task_await<'a>(
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
comment: None,
|
lines_between: &[],
|
||||||
body_pattern: arena.alloc(Loc::at(
|
body_pattern: arena.alloc(Loc::at(
|
||||||
loc_pat.region,
|
loc_pat.region,
|
||||||
Pattern::Identifier { ident: new_ident },
|
Pattern::Identifier { ident: new_ident },
|
||||||
|
|
|
@ -62,7 +62,7 @@ Defs {
|
||||||
@11-15 Inferred,
|
@11-15 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @11-15 Identifier {
|
body_pattern: @11-15 Identifier {
|
||||||
ident: "#!0_stmt",
|
ident: "#!0_stmt",
|
||||||
},
|
},
|
||||||
|
|
|
@ -89,7 +89,7 @@ Defs {
|
||||||
@31-43 Inferred,
|
@31-43 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @31-43 Identifier {
|
body_pattern: @31-43 Identifier {
|
||||||
ident: "#!0_stmt",
|
ident: "#!0_stmt",
|
||||||
},
|
},
|
||||||
|
|
|
@ -62,7 +62,9 @@ Defs {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @35-36 Identifier {
|
body_pattern: @35-36 Identifier {
|
||||||
ident: "x",
|
ident: "x",
|
||||||
},
|
},
|
||||||
|
@ -111,7 +113,7 @@ Defs {
|
||||||
@60-69 Inferred,
|
@60-69 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @78-79 Identifier {
|
body_pattern: @78-79 Identifier {
|
||||||
ident: "#!0_expr",
|
ident: "#!0_expr",
|
||||||
},
|
},
|
||||||
|
|
|
@ -78,7 +78,9 @@ Defs {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @50-53 Identifier {
|
body_pattern: @50-53 Identifier {
|
||||||
ident: "foo",
|
ident: "foo",
|
||||||
},
|
},
|
||||||
|
@ -132,7 +134,7 @@ Defs {
|
||||||
@76-83 Inferred,
|
@76-83 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @76-83 Identifier {
|
body_pattern: @76-83 Identifier {
|
||||||
ident: "#!1_stmt",
|
ident: "#!1_stmt",
|
||||||
},
|
},
|
||||||
|
@ -201,7 +203,7 @@ Defs {
|
||||||
@92-99 Inferred,
|
@92-99 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @92-99 Identifier {
|
body_pattern: @92-99 Identifier {
|
||||||
ident: "#!0_stmt",
|
ident: "#!0_stmt",
|
||||||
},
|
},
|
||||||
|
|
|
@ -97,7 +97,7 @@ Defs {
|
||||||
@25-39 Inferred,
|
@25-39 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @25-39 Identifier {
|
body_pattern: @25-39 Identifier {
|
||||||
ident: "#!1_stmt",
|
ident: "#!1_stmt",
|
||||||
},
|
},
|
||||||
|
|
|
@ -114,7 +114,9 @@ Defs {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @95-98 Identifier {
|
body_pattern: @95-98 Identifier {
|
||||||
ident: "msg",
|
ident: "msg",
|
||||||
},
|
},
|
||||||
|
@ -192,7 +194,7 @@ Defs {
|
||||||
@140-152 Inferred,
|
@140-152 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @140-152 Identifier {
|
body_pattern: @140-152 Identifier {
|
||||||
ident: "#!0_stmt",
|
ident: "#!0_stmt",
|
||||||
},
|
},
|
||||||
|
@ -314,7 +316,7 @@ Defs {
|
||||||
@227-239 Inferred,
|
@227-239 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @227-239 Identifier {
|
body_pattern: @227-239 Identifier {
|
||||||
ident: "#!2_stmt",
|
ident: "#!2_stmt",
|
||||||
},
|
},
|
||||||
|
|
|
@ -62,7 +62,7 @@ Defs {
|
||||||
@11-15 Inferred,
|
@11-15 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @11-15 Identifier {
|
body_pattern: @11-15 Identifier {
|
||||||
ident: "#!2_stmt",
|
ident: "#!2_stmt",
|
||||||
},
|
},
|
||||||
|
@ -122,7 +122,7 @@ Defs {
|
||||||
@20-24 Inferred,
|
@20-24 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @20-24 Identifier {
|
body_pattern: @20-24 Identifier {
|
||||||
ident: "#!1_stmt",
|
ident: "#!1_stmt",
|
||||||
},
|
},
|
||||||
|
|
|
@ -62,7 +62,7 @@ Defs {
|
||||||
@11-23 Inferred,
|
@11-23 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @11-23 Identifier {
|
body_pattern: @11-23 Identifier {
|
||||||
ident: "#!0_stmt",
|
ident: "#!0_stmt",
|
||||||
},
|
},
|
||||||
|
|
|
@ -69,7 +69,7 @@ Defs {
|
||||||
@11-16 Inferred,
|
@11-16 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @11-16 Identifier {
|
body_pattern: @11-16 Identifier {
|
||||||
ident: "#!1_stmt",
|
ident: "#!1_stmt",
|
||||||
},
|
},
|
||||||
|
|
|
@ -62,7 +62,7 @@ Defs {
|
||||||
@11-57 Inferred,
|
@11-57 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @11-57 Identifier {
|
body_pattern: @11-57 Identifier {
|
||||||
ident: "#!0_stmt",
|
ident: "#!0_stmt",
|
||||||
},
|
},
|
||||||
|
|
|
@ -71,7 +71,7 @@ Defs {
|
||||||
@19-30 Inferred,
|
@19-30 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @19-30 Identifier {
|
body_pattern: @19-30 Identifier {
|
||||||
ident: "#!1_stmt",
|
ident: "#!1_stmt",
|
||||||
},
|
},
|
||||||
|
|
|
@ -69,7 +69,7 @@ Defs {
|
||||||
@18-19 Inferred,
|
@18-19 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @24-25 Identifier {
|
body_pattern: @24-25 Identifier {
|
||||||
ident: "#!0_expr",
|
ident: "#!0_expr",
|
||||||
},
|
},
|
||||||
|
|
|
@ -90,7 +90,7 @@ Defs {
|
||||||
@54-65 Inferred,
|
@54-65 Inferred,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [],
|
||||||
body_pattern: @54-65 Identifier {
|
body_pattern: @54-65 Identifier {
|
||||||
ident: "#!1_stmt",
|
ident: "#!1_stmt",
|
||||||
},
|
},
|
||||||
|
|
|
@ -450,17 +450,13 @@ impl<'a> Formattable for ValueDef<'a> {
|
||||||
AnnotatedBody {
|
AnnotatedBody {
|
||||||
ann_pattern,
|
ann_pattern,
|
||||||
ann_type,
|
ann_type,
|
||||||
comment,
|
lines_between,
|
||||||
body_pattern,
|
body_pattern,
|
||||||
body_expr,
|
body_expr,
|
||||||
} => {
|
} => {
|
||||||
fmt_general_def(ann_pattern, buf, indent, ":", &ann_type.value, newlines);
|
fmt_general_def(ann_pattern, buf, indent, ":", &ann_type.value, newlines);
|
||||||
|
|
||||||
if let Some(comment_str) = comment {
|
fmt_annotated_body_comment(buf, indent, lines_between);
|
||||||
buf.push_str(" #");
|
|
||||||
buf.spaces(1);
|
|
||||||
buf.push_str(comment_str.trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.newline();
|
buf.newline();
|
||||||
fmt_body(buf, &body_pattern.value, &body_expr.value, indent);
|
fmt_body(buf, &body_pattern.value, &body_expr.value, indent);
|
||||||
|
@ -586,6 +582,49 @@ pub fn fmt_defs(buf: &mut Buf, defs: &Defs, indent: u16) {
|
||||||
defs.format(buf, indent);
|
defs.format(buf, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fmt_annotated_body_comment<'a>(
|
||||||
|
buf: &mut Buf,
|
||||||
|
indent: u16,
|
||||||
|
lines_between: &'a [roc_parse::ast::CommentOrNewline<'a>],
|
||||||
|
) {
|
||||||
|
let mut comment_iter = lines_between.iter();
|
||||||
|
if let Some(comment_first) = comment_iter.next() {
|
||||||
|
match comment_first {
|
||||||
|
roc_parse::ast::CommentOrNewline::Newline => (),
|
||||||
|
roc_parse::ast::CommentOrNewline::DocComment(comment_str) => {
|
||||||
|
buf.push_str(" # #");
|
||||||
|
buf.spaces(1);
|
||||||
|
buf.push_str(comment_str.trim());
|
||||||
|
}
|
||||||
|
roc_parse::ast::CommentOrNewline::LineComment(comment_str) => {
|
||||||
|
buf.push_str(" #");
|
||||||
|
buf.spaces(1);
|
||||||
|
buf.push_str(comment_str.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for comment_or_newline in comment_iter {
|
||||||
|
match comment_or_newline {
|
||||||
|
roc_parse::ast::CommentOrNewline::Newline => (),
|
||||||
|
roc_parse::ast::CommentOrNewline::DocComment(comment_str) => {
|
||||||
|
buf.newline();
|
||||||
|
buf.indent(indent);
|
||||||
|
buf.push_str("# #");
|
||||||
|
buf.spaces(1);
|
||||||
|
buf.push_str(comment_str.trim());
|
||||||
|
}
|
||||||
|
roc_parse::ast::CommentOrNewline::LineComment(comment_str) => {
|
||||||
|
buf.newline();
|
||||||
|
buf.indent(indent);
|
||||||
|
buf.push_str("#");
|
||||||
|
buf.spaces(1);
|
||||||
|
buf.push_str(comment_str.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fmt_body<'a>(buf: &mut Buf, pattern: &'a Pattern<'a>, body: &'a Expr<'a>, indent: u16) {
|
pub fn fmt_body<'a>(buf: &mut Buf, pattern: &'a Pattern<'a>, body: &'a Expr<'a>, indent: u16) {
|
||||||
// Check if this is an assignment into the unit value
|
// Check if this is an assignment into the unit value
|
||||||
let is_unit_assignment = if let Pattern::RecordDestructure(collection) = pattern {
|
let is_unit_assignment = if let Pattern::RecordDestructure(collection) = pattern {
|
||||||
|
|
|
@ -801,7 +801,7 @@ pub enum ValueDef<'a> {
|
||||||
AnnotatedBody {
|
AnnotatedBody {
|
||||||
ann_pattern: &'a Loc<Pattern<'a>>,
|
ann_pattern: &'a Loc<Pattern<'a>>,
|
||||||
ann_type: &'a Loc<TypeAnnotation<'a>>,
|
ann_type: &'a Loc<TypeAnnotation<'a>>,
|
||||||
comment: Option<&'a str>,
|
lines_between: &'a [CommentOrNewline<'a>],
|
||||||
body_pattern: &'a Loc<Pattern<'a>>,
|
body_pattern: &'a Loc<Pattern<'a>>,
|
||||||
body_expr: &'a Loc<Expr<'a>>,
|
body_expr: &'a Loc<Expr<'a>>,
|
||||||
},
|
},
|
||||||
|
@ -1044,7 +1044,7 @@ impl<'a, 'b> Iterator for RecursiveValueDefIter<'a, 'b> {
|
||||||
ValueDef::AnnotatedBody {
|
ValueDef::AnnotatedBody {
|
||||||
ann_pattern: _,
|
ann_pattern: _,
|
||||||
ann_type: _,
|
ann_type: _,
|
||||||
comment: _,
|
lines_between: _,
|
||||||
body_pattern: _,
|
body_pattern: _,
|
||||||
body_expr,
|
body_expr,
|
||||||
} => self.push_pending_from_expr(&body_expr.value),
|
} => self.push_pending_from_expr(&body_expr.value),
|
||||||
|
@ -2726,7 +2726,7 @@ impl<'a> Malformed for ValueDef<'a> {
|
||||||
ValueDef::AnnotatedBody {
|
ValueDef::AnnotatedBody {
|
||||||
ann_pattern,
|
ann_pattern,
|
||||||
ann_type,
|
ann_type,
|
||||||
comment: _,
|
lines_between: _,
|
||||||
body_pattern,
|
body_pattern,
|
||||||
body_expr,
|
body_expr,
|
||||||
} => {
|
} => {
|
||||||
|
|
|
@ -3166,9 +3166,7 @@ fn stmts_to_defs<'a>(
|
||||||
let value_def = ValueDef::AnnotatedBody {
|
let value_def = ValueDef::AnnotatedBody {
|
||||||
ann_pattern: arena.alloc(ann_pattern),
|
ann_pattern: arena.alloc(ann_pattern),
|
||||||
ann_type: arena.alloc(ann_type),
|
ann_type: arena.alloc(ann_type),
|
||||||
comment: spaces_middle
|
lines_between: spaces_middle,
|
||||||
.first() // TODO: Why do we drop all but the first comment????
|
|
||||||
.and_then(crate::ast::CommentOrNewline::comment_str),
|
|
||||||
body_pattern: loc_pattern,
|
body_pattern: loc_pattern,
|
||||||
body_expr: loc_def_expr,
|
body_expr: loc_def_expr,
|
||||||
};
|
};
|
||||||
|
@ -3213,9 +3211,7 @@ pub fn join_alias_to_body<'a>(
|
||||||
ValueDef::AnnotatedBody {
|
ValueDef::AnnotatedBody {
|
||||||
ann_pattern: arena.alloc(loc_ann_pattern),
|
ann_pattern: arena.alloc(loc_ann_pattern),
|
||||||
ann_type: arena.alloc(ann_type),
|
ann_type: arena.alloc(ann_type),
|
||||||
comment: spaces_middle
|
lines_between: spaces_middle,
|
||||||
.first() // TODO: Why do we drop all but the first comment????
|
|
||||||
.and_then(crate::ast::CommentOrNewline::comment_str),
|
|
||||||
body_pattern,
|
body_pattern,
|
||||||
body_expr,
|
body_expr,
|
||||||
}
|
}
|
||||||
|
|
|
@ -397,13 +397,13 @@ impl<'a> RemoveSpaces<'a> for ValueDef<'a> {
|
||||||
AnnotatedBody {
|
AnnotatedBody {
|
||||||
ann_pattern,
|
ann_pattern,
|
||||||
ann_type,
|
ann_type,
|
||||||
comment: _,
|
lines_between: _,
|
||||||
body_pattern,
|
body_pattern,
|
||||||
body_expr,
|
body_expr,
|
||||||
} => AnnotatedBody {
|
} => AnnotatedBody {
|
||||||
ann_pattern: arena.alloc(ann_pattern.remove_spaces(arena)),
|
ann_pattern: arena.alloc(ann_pattern.remove_spaces(arena)),
|
||||||
ann_type: arena.alloc(ann_type.remove_spaces(arena)),
|
ann_type: arena.alloc(ann_type.remove_spaces(arena)),
|
||||||
comment: None,
|
lines_between: &[],
|
||||||
body_pattern: arena.alloc(body_pattern.remove_spaces(arena)),
|
body_pattern: arena.alloc(body_pattern.remove_spaces(arena)),
|
||||||
body_expr: arena.alloc(body_expr.remove_spaces(arena)),
|
body_expr: arena.alloc(body_expr.remove_spaces(arena)),
|
||||||
},
|
},
|
||||||
|
|
|
@ -38,7 +38,9 @@ Defs(
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @28-31 Identifier {
|
body_pattern: @28-31 Identifier {
|
||||||
ident: "foo",
|
ident: "foo",
|
||||||
},
|
},
|
||||||
|
|
|
@ -40,7 +40,9 @@ Defs(
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @29-32 Identifier {
|
body_pattern: @29-32 Identifier {
|
||||||
ident: "foo",
|
ident: "foo",
|
||||||
},
|
},
|
||||||
|
|
|
@ -32,7 +32,9 @@ SpaceAfter(
|
||||||
"Foo",
|
"Foo",
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @15-23 RecordDestructure(
|
body_pattern: @15-23 RecordDestructure(
|
||||||
[
|
[
|
||||||
@17-18 Identifier {
|
@17-18 Identifier {
|
||||||
|
|
|
@ -42,7 +42,9 @@ SpaceAfter(
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @26-34 Apply(
|
body_pattern: @26-34 Apply(
|
||||||
@26-32 Tag(
|
@26-32 Tag(
|
||||||
"UserId",
|
"UserId",
|
||||||
|
|
|
@ -32,7 +32,9 @@ SpaceAfter(
|
||||||
"Foo",
|
"Foo",
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @15-23 Tuple(
|
body_pattern: @15-23 Tuple(
|
||||||
[
|
[
|
||||||
@17-18 Identifier {
|
@17-18 Identifier {
|
||||||
|
|
|
@ -62,7 +62,9 @@ Defs {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @30-34 Identifier {
|
body_pattern: @30-34 Identifier {
|
||||||
ident: "html",
|
ident: "html",
|
||||||
},
|
},
|
||||||
|
@ -166,7 +168,9 @@ Defs {
|
||||||
],
|
],
|
||||||
ext: None,
|
ext: None,
|
||||||
},
|
},
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @190-196 Identifier {
|
body_pattern: @190-196 Identifier {
|
||||||
ident: "actual",
|
ident: "actual",
|
||||||
},
|
},
|
||||||
|
@ -246,7 +250,9 @@ Defs {
|
||||||
],
|
],
|
||||||
ext: None,
|
ext: None,
|
||||||
},
|
},
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @326-334 Identifier {
|
body_pattern: @326-334 Identifier {
|
||||||
ident: "expected",
|
ident: "expected",
|
||||||
},
|
},
|
||||||
|
|
|
@ -52,7 +52,9 @@ Defs(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @45-50 Identifier {
|
body_pattern: @45-50 Identifier {
|
||||||
ident: "table",
|
ident: "table",
|
||||||
},
|
},
|
||||||
|
|
|
@ -52,7 +52,9 @@ SpaceAfter(
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @21-22 Identifier {
|
body_pattern: @21-22 Identifier {
|
||||||
ident: "f",
|
ident: "f",
|
||||||
},
|
},
|
||||||
|
|
|
@ -44,7 +44,9 @@ SpaceAfter(
|
||||||
ext: None,
|
ext: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @22-23 Identifier {
|
body_pattern: @22-23 Identifier {
|
||||||
ident: "f",
|
ident: "f",
|
||||||
},
|
},
|
||||||
|
|
|
@ -57,7 +57,9 @@ Defs {
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @43-55 Identifier {
|
body_pattern: @43-55 Identifier {
|
||||||
ident: "wrappedNotEq",
|
ident: "wrappedNotEq",
|
||||||
},
|
},
|
||||||
|
|
|
@ -53,7 +53,9 @@ Defs(
|
||||||
ext: None,
|
ext: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @28-29 Identifier {
|
body_pattern: @28-29 Identifier {
|
||||||
ident: "f",
|
ident: "f",
|
||||||
},
|
},
|
||||||
|
|
|
@ -61,7 +61,9 @@ Defs(
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @30-31 Identifier {
|
body_pattern: @30-31 Identifier {
|
||||||
ident: "f",
|
ident: "f",
|
||||||
},
|
},
|
||||||
|
|
|
@ -24,7 +24,9 @@ Defs(
|
||||||
"Int",
|
"Int",
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @10-13 Identifier {
|
body_pattern: @10-13 Identifier {
|
||||||
ident: "foo",
|
ident: "foo",
|
||||||
},
|
},
|
||||||
|
|
|
@ -38,7 +38,9 @@ Defs(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @25-28 Identifier {
|
body_pattern: @25-28 Identifier {
|
||||||
ident: "foo",
|
ident: "foo",
|
||||||
},
|
},
|
||||||
|
|
|
@ -34,7 +34,9 @@ SpaceAfter(
|
||||||
],
|
],
|
||||||
ext: None,
|
ext: None,
|
||||||
},
|
},
|
||||||
comment: None,
|
lines_between: [
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
body_pattern: @21-26 Identifier {
|
body_pattern: @21-26 Identifier {
|
||||||
ident: "where",
|
ident: "where",
|
||||||
},
|
},
|
||||||
|
|
|
@ -6231,13 +6231,108 @@ mod test_fmt {
|
||||||
[first as last]
|
[first as last]
|
||||||
| [first, last] ->
|
| [first, last] ->
|
||||||
first
|
first
|
||||||
|
|
||||||
_ -> Not
|
_ -> Not
|
||||||
"
|
"
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn preserve_annotated_body() {
|
||||||
|
expr_formats_same(indoc!(
|
||||||
|
r"
|
||||||
|
x : i32
|
||||||
|
x = 1
|
||||||
|
x
|
||||||
|
"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn preserve_annotated_body_comment() {
|
||||||
|
expr_formats_same(indoc!(
|
||||||
|
r"
|
||||||
|
x : i32 # comment
|
||||||
|
x = 1
|
||||||
|
x
|
||||||
|
"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn preserve_annotated_body_comments() {
|
||||||
|
expr_formats_same(indoc!(
|
||||||
|
r"
|
||||||
|
x : i32
|
||||||
|
# comment
|
||||||
|
# comment 2
|
||||||
|
x = 1
|
||||||
|
x
|
||||||
|
"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn preserve_annotated_body_comments_without_newlines() {
|
||||||
|
expr_formats_to(
|
||||||
|
indoc!(
|
||||||
|
r"
|
||||||
|
x : i32
|
||||||
|
|
||||||
|
# comment
|
||||||
|
|
||||||
|
# comment 2
|
||||||
|
|
||||||
|
x = 1
|
||||||
|
x
|
||||||
|
"
|
||||||
|
),
|
||||||
|
indoc!(
|
||||||
|
r"
|
||||||
|
x : i32
|
||||||
|
# comment
|
||||||
|
# comment 2
|
||||||
|
x = 1
|
||||||
|
x
|
||||||
|
"
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn preserve_annotated_body_blank_comment() {
|
||||||
|
expr_formats_same(indoc!(
|
||||||
|
r"
|
||||||
|
x : i32
|
||||||
|
#
|
||||||
|
x = 1
|
||||||
|
x
|
||||||
|
"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn preserve_annotated_body_without_newlines() {
|
||||||
|
expr_formats_to(
|
||||||
|
indoc!(
|
||||||
|
r"
|
||||||
|
x : i32
|
||||||
|
|
||||||
|
x = 1
|
||||||
|
x
|
||||||
|
"
|
||||||
|
),
|
||||||
|
indoc!(
|
||||||
|
r"
|
||||||
|
x : i32
|
||||||
|
x = 1
|
||||||
|
x
|
||||||
|
"
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// this is a parse error atm
|
// this is a parse error atm
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn multiline_apply() {
|
// fn multiline_apply() {
|
||||||
|
|
|
@ -627,7 +627,7 @@ impl IterTokens for ValueDef<'_> {
|
||||||
ValueDef::AnnotatedBody {
|
ValueDef::AnnotatedBody {
|
||||||
ann_pattern,
|
ann_pattern,
|
||||||
ann_type,
|
ann_type,
|
||||||
comment: _,
|
lines_between: _,
|
||||||
body_pattern,
|
body_pattern,
|
||||||
body_expr,
|
body_expr,
|
||||||
} => (ann_pattern.iter_tokens(arena).into_iter())
|
} => (ann_pattern.iter_tokens(arena).into_iter())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue