2023-01-15 06:56:24 +08:00
|
|
|
#![allow(non_camel_case_types)]
|
|
|
|
#![allow(dead_code)]
|
|
|
|
#![allow(non_upper_case_globals)]
|
2023-03-05 14:54:17 +08:00
|
|
|
#![allow(clippy::bool_assert_comparison)]
|
2023-10-09 05:22:27 +08:00
|
|
|
#![allow(clippy::box_default)]
|
|
|
|
#![allow(clippy::collapsible_if)]
|
|
|
|
#![allow(clippy::comparison_chain)]
|
2023-03-05 14:54:17 +08:00
|
|
|
#![allow(clippy::derivable_impls)]
|
2023-10-09 01:08:46 +08:00
|
|
|
#![allow(clippy::field_reassign_with_default)]
|
2023-10-09 05:22:27 +08:00
|
|
|
#![allow(clippy::if_same_then_else)]
|
2023-10-09 01:08:46 +08:00
|
|
|
#![allow(clippy::manual_is_ascii_check)]
|
2023-10-09 05:22:27 +08:00
|
|
|
#![allow(clippy::mut_from_ref)]
|
2023-10-09 01:08:46 +08:00
|
|
|
#![allow(clippy::needless_return)]
|
2023-04-18 18:53:32 +08:00
|
|
|
#![allow(clippy::option_map_unit_fn)]
|
2023-04-22 02:56:15 +08:00
|
|
|
#![allow(clippy::ptr_arg)]
|
2023-10-09 05:22:27 +08:00
|
|
|
#![allow(clippy::redundant_slicing)]
|
|
|
|
#![allow(clippy::too_many_arguments)]
|
2023-10-09 01:08:46 +08:00
|
|
|
#![allow(clippy::uninlined_format_args)]
|
2023-10-09 05:22:27 +08:00
|
|
|
#![allow(clippy::unnecessary_to_owned)]
|
|
|
|
#![allow(clippy::unnecessary_unwrap)]
|
2023-01-15 06:56:24 +08:00
|
|
|
|
2023-08-20 21:48:41 +08:00
|
|
|
pub const BUILD_VERSION: &str = match option_env!("FISH_BUILD_VERSION") {
|
|
|
|
Some(v) => v,
|
|
|
|
None => git_version::git_version!(args = ["--always", "--dirty=-dirty"], fallback = "unknown"),
|
|
|
|
};
|
|
|
|
|
2023-02-26 23:34:03 +08:00
|
|
|
#[macro_use]
|
2023-02-11 20:31:42 +08:00
|
|
|
mod common;
|
2023-04-02 22:42:59 +08:00
|
|
|
|
2023-03-26 01:43:56 +08:00
|
|
|
mod abbrs;
|
Port AST to Rust
The translation is fairly direct though it adds some duplication, for example
there are multiple "match" statements that mimic function overloading.
Rust has no overloading, and we cannot have generic methods in the Node trait
(due to a Rust limitation, the error is like "cannot be made into an object")
so we include the type name in method names.
Give clients like "indent_visitor_t" a Rust companion ("IndentVisitor")
that takes care of the AST traversal while the AST consumption remains
in C++ for now. In future, "IndentVisitor" should absorb the entirety of
"indent_visitor_t". This pattern requires that "fish_indent" be exposed
includable header to the CXX bridge.
Alternatively, we could define FFI wrappers for recursive AST traversal.
Rust requires we separate the AST visitors for "mut" and "const"
scenarios. Take this opportunity to concretize both visitors:
The only client that requires mutable access is the populator. To match the
structure of the C++ populator which makes heavy use of function overloading,
we need to add a bunch of functions to the trait. Since there is no other
mutable visit, this seems acceptable.
The "const" visitors never use "will_visit_fields_of()" or
"did_visit_fields_of()", so remove them (though this is debatable).
Like in the C++ implementation, the AST nodes themselves are largely defined
via macros. Union fields like "Statement" and "ArgumentOrRedirection"
do currently not use macros but may in future.
This commit also introduces a precedent for a type that is defined in one
CXX bridge and used in another one - "ParseErrorList". To make this work
we need to manually define "ExternType".
There is one annoyance with CXX: functions that take explicit lifetime
parameters require to be marked as unsafe. This makes little sense
because functions that return `&Foo` with implicit lifetime can be
misused the same way on the C++ side.
One notable change is that we cannot directly port "find_block_open_keyword()"
(which is used to compute an error) because it relies on the stack of visited
nodes. We cannot modify a stack of node references while we do the "mut"
walk. Happily, an idiomatic solution is easy: we can tell the AST visitor
to backtrack to the parent node and create the error there.
Since "node_t::accept_base" is no longer a template we don't need the
"node_visitation_t" trampoline anymore.
The added copying at the FFI boundary makes things slower (memcpy dominates
the profile) but it's not unusable, which is good news:
$ hyperfine ./fish.{old,new}" -c 'source ../share/completions/git.fish'"
Benchmark 1: ./fish.old -c 'source ../share/completions/git.fish'
Time (mean ± σ): 195.5 ms ± 2.9 ms [User: 190.1 ms, System: 4.4 ms]
Range (min … max): 193.2 ms … 205.1 ms 15 runs
Benchmark 2: ./fish.new -c 'source ../share/completions/git.fish'
Time (mean ± σ): 677.5 ms ± 62.0 ms [User: 665.4 ms, System: 10.0 ms]
Range (min … max): 611.7 ms … 805.5 ms 10 runs
Summary
'./fish.old -c 'source ../share/completions/git.fish'' ran
3.47 ± 0.32 times faster than './fish.new -c 'source ../share/completions/git.fish''
Leftovers:
- Enum variants are still snakecase; I didn't get around to changing this yet.
- "ast_type_to_string()" still returns a snakecase name. This could be
changed since it's not user visible.
2023-04-02 22:42:59 +08:00
|
|
|
mod ast;
|
2023-10-09 05:22:27 +08:00
|
|
|
mod autoload;
|
2023-03-26 01:43:56 +08:00
|
|
|
mod builtins;
|
2023-02-27 04:56:50 +08:00
|
|
|
mod color;
|
2023-03-26 23:23:05 +08:00
|
|
|
mod compat;
|
2023-07-26 21:03:03 +08:00
|
|
|
mod complete;
|
2023-05-17 04:12:22 +08:00
|
|
|
mod curses;
|
2023-03-26 01:43:56 +08:00
|
|
|
mod env;
|
2023-05-17 09:51:34 +08:00
|
|
|
mod env_dispatch;
|
2023-10-09 05:22:27 +08:00
|
|
|
mod env_universal_common;
|
2023-02-12 04:31:08 +08:00
|
|
|
mod event;
|
2023-10-09 05:22:27 +08:00
|
|
|
mod exec;
|
2023-03-26 01:43:56 +08:00
|
|
|
mod expand;
|
2023-04-09 19:37:12 +08:00
|
|
|
mod fallback;
|
2023-02-18 09:21:44 +08:00
|
|
|
mod fd_monitor;
|
2023-01-15 06:56:24 +08:00
|
|
|
mod fd_readable_set;
|
|
|
|
mod fds;
|
2023-02-05 07:59:44 +08:00
|
|
|
#[allow(rustdoc::broken_intra_doc_links)]
|
|
|
|
#[allow(clippy::module_inception)]
|
|
|
|
#[allow(clippy::new_ret_no_self)]
|
|
|
|
#[allow(clippy::wrong_self_convention)]
|
2023-02-12 22:46:44 +08:00
|
|
|
#[allow(clippy::needless_lifetimes)]
|
2023-01-15 06:56:24 +08:00
|
|
|
mod ffi;
|
|
|
|
mod ffi_init;
|
2023-01-16 06:56:04 +08:00
|
|
|
mod ffi_tests;
|
2023-08-18 13:33:51 +08:00
|
|
|
mod fish;
|
Port AST to Rust
The translation is fairly direct though it adds some duplication, for example
there are multiple "match" statements that mimic function overloading.
Rust has no overloading, and we cannot have generic methods in the Node trait
(due to a Rust limitation, the error is like "cannot be made into an object")
so we include the type name in method names.
Give clients like "indent_visitor_t" a Rust companion ("IndentVisitor")
that takes care of the AST traversal while the AST consumption remains
in C++ for now. In future, "IndentVisitor" should absorb the entirety of
"indent_visitor_t". This pattern requires that "fish_indent" be exposed
includable header to the CXX bridge.
Alternatively, we could define FFI wrappers for recursive AST traversal.
Rust requires we separate the AST visitors for "mut" and "const"
scenarios. Take this opportunity to concretize both visitors:
The only client that requires mutable access is the populator. To match the
structure of the C++ populator which makes heavy use of function overloading,
we need to add a bunch of functions to the trait. Since there is no other
mutable visit, this seems acceptable.
The "const" visitors never use "will_visit_fields_of()" or
"did_visit_fields_of()", so remove them (though this is debatable).
Like in the C++ implementation, the AST nodes themselves are largely defined
via macros. Union fields like "Statement" and "ArgumentOrRedirection"
do currently not use macros but may in future.
This commit also introduces a precedent for a type that is defined in one
CXX bridge and used in another one - "ParseErrorList". To make this work
we need to manually define "ExternType".
There is one annoyance with CXX: functions that take explicit lifetime
parameters require to be marked as unsafe. This makes little sense
because functions that return `&Foo` with implicit lifetime can be
misused the same way on the C++ side.
One notable change is that we cannot directly port "find_block_open_keyword()"
(which is used to compute an error) because it relies on the stack of visited
nodes. We cannot modify a stack of node references while we do the "mut"
walk. Happily, an idiomatic solution is easy: we can tell the AST visitor
to backtrack to the parent node and create the error there.
Since "node_t::accept_base" is no longer a template we don't need the
"node_visitation_t" trampoline anymore.
The added copying at the FFI boundary makes things slower (memcpy dominates
the profile) but it's not unusable, which is good news:
$ hyperfine ./fish.{old,new}" -c 'source ../share/completions/git.fish'"
Benchmark 1: ./fish.old -c 'source ../share/completions/git.fish'
Time (mean ± σ): 195.5 ms ± 2.9 ms [User: 190.1 ms, System: 4.4 ms]
Range (min … max): 193.2 ms … 205.1 ms 15 runs
Benchmark 2: ./fish.new -c 'source ../share/completions/git.fish'
Time (mean ± σ): 677.5 ms ± 62.0 ms [User: 665.4 ms, System: 10.0 ms]
Range (min … max): 611.7 ms … 805.5 ms 10 runs
Summary
'./fish.old -c 'source ../share/completions/git.fish'' ran
3.47 ± 0.32 times faster than './fish.new -c 'source ../share/completions/git.fish''
Leftovers:
- Enum variants are still snakecase; I didn't get around to changing this yet.
- "ast_type_to_string()" still returns a snakecase name. This could be
changed since it's not user visible.
2023-04-02 22:42:59 +08:00
|
|
|
mod fish_indent;
|
2023-01-15 06:56:24 +08:00
|
|
|
mod flog;
|
2023-09-10 04:08:26 +08:00
|
|
|
mod fork_exec;
|
2023-05-14 12:05:39 +08:00
|
|
|
mod function;
|
2023-02-03 23:34:29 +08:00
|
|
|
mod future_feature_flags;
|
2023-03-28 23:59:51 +08:00
|
|
|
mod global_safety;
|
Port AST to Rust
The translation is fairly direct though it adds some duplication, for example
there are multiple "match" statements that mimic function overloading.
Rust has no overloading, and we cannot have generic methods in the Node trait
(due to a Rust limitation, the error is like "cannot be made into an object")
so we include the type name in method names.
Give clients like "indent_visitor_t" a Rust companion ("IndentVisitor")
that takes care of the AST traversal while the AST consumption remains
in C++ for now. In future, "IndentVisitor" should absorb the entirety of
"indent_visitor_t". This pattern requires that "fish_indent" be exposed
includable header to the CXX bridge.
Alternatively, we could define FFI wrappers for recursive AST traversal.
Rust requires we separate the AST visitors for "mut" and "const"
scenarios. Take this opportunity to concretize both visitors:
The only client that requires mutable access is the populator. To match the
structure of the C++ populator which makes heavy use of function overloading,
we need to add a bunch of functions to the trait. Since there is no other
mutable visit, this seems acceptable.
The "const" visitors never use "will_visit_fields_of()" or
"did_visit_fields_of()", so remove them (though this is debatable).
Like in the C++ implementation, the AST nodes themselves are largely defined
via macros. Union fields like "Statement" and "ArgumentOrRedirection"
do currently not use macros but may in future.
This commit also introduces a precedent for a type that is defined in one
CXX bridge and used in another one - "ParseErrorList". To make this work
we need to manually define "ExternType".
There is one annoyance with CXX: functions that take explicit lifetime
parameters require to be marked as unsafe. This makes little sense
because functions that return `&Foo` with implicit lifetime can be
misused the same way on the C++ side.
One notable change is that we cannot directly port "find_block_open_keyword()"
(which is used to compute an error) because it relies on the stack of visited
nodes. We cannot modify a stack of node references while we do the "mut"
walk. Happily, an idiomatic solution is easy: we can tell the AST visitor
to backtrack to the parent node and create the error there.
Since "node_t::accept_base" is no longer a template we don't need the
"node_visitation_t" trampoline anymore.
The added copying at the FFI boundary makes things slower (memcpy dominates
the profile) but it's not unusable, which is good news:
$ hyperfine ./fish.{old,new}" -c 'source ../share/completions/git.fish'"
Benchmark 1: ./fish.old -c 'source ../share/completions/git.fish'
Time (mean ± σ): 195.5 ms ± 2.9 ms [User: 190.1 ms, System: 4.4 ms]
Range (min … max): 193.2 ms … 205.1 ms 15 runs
Benchmark 2: ./fish.new -c 'source ../share/completions/git.fish'
Time (mean ± σ): 677.5 ms ± 62.0 ms [User: 665.4 ms, System: 10.0 ms]
Range (min … max): 611.7 ms … 805.5 ms 10 runs
Summary
'./fish.old -c 'source ../share/completions/git.fish'' ran
3.47 ± 0.32 times faster than './fish.new -c 'source ../share/completions/git.fish''
Leftovers:
- Enum variants are still snakecase; I didn't get around to changing this yet.
- "ast_type_to_string()" still returns a snakecase name. This could be
changed since it's not user visible.
2023-04-02 22:42:59 +08:00
|
|
|
mod highlight;
|
2023-08-18 13:01:04 +08:00
|
|
|
mod history;
|
2023-10-09 05:22:27 +08:00
|
|
|
mod input;
|
|
|
|
mod input_common;
|
2023-04-09 20:06:40 +08:00
|
|
|
mod io;
|
2023-02-26 06:42:45 +08:00
|
|
|
mod job_group;
|
2023-05-31 05:22:09 +08:00
|
|
|
mod kill;
|
2023-03-06 12:06:30 +08:00
|
|
|
mod locale;
|
2023-02-15 05:54:18 +08:00
|
|
|
mod nix;
|
2023-04-09 03:49:57 +08:00
|
|
|
mod null_terminated_array;
|
2023-04-18 18:53:32 +08:00
|
|
|
mod operation_context;
|
2023-05-17 03:46:16 +08:00
|
|
|
mod output;
|
2023-02-05 16:35:06 +08:00
|
|
|
mod parse_constants;
|
2023-10-09 05:22:27 +08:00
|
|
|
mod parse_execution;
|
Port AST to Rust
The translation is fairly direct though it adds some duplication, for example
there are multiple "match" statements that mimic function overloading.
Rust has no overloading, and we cannot have generic methods in the Node trait
(due to a Rust limitation, the error is like "cannot be made into an object")
so we include the type name in method names.
Give clients like "indent_visitor_t" a Rust companion ("IndentVisitor")
that takes care of the AST traversal while the AST consumption remains
in C++ for now. In future, "IndentVisitor" should absorb the entirety of
"indent_visitor_t". This pattern requires that "fish_indent" be exposed
includable header to the CXX bridge.
Alternatively, we could define FFI wrappers for recursive AST traversal.
Rust requires we separate the AST visitors for "mut" and "const"
scenarios. Take this opportunity to concretize both visitors:
The only client that requires mutable access is the populator. To match the
structure of the C++ populator which makes heavy use of function overloading,
we need to add a bunch of functions to the trait. Since there is no other
mutable visit, this seems acceptable.
The "const" visitors never use "will_visit_fields_of()" or
"did_visit_fields_of()", so remove them (though this is debatable).
Like in the C++ implementation, the AST nodes themselves are largely defined
via macros. Union fields like "Statement" and "ArgumentOrRedirection"
do currently not use macros but may in future.
This commit also introduces a precedent for a type that is defined in one
CXX bridge and used in another one - "ParseErrorList". To make this work
we need to manually define "ExternType".
There is one annoyance with CXX: functions that take explicit lifetime
parameters require to be marked as unsafe. This makes little sense
because functions that return `&Foo` with implicit lifetime can be
misused the same way on the C++ side.
One notable change is that we cannot directly port "find_block_open_keyword()"
(which is used to compute an error) because it relies on the stack of visited
nodes. We cannot modify a stack of node references while we do the "mut"
walk. Happily, an idiomatic solution is easy: we can tell the AST visitor
to backtrack to the parent node and create the error there.
Since "node_t::accept_base" is no longer a template we don't need the
"node_visitation_t" trampoline anymore.
The added copying at the FFI boundary makes things slower (memcpy dominates
the profile) but it's not unusable, which is good news:
$ hyperfine ./fish.{old,new}" -c 'source ../share/completions/git.fish'"
Benchmark 1: ./fish.old -c 'source ../share/completions/git.fish'
Time (mean ± σ): 195.5 ms ± 2.9 ms [User: 190.1 ms, System: 4.4 ms]
Range (min … max): 193.2 ms … 205.1 ms 15 runs
Benchmark 2: ./fish.new -c 'source ../share/completions/git.fish'
Time (mean ± σ): 677.5 ms ± 62.0 ms [User: 665.4 ms, System: 10.0 ms]
Range (min … max): 611.7 ms … 805.5 ms 10 runs
Summary
'./fish.old -c 'source ../share/completions/git.fish'' ran
3.47 ± 0.32 times faster than './fish.new -c 'source ../share/completions/git.fish''
Leftovers:
- Enum variants are still snakecase; I didn't get around to changing this yet.
- "ast_type_to_string()" still returns a snakecase name. This could be
changed since it's not user visible.
2023-04-02 22:42:59 +08:00
|
|
|
mod parse_tree;
|
|
|
|
mod parse_util;
|
2023-10-09 05:22:27 +08:00
|
|
|
mod parser;
|
2023-04-20 01:04:02 +08:00
|
|
|
mod parser_keywords;
|
2023-03-26 01:43:56 +08:00
|
|
|
mod path;
|
2023-10-09 05:22:27 +08:00
|
|
|
mod pointer;
|
2023-05-29 09:05:10 +08:00
|
|
|
mod print_help;
|
2023-10-09 05:22:27 +08:00
|
|
|
mod proc;
|
2023-03-26 01:43:56 +08:00
|
|
|
mod re;
|
2023-05-17 03:46:16 +08:00
|
|
|
mod reader;
|
2023-02-04 18:21:42 +08:00
|
|
|
mod redirection;
|
2023-01-15 06:56:24 +08:00
|
|
|
mod signal;
|
|
|
|
mod smoke;
|
2023-03-19 11:11:18 +08:00
|
|
|
mod termsize;
|
2023-02-18 09:21:44 +08:00
|
|
|
mod threads;
|
2023-02-15 05:54:18 +08:00
|
|
|
mod timer;
|
2023-04-15 19:40:38 +08:00
|
|
|
mod tinyexpr;
|
2023-02-05 16:35:06 +08:00
|
|
|
mod tokenizer;
|
2023-01-15 06:56:24 +08:00
|
|
|
mod topic_monitor;
|
2023-03-28 23:59:51 +08:00
|
|
|
mod trace;
|
2023-01-31 04:23:01 +08:00
|
|
|
mod util;
|
2023-03-14 10:23:31 +08:00
|
|
|
mod wait_handle;
|
2023-01-15 06:56:24 +08:00
|
|
|
mod wchar;
|
|
|
|
mod wchar_ext;
|
|
|
|
mod wchar_ffi;
|
2023-03-26 19:34:51 +08:00
|
|
|
mod wcstringutil;
|
2023-01-15 06:56:24 +08:00
|
|
|
mod wgetopt;
|
2023-04-09 00:26:45 +08:00
|
|
|
mod widecharwidth;
|
2023-03-26 23:23:05 +08:00
|
|
|
mod wildcard;
|
2023-01-15 08:34:49 +08:00
|
|
|
mod wutil;
|
2023-01-16 11:52:08 +08:00
|
|
|
|
2023-10-09 05:22:27 +08:00
|
|
|
#[cfg(any(test, feature = "fish-ffi-tests"))]
|
|
|
|
#[allow(unused_imports)] // Easy way to suppress warnings while we have two testing modes.
|
2023-03-05 13:49:17 +08:00
|
|
|
mod tests;
|