From c3d35d61d511e290a14e2b1e38bf24e5e5f6b144 Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Fri, 5 Jul 2024 14:17:16 +0200 Subject: [PATCH 01/16] Snapshot tests for scarb-doc --- Cargo.lock | 2 + Cargo.toml | 1 + extensions/scarb-doc/Cargo.toml | 2 + extensions/scarb-doc/src/types.rs | 107 ++++- .../tests/data/integration_test_data.txt | 382 ++++++++++++++++++ extensions/scarb-doc/tests/test.rs | 225 +---------- 6 files changed, 477 insertions(+), 242 deletions(-) create mode 100644 extensions/scarb-doc/tests/data/integration_test_data.txt diff --git a/Cargo.lock b/Cargo.lock index b7b543b7d..65695dd8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4727,6 +4727,8 @@ dependencies = [ "cairo-lang-syntax", "cairo-lang-utils", "clap", + "derivative", + "expect-test", "indoc", "itertools 0.12.1", "salsa", diff --git a/Cargo.toml b/Cargo.toml index 63a6313d0..7e0d646a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,6 +67,7 @@ convert_case = "0.6.0" darling = "0.20" data-encoding = "2" deno_task_shell = ">=0.13" +derivative = "2.2.0" derive_builder = ">=0.12" directories = "5" dunce = "1" diff --git a/extensions/scarb-doc/Cargo.toml b/extensions/scarb-doc/Cargo.toml index 77d333bc4..2b06b657e 100644 --- a/extensions/scarb-doc/Cargo.toml +++ b/extensions/scarb-doc/Cargo.toml @@ -20,6 +20,8 @@ cairo-lang-semantic.workspace = true cairo-lang-starknet.workspace = true cairo-lang-syntax.workspace = true cairo-lang-utils.workspace = true +derivative.workspace = true +expect-test.workspace = true itertools.workspace = true scarb-metadata = { path = "../../scarb-metadata" } scarb-ui = { path = "../../utils/scarb-ui" } diff --git a/extensions/scarb-doc/src/types.rs b/extensions/scarb-doc/src/types.rs index 84ef7e7c9..efae5cf8b 100644 --- a/extensions/scarb-doc/src/types.rs +++ b/extensions/scarb-doc/src/types.rs @@ -20,8 +20,9 @@ use cairo_lang_syntax::node::ast; use cairo_lang_syntax::node::db::SyntaxGroup; use cairo_lang_syntax::node::kind::SyntaxKind; use cairo_lang_utils::Upcast; +use derivative::Derivative; -#[derive(Clone, Debug)] +#[derive(Debug, Clone)] pub struct Crate { pub root_module: Module, } @@ -34,8 +35,10 @@ impl Crate { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct Module { + #[derivative(Debug = "ignore")] pub module_id: ModuleId, pub item_data: ItemData, @@ -54,7 +57,7 @@ pub struct Module { impl Module { pub fn new(db: &ScarbDocDatabase, module_id: ModuleId) -> Self { - // TODO: temporary before crate root module doc fetching works. + // FIXME: compiler doesn't support fetching root crate doc let item_data = match module_id { ModuleId::CrateRoot(crate_id) => ItemData { name: crate_id.name(db).to_string(), @@ -153,7 +156,8 @@ impl Module { } } -#[derive(Clone, Debug, PartialEq)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct ItemData { pub name: String, pub doc: Option, @@ -190,9 +194,12 @@ impl ItemData { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct Constant { + #[derivative(Debug = "ignore")] pub id: ConstantId, + #[derivative(Debug = "ignore")] pub node: ast::ItemConstantPtr, pub item_data: ItemData, @@ -209,9 +216,12 @@ impl Constant { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct FreeFunction { + #[derivative(Debug = "ignore")] pub id: FreeFunctionId, + #[derivative(Debug = "ignore")] pub node: ast::FunctionWithBodyPtr, pub item_data: ItemData, @@ -232,9 +242,12 @@ impl FreeFunction { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct Struct { + #[derivative(Debug = "ignore")] pub id: StructId, + #[derivative(Debug = "ignore")] pub node: ast::ItemStructPtr, pub members: Vec, @@ -269,9 +282,12 @@ impl Struct { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct Member { + #[derivative(Debug = "ignore")] pub id: MemberId, + #[derivative(Debug = "ignore")] pub node: ast::MemberPtr, pub item_data: ItemData, @@ -301,9 +317,12 @@ impl Member { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct Enum { + #[derivative(Debug = "ignore")] pub id: EnumId, + #[derivative(Debug = "ignore")] pub node: ast::ItemEnumPtr, pub variants: Vec, @@ -335,9 +354,12 @@ impl Enum { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct Variant { + #[derivative(Debug = "ignore")] pub id: VariantId, + #[derivative(Debug = "ignore")] pub node: ast::VariantPtr, pub item_data: ItemData, @@ -367,9 +389,12 @@ impl Variant { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct TypeAlias { + #[derivative(Debug = "ignore")] pub id: ModuleTypeAliasId, + #[derivative(Debug = "ignore")] pub node: ast::ItemTypeAliasPtr, pub item_data: ItemData, @@ -390,9 +415,12 @@ impl TypeAlias { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct ImplAlias { + #[derivative(Debug = "ignore")] pub id: ImplAliasId, + #[derivative(Debug = "ignore")] pub node: ast::ItemImplAliasPtr, pub item_data: ItemData, @@ -413,9 +441,12 @@ impl ImplAlias { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct Trait { + #[derivative(Debug = "ignore")] pub id: TraitId, + #[derivative(Debug = "ignore")] pub node: ast::ItemTraitPtr, pub trait_constants: Vec, @@ -457,9 +488,12 @@ impl Trait { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct TraitConstant { + #[derivative(Debug = "ignore")] pub id: TraitConstantId, + #[derivative(Debug = "ignore")] pub node: ast::TraitItemConstantPtr, pub item_data: ItemData, @@ -471,6 +505,8 @@ impl TraitConstant { Self { id, node, + // FIXME: compiler returns empty string for a signature + // FIXME: incorrect full path item_data: ItemData::new_without_signature( db, id, @@ -480,9 +516,12 @@ impl TraitConstant { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct TraitType { + #[derivative(Debug = "ignore")] pub id: TraitTypeId, + #[derivative(Debug = "ignore")] pub node: ast::TraitItemTypePtr, pub item_data: ItemData, @@ -494,6 +533,8 @@ impl TraitType { Self { id, node, + // FIXME: compiler returns empty string for a signature + // FIXME: incorrect full path item_data: ItemData::new_without_signature( db, id, @@ -503,9 +544,12 @@ impl TraitType { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct TraitFunction { + #[derivative(Debug = "ignore")] pub id: TraitFunctionId, + #[derivative(Debug = "ignore")] pub node: ast::TraitItemFunctionPtr, pub item_data: ItemData, @@ -517,14 +561,18 @@ impl TraitFunction { Self { id, node, + // FIXME: incorrect full path item_data: ItemData::new(db, id, LookupItemId::TraitItem(TraitItemId::Function(id))), } } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct Impl { + #[derivative(Debug = "ignore")] pub id: ImplDefId, + #[derivative(Debug = "ignore")] pub node: ast::ItemImplPtr, pub impl_types: Vec, @@ -566,9 +614,12 @@ impl Impl { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct ImplType { + #[derivative(Debug = "ignore")] pub id: ImplTypeDefId, + #[derivative(Debug = "ignore")] pub node: ast::ItemTypeAliasPtr, pub item_data: ItemData, @@ -580,14 +631,18 @@ impl ImplType { Self { id, node, + // FIXME: incorrect full path item_data: ItemData::new(db, id, LookupItemId::ImplItem(ImplItemId::Type(id))), } } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct ImplConstant { + #[derivative(Debug = "ignore")] pub id: ImplConstantDefId, + #[derivative(Debug = "ignore")] pub node: ast::ItemConstantPtr, pub item_data: ItemData, @@ -599,12 +654,14 @@ impl ImplConstant { Self { id, node, + // FIXME: incorrect full path item_data: ItemData::new(db, id, LookupItemId::ImplItem(ImplItemId::Constant(id))), } } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct ImplFunction { pub id: ImplFunctionId, pub node: ast::FunctionWithBodyPtr, @@ -623,9 +680,12 @@ impl ImplFunction { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct ExternType { + #[derivative(Debug = "ignore")] pub id: ExternTypeId, + #[derivative(Debug = "ignore")] pub node: ast::ItemExternTypePtr, pub item_data: ItemData, @@ -646,9 +706,12 @@ impl ExternType { } } -#[derive(Clone, Debug)] +#[derive(Derivative, Clone)] +#[derivative(Debug)] pub struct ExternFunction { + #[derivative(Debug = "ignore")] pub id: ExternFunctionId, + #[derivative(Debug = "ignore")] pub node: ast::ItemExternFunctionPtr, pub item_data: ItemData, diff --git a/extensions/scarb-doc/tests/data/integration_test_data.txt b/extensions/scarb-doc/tests/data/integration_test_data.txt new file mode 100644 index 000000000..07149cb41 --- /dev/null +++ b/extensions/scarb-doc/tests/data/integration_test_data.txt @@ -0,0 +1,382 @@ +Crate { + root_module: Module { + item_data: ItemData { + name: "hello_world", + doc: None, + signature: None, + full_path: "hello_world", + }, + submodules: [ + Module { + item_data: ItemData { + name: "tests", + doc: Some( + "Tests module\n", + ), + signature: None, + full_path: "hello_world::tests", + }, + submodules: [], + constants: [], + free_functions: [ + FreeFunction { + item_data: ItemData { + name: "it_works", + doc: Some( + "Really\nworks.\n", + ), + signature: Some( + "fn it_works()", + ), + full_path: "hello_world::tests::it_works", + }, + }, + ], + structs: [], + enums: [], + type_aliases: [], + impl_aliases: [], + traits: [], + impls: [], + extern_types: [], + extern_functions: [], + }, + ], + constants: [ + Constant { + item_data: ItemData { + name: "FOO", + doc: Some( + "FOO constant with value 42\n", + ), + signature: Some( + "const FOO: u32 = 42;", + ), + full_path: "hello_world::FOO", + }, + }, + ], + free_functions: [ + FreeFunction { + item_data: ItemData { + name: "main", + doc: Some( + "Fibonacci sequence calculator\nMain function that calculates the 16th Fibonacci number\n", + ), + signature: Some( + "fn main() -> u32", + ), + full_path: "hello_world::main", + }, + }, + FreeFunction { + item_data: ItemData { + name: "fib", + doc: Some( + "Calculate the nth Fibonacci number\n\n# Arguments\n* `n` - The index of the Fibonacci number to calculate\n", + ), + signature: Some( + "fn fib(mut n: u32) -> u32", + ), + full_path: "hello_world::fib", + }, + }, + ], + structs: [ + Struct { + members: [ + Member { + item_data: ItemData { + name: "radius", + doc: Some( + "Radius of the circle", + ), + signature: None, + full_path: "hello_world::Circle::radius", + }, + }, + ], + item_data: ItemData { + name: "Circle", + doc: Some( + "Circle struct with radius field\n", + ), + signature: None, + full_path: "hello_world::Circle", + }, + }, + ], + enums: [ + Enum { + variants: [ + Variant { + item_data: ItemData { + name: "Red", + doc: Some( + "Red color", + ), + signature: None, + full_path: "hello_world::Color::Red", + }, + }, + Variant { + item_data: ItemData { + name: "Green", + doc: Some( + "Green color", + ), + signature: None, + full_path: "hello_world::Color::Green", + }, + }, + Variant { + item_data: ItemData { + name: "Blue", + doc: Some( + "Blue color", + ), + signature: None, + full_path: "hello_world::Color::Blue", + }, + }, + ], + item_data: ItemData { + name: "Color", + doc: Some( + "Color enum with Red, Green, and Blue variants\n", + ), + signature: None, + full_path: "hello_world::Color", + }, + }, + ], + type_aliases: [ + TypeAlias { + item_data: ItemData { + name: "Pair", + doc: Some( + "Pair type alias for a tuple of two u32 values\n", + ), + signature: Some( + "type Pair = (u32, u32);", + ), + full_path: "hello_world::Pair", + }, + }, + ], + impl_aliases: [], + traits: [ + Trait { + trait_constants: [ + TraitConstant { + item_data: ItemData { + name: "SHAPE_CONST", + doc: Some( + "Constant for the shape type\n", + ), + signature: None, + full_path: "Shape::SHAPE_CONST", + }, + }, + ], + trait_types: [ + TraitType { + item_data: ItemData { + name: "ShapePair", + doc: Some( + "Type alias for a pair of shapes\n", + ), + signature: None, + full_path: "Shape::ShapePair", + }, + }, + ], + trait_functions: [ + TraitFunction { + item_data: ItemData { + name: "area", + doc: Some( + "Calculate the area of the shape\n", + ), + signature: Some( + "fn area(self: T) -> u32", + ), + full_path: "Shape::area", + }, + }, + ], + item_data: ItemData { + name: "Shape", + doc: Some( + "Shape trait for objects that have an area\n", + ), + signature: Some( + "trait Shape", + ), + full_path: "hello_world::Shape", + }, + }, + ], + impls: [ + Impl { + impl_types: [ + ImplType { + item_data: ItemData { + name: "ShapePair", + doc: Some( + "Type alias for a pair of circles\n", + ), + signature: Some( + "type ShapePair = (Circle, Circle);", + ), + full_path: "CircleShape::ShapePair", + }, + }, + ], + impl_constants: [ + ImplConstant { + item_data: ItemData { + name: "SHAPE_CONST", + doc: Some( + "Shape constant\n", + ), + signature: Some( + "const SHAPE_CONST = \"xyz\";", + ), + full_path: "CircleShape::SHAPE_CONST", + }, + }, + ], + impl_functions: [ + ImplFunction { + id: ImplFunctionId( + 0, + ), + node: FunctionWithBodyPtr( + SyntaxStablePtrId( + 256, + ), + ), + item_data: ItemData { + name: "area", + doc: Some( + "Implementation of the area method for Circle\n", + ), + signature: Some( + "fn area(self: Circle) -> u32", + ), + full_path: "hello_world::CircleShape::area", + }, + }, + ], + item_data: ItemData { + name: "CircleShape", + doc: Some( + "Implementation of the Shape trait for Circle\n", + ), + signature: Some( + "impl CircleShape of Shape", + ), + full_path: "hello_world::CircleShape", + }, + }, + Impl { + impl_types: [], + impl_constants: [], + impl_functions: [], + item_data: ItemData { + name: "CircleDrop", + doc: None, + signature: Some( + "impl CircleDrop of core::traits::Drop;", + ), + full_path: "hello_world::CircleDrop", + }, + }, + Impl { + impl_types: [], + impl_constants: [], + impl_functions: [ + ImplFunction { + id: ImplFunctionId( + 1, + ), + node: FunctionWithBodyPtr( + SyntaxStablePtrId( + 310, + ), + ), + item_data: ItemData { + name: "serialize", + doc: None, + signature: Some( + "fn serialize(self: @Circle, ref output: core::array::Array)", + ), + full_path: "hello_world::CircleSerde::serialize", + }, + }, + ImplFunction { + id: ImplFunctionId( + 2, + ), + node: FunctionWithBodyPtr( + SyntaxStablePtrId( + 311, + ), + ), + item_data: ItemData { + name: "deserialize", + doc: None, + signature: Some( + "fn deserialize(ref serialized: core::array::Span) -> core::option::Option", + ), + full_path: "hello_world::CircleSerde::deserialize", + }, + }, + ], + item_data: ItemData { + name: "CircleSerde", + doc: None, + signature: Some( + "impl CircleSerde of core::serde::Serde", + ), + full_path: "hello_world::CircleSerde", + }, + }, + Impl { + impl_types: [], + impl_constants: [], + impl_functions: [ + ImplFunction { + id: ImplFunctionId( + 3, + ), + node: FunctionWithBodyPtr( + SyntaxStablePtrId( + 323, + ), + ), + item_data: ItemData { + name: "eq", + doc: None, + signature: Some( + "fn eq(lhs: @Circle, rhs: @Circle) -> bool", + ), + full_path: "hello_world::CirclePartialEq::eq", + }, + }, + ], + item_data: ItemData { + name: "CirclePartialEq", + doc: None, + signature: Some( + "impl CirclePartialEq of core::traits::PartialEq", + ), + full_path: "hello_world::CirclePartialEq", + }, + }, + ], + extern_types: [], + extern_functions: [], + }, +} diff --git a/extensions/scarb-doc/tests/test.rs b/extensions/scarb-doc/tests/test.rs index c8ea77777..c00103ded 100644 --- a/extensions/scarb-doc/tests/test.rs +++ b/extensions/scarb-doc/tests/test.rs @@ -1,7 +1,7 @@ use assert_fs::TempDir; +use expect_test::expect_file; use indoc::indoc; use std::env; -use std::iter::zip; use std::path::PathBuf; use scarb_metadata::MetadataCommand; @@ -10,7 +10,6 @@ use scarb_test_support::project_builder::ProjectBuilder; use scarb_doc::compilation::get_project_config; use scarb_doc::generate_language_elements_tree_for_package; -use scarb_doc::types::ItemData; fn scarb_bin() -> PathBuf { env::var_os("SCARB_TEST_BIN") @@ -130,224 +129,10 @@ fn integration_test() { let project_config = get_project_config(&metadata, package_metadata); - let root_module = + let crate_ = generate_language_elements_tree_for_package(package_metadata.name.clone(), project_config) - .expect("Failed to generate language elements tree") - .root_module; + .expect("Failed to generate language elements tree"); - assert_eq!( - root_module.item_data, - ItemData { - name: "hello_world".to_string(), - doc: None, // FIXME: compiler doesn't support fetching root crate doc - signature: None, - full_path: "hello_world".to_string(), - } - ); - - let tests_submodule = &root_module.submodules[0]; - assert_eq!( - tests_submodule.item_data, - ItemData { - name: "tests".to_string(), - doc: Some("Tests module\n".to_string()), - signature: None, - full_path: "hello_world::tests".to_string(), - } - ); - - let free_func_in_submodule = &tests_submodule.free_functions[0]; - assert_eq!( - free_func_in_submodule.item_data, - ItemData { - name: "it_works".to_string(), - doc: Some("Really\nworks.\n".to_string()), - signature: Some("fn it_works()".to_string()), - full_path: "hello_world::tests::it_works".to_string(), - } - ); - - let constant = &root_module.constants[0]; - assert_eq!( - constant.item_data, - ItemData { - name: "FOO".to_string(), - doc: Some("FOO constant with value 42\n".to_string()), - signature: Some("const FOO: u32 = 42;".to_string()), - full_path: "hello_world::FOO".to_string(), - } - ); - - let main_function = &root_module.free_functions[0]; - assert_eq!( - main_function.item_data, - ItemData { - name: "main".to_string(), - doc: Some("Fibonacci sequence calculator\nMain function that calculates the 16th Fibonacci number\n".to_string()), - signature: Some("fn main() -> u32".to_string()), - full_path: "hello_world::main".to_string(), - } - ); - - let fib_function = &root_module.free_functions[1]; - assert_eq!( - fib_function.item_data, - ItemData { - name: "fib".to_string(), - doc: Some("Calculate the nth Fibonacci number\n\n# Arguments\n* `n` - The index of the Fibonacci number to calculate\n".to_string()), - signature: Some("fn fib(mut n: u32) -> u32".to_string()), - full_path: "hello_world::fib".to_string(), - } - ); - - let circle_struct = &root_module.structs[0]; - - assert_eq!( - circle_struct.item_data, - ItemData { - name: "Circle".to_string(), - doc: Some("Circle struct with radius field\n".to_string()), - signature: None, - full_path: "hello_world::Circle".to_string(), - } - ); - - let radius_field = &circle_struct.members[0]; - assert_eq!( - radius_field.item_data, - ItemData { - name: "radius".to_string(), - doc: Some("Radius of the circle".to_string()), - signature: None, - full_path: "hello_world::Circle::radius".to_string(), - } - ); - - let color_enum = &root_module.enums[0]; - assert_eq!( - color_enum.item_data, - ItemData { - name: "Color".to_string(), - doc: Some("Color enum with Red, Green, and Blue variants\n".to_string()), - signature: None, - full_path: "hello_world::Color".to_string(), - } - ); - - for (variant, color_name) in zip(&color_enum.variants, ["Red", "Green", "Blue"]) { - assert_eq!( - variant.item_data, - ItemData { - name: color_name.to_string(), - doc: Some(format!("{color_name} color")), - signature: None, - full_path: format!("hello_world::Color::{color_name}"), - } - ); - } - - let pair_type_alias = &root_module.type_aliases[0]; - assert_eq!( - pair_type_alias.item_data, - ItemData { - name: "Pair".to_string(), - doc: Some("Pair type alias for a tuple of two u32 values\n".to_string()), - signature: Some("type Pair = (u32, u32);".to_string()), - full_path: "hello_world::Pair".to_string(), - } - ); - - let shape_trait = &root_module.traits[0]; - assert_eq!( - shape_trait.item_data, - ItemData { - name: "Shape".to_string(), - doc: Some("Shape trait for objects that have an area\n".to_string()), - signature: Some("trait Shape".to_string()), - full_path: "hello_world::Shape".to_string(), - } - ); - - let trait_constant = &shape_trait.trait_constants[0]; - assert_eq!( - trait_constant.item_data, - ItemData { - name: "SHAPE_CONST".to_string(), - doc: Some("Constant for the shape type\n".to_string()), - signature: None, // FIXME: compiler returns empty string here - full_path: "Shape::SHAPE_CONST".to_string(), // FIXME: incorrect path - } - ); - - let trait_type = &shape_trait.trait_types[0]; - assert_eq!( - trait_type.item_data, - ItemData { - name: "ShapePair".to_string(), - doc: Some("Type alias for a pair of shapes\n".to_string()), - signature: None, // FIXME: compiler returns empty string here - full_path: "Shape::ShapePair".to_string(), // FIXME: incorrect path - } - ); - - let trait_function = &shape_trait.trait_functions[0]; - assert_eq!( - trait_function.item_data, - ItemData { - name: "area".to_string(), - doc: Some("Calculate the area of the shape\n".to_string()), - signature: Some("fn area(self: T) -> u32".to_string()), - full_path: "Shape::area".to_string(), // FIXME: incorrect path - } - ); - - let circle_shape_impl = &root_module.impls[0]; - assert_eq!( - circle_shape_impl.item_data, - ItemData { - name: "CircleShape".to_string(), - doc: Some("Implementation of the Shape trait for Circle\n".to_string()), - signature: Some("impl CircleShape of Shape".to_string()), - full_path: "hello_world::CircleShape".to_string(), - } - ); - - let impl_func = &circle_shape_impl.impl_functions[0]; - assert_eq!( - impl_func.item_data, - ItemData { - name: "area".to_string(), - doc: Some("Implementation of the area method for Circle\n".to_string()), - signature: Some("fn area(self: Circle) -> u32".to_string()), - full_path: "hello_world::CircleShape::area".to_string(), - } - ); - - let impl_const = &circle_shape_impl.impl_constants[0]; - assert_eq!( - impl_const.item_data, - ItemData { - name: "SHAPE_CONST".to_string(), - doc: Some("Shape constant\n".to_string()), - signature: Some("const SHAPE_CONST = \"xyz\";".to_string()), - full_path: "CircleShape::SHAPE_CONST".to_string(), // FIXME: incorrect path - } - ); - - let impl_type = &circle_shape_impl.impl_types[0]; - assert_eq!( - impl_type.item_data, - ItemData { - name: "ShapePair".to_string(), - doc: Some("Type alias for a pair of circles\n".to_string()), - signature: Some("type ShapePair = (Circle, Circle);".to_string()), - full_path: "CircleShape::ShapePair".to_string(), // FIXME: incorrect path - } - ); - - assert_eq!( - root_module.impls.len(), - 4, - "Traits from derive are not present" - ); + let expected = expect_file!["./data/integration_test_data.txt"]; + expected.assert_debug_eq(&crate_); } From 4a9cf0504647c72ed8af66cce7c38955928d265d Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Fri, 5 Jul 2024 14:23:45 +0200 Subject: [PATCH 02/16] add ignore to impl --- extensions/scarb-doc/src/types.rs | 2 ++ .../tests/data/integration_test_data.txt | 32 ------------------- 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/extensions/scarb-doc/src/types.rs b/extensions/scarb-doc/src/types.rs index efae5cf8b..b3fd0885a 100644 --- a/extensions/scarb-doc/src/types.rs +++ b/extensions/scarb-doc/src/types.rs @@ -663,7 +663,9 @@ impl ImplConstant { #[derive(Derivative, Clone)] #[derivative(Debug)] pub struct ImplFunction { + #[derivative(Debug = "ignore")] pub id: ImplFunctionId, + #[derivative(Debug = "ignore")] pub node: ast::FunctionWithBodyPtr, pub item_data: ItemData, diff --git a/extensions/scarb-doc/tests/data/integration_test_data.txt b/extensions/scarb-doc/tests/data/integration_test_data.txt index 07149cb41..0a51fd9cf 100644 --- a/extensions/scarb-doc/tests/data/integration_test_data.txt +++ b/extensions/scarb-doc/tests/data/integration_test_data.txt @@ -249,14 +249,6 @@ Crate { ], impl_functions: [ ImplFunction { - id: ImplFunctionId( - 0, - ), - node: FunctionWithBodyPtr( - SyntaxStablePtrId( - 256, - ), - ), item_data: ItemData { name: "area", doc: Some( @@ -298,14 +290,6 @@ Crate { impl_constants: [], impl_functions: [ ImplFunction { - id: ImplFunctionId( - 1, - ), - node: FunctionWithBodyPtr( - SyntaxStablePtrId( - 310, - ), - ), item_data: ItemData { name: "serialize", doc: None, @@ -316,14 +300,6 @@ Crate { }, }, ImplFunction { - id: ImplFunctionId( - 2, - ), - node: FunctionWithBodyPtr( - SyntaxStablePtrId( - 311, - ), - ), item_data: ItemData { name: "deserialize", doc: None, @@ -348,14 +324,6 @@ Crate { impl_constants: [], impl_functions: [ ImplFunction { - id: ImplFunctionId( - 3, - ), - node: FunctionWithBodyPtr( - SyntaxStablePtrId( - 323, - ), - ), item_data: ItemData { name: "eq", doc: None, From 8753f3c6eb791cdf4124b51ada31ddd9228af2a3 Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Fri, 5 Jul 2024 14:37:20 +0200 Subject: [PATCH 03/16] doc --- extensions/scarb-doc/tests/test.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/scarb-doc/tests/test.rs b/extensions/scarb-doc/tests/test.rs index c00103ded..ec77c55c9 100644 --- a/extensions/scarb-doc/tests/test.rs +++ b/extensions/scarb-doc/tests/test.rs @@ -17,6 +17,7 @@ fn scarb_bin() -> PathBuf { .unwrap_or_else(|| cargo_bin("scarb")) } +// Run `UPDATE_EXPECT=1 cargo test` to fix this test. #[test] fn integration_test() { let t = TempDir::new().unwrap(); From e0b2a23d59b1559b844a009df999623ca85a753f Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Fri, 5 Jul 2024 23:47:49 +0200 Subject: [PATCH 04/16] move to serde --- extensions/scarb-doc/Cargo.toml | 2 +- extensions/scarb-doc/src/types.rs | 141 +++---- .../tests/data/integration_test_data.json | 276 ++++++++++++++ .../tests/data/integration_test_data.txt | 350 ------------------ extensions/scarb-doc/tests/test.rs | 6 +- 5 files changed, 342 insertions(+), 433 deletions(-) create mode 100644 extensions/scarb-doc/tests/data/integration_test_data.json delete mode 100644 extensions/scarb-doc/tests/data/integration_test_data.txt diff --git a/extensions/scarb-doc/Cargo.toml b/extensions/scarb-doc/Cargo.toml index 2b06b657e..3be369c66 100644 --- a/extensions/scarb-doc/Cargo.toml +++ b/extensions/scarb-doc/Cargo.toml @@ -20,11 +20,11 @@ cairo-lang-semantic.workspace = true cairo-lang-starknet.workspace = true cairo-lang-syntax.workspace = true cairo-lang-utils.workspace = true -derivative.workspace = true expect-test.workspace = true itertools.workspace = true scarb-metadata = { path = "../../scarb-metadata" } scarb-ui = { path = "../../utils/scarb-ui" } +serde.workspace = true serde_json.workspace = true salsa.workspace = true smol_str.workspace = true diff --git a/extensions/scarb-doc/src/types.rs b/extensions/scarb-doc/src/types.rs index b3fd0885a..0547f1d3e 100644 --- a/extensions/scarb-doc/src/types.rs +++ b/extensions/scarb-doc/src/types.rs @@ -2,8 +2,8 @@ #![allow(dead_code)] use itertools::Itertools; +use serde::Serialize; -use crate::db::ScarbDocDatabase; use cairo_lang_defs::db::DefsGroup; use cairo_lang_defs::diagnostic_utils::StableLocation; use cairo_lang_defs::ids::{ @@ -20,9 +20,10 @@ use cairo_lang_syntax::node::ast; use cairo_lang_syntax::node::db::SyntaxGroup; use cairo_lang_syntax::node::kind::SyntaxKind; use cairo_lang_utils::Upcast; -use derivative::Derivative; -#[derive(Debug, Clone)] +use crate::db::ScarbDocDatabase; + +#[derive(Serialize, Clone)] pub struct Crate { pub root_module: Module, } @@ -35,10 +36,9 @@ impl Crate { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct Module { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub module_id: ModuleId, pub item_data: ItemData, @@ -156,8 +156,7 @@ impl Module { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct ItemData { pub name: String, pub doc: Option, @@ -194,12 +193,11 @@ impl ItemData { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct Constant { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: ConstantId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::ItemConstantPtr, pub item_data: ItemData, @@ -216,12 +214,11 @@ impl Constant { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct FreeFunction { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: FreeFunctionId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::FunctionWithBodyPtr, pub item_data: ItemData, @@ -242,12 +239,11 @@ impl FreeFunction { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct Struct { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: StructId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::ItemStructPtr, pub members: Vec, @@ -282,12 +278,11 @@ impl Struct { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct Member { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: MemberId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::MemberPtr, pub item_data: ItemData, @@ -317,12 +312,11 @@ impl Member { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct Enum { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: EnumId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::ItemEnumPtr, pub variants: Vec, @@ -354,12 +348,11 @@ impl Enum { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct Variant { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: VariantId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::VariantPtr, pub item_data: ItemData, @@ -389,12 +382,11 @@ impl Variant { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct TypeAlias { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: ModuleTypeAliasId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::ItemTypeAliasPtr, pub item_data: ItemData, @@ -415,12 +407,11 @@ impl TypeAlias { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct ImplAlias { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: ImplAliasId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::ItemImplAliasPtr, pub item_data: ItemData, @@ -441,12 +432,11 @@ impl ImplAlias { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct Trait { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: TraitId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::ItemTraitPtr, pub trait_constants: Vec, @@ -488,12 +478,11 @@ impl Trait { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct TraitConstant { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: TraitConstantId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::TraitItemConstantPtr, pub item_data: ItemData, @@ -516,12 +505,11 @@ impl TraitConstant { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct TraitType { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: TraitTypeId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::TraitItemTypePtr, pub item_data: ItemData, @@ -544,12 +532,11 @@ impl TraitType { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct TraitFunction { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: TraitFunctionId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::TraitItemFunctionPtr, pub item_data: ItemData, @@ -567,12 +554,11 @@ impl TraitFunction { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct Impl { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: ImplDefId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::ItemImplPtr, pub impl_types: Vec, @@ -614,12 +600,11 @@ impl Impl { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct ImplType { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: ImplTypeDefId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::ItemTypeAliasPtr, pub item_data: ItemData, @@ -637,12 +622,11 @@ impl ImplType { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct ImplConstant { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: ImplConstantDefId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::ItemConstantPtr, pub item_data: ItemData, @@ -660,12 +644,11 @@ impl ImplConstant { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct ImplFunction { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: ImplFunctionId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::FunctionWithBodyPtr, pub item_data: ItemData, @@ -682,12 +665,11 @@ impl ImplFunction { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct ExternType { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: ExternTypeId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::ItemExternTypePtr, pub item_data: ItemData, @@ -708,12 +690,11 @@ impl ExternType { } } -#[derive(Derivative, Clone)] -#[derivative(Debug)] +#[derive(Serialize, Clone)] pub struct ExternFunction { - #[derivative(Debug = "ignore")] + #[serde(skip)] pub id: ExternFunctionId, - #[derivative(Debug = "ignore")] + #[serde(skip)] pub node: ast::ItemExternFunctionPtr, pub item_data: ItemData, diff --git a/extensions/scarb-doc/tests/data/integration_test_data.json b/extensions/scarb-doc/tests/data/integration_test_data.json new file mode 100644 index 000000000..39520be19 --- /dev/null +++ b/extensions/scarb-doc/tests/data/integration_test_data.json @@ -0,0 +1,276 @@ +{ + "root_module": { + "item_data": { + "name": "hello_world", + "doc": null, + "signature": null, + "full_path": "hello_world" + }, + "submodules": [ + { + "item_data": { + "name": "tests", + "doc": "Tests module\n", + "signature": null, + "full_path": "hello_world::tests" + }, + "submodules": [], + "constants": [], + "free_functions": [ + { + "item_data": { + "name": "it_works", + "doc": "Really\nworks.\n", + "signature": "fn it_works()", + "full_path": "hello_world::tests::it_works" + } + } + ], + "structs": [], + "enums": [], + "type_aliases": [], + "impl_aliases": [], + "traits": [], + "impls": [], + "extern_types": [], + "extern_functions": [] + } + ], + "constants": [ + { + "item_data": { + "name": "FOO", + "doc": "FOO constant with value 42\n", + "signature": "const FOO: u32 = 42;", + "full_path": "hello_world::FOO" + } + } + ], + "free_functions": [ + { + "item_data": { + "name": "main", + "doc": "Fibonacci sequence calculator\nMain function that calculates the 16th Fibonacci number\n", + "signature": "fn main() -> u32", + "full_path": "hello_world::main" + } + }, + { + "item_data": { + "name": "fib", + "doc": "Calculate the nth Fibonacci number\n\n# Arguments\n* `n` - The index of the Fibonacci number to calculate\n", + "signature": "fn fib(mut n: u32) -> u32", + "full_path": "hello_world::fib" + } + } + ], + "structs": [ + { + "members": [ + { + "item_data": { + "name": "radius", + "doc": "Radius of the circle", + "signature": null, + "full_path": "hello_world::Circle::radius" + } + } + ], + "item_data": { + "name": "Circle", + "doc": "Circle struct with radius field\n", + "signature": null, + "full_path": "hello_world::Circle" + } + } + ], + "enums": [ + { + "variants": [ + { + "item_data": { + "name": "Red", + "doc": "Red color", + "signature": null, + "full_path": "hello_world::Color::Red" + } + }, + { + "item_data": { + "name": "Green", + "doc": "Green color", + "signature": null, + "full_path": "hello_world::Color::Green" + } + }, + { + "item_data": { + "name": "Blue", + "doc": "Blue color", + "signature": null, + "full_path": "hello_world::Color::Blue" + } + } + ], + "item_data": { + "name": "Color", + "doc": "Color enum with Red, Green, and Blue variants\n", + "signature": null, + "full_path": "hello_world::Color" + } + } + ], + "type_aliases": [ + { + "item_data": { + "name": "Pair", + "doc": "Pair type alias for a tuple of two u32 values\n", + "signature": "type Pair = (u32, u32);", + "full_path": "hello_world::Pair" + } + } + ], + "impl_aliases": [], + "traits": [ + { + "trait_constants": [ + { + "item_data": { + "name": "SHAPE_CONST", + "doc": "Constant for the shape type\n", + "signature": null, + "full_path": "Shape::SHAPE_CONST" + } + } + ], + "trait_types": [ + { + "item_data": { + "name": "ShapePair", + "doc": "Type alias for a pair of shapes\n", + "signature": null, + "full_path": "Shape::ShapePair" + } + } + ], + "trait_functions": [ + { + "item_data": { + "name": "area", + "doc": "Calculate the area of the shape\n", + "signature": "fn area(self: T) -> u32", + "full_path": "Shape::area" + } + } + ], + "item_data": { + "name": "Shape", + "doc": "Shape trait for objects that have an area\n", + "signature": "trait Shape", + "full_path": "hello_world::Shape" + } + } + ], + "impls": [ + { + "impl_types": [ + { + "item_data": { + "name": "ShapePair", + "doc": "Type alias for a pair of circles\n", + "signature": "type ShapePair = (Circle, Circle);", + "full_path": "CircleShape::ShapePair" + } + } + ], + "impl_constants": [ + { + "item_data": { + "name": "SHAPE_CONST", + "doc": "Shape constant\n", + "signature": "const SHAPE_CONST = \"xyz\";", + "full_path": "CircleShape::SHAPE_CONST" + } + } + ], + "impl_functions": [ + { + "item_data": { + "name": "area", + "doc": "Implementation of the area method for Circle\n", + "signature": "fn area(self: Circle) -> u32", + "full_path": "hello_world::CircleShape::area" + } + } + ], + "item_data": { + "name": "CircleShape", + "doc": "Implementation of the Shape trait for Circle\n", + "signature": "impl CircleShape of Shape", + "full_path": "hello_world::CircleShape" + } + }, + { + "impl_types": [], + "impl_constants": [], + "impl_functions": [], + "item_data": { + "name": "CircleDrop", + "doc": null, + "signature": "impl CircleDrop of core::traits::Drop;", + "full_path": "hello_world::CircleDrop" + } + }, + { + "impl_types": [], + "impl_constants": [], + "impl_functions": [ + { + "item_data": { + "name": "serialize", + "doc": null, + "signature": "fn serialize(self: @Circle, ref output: core::array::Array)", + "full_path": "hello_world::CircleSerde::serialize" + } + }, + { + "item_data": { + "name": "deserialize", + "doc": null, + "signature": "fn deserialize(ref serialized: core::array::Span) -> core::option::Option", + "full_path": "hello_world::CircleSerde::deserialize" + } + } + ], + "item_data": { + "name": "CircleSerde", + "doc": null, + "signature": "impl CircleSerde of core::serde::Serde", + "full_path": "hello_world::CircleSerde" + } + }, + { + "impl_types": [], + "impl_constants": [], + "impl_functions": [ + { + "item_data": { + "name": "eq", + "doc": null, + "signature": "fn eq(lhs: @Circle, rhs: @Circle) -> bool", + "full_path": "hello_world::CirclePartialEq::eq" + } + } + ], + "item_data": { + "name": "CirclePartialEq", + "doc": null, + "signature": "impl CirclePartialEq of core::traits::PartialEq", + "full_path": "hello_world::CirclePartialEq" + } + } + ], + "extern_types": [], + "extern_functions": [] + } +} \ No newline at end of file diff --git a/extensions/scarb-doc/tests/data/integration_test_data.txt b/extensions/scarb-doc/tests/data/integration_test_data.txt deleted file mode 100644 index 0a51fd9cf..000000000 --- a/extensions/scarb-doc/tests/data/integration_test_data.txt +++ /dev/null @@ -1,350 +0,0 @@ -Crate { - root_module: Module { - item_data: ItemData { - name: "hello_world", - doc: None, - signature: None, - full_path: "hello_world", - }, - submodules: [ - Module { - item_data: ItemData { - name: "tests", - doc: Some( - "Tests module\n", - ), - signature: None, - full_path: "hello_world::tests", - }, - submodules: [], - constants: [], - free_functions: [ - FreeFunction { - item_data: ItemData { - name: "it_works", - doc: Some( - "Really\nworks.\n", - ), - signature: Some( - "fn it_works()", - ), - full_path: "hello_world::tests::it_works", - }, - }, - ], - structs: [], - enums: [], - type_aliases: [], - impl_aliases: [], - traits: [], - impls: [], - extern_types: [], - extern_functions: [], - }, - ], - constants: [ - Constant { - item_data: ItemData { - name: "FOO", - doc: Some( - "FOO constant with value 42\n", - ), - signature: Some( - "const FOO: u32 = 42;", - ), - full_path: "hello_world::FOO", - }, - }, - ], - free_functions: [ - FreeFunction { - item_data: ItemData { - name: "main", - doc: Some( - "Fibonacci sequence calculator\nMain function that calculates the 16th Fibonacci number\n", - ), - signature: Some( - "fn main() -> u32", - ), - full_path: "hello_world::main", - }, - }, - FreeFunction { - item_data: ItemData { - name: "fib", - doc: Some( - "Calculate the nth Fibonacci number\n\n# Arguments\n* `n` - The index of the Fibonacci number to calculate\n", - ), - signature: Some( - "fn fib(mut n: u32) -> u32", - ), - full_path: "hello_world::fib", - }, - }, - ], - structs: [ - Struct { - members: [ - Member { - item_data: ItemData { - name: "radius", - doc: Some( - "Radius of the circle", - ), - signature: None, - full_path: "hello_world::Circle::radius", - }, - }, - ], - item_data: ItemData { - name: "Circle", - doc: Some( - "Circle struct with radius field\n", - ), - signature: None, - full_path: "hello_world::Circle", - }, - }, - ], - enums: [ - Enum { - variants: [ - Variant { - item_data: ItemData { - name: "Red", - doc: Some( - "Red color", - ), - signature: None, - full_path: "hello_world::Color::Red", - }, - }, - Variant { - item_data: ItemData { - name: "Green", - doc: Some( - "Green color", - ), - signature: None, - full_path: "hello_world::Color::Green", - }, - }, - Variant { - item_data: ItemData { - name: "Blue", - doc: Some( - "Blue color", - ), - signature: None, - full_path: "hello_world::Color::Blue", - }, - }, - ], - item_data: ItemData { - name: "Color", - doc: Some( - "Color enum with Red, Green, and Blue variants\n", - ), - signature: None, - full_path: "hello_world::Color", - }, - }, - ], - type_aliases: [ - TypeAlias { - item_data: ItemData { - name: "Pair", - doc: Some( - "Pair type alias for a tuple of two u32 values\n", - ), - signature: Some( - "type Pair = (u32, u32);", - ), - full_path: "hello_world::Pair", - }, - }, - ], - impl_aliases: [], - traits: [ - Trait { - trait_constants: [ - TraitConstant { - item_data: ItemData { - name: "SHAPE_CONST", - doc: Some( - "Constant for the shape type\n", - ), - signature: None, - full_path: "Shape::SHAPE_CONST", - }, - }, - ], - trait_types: [ - TraitType { - item_data: ItemData { - name: "ShapePair", - doc: Some( - "Type alias for a pair of shapes\n", - ), - signature: None, - full_path: "Shape::ShapePair", - }, - }, - ], - trait_functions: [ - TraitFunction { - item_data: ItemData { - name: "area", - doc: Some( - "Calculate the area of the shape\n", - ), - signature: Some( - "fn area(self: T) -> u32", - ), - full_path: "Shape::area", - }, - }, - ], - item_data: ItemData { - name: "Shape", - doc: Some( - "Shape trait for objects that have an area\n", - ), - signature: Some( - "trait Shape", - ), - full_path: "hello_world::Shape", - }, - }, - ], - impls: [ - Impl { - impl_types: [ - ImplType { - item_data: ItemData { - name: "ShapePair", - doc: Some( - "Type alias for a pair of circles\n", - ), - signature: Some( - "type ShapePair = (Circle, Circle);", - ), - full_path: "CircleShape::ShapePair", - }, - }, - ], - impl_constants: [ - ImplConstant { - item_data: ItemData { - name: "SHAPE_CONST", - doc: Some( - "Shape constant\n", - ), - signature: Some( - "const SHAPE_CONST = \"xyz\";", - ), - full_path: "CircleShape::SHAPE_CONST", - }, - }, - ], - impl_functions: [ - ImplFunction { - item_data: ItemData { - name: "area", - doc: Some( - "Implementation of the area method for Circle\n", - ), - signature: Some( - "fn area(self: Circle) -> u32", - ), - full_path: "hello_world::CircleShape::area", - }, - }, - ], - item_data: ItemData { - name: "CircleShape", - doc: Some( - "Implementation of the Shape trait for Circle\n", - ), - signature: Some( - "impl CircleShape of Shape", - ), - full_path: "hello_world::CircleShape", - }, - }, - Impl { - impl_types: [], - impl_constants: [], - impl_functions: [], - item_data: ItemData { - name: "CircleDrop", - doc: None, - signature: Some( - "impl CircleDrop of core::traits::Drop;", - ), - full_path: "hello_world::CircleDrop", - }, - }, - Impl { - impl_types: [], - impl_constants: [], - impl_functions: [ - ImplFunction { - item_data: ItemData { - name: "serialize", - doc: None, - signature: Some( - "fn serialize(self: @Circle, ref output: core::array::Array)", - ), - full_path: "hello_world::CircleSerde::serialize", - }, - }, - ImplFunction { - item_data: ItemData { - name: "deserialize", - doc: None, - signature: Some( - "fn deserialize(ref serialized: core::array::Span) -> core::option::Option", - ), - full_path: "hello_world::CircleSerde::deserialize", - }, - }, - ], - item_data: ItemData { - name: "CircleSerde", - doc: None, - signature: Some( - "impl CircleSerde of core::serde::Serde", - ), - full_path: "hello_world::CircleSerde", - }, - }, - Impl { - impl_types: [], - impl_constants: [], - impl_functions: [ - ImplFunction { - item_data: ItemData { - name: "eq", - doc: None, - signature: Some( - "fn eq(lhs: @Circle, rhs: @Circle) -> bool", - ), - full_path: "hello_world::CirclePartialEq::eq", - }, - }, - ], - item_data: ItemData { - name: "CirclePartialEq", - doc: None, - signature: Some( - "impl CirclePartialEq of core::traits::PartialEq", - ), - full_path: "hello_world::CirclePartialEq", - }, - }, - ], - extern_types: [], - extern_functions: [], - }, -} diff --git a/extensions/scarb-doc/tests/test.rs b/extensions/scarb-doc/tests/test.rs index ec77c55c9..6cda055a0 100644 --- a/extensions/scarb-doc/tests/test.rs +++ b/extensions/scarb-doc/tests/test.rs @@ -134,6 +134,8 @@ fn integration_test() { generate_language_elements_tree_for_package(package_metadata.name.clone(), project_config) .expect("Failed to generate language elements tree"); - let expected = expect_file!["./data/integration_test_data.txt"]; - expected.assert_debug_eq(&crate_); + let serialized_crate = serde_json::to_string_pretty(&crate_).unwrap(); + + let expected = expect_file!["./data/integration_test_data.json"]; + expected.assert_eq(&serialized_crate); } From 6860d4cd3afa54980bbf7951c2936f1d20efe10e Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Sat, 6 Jul 2024 12:42:04 +0200 Subject: [PATCH 05/16] toml --- Cargo.lock | 2 +- Cargo.toml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 65695dd8d..f26631afa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4727,7 +4727,6 @@ dependencies = [ "cairo-lang-syntax", "cairo-lang-utils", "clap", - "derivative", "expect-test", "indoc", "itertools 0.12.1", @@ -4735,6 +4734,7 @@ dependencies = [ "scarb-metadata 1.12.0", "scarb-test-support", "scarb-ui", + "serde", "serde_json", "smol_str", ] diff --git a/Cargo.toml b/Cargo.toml index 7e0d646a5..63a6313d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,7 +67,6 @@ convert_case = "0.6.0" darling = "0.20" data-encoding = "2" deno_task_shell = ">=0.13" -derivative = "2.2.0" derive_builder = ">=0.12" directories = "5" dunce = "1" From d5c6b54372e7b6810e69df08377f97dd1406565f Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Mon, 8 Jul 2024 13:42:49 +0200 Subject: [PATCH 06/16] JSON output for scarb-doc --- extensions/scarb-doc/src/main.rs | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/extensions/scarb-doc/src/main.rs b/extensions/scarb-doc/src/main.rs index d6eb45f4c..7533b6369 100644 --- a/extensions/scarb-doc/src/main.rs +++ b/extensions/scarb-doc/src/main.rs @@ -12,6 +12,13 @@ use scarb_doc::generate_language_elements_tree_for_package; struct Args { #[command(flatten)] packages_filter: PackagesFilter, + + /// Print information collected from packages to stdout in JSON format instead of generating a + /// documentation. + /// This feature may be useful if you want to generate documentation files by yourself. + /// The precise output structure is not guaranteed to be stable. + #[arg(long)] + unstable_json_output: bool, } fn main() -> Result<()> { @@ -20,10 +27,27 @@ fn main() -> Result<()> { let metadata = MetadataCommand::new().inherit_stderr().exec()?; let metadata_for_packages = args.packages_filter.match_many(&metadata)?; + let mut json_output = serde_json::Map::new(); + for package_metadata in metadata_for_packages { let project_config = get_project_config(&metadata, &package_metadata); - let _crate_ = - generate_language_elements_tree_for_package(package_metadata.name, project_config)?; + let crate_ = generate_language_elements_tree_for_package( + package_metadata.name.clone(), + project_config, + )?; + + json_output.insert( + package_metadata.name, + serde_json::to_value(crate_).expect("Failed to serialize information about a crate"), + ); + } + + if args.unstable_json_output { + println!( + "{}", + serde_json::to_string_pretty(&json_output) + .expect("Failed to serialize information about crates") + ); } Ok(()) From 15eaa86e458e83dceb3cd7638b2b87cfa11ea5ac Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Mon, 8 Jul 2024 18:15:34 +0200 Subject: [PATCH 07/16] wip --- extensions/scarb-doc/src/main.rs | 53 ++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/extensions/scarb-doc/src/main.rs b/extensions/scarb-doc/src/main.rs index 7533b6369..fc727b423 100644 --- a/extensions/scarb-doc/src/main.rs +++ b/extensions/scarb-doc/src/main.rs @@ -1,27 +1,37 @@ use anyhow::Result; use clap::Parser; use scarb_doc::compilation::get_project_config; +use std::fs; use scarb_metadata::MetadataCommand; use scarb_ui::args::PackagesFilter; use scarb_doc::generate_language_elements_tree_for_package; +#[derive(Default, Debug, Clone, clap::ValueEnum)] +enum OutputFormat { + /// Generates documentation in Markdown format. + #[default] + Markdown, + /// Saves information collected from packages in JSON format instead of generating + /// documentation. + /// This may be useful if you want to generate documentation files by yourself. + /// The precise output structure is not guaranteed to be stable. + Json, +} + #[derive(Parser, Debug)] #[command(version, about, long_about = None)] struct Args { #[command(flatten)] packages_filter: PackagesFilter, - /// Print information collected from packages to stdout in JSON format instead of generating a - /// documentation. - /// This feature may be useful if you want to generate documentation files by yourself. - /// The precise output structure is not guaranteed to be stable. - #[arg(long)] - unstable_json_output: bool, + /// Specifies a format of generated files. + #[arg(long, value_enum, default_value_t)] + output_format: OutputFormat, } -fn main() -> Result<()> { +fn main_inner() -> Result<()> { let args = Args::parse(); let metadata = MetadataCommand::new().inherit_stderr().exec()?; @@ -42,13 +52,30 @@ fn main() -> Result<()> { ); } - if args.unstable_json_output { - println!( - "{}", - serde_json::to_string_pretty(&json_output) - .expect("Failed to serialize information about crates") - ); + let output_dir = metadata + .target_dir + .unwrap_or_else(|| metadata.workspace.root.join("target")) + .join("doc"); + + match args.output_format { + OutputFormat::Json => { + let output = serde_json::to_string_pretty(&json_output) + .expect("Failed to serialize information about crates"); + fs::write(output_dir, output)?; + } + OutputFormat::Markdown => todo!("#1424"), } Ok(()) } + +fn main() { + match main_inner() { + Ok(()) => {} + Err(error) => { + scarb_ui::Ui::new(scarb_ui::Verbosity::Normal, scarb_ui::OutputFormat::Text) + .error(error.to_string()); + std::process::exit(1); + } + } +} From 3ba4631c69a3bc845bfdd6c85a6d535168ac4a53 Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Tue, 9 Jul 2024 13:18:31 +0200 Subject: [PATCH 08/16] e2e test --- extensions/scarb-doc/src/lib.rs | 6 +- extensions/scarb-doc/src/main.rs | 18 +- .../tests/data/integration_test_data.json | 500 +++++++++--------- extensions/scarb-doc/tests/test.rs | 45 +- 4 files changed, 278 insertions(+), 291 deletions(-) diff --git a/extensions/scarb-doc/src/lib.rs b/extensions/scarb-doc/src/lib.rs index eb14edebf..adba341b1 100644 --- a/extensions/scarb-doc/src/lib.rs +++ b/extensions/scarb-doc/src/lib.rs @@ -1,5 +1,3 @@ -use anyhow::Result; - use cairo_lang_compiler::project::ProjectConfig; use cairo_lang_filesystem::db::FilesGroup; use cairo_lang_filesystem::ids::CrateLongId; @@ -14,10 +12,10 @@ pub mod types; pub fn generate_language_elements_tree_for_package( package_name: String, project_config: ProjectConfig, -) -> Result { +) -> Crate { let db = ScarbDocDatabase::new(Some(project_config)); let main_crate_id = db.intern_crate(CrateLongId::Real(package_name.into())); - Ok(Crate::new(&db, main_crate_id)) + Crate::new(&db, main_crate_id) } diff --git a/extensions/scarb-doc/src/main.rs b/extensions/scarb-doc/src/main.rs index fc727b423..971987e5d 100644 --- a/extensions/scarb-doc/src/main.rs +++ b/extensions/scarb-doc/src/main.rs @@ -1,4 +1,4 @@ -use anyhow::Result; +use anyhow::{Context, Result}; use clap::Parser; use scarb_doc::compilation::get_project_config; use std::fs; @@ -34,7 +34,10 @@ struct Args { fn main_inner() -> Result<()> { let args = Args::parse(); - let metadata = MetadataCommand::new().inherit_stderr().exec()?; + let metadata = MetadataCommand::new() + .inherit_stderr() + .exec() + .context("Metadata command failed")?; let metadata_for_packages = args.packages_filter.match_many(&metadata)?; let mut json_output = serde_json::Map::new(); @@ -44,7 +47,7 @@ fn main_inner() -> Result<()> { let crate_ = generate_language_elements_tree_for_package( package_metadata.name.clone(), project_config, - )?; + ); json_output.insert( package_metadata.name, @@ -57,11 +60,16 @@ fn main_inner() -> Result<()> { .unwrap_or_else(|| metadata.workspace.root.join("target")) .join("doc"); + fs::create_dir_all(&output_dir).context("Failed to create output directory for scarb doc")?; + match args.output_format { OutputFormat::Json => { let output = serde_json::to_string_pretty(&json_output) .expect("Failed to serialize information about crates"); - fs::write(output_dir, output)?; + let output_path = output_dir.join("output.json"); + + fs::write(output_path, output) + .context("Failed to write output of scarb doc to a file")?; } OutputFormat::Markdown => todo!("#1424"), } @@ -71,7 +79,7 @@ fn main_inner() -> Result<()> { fn main() { match main_inner() { - Ok(()) => {} + Ok(()) => std::process::exit(0), Err(error) => { scarb_ui::Ui::new(scarb_ui::Verbosity::Normal, scarb_ui::OutputFormat::Text) .error(error.to_string()); diff --git a/extensions/scarb-doc/tests/data/integration_test_data.json b/extensions/scarb-doc/tests/data/integration_test_data.json index 39520be19..450320f69 100644 --- a/extensions/scarb-doc/tests/data/integration_test_data.json +++ b/extensions/scarb-doc/tests/data/integration_test_data.json @@ -1,276 +1,278 @@ { - "root_module": { - "item_data": { - "name": "hello_world", - "doc": null, - "signature": null, - "full_path": "hello_world" - }, - "submodules": [ - { - "item_data": { - "name": "tests", - "doc": "Tests module\n", - "signature": null, - "full_path": "hello_world::tests" - }, - "submodules": [], - "constants": [], - "free_functions": [ - { - "item_data": { - "name": "it_works", - "doc": "Really\nworks.\n", - "signature": "fn it_works()", - "full_path": "hello_world::tests::it_works" - } - } - ], - "structs": [], - "enums": [], - "type_aliases": [], - "impl_aliases": [], - "traits": [], - "impls": [], - "extern_types": [], - "extern_functions": [] - } - ], - "constants": [ - { - "item_data": { - "name": "FOO", - "doc": "FOO constant with value 42\n", - "signature": "const FOO: u32 = 42;", - "full_path": "hello_world::FOO" - } - } - ], - "free_functions": [ - { - "item_data": { - "name": "main", - "doc": "Fibonacci sequence calculator\nMain function that calculates the 16th Fibonacci number\n", - "signature": "fn main() -> u32", - "full_path": "hello_world::main" - } - }, - { - "item_data": { - "name": "fib", - "doc": "Calculate the nth Fibonacci number\n\n# Arguments\n* `n` - The index of the Fibonacci number to calculate\n", - "signature": "fn fib(mut n: u32) -> u32", - "full_path": "hello_world::fib" - } - } - ], - "structs": [ - { - "members": [ - { - "item_data": { - "name": "radius", - "doc": "Radius of the circle", - "signature": null, - "full_path": "hello_world::Circle::radius" - } + "hello_world": { + "root_module": { + "constants": [ + { + "item_data": { + "doc": "FOO constant with value 42\n", + "full_path": "hello_world::FOO", + "name": "FOO", + "signature": "const FOO: u32 = 42;" } - ], - "item_data": { - "name": "Circle", - "doc": "Circle struct with radius field\n", - "signature": null, - "full_path": "hello_world::Circle" } - } - ], - "enums": [ - { - "variants": [ - { - "item_data": { - "name": "Red", - "doc": "Red color", - "signature": null, - "full_path": "hello_world::Color::Red" - } - }, - { - "item_data": { - "name": "Green", - "doc": "Green color", - "signature": null, - "full_path": "hello_world::Color::Green" - } + ], + "enums": [ + { + "item_data": { + "doc": "Color enum with Red, Green, and Blue variants\n", + "full_path": "hello_world::Color", + "name": "Color", + "signature": null }, - { - "item_data": { - "name": "Blue", - "doc": "Blue color", - "signature": null, - "full_path": "hello_world::Color::Blue" + "variants": [ + { + "item_data": { + "doc": "Red color", + "full_path": "hello_world::Color::Red", + "name": "Red", + "signature": null + } + }, + { + "item_data": { + "doc": "Green color", + "full_path": "hello_world::Color::Green", + "name": "Green", + "signature": null + } + }, + { + "item_data": { + "doc": "Blue color", + "full_path": "hello_world::Color::Blue", + "name": "Blue", + "signature": null + } } - } - ], - "item_data": { - "name": "Color", - "doc": "Color enum with Red, Green, and Blue variants\n", - "signature": null, - "full_path": "hello_world::Color" + ] } - } - ], - "type_aliases": [ - { - "item_data": { - "name": "Pair", - "doc": "Pair type alias for a tuple of two u32 values\n", - "signature": "type Pair = (u32, u32);", - "full_path": "hello_world::Pair" + ], + "extern_functions": [], + "extern_types": [], + "free_functions": [ + { + "item_data": { + "doc": "Fibonacci sequence calculator\nMain function that calculates the 16th Fibonacci number\n", + "full_path": "hello_world::main", + "name": "main", + "signature": "fn main() -> u32" + } + }, + { + "item_data": { + "doc": "Calculate the nth Fibonacci number\n\n# Arguments\n* `n` - The index of the Fibonacci number to calculate\n", + "full_path": "hello_world::fib", + "name": "fib", + "signature": "fn fib(mut n: u32) -> u32" + } } - } - ], - "impl_aliases": [], - "traits": [ - { - "trait_constants": [ - { - "item_data": { - "name": "SHAPE_CONST", - "doc": "Constant for the shape type\n", - "signature": null, - "full_path": "Shape::SHAPE_CONST" + ], + "impl_aliases": [], + "impls": [ + { + "impl_constants": [ + { + "item_data": { + "doc": "Shape constant\n", + "full_path": "CircleShape::SHAPE_CONST", + "name": "SHAPE_CONST", + "signature": "const SHAPE_CONST = \"xyz\";" + } } - } - ], - "trait_types": [ - { - "item_data": { - "name": "ShapePair", - "doc": "Type alias for a pair of shapes\n", - "signature": null, - "full_path": "Shape::ShapePair" + ], + "impl_functions": [ + { + "item_data": { + "doc": "Implementation of the area method for Circle\n", + "full_path": "hello_world::CircleShape::area", + "name": "area", + "signature": "fn area(self: Circle) -> u32" + } } - } - ], - "trait_functions": [ - { - "item_data": { - "name": "area", - "doc": "Calculate the area of the shape\n", - "signature": "fn area(self: T) -> u32", - "full_path": "Shape::area" + ], + "impl_types": [ + { + "item_data": { + "doc": "Type alias for a pair of circles\n", + "full_path": "CircleShape::ShapePair", + "name": "ShapePair", + "signature": "type ShapePair = (Circle, Circle);" + } } + ], + "item_data": { + "doc": "Implementation of the Shape trait for Circle\n", + "full_path": "hello_world::CircleShape", + "name": "CircleShape", + "signature": "impl CircleShape of Shape" } - ], - "item_data": { - "name": "Shape", - "doc": "Shape trait for objects that have an area\n", - "signature": "trait Shape", - "full_path": "hello_world::Shape" - } - } - ], - "impls": [ - { - "impl_types": [ - { - "item_data": { - "name": "ShapePair", - "doc": "Type alias for a pair of circles\n", - "signature": "type ShapePair = (Circle, Circle);", - "full_path": "CircleShape::ShapePair" - } + }, + { + "impl_constants": [], + "impl_functions": [], + "impl_types": [], + "item_data": { + "doc": null, + "full_path": "hello_world::CircleDrop", + "name": "CircleDrop", + "signature": "impl CircleDrop of core::traits::Drop;" } - ], - "impl_constants": [ - { - "item_data": { - "name": "SHAPE_CONST", - "doc": "Shape constant\n", - "signature": "const SHAPE_CONST = \"xyz\";", - "full_path": "CircleShape::SHAPE_CONST" + }, + { + "impl_constants": [], + "impl_functions": [ + { + "item_data": { + "doc": null, + "full_path": "hello_world::CircleSerde::serialize", + "name": "serialize", + "signature": "fn serialize(self: @Circle, ref output: core::array::Array)" + } + }, + { + "item_data": { + "doc": null, + "full_path": "hello_world::CircleSerde::deserialize", + "name": "deserialize", + "signature": "fn deserialize(ref serialized: core::array::Span) -> core::option::Option" + } } + ], + "impl_types": [], + "item_data": { + "doc": null, + "full_path": "hello_world::CircleSerde", + "name": "CircleSerde", + "signature": "impl CircleSerde of core::serde::Serde" } - ], - "impl_functions": [ - { - "item_data": { - "name": "area", - "doc": "Implementation of the area method for Circle\n", - "signature": "fn area(self: Circle) -> u32", - "full_path": "hello_world::CircleShape::area" + }, + { + "impl_constants": [], + "impl_functions": [ + { + "item_data": { + "doc": null, + "full_path": "hello_world::CirclePartialEq::eq", + "name": "eq", + "signature": "fn eq(lhs: @Circle, rhs: @Circle) -> bool" + } } + ], + "impl_types": [], + "item_data": { + "doc": null, + "full_path": "hello_world::CirclePartialEq", + "name": "CirclePartialEq", + "signature": "impl CirclePartialEq of core::traits::PartialEq" } - ], - "item_data": { - "name": "CircleShape", - "doc": "Implementation of the Shape trait for Circle\n", - "signature": "impl CircleShape of Shape", - "full_path": "hello_world::CircleShape" } + ], + "item_data": { + "doc": null, + "full_path": "hello_world", + "name": "hello_world", + "signature": null }, - { - "impl_types": [], - "impl_constants": [], - "impl_functions": [], - "item_data": { - "name": "CircleDrop", - "doc": null, - "signature": "impl CircleDrop of core::traits::Drop;", - "full_path": "hello_world::CircleDrop" + "structs": [ + { + "item_data": { + "doc": "Circle struct with radius field\n", + "full_path": "hello_world::Circle", + "name": "Circle", + "signature": null + }, + "members": [ + { + "item_data": { + "doc": "Radius of the circle", + "full_path": "hello_world::Circle::radius", + "name": "radius", + "signature": null + } + } + ] } - }, - { - "impl_types": [], - "impl_constants": [], - "impl_functions": [ - { - "item_data": { - "name": "serialize", - "doc": null, - "signature": "fn serialize(self: @Circle, ref output: core::array::Array)", - "full_path": "hello_world::CircleSerde::serialize" + ], + "submodules": [ + { + "constants": [], + "enums": [], + "extern_functions": [], + "extern_types": [], + "free_functions": [ + { + "item_data": { + "doc": "Really\nworks.\n", + "full_path": "hello_world::tests::it_works", + "name": "it_works", + "signature": "fn it_works()" + } } + ], + "impl_aliases": [], + "impls": [], + "item_data": { + "doc": "Tests module\n", + "full_path": "hello_world::tests", + "name": "tests", + "signature": null }, - { - "item_data": { - "name": "deserialize", - "doc": null, - "signature": "fn deserialize(ref serialized: core::array::Span) -> core::option::Option", - "full_path": "hello_world::CircleSerde::deserialize" - } - } - ], - "item_data": { - "name": "CircleSerde", - "doc": null, - "signature": "impl CircleSerde of core::serde::Serde", - "full_path": "hello_world::CircleSerde" + "structs": [], + "submodules": [], + "traits": [], + "type_aliases": [] } - }, - { - "impl_types": [], - "impl_constants": [], - "impl_functions": [ - { - "item_data": { - "name": "eq", - "doc": null, - "signature": "fn eq(lhs: @Circle, rhs: @Circle) -> bool", - "full_path": "hello_world::CirclePartialEq::eq" + ], + "traits": [ + { + "item_data": { + "doc": "Shape trait for objects that have an area\n", + "full_path": "hello_world::Shape", + "name": "Shape", + "signature": "trait Shape" + }, + "trait_constants": [ + { + "item_data": { + "doc": "Constant for the shape type\n", + "full_path": "Shape::SHAPE_CONST", + "name": "SHAPE_CONST", + "signature": null + } + } + ], + "trait_functions": [ + { + "item_data": { + "doc": "Calculate the area of the shape\n", + "full_path": "Shape::area", + "name": "area", + "signature": "fn area(self: T) -> u32" + } } + ], + "trait_types": [ + { + "item_data": { + "doc": "Type alias for a pair of shapes\n", + "full_path": "Shape::ShapePair", + "name": "ShapePair", + "signature": null + } + } + ] + } + ], + "type_aliases": [ + { + "item_data": { + "doc": "Pair type alias for a tuple of two u32 values\n", + "full_path": "hello_world::Pair", + "name": "Pair", + "signature": "type Pair = (u32, u32);" } - ], - "item_data": { - "name": "CirclePartialEq", - "doc": null, - "signature": "impl CirclePartialEq of core::traits::PartialEq", - "full_path": "hello_world::CirclePartialEq" } - } - ], - "extern_types": [], - "extern_functions": [] + ] + } } } \ No newline at end of file diff --git a/extensions/scarb-doc/tests/test.rs b/extensions/scarb-doc/tests/test.rs index 6cda055a0..e1c1fd018 100644 --- a/extensions/scarb-doc/tests/test.rs +++ b/extensions/scarb-doc/tests/test.rs @@ -1,25 +1,14 @@ use assert_fs::TempDir; use expect_test::expect_file; use indoc::indoc; -use std::env; -use std::path::PathBuf; +use std::fs; -use scarb_metadata::MetadataCommand; -use scarb_test_support::cargo::cargo_bin; +use scarb_test_support::command::Scarb; use scarb_test_support::project_builder::ProjectBuilder; -use scarb_doc::compilation::get_project_config; -use scarb_doc::generate_language_elements_tree_for_package; - -fn scarb_bin() -> PathBuf { - env::var_os("SCARB_TEST_BIN") - .map(PathBuf::from) - .unwrap_or_else(|| cargo_bin("scarb")) -} - // Run `UPDATE_EXPECT=1 cargo test` to fix this test. #[test] -fn integration_test() { +fn json_output() { let t = TempDir::new().unwrap(); ProjectBuilder::start() .name("hello_world") @@ -117,25 +106,15 @@ fn integration_test() { "#}) .build(&t); - let metadata = MetadataCommand::new() - .scarb_path(scarb_bin()) - .current_dir(t.path()) - .exec() - .expect("Failed to obtain metadata"); - let package_metadata = metadata - .packages - .iter() - .find(|pkg| pkg.id == metadata.workspace.members[0]) - .unwrap(); - - let project_config = get_project_config(&metadata, package_metadata); - - let crate_ = - generate_language_elements_tree_for_package(package_metadata.name.clone(), project_config) - .expect("Failed to generate language elements tree"); - - let serialized_crate = serde_json::to_string_pretty(&crate_).unwrap(); + Scarb::quick_snapbox() + .arg("doc") + .args(["--output-format", "json"]) + .current_dir(&t) + .assert() + .success(); + let serialized_crates = fs::read_to_string(t.path().join("target/doc/output.json")) + .expect("Failed to read from file"); let expected = expect_file!["./data/integration_test_data.json"]; - expected.assert_eq(&serialized_crate); + expected.assert_eq(&serialized_crates); } From 21100d2ffc7034aca5209656fb6a42b76d695e12 Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Tue, 9 Jul 2024 13:19:32 +0200 Subject: [PATCH 09/16] e2e test --- .../{integration_test_data.json => json_output_test_data.json} | 0 extensions/scarb-doc/tests/test.rs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename extensions/scarb-doc/tests/data/{integration_test_data.json => json_output_test_data.json} (100%) diff --git a/extensions/scarb-doc/tests/data/integration_test_data.json b/extensions/scarb-doc/tests/data/json_output_test_data.json similarity index 100% rename from extensions/scarb-doc/tests/data/integration_test_data.json rename to extensions/scarb-doc/tests/data/json_output_test_data.json diff --git a/extensions/scarb-doc/tests/test.rs b/extensions/scarb-doc/tests/test.rs index e1c1fd018..bbd7f0c35 100644 --- a/extensions/scarb-doc/tests/test.rs +++ b/extensions/scarb-doc/tests/test.rs @@ -115,6 +115,6 @@ fn json_output() { let serialized_crates = fs::read_to_string(t.path().join("target/doc/output.json")) .expect("Failed to read from file"); - let expected = expect_file!["./data/integration_test_data.json"]; + let expected = expect_file!["./data/json_output_test_data.json"]; expected.assert_eq(&serialized_crates); } From e986a22c5e2ddb8b414f13be86e25e3869368833 Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Tue, 9 Jul 2024 13:23:55 +0200 Subject: [PATCH 10/16] fix merge --- .../tests/data/integration_test_data.json | 276 ------------------ 1 file changed, 276 deletions(-) delete mode 100644 extensions/scarb-doc/tests/data/integration_test_data.json diff --git a/extensions/scarb-doc/tests/data/integration_test_data.json b/extensions/scarb-doc/tests/data/integration_test_data.json deleted file mode 100644 index 39520be19..000000000 --- a/extensions/scarb-doc/tests/data/integration_test_data.json +++ /dev/null @@ -1,276 +0,0 @@ -{ - "root_module": { - "item_data": { - "name": "hello_world", - "doc": null, - "signature": null, - "full_path": "hello_world" - }, - "submodules": [ - { - "item_data": { - "name": "tests", - "doc": "Tests module\n", - "signature": null, - "full_path": "hello_world::tests" - }, - "submodules": [], - "constants": [], - "free_functions": [ - { - "item_data": { - "name": "it_works", - "doc": "Really\nworks.\n", - "signature": "fn it_works()", - "full_path": "hello_world::tests::it_works" - } - } - ], - "structs": [], - "enums": [], - "type_aliases": [], - "impl_aliases": [], - "traits": [], - "impls": [], - "extern_types": [], - "extern_functions": [] - } - ], - "constants": [ - { - "item_data": { - "name": "FOO", - "doc": "FOO constant with value 42\n", - "signature": "const FOO: u32 = 42;", - "full_path": "hello_world::FOO" - } - } - ], - "free_functions": [ - { - "item_data": { - "name": "main", - "doc": "Fibonacci sequence calculator\nMain function that calculates the 16th Fibonacci number\n", - "signature": "fn main() -> u32", - "full_path": "hello_world::main" - } - }, - { - "item_data": { - "name": "fib", - "doc": "Calculate the nth Fibonacci number\n\n# Arguments\n* `n` - The index of the Fibonacci number to calculate\n", - "signature": "fn fib(mut n: u32) -> u32", - "full_path": "hello_world::fib" - } - } - ], - "structs": [ - { - "members": [ - { - "item_data": { - "name": "radius", - "doc": "Radius of the circle", - "signature": null, - "full_path": "hello_world::Circle::radius" - } - } - ], - "item_data": { - "name": "Circle", - "doc": "Circle struct with radius field\n", - "signature": null, - "full_path": "hello_world::Circle" - } - } - ], - "enums": [ - { - "variants": [ - { - "item_data": { - "name": "Red", - "doc": "Red color", - "signature": null, - "full_path": "hello_world::Color::Red" - } - }, - { - "item_data": { - "name": "Green", - "doc": "Green color", - "signature": null, - "full_path": "hello_world::Color::Green" - } - }, - { - "item_data": { - "name": "Blue", - "doc": "Blue color", - "signature": null, - "full_path": "hello_world::Color::Blue" - } - } - ], - "item_data": { - "name": "Color", - "doc": "Color enum with Red, Green, and Blue variants\n", - "signature": null, - "full_path": "hello_world::Color" - } - } - ], - "type_aliases": [ - { - "item_data": { - "name": "Pair", - "doc": "Pair type alias for a tuple of two u32 values\n", - "signature": "type Pair = (u32, u32);", - "full_path": "hello_world::Pair" - } - } - ], - "impl_aliases": [], - "traits": [ - { - "trait_constants": [ - { - "item_data": { - "name": "SHAPE_CONST", - "doc": "Constant for the shape type\n", - "signature": null, - "full_path": "Shape::SHAPE_CONST" - } - } - ], - "trait_types": [ - { - "item_data": { - "name": "ShapePair", - "doc": "Type alias for a pair of shapes\n", - "signature": null, - "full_path": "Shape::ShapePair" - } - } - ], - "trait_functions": [ - { - "item_data": { - "name": "area", - "doc": "Calculate the area of the shape\n", - "signature": "fn area(self: T) -> u32", - "full_path": "Shape::area" - } - } - ], - "item_data": { - "name": "Shape", - "doc": "Shape trait for objects that have an area\n", - "signature": "trait Shape", - "full_path": "hello_world::Shape" - } - } - ], - "impls": [ - { - "impl_types": [ - { - "item_data": { - "name": "ShapePair", - "doc": "Type alias for a pair of circles\n", - "signature": "type ShapePair = (Circle, Circle);", - "full_path": "CircleShape::ShapePair" - } - } - ], - "impl_constants": [ - { - "item_data": { - "name": "SHAPE_CONST", - "doc": "Shape constant\n", - "signature": "const SHAPE_CONST = \"xyz\";", - "full_path": "CircleShape::SHAPE_CONST" - } - } - ], - "impl_functions": [ - { - "item_data": { - "name": "area", - "doc": "Implementation of the area method for Circle\n", - "signature": "fn area(self: Circle) -> u32", - "full_path": "hello_world::CircleShape::area" - } - } - ], - "item_data": { - "name": "CircleShape", - "doc": "Implementation of the Shape trait for Circle\n", - "signature": "impl CircleShape of Shape", - "full_path": "hello_world::CircleShape" - } - }, - { - "impl_types": [], - "impl_constants": [], - "impl_functions": [], - "item_data": { - "name": "CircleDrop", - "doc": null, - "signature": "impl CircleDrop of core::traits::Drop;", - "full_path": "hello_world::CircleDrop" - } - }, - { - "impl_types": [], - "impl_constants": [], - "impl_functions": [ - { - "item_data": { - "name": "serialize", - "doc": null, - "signature": "fn serialize(self: @Circle, ref output: core::array::Array)", - "full_path": "hello_world::CircleSerde::serialize" - } - }, - { - "item_data": { - "name": "deserialize", - "doc": null, - "signature": "fn deserialize(ref serialized: core::array::Span) -> core::option::Option", - "full_path": "hello_world::CircleSerde::deserialize" - } - } - ], - "item_data": { - "name": "CircleSerde", - "doc": null, - "signature": "impl CircleSerde of core::serde::Serde", - "full_path": "hello_world::CircleSerde" - } - }, - { - "impl_types": [], - "impl_constants": [], - "impl_functions": [ - { - "item_data": { - "name": "eq", - "doc": null, - "signature": "fn eq(lhs: @Circle, rhs: @Circle) -> bool", - "full_path": "hello_world::CirclePartialEq::eq" - } - } - ], - "item_data": { - "name": "CirclePartialEq", - "doc": null, - "signature": "impl CirclePartialEq of core::traits::PartialEq", - "full_path": "hello_world::CirclePartialEq" - } - } - ], - "extern_types": [], - "extern_functions": [] - } -} \ No newline at end of file From 67e2e750d14ac456bbda5446ef2a2d042a89f96e Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Tue, 9 Jul 2024 13:49:50 +0200 Subject: [PATCH 11/16] lowercase messages --- extensions/scarb-doc/src/main.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/extensions/scarb-doc/src/main.rs b/extensions/scarb-doc/src/main.rs index 971987e5d..0a7faa675 100644 --- a/extensions/scarb-doc/src/main.rs +++ b/extensions/scarb-doc/src/main.rs @@ -37,7 +37,7 @@ fn main_inner() -> Result<()> { let metadata = MetadataCommand::new() .inherit_stderr() .exec() - .context("Metadata command failed")?; + .context("metadata command failed")?; let metadata_for_packages = args.packages_filter.match_many(&metadata)?; let mut json_output = serde_json::Map::new(); @@ -51,7 +51,7 @@ fn main_inner() -> Result<()> { json_output.insert( package_metadata.name, - serde_json::to_value(crate_).expect("Failed to serialize information about a crate"), + serde_json::to_value(crate_).expect("failed to serialize information about a crate"), ); } @@ -60,16 +60,16 @@ fn main_inner() -> Result<()> { .unwrap_or_else(|| metadata.workspace.root.join("target")) .join("doc"); - fs::create_dir_all(&output_dir).context("Failed to create output directory for scarb doc")?; + fs::create_dir_all(&output_dir).context("failed to create output directory for scarb doc")?; match args.output_format { OutputFormat::Json => { let output = serde_json::to_string_pretty(&json_output) - .expect("Failed to serialize information about crates"); + .expect("failed to serialize information about crates"); let output_path = output_dir.join("output.json"); fs::write(output_path, output) - .context("Failed to write output of scarb doc to a file")?; + .context("failed to write output of scarb doc to a file")?; } OutputFormat::Markdown => todo!("#1424"), } From 84fd9c7aea77c9ae441205a251723f03f70660af Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Tue, 9 Jul 2024 14:14:31 +0200 Subject: [PATCH 12/16] improve typing --- extensions/scarb-doc/src/main.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/extensions/scarb-doc/src/main.rs b/extensions/scarb-doc/src/main.rs index 0a7faa675..b219ffd00 100644 --- a/extensions/scarb-doc/src/main.rs +++ b/extensions/scarb-doc/src/main.rs @@ -1,6 +1,7 @@ use anyhow::{Context, Result}; use clap::Parser; use scarb_doc::compilation::get_project_config; +use std::collections::BTreeMap; use std::fs; use scarb_metadata::MetadataCommand; @@ -40,7 +41,7 @@ fn main_inner() -> Result<()> { .context("metadata command failed")?; let metadata_for_packages = args.packages_filter.match_many(&metadata)?; - let mut json_output = serde_json::Map::new(); + let mut package_information_map = BTreeMap::new(); for package_metadata in metadata_for_packages { let project_config = get_project_config(&metadata, &package_metadata); @@ -49,7 +50,7 @@ fn main_inner() -> Result<()> { project_config, ); - json_output.insert( + package_information_map.insert( package_metadata.name, serde_json::to_value(crate_).expect("failed to serialize information about a crate"), ); @@ -64,7 +65,7 @@ fn main_inner() -> Result<()> { match args.output_format { OutputFormat::Json => { - let output = serde_json::to_string_pretty(&json_output) + let output = serde_json::to_string_pretty(&package_information_map) .expect("failed to serialize information about crates"); let output_path = output_dir.join("output.json"); From d7afd9575c9998e2fed45a950584edb44f8ed54d Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Tue, 9 Jul 2024 15:01:32 +0200 Subject: [PATCH 13/16] add versioned output --- extensions/scarb-doc/src/lib.rs | 1 + extensions/scarb-doc/src/main.rs | 9 +- .../scarb-doc/src/versioned_json_output.rs | 22 + .../tests/data/json_output_test_data.json | 499 +++++++++--------- 4 files changed, 278 insertions(+), 253 deletions(-) create mode 100644 extensions/scarb-doc/src/versioned_json_output.rs diff --git a/extensions/scarb-doc/src/lib.rs b/extensions/scarb-doc/src/lib.rs index adba341b1..9f8eb467d 100644 --- a/extensions/scarb-doc/src/lib.rs +++ b/extensions/scarb-doc/src/lib.rs @@ -8,6 +8,7 @@ use types::Crate; pub mod compilation; pub mod db; pub mod types; +pub mod versioned_json_output; pub fn generate_language_elements_tree_for_package( package_name: String, diff --git a/extensions/scarb-doc/src/main.rs b/extensions/scarb-doc/src/main.rs index b219ffd00..7cf7dbafb 100644 --- a/extensions/scarb-doc/src/main.rs +++ b/extensions/scarb-doc/src/main.rs @@ -8,6 +8,7 @@ use scarb_metadata::MetadataCommand; use scarb_ui::args::PackagesFilter; use scarb_doc::generate_language_elements_tree_for_package; +use scarb_doc::versioned_json_output::VersionedJsonOutput; #[derive(Default, Debug, Clone, clap::ValueEnum)] enum OutputFormat { @@ -50,10 +51,7 @@ fn main_inner() -> Result<()> { project_config, ); - package_information_map.insert( - package_metadata.name, - serde_json::to_value(crate_).expect("failed to serialize information about a crate"), - ); + package_information_map.insert(package_metadata.name, crate_); } let output_dir = metadata @@ -65,7 +63,8 @@ fn main_inner() -> Result<()> { match args.output_format { OutputFormat::Json => { - let output = serde_json::to_string_pretty(&package_information_map) + let versioned_json_output = VersionedJsonOutput::new(package_information_map); + let output = serde_json::to_string_pretty(&versioned_json_output) .expect("failed to serialize information about crates"); let output_path = output_dir.join("output.json"); diff --git a/extensions/scarb-doc/src/versioned_json_output.rs b/extensions/scarb-doc/src/versioned_json_output.rs new file mode 100644 index 000000000..b624a2618 --- /dev/null +++ b/extensions/scarb-doc/src/versioned_json_output.rs @@ -0,0 +1,22 @@ +use crate::types::Crate; +use serde::Serialize; +use std::collections::BTreeMap; + +type PackageName = String; + +const FORMAT_VERSION: u8 = 1; + +#[derive(Serialize)] +pub struct VersionedJsonOutput { + pub format_version: u8, + pub package_information_map: BTreeMap, +} + +impl VersionedJsonOutput { + pub fn new(package_information_map: BTreeMap) -> Self { + Self { + format_version: FORMAT_VERSION, + package_information_map, + } + } +} diff --git a/extensions/scarb-doc/tests/data/json_output_test_data.json b/extensions/scarb-doc/tests/data/json_output_test_data.json index 450320f69..5d1c4e451 100644 --- a/extensions/scarb-doc/tests/data/json_output_test_data.json +++ b/extensions/scarb-doc/tests/data/json_output_test_data.json @@ -1,278 +1,281 @@ { - "hello_world": { - "root_module": { - "constants": [ - { - "item_data": { - "doc": "FOO constant with value 42\n", - "full_path": "hello_world::FOO", - "name": "FOO", - "signature": "const FOO: u32 = 42;" - } - } - ], - "enums": [ - { - "item_data": { - "doc": "Color enum with Red, Green, and Blue variants\n", - "full_path": "hello_world::Color", - "name": "Color", - "signature": null - }, - "variants": [ - { - "item_data": { - "doc": "Red color", - "full_path": "hello_world::Color::Red", - "name": "Red", - "signature": null - } - }, - { - "item_data": { - "doc": "Green color", - "full_path": "hello_world::Color::Green", - "name": "Green", - "signature": null - } + "format_version": 1, + "package_information_map": { + "hello_world": { + "root_module": { + "item_data": { + "name": "hello_world", + "doc": null, + "signature": null, + "full_path": "hello_world" + }, + "submodules": [ + { + "item_data": { + "name": "tests", + "doc": "Tests module\n", + "signature": null, + "full_path": "hello_world::tests" }, - { - "item_data": { - "doc": "Blue color", - "full_path": "hello_world::Color::Blue", - "name": "Blue", - "signature": null + "submodules": [], + "constants": [], + "free_functions": [ + { + "item_data": { + "name": "it_works", + "doc": "Really\nworks.\n", + "signature": "fn it_works()", + "full_path": "hello_world::tests::it_works" + } } - } - ] - } - ], - "extern_functions": [], - "extern_types": [], - "free_functions": [ - { - "item_data": { - "doc": "Fibonacci sequence calculator\nMain function that calculates the 16th Fibonacci number\n", - "full_path": "hello_world::main", - "name": "main", - "signature": "fn main() -> u32" + ], + "structs": [], + "enums": [], + "type_aliases": [], + "impl_aliases": [], + "traits": [], + "impls": [], + "extern_types": [], + "extern_functions": [] } - }, - { - "item_data": { - "doc": "Calculate the nth Fibonacci number\n\n# Arguments\n* `n` - The index of the Fibonacci number to calculate\n", - "full_path": "hello_world::fib", - "name": "fib", - "signature": "fn fib(mut n: u32) -> u32" + ], + "constants": [ + { + "item_data": { + "name": "FOO", + "doc": "FOO constant with value 42\n", + "signature": "const FOO: u32 = 42;", + "full_path": "hello_world::FOO" + } } - } - ], - "impl_aliases": [], - "impls": [ - { - "impl_constants": [ - { - "item_data": { - "doc": "Shape constant\n", - "full_path": "CircleShape::SHAPE_CONST", - "name": "SHAPE_CONST", - "signature": "const SHAPE_CONST = \"xyz\";" - } + ], + "free_functions": [ + { + "item_data": { + "name": "main", + "doc": "Fibonacci sequence calculator\nMain function that calculates the 16th Fibonacci number\n", + "signature": "fn main() -> u32", + "full_path": "hello_world::main" } - ], - "impl_functions": [ - { - "item_data": { - "doc": "Implementation of the area method for Circle\n", - "full_path": "hello_world::CircleShape::area", - "name": "area", - "signature": "fn area(self: Circle) -> u32" + }, + { + "item_data": { + "name": "fib", + "doc": "Calculate the nth Fibonacci number\n\n# Arguments\n* `n` - The index of the Fibonacci number to calculate\n", + "signature": "fn fib(mut n: u32) -> u32", + "full_path": "hello_world::fib" + } + } + ], + "structs": [ + { + "members": [ + { + "item_data": { + "name": "radius", + "doc": "Radius of the circle", + "signature": null, + "full_path": "hello_world::Circle::radius" + } } + ], + "item_data": { + "name": "Circle", + "doc": "Circle struct with radius field\n", + "signature": null, + "full_path": "hello_world::Circle" } - ], - "impl_types": [ - { - "item_data": { - "doc": "Type alias for a pair of circles\n", - "full_path": "CircleShape::ShapePair", - "name": "ShapePair", - "signature": "type ShapePair = (Circle, Circle);" + } + ], + "enums": [ + { + "variants": [ + { + "item_data": { + "name": "Red", + "doc": "Red color", + "signature": null, + "full_path": "hello_world::Color::Red" + } + }, + { + "item_data": { + "name": "Green", + "doc": "Green color", + "signature": null, + "full_path": "hello_world::Color::Green" + } + }, + { + "item_data": { + "name": "Blue", + "doc": "Blue color", + "signature": null, + "full_path": "hello_world::Color::Blue" + } } + ], + "item_data": { + "name": "Color", + "doc": "Color enum with Red, Green, and Blue variants\n", + "signature": null, + "full_path": "hello_world::Color" } - ], - "item_data": { - "doc": "Implementation of the Shape trait for Circle\n", - "full_path": "hello_world::CircleShape", - "name": "CircleShape", - "signature": "impl CircleShape of Shape" } - }, - { - "impl_constants": [], - "impl_functions": [], - "impl_types": [], - "item_data": { - "doc": null, - "full_path": "hello_world::CircleDrop", - "name": "CircleDrop", - "signature": "impl CircleDrop of core::traits::Drop;" + ], + "type_aliases": [ + { + "item_data": { + "name": "Pair", + "doc": "Pair type alias for a tuple of two u32 values\n", + "signature": "type Pair = (u32, u32);", + "full_path": "hello_world::Pair" + } } - }, - { - "impl_constants": [], - "impl_functions": [ - { - "item_data": { - "doc": null, - "full_path": "hello_world::CircleSerde::serialize", - "name": "serialize", - "signature": "fn serialize(self: @Circle, ref output: core::array::Array)" + ], + "impl_aliases": [], + "traits": [ + { + "trait_constants": [ + { + "item_data": { + "name": "SHAPE_CONST", + "doc": "Constant for the shape type\n", + "signature": null, + "full_path": "Shape::SHAPE_CONST" + } } - }, - { - "item_data": { - "doc": null, - "full_path": "hello_world::CircleSerde::deserialize", - "name": "deserialize", - "signature": "fn deserialize(ref serialized: core::array::Span) -> core::option::Option" + ], + "trait_types": [ + { + "item_data": { + "name": "ShapePair", + "doc": "Type alias for a pair of shapes\n", + "signature": null, + "full_path": "Shape::ShapePair" + } } - } - ], - "impl_types": [], - "item_data": { - "doc": null, - "full_path": "hello_world::CircleSerde", - "name": "CircleSerde", - "signature": "impl CircleSerde of core::serde::Serde" - } - }, - { - "impl_constants": [], - "impl_functions": [ - { - "item_data": { - "doc": null, - "full_path": "hello_world::CirclePartialEq::eq", - "name": "eq", - "signature": "fn eq(lhs: @Circle, rhs: @Circle) -> bool" + ], + "trait_functions": [ + { + "item_data": { + "name": "area", + "doc": "Calculate the area of the shape\n", + "signature": "fn area(self: T) -> u32", + "full_path": "Shape::area" + } } + ], + "item_data": { + "name": "Shape", + "doc": "Shape trait for objects that have an area\n", + "signature": "trait Shape", + "full_path": "hello_world::Shape" } - ], - "impl_types": [], - "item_data": { - "doc": null, - "full_path": "hello_world::CirclePartialEq", - "name": "CirclePartialEq", - "signature": "impl CirclePartialEq of core::traits::PartialEq" } - } - ], - "item_data": { - "doc": null, - "full_path": "hello_world", - "name": "hello_world", - "signature": null - }, - "structs": [ - { - "item_data": { - "doc": "Circle struct with radius field\n", - "full_path": "hello_world::Circle", - "name": "Circle", - "signature": null - }, - "members": [ - { - "item_data": { - "doc": "Radius of the circle", - "full_path": "hello_world::Circle::radius", - "name": "radius", - "signature": null + ], + "impls": [ + { + "impl_types": [ + { + "item_data": { + "name": "ShapePair", + "doc": "Type alias for a pair of circles\n", + "signature": "type ShapePair = (Circle, Circle);", + "full_path": "CircleShape::ShapePair" + } } - } - ] - } - ], - "submodules": [ - { - "constants": [], - "enums": [], - "extern_functions": [], - "extern_types": [], - "free_functions": [ - { - "item_data": { - "doc": "Really\nworks.\n", - "full_path": "hello_world::tests::it_works", - "name": "it_works", - "signature": "fn it_works()" + ], + "impl_constants": [ + { + "item_data": { + "name": "SHAPE_CONST", + "doc": "Shape constant\n", + "signature": "const SHAPE_CONST = \"xyz\";", + "full_path": "CircleShape::SHAPE_CONST" + } } + ], + "impl_functions": [ + { + "item_data": { + "name": "area", + "doc": "Implementation of the area method for Circle\n", + "signature": "fn area(self: Circle) -> u32", + "full_path": "hello_world::CircleShape::area" + } + } + ], + "item_data": { + "name": "CircleShape", + "doc": "Implementation of the Shape trait for Circle\n", + "signature": "impl CircleShape of Shape", + "full_path": "hello_world::CircleShape" } - ], - "impl_aliases": [], - "impls": [], - "item_data": { - "doc": "Tests module\n", - "full_path": "hello_world::tests", - "name": "tests", - "signature": null - }, - "structs": [], - "submodules": [], - "traits": [], - "type_aliases": [] - } - ], - "traits": [ - { - "item_data": { - "doc": "Shape trait for objects that have an area\n", - "full_path": "hello_world::Shape", - "name": "Shape", - "signature": "trait Shape" }, - "trait_constants": [ - { - "item_data": { - "doc": "Constant for the shape type\n", - "full_path": "Shape::SHAPE_CONST", - "name": "SHAPE_CONST", - "signature": null - } + { + "impl_types": [], + "impl_constants": [], + "impl_functions": [], + "item_data": { + "name": "CircleDrop", + "doc": null, + "signature": "impl CircleDrop of core::traits::Drop;", + "full_path": "hello_world::CircleDrop" } - ], - "trait_functions": [ - { - "item_data": { - "doc": "Calculate the area of the shape\n", - "full_path": "Shape::area", - "name": "area", - "signature": "fn area(self: T) -> u32" + }, + { + "impl_types": [], + "impl_constants": [], + "impl_functions": [ + { + "item_data": { + "name": "serialize", + "doc": null, + "signature": "fn serialize(self: @Circle, ref output: core::array::Array)", + "full_path": "hello_world::CircleSerde::serialize" + } + }, + { + "item_data": { + "name": "deserialize", + "doc": null, + "signature": "fn deserialize(ref serialized: core::array::Span) -> core::option::Option", + "full_path": "hello_world::CircleSerde::deserialize" + } } + ], + "item_data": { + "name": "CircleSerde", + "doc": null, + "signature": "impl CircleSerde of core::serde::Serde", + "full_path": "hello_world::CircleSerde" } - ], - "trait_types": [ - { - "item_data": { - "doc": "Type alias for a pair of shapes\n", - "full_path": "Shape::ShapePair", - "name": "ShapePair", - "signature": null + }, + { + "impl_types": [], + "impl_constants": [], + "impl_functions": [ + { + "item_data": { + "name": "eq", + "doc": null, + "signature": "fn eq(lhs: @Circle, rhs: @Circle) -> bool", + "full_path": "hello_world::CirclePartialEq::eq" + } } + ], + "item_data": { + "name": "CirclePartialEq", + "doc": null, + "signature": "impl CirclePartialEq of core::traits::PartialEq", + "full_path": "hello_world::CirclePartialEq" } - ] - } - ], - "type_aliases": [ - { - "item_data": { - "doc": "Pair type alias for a tuple of two u32 values\n", - "full_path": "hello_world::Pair", - "name": "Pair", - "signature": "type Pair = (u32, u32);" } - } - ] + ], + "extern_types": [], + "extern_functions": [] + } } } } \ No newline at end of file From cabdd3acdb5c0d92d28d7a8f121e8a70b69616a6 Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Tue, 9 Jul 2024 15:06:23 +0200 Subject: [PATCH 14/16] . --- extensions/scarb-doc/src/versioned_json_output.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/scarb-doc/src/versioned_json_output.rs b/extensions/scarb-doc/src/versioned_json_output.rs index b624a2618..72a1f7750 100644 --- a/extensions/scarb-doc/src/versioned_json_output.rs +++ b/extensions/scarb-doc/src/versioned_json_output.rs @@ -8,7 +8,7 @@ const FORMAT_VERSION: u8 = 1; #[derive(Serialize)] pub struct VersionedJsonOutput { - pub format_version: u8, + format_version: u8, pub package_information_map: BTreeMap, } From 726738d10495d189a5ee46662481e9ba5f8f13ee Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Tue, 9 Jul 2024 15:07:10 +0200 Subject: [PATCH 15/16] . --- extensions/scarb-doc/src/versioned_json_output.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/scarb-doc/src/versioned_json_output.rs b/extensions/scarb-doc/src/versioned_json_output.rs index 72a1f7750..615e4f652 100644 --- a/extensions/scarb-doc/src/versioned_json_output.rs +++ b/extensions/scarb-doc/src/versioned_json_output.rs @@ -13,7 +13,7 @@ pub struct VersionedJsonOutput { } impl VersionedJsonOutput { - pub fn new(package_information_map: BTreeMap) -> Self { + pub fn new(package_information_map: BTreeMap) -> Self { Self { format_version: FORMAT_VERSION, package_information_map, From 340d4f73a631a58889a7f8e8c5eae9b2aec22bb1 Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Tue, 9 Jul 2024 15:13:36 +0200 Subject: [PATCH 16/16] . --- extensions/scarb-doc/src/main.rs | 3 ++- extensions/scarb-doc/tests/data/json_output_test_data.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/extensions/scarb-doc/src/main.rs b/extensions/scarb-doc/src/main.rs index 7cf7dbafb..8dde04637 100644 --- a/extensions/scarb-doc/src/main.rs +++ b/extensions/scarb-doc/src/main.rs @@ -65,7 +65,8 @@ fn main_inner() -> Result<()> { OutputFormat::Json => { let versioned_json_output = VersionedJsonOutput::new(package_information_map); let output = serde_json::to_string_pretty(&versioned_json_output) - .expect("failed to serialize information about crates"); + .expect("failed to serialize information about crates") + + "\n"; let output_path = output_dir.join("output.json"); fs::write(output_path, output) diff --git a/extensions/scarb-doc/tests/data/json_output_test_data.json b/extensions/scarb-doc/tests/data/json_output_test_data.json index 5d1c4e451..c0f58e917 100644 --- a/extensions/scarb-doc/tests/data/json_output_test_data.json +++ b/extensions/scarb-doc/tests/data/json_output_test_data.json @@ -278,4 +278,4 @@ } } } -} \ No newline at end of file +}