mirror of
https://github.com/WhatsApp/erlang-language-platform.git
synced 2025-12-23 12:26:48 +00:00
Add tree_print for a whole module
Some checks are pending
ELP CI / ci (26, 26.2.5.13, linux, 26.2, ubuntu-22.04-arm, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, true, linux-arm64) (push) Blocked by required conditions
ELP CI / ci (26, 26.2.5.13, macos, 26.2, macos-13, macos-13-x64, x86_64-apple-darwin, true, darwin-x64) (push) Blocked by required conditions
ELP CI / ci (26, 26.2.5.13, macos, 26.2, macos-latest, macos-latest-arm, aarch64-apple-darwin, true, darwin-arm64) (push) Blocked by required conditions
ELP CI / ci (26, 26.2.5.13, windows, 26.2, windows-2022, windows-2022-x64, x86_64-pc-windows-msvc, true, win32-x64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, linux, 27.3, ubuntu-22.04, ubuntu-22.04-x64, x86_64-unknown-linux-gnu, false, linux-x64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, linux, 27.3, ubuntu-22.04-arm, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, false, linux-arm64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, macos, 27.3, macos-13, macos-13-x64, x86_64-apple-darwin, false, darwin-x64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, macos, 27.3, macos-latest, macos-latest-arm, aarch64-apple-darwin, false, darwin-arm64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, windows, 27.3, windows-2022, windows-2022-x64, x86_64-pc-windows-msvc, false, win32-x64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, linux, 28, ubuntu-22.04, ubuntu-22.04-x64, x86_64-unknown-linux-gnu, false, linux-x64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, linux, 28, ubuntu-22.04-arm, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, false, linux-arm64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, macos, 28, macos-13, macos-13-x64, x86_64-apple-darwin, false, darwin-x64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, macos, 28, macos-latest, macos-latest-arm, aarch64-apple-darwin, false, darwin-arm64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, windows, 28, windows-2022, windows-2022-x64, x86_64-pc-windows-msvc, false, win32-x64) (push) Blocked by required conditions
ELP CI / edb (push) Waiting to run
ELP CI / ci (26, 26.2.5.13, linux, 26.2, ubuntu-22.04, ubuntu-22.04-x64, x86_64-unknown-linux-gnu, true, linux-x64) (push) Blocked by required conditions
Deploy Website to GitHub Pages / Deploy Website to GitHub Pages (push) Waiting to run
Some checks are pending
ELP CI / ci (26, 26.2.5.13, linux, 26.2, ubuntu-22.04-arm, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, true, linux-arm64) (push) Blocked by required conditions
ELP CI / ci (26, 26.2.5.13, macos, 26.2, macos-13, macos-13-x64, x86_64-apple-darwin, true, darwin-x64) (push) Blocked by required conditions
ELP CI / ci (26, 26.2.5.13, macos, 26.2, macos-latest, macos-latest-arm, aarch64-apple-darwin, true, darwin-arm64) (push) Blocked by required conditions
ELP CI / ci (26, 26.2.5.13, windows, 26.2, windows-2022, windows-2022-x64, x86_64-pc-windows-msvc, true, win32-x64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, linux, 27.3, ubuntu-22.04, ubuntu-22.04-x64, x86_64-unknown-linux-gnu, false, linux-x64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, linux, 27.3, ubuntu-22.04-arm, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, false, linux-arm64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, macos, 27.3, macos-13, macos-13-x64, x86_64-apple-darwin, false, darwin-x64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, macos, 27.3, macos-latest, macos-latest-arm, aarch64-apple-darwin, false, darwin-arm64) (push) Blocked by required conditions
ELP CI / ci (27, 27.3.4, windows, 27.3, windows-2022, windows-2022-x64, x86_64-pc-windows-msvc, false, win32-x64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, linux, 28, ubuntu-22.04, ubuntu-22.04-x64, x86_64-unknown-linux-gnu, false, linux-x64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, linux, 28, ubuntu-22.04-arm, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, false, linux-arm64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, macos, 28, macos-13, macos-13-x64, x86_64-apple-darwin, false, darwin-x64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, macos, 28, macos-latest, macos-latest-arm, aarch64-apple-darwin, false, darwin-arm64) (push) Blocked by required conditions
ELP CI / ci (28, 28.0.1, windows, 28, windows-2022, windows-2022-x64, x86_64-pc-windows-msvc, false, win32-x64) (push) Blocked by required conditions
ELP CI / edb (push) Waiting to run
ELP CI / ci (26, 26.2.5.13, linux, 26.2, ubuntu-22.04, ubuntu-22.04-x64, x86_64-unknown-linux-gnu, true, linux-x64) (push) Blocked by required conditions
Deploy Website to GitHub Pages / Deploy Website to GitHub Pages (push) Waiting to run
Summary: As per title. We use tree_print as a development diagnostic tool. The test runner for tree_print itself had code to tree_print an entire module via its forms. This diff extracts this code and makes it available for use elsewhere. Reviewed By: TD5 Differential Revision: D88159685 fbshipit-source-id: daf1bd1c25d22b9d9f48863b428538efe37a267c
This commit is contained in:
parent
cbe9a058cc
commit
8558c9d5dc
1 changed files with 174 additions and 52 deletions
|
|
@ -15,6 +15,8 @@ use std::fmt;
|
|||
use std::fmt::Write as _;
|
||||
use std::str;
|
||||
|
||||
use elp_base_db::FileId;
|
||||
|
||||
use super::DefineBody;
|
||||
use super::FoldBody;
|
||||
use super::RecordBody;
|
||||
|
|
@ -33,11 +35,15 @@ use crate::ComprehensionExpr;
|
|||
use crate::Define;
|
||||
use crate::Expr;
|
||||
use crate::ExprId;
|
||||
use crate::FormIdx;
|
||||
use crate::FunType;
|
||||
use crate::FunctionBody;
|
||||
use crate::FunctionClauseBody;
|
||||
use crate::FunctionDefId;
|
||||
use crate::InFile;
|
||||
use crate::ListType;
|
||||
use crate::Literal;
|
||||
use crate::PPDirective;
|
||||
use crate::Pat;
|
||||
use crate::PatId;
|
||||
use crate::Record;
|
||||
|
|
@ -50,6 +56,7 @@ use crate::TermId;
|
|||
use crate::TypeAlias;
|
||||
use crate::TypeExpr;
|
||||
use crate::TypeExprId;
|
||||
use crate::db::DefDatabase;
|
||||
use crate::db::InternDatabase;
|
||||
use crate::expr::Guards;
|
||||
use crate::expr::MaybeExpr;
|
||||
|
|
@ -332,6 +339,63 @@ pub(crate) fn print_ssr(db: &dyn InternDatabase, body: &SsrBody) -> String {
|
|||
printer.result()
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // This is used for debugging
|
||||
pub fn print_form_list(db: &dyn DefDatabase, file_id: FileId, strategy: Strategy) -> String {
|
||||
let form_list = db.file_form_list(file_id);
|
||||
let dbi: &dyn InternDatabase = db;
|
||||
form_list
|
||||
.forms()
|
||||
.iter()
|
||||
.flat_map(|&form_idx| -> Option<String> {
|
||||
match form_idx {
|
||||
FormIdx::FunctionClause(function_id) => {
|
||||
let body =
|
||||
db.function_body(InFile::new(file_id, FunctionDefId::new(function_id)));
|
||||
Some(body.tree_print(dbi, strategy))
|
||||
}
|
||||
FormIdx::TypeAlias(type_alias_id) => {
|
||||
let type_alias = &form_list[type_alias_id];
|
||||
let body = db.type_body(InFile::new(file_id, type_alias_id));
|
||||
Some(body.tree_print(dbi, type_alias))
|
||||
}
|
||||
FormIdx::Spec(spec_id) => {
|
||||
let spec = SpecOrCallback::Spec(form_list[spec_id].clone());
|
||||
let body = db.spec_body(InFile::new(file_id, spec_id));
|
||||
Some(body.tree_print(dbi, spec))
|
||||
}
|
||||
FormIdx::Callback(callback_id) => {
|
||||
let spec = SpecOrCallback::Callback(form_list[callback_id].clone());
|
||||
let body = db.callback_body(InFile::new(file_id, callback_id));
|
||||
Some(body.tree_print(dbi, spec))
|
||||
}
|
||||
FormIdx::Record(record_id) => {
|
||||
let body = db.record_body(InFile::new(file_id, record_id));
|
||||
Some(body.print(dbi, &form_list, record_id))
|
||||
}
|
||||
FormIdx::Attribute(attribute_id) => {
|
||||
let attribute = AnyAttribute::Attribute(form_list[attribute_id].clone());
|
||||
let body = db.attribute_body(InFile::new(file_id, attribute_id));
|
||||
Some(body.print(dbi, attribute))
|
||||
}
|
||||
FormIdx::CompileOption(attribute_id) => {
|
||||
let attribute = AnyAttribute::CompileOption(form_list[attribute_id].clone());
|
||||
let body = db.compile_body(InFile::new(file_id, attribute_id));
|
||||
Some(body.tree_print(dbi, attribute))
|
||||
}
|
||||
FormIdx::PPDirective(pp) => match form_list[pp] {
|
||||
PPDirective::Define(define) => {
|
||||
let body = db.define_body(InFile::new(file_id, define));
|
||||
Some(body.tree_print(dbi, &form_list[define]))
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("")
|
||||
}
|
||||
|
||||
struct Printer<'a> {
|
||||
db: &'a dyn InternDatabase,
|
||||
body: &'a FoldBody<'a>,
|
||||
|
|
@ -1523,13 +1587,8 @@ mod tests {
|
|||
use expect_test::Expect;
|
||||
use expect_test::expect;
|
||||
|
||||
use crate::AnyAttribute;
|
||||
use crate::FormIdx;
|
||||
use crate::FunctionDefId;
|
||||
use crate::InFile;
|
||||
use crate::SpecOrCallback;
|
||||
use crate::Strategy;
|
||||
use crate::db::DefDatabase;
|
||||
use crate::body::tree_print::print_form_list;
|
||||
use crate::fold::MacroStrategy;
|
||||
use crate::fold::ParenStrategy;
|
||||
use crate::test_db::TestDB;
|
||||
|
|
@ -1546,52 +1605,7 @@ mod tests {
|
|||
#[track_caller]
|
||||
fn check_with_strategy(strategy: Strategy, fixture: &str, expect: Expect) {
|
||||
let (db, file_id) = TestDB::with_single_file(fixture);
|
||||
let form_list = db.file_form_list(file_id);
|
||||
let pretty = form_list
|
||||
.forms()
|
||||
.iter()
|
||||
.flat_map(|&form_idx| -> Option<String> {
|
||||
match form_idx {
|
||||
FormIdx::FunctionClause(function_id) => {
|
||||
let body =
|
||||
db.function_body(InFile::new(file_id, FunctionDefId::new(function_id)));
|
||||
Some(body.tree_print(&db, strategy))
|
||||
}
|
||||
FormIdx::TypeAlias(type_alias_id) => {
|
||||
let type_alias = &form_list[type_alias_id];
|
||||
let body = db.type_body(InFile::new(file_id, type_alias_id));
|
||||
Some(body.tree_print(&db, type_alias))
|
||||
}
|
||||
FormIdx::Spec(spec_id) => {
|
||||
let spec = SpecOrCallback::Spec(form_list[spec_id].clone());
|
||||
let body = db.spec_body(InFile::new(file_id, spec_id));
|
||||
Some(body.tree_print(&db, spec))
|
||||
}
|
||||
FormIdx::Callback(callback_id) => {
|
||||
let spec = SpecOrCallback::Callback(form_list[callback_id].clone());
|
||||
let body = db.callback_body(InFile::new(file_id, callback_id));
|
||||
Some(body.tree_print(&db, spec))
|
||||
}
|
||||
FormIdx::Record(record_id) => {
|
||||
let body = db.record_body(InFile::new(file_id, record_id));
|
||||
Some(body.print(&db, &form_list, record_id))
|
||||
}
|
||||
FormIdx::Attribute(attribute_id) => {
|
||||
let attribute = AnyAttribute::Attribute(form_list[attribute_id].clone());
|
||||
let body = db.attribute_body(InFile::new(file_id, attribute_id));
|
||||
Some(body.print(&db, attribute))
|
||||
}
|
||||
FormIdx::CompileOption(attribute_id) => {
|
||||
let attribute =
|
||||
AnyAttribute::CompileOption(form_list[attribute_id].clone());
|
||||
let body = db.compile_body(InFile::new(file_id, attribute_id));
|
||||
Some(body.tree_print(&db, attribute))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("");
|
||||
let pretty = print_form_list(&db, file_id, strategy);
|
||||
expect.assert_eq(pretty.trim_start());
|
||||
}
|
||||
|
||||
|
|
@ -1999,6 +2013,16 @@ mod tests {
|
|||
foo() -> ?EXPR(2).
|
||||
"#,
|
||||
expect![[r#"
|
||||
-define(EXPR/1,
|
||||
Expr<2>:Expr::BinaryOp {
|
||||
lhs
|
||||
Expr<0>:Literal(Integer(1))
|
||||
rhs
|
||||
Expr<1>:Expr::Var(X)
|
||||
op
|
||||
ArithOp(Add),
|
||||
}
|
||||
).
|
||||
function: foo/0
|
||||
Clause {
|
||||
pats
|
||||
|
|
@ -3420,4 +3444,102 @@ mod tests {
|
|||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn top_level_macro() {
|
||||
// Note: we currently lower a macro as an Expr only.
|
||||
// We have special processing in lower_clause_or_macro_body
|
||||
// to deal with top level macros, at the ast level.
|
||||
check(
|
||||
r#"
|
||||
-define(FOO(X), baz() -> X).
|
||||
-define(BAR(X), {X}).
|
||||
?FOO(42).
|
||||
foo() -> ?BAR(42).
|
||||
"#,
|
||||
expect![[r#"
|
||||
-define(FOO/1,
|
||||
Expr<0>:Expr::Missing
|
||||
).
|
||||
|
||||
-define(BAR/1,
|
||||
Expr<1>:Expr::Tuple {
|
||||
Expr<0>:Expr::Var(X),
|
||||
}
|
||||
).
|
||||
function: baz/0
|
||||
Clause {
|
||||
pats
|
||||
guards
|
||||
exprs
|
||||
Expr<2>:Literal(Integer(42)),
|
||||
}.
|
||||
function: foo/0
|
||||
Clause {
|
||||
pats
|
||||
guards
|
||||
exprs
|
||||
Expr<4>:Expr::MacroCall {
|
||||
args
|
||||
Expr<3>:Literal(Integer(42)),
|
||||
macro_def
|
||||
Some(InFile { file_id: FileId(0), value: Idx::<Define>(1) })
|
||||
expansion
|
||||
Expr<2>:Expr::Tuple {
|
||||
Expr<1>:Literal(Integer(42)),
|
||||
}
|
||||
},
|
||||
}.
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn top_level_forms() {
|
||||
check(
|
||||
r#"
|
||||
-module(main).
|
||||
bug
|
||||
-compile([export_all]).
|
||||
-wild('foo').
|
||||
-type foo() :: ok.
|
||||
-spec bar() -> ok.
|
||||
bar() -> ok.
|
||||
-callback baz() -> ok.
|
||||
-record(rec, {f}).
|
||||
"#,
|
||||
expect![[r#"
|
||||
-compile(
|
||||
Term::List {
|
||||
exprs
|
||||
Literal(Atom('export_all')),
|
||||
tail
|
||||
}
|
||||
).
|
||||
|
||||
-wild(foo).
|
||||
|
||||
-type foo() :: Literal(Atom('ok')).
|
||||
|
||||
-spec bar
|
||||
() ->
|
||||
Literal(Atom('ok')).
|
||||
function: bar/0
|
||||
Clause {
|
||||
pats
|
||||
guards
|
||||
exprs
|
||||
Expr<1>:Literal(Atom('ok')),
|
||||
}.
|
||||
|
||||
-callback baz
|
||||
() ->
|
||||
Literal(Atom('ok')).
|
||||
|
||||
-record(rec, {
|
||||
f
|
||||
}).
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue