From ba3eb873f63ac233376869a5949d26d7291a5cd3 Mon Sep 17 00:00:00 2001 From: Timothy Zakian Date: Tue, 22 Oct 2024 16:27:14 -0700 Subject: [PATCH 1/2] [move] Move core parsing tests into separate file --- .../move-core-types/src/parsing/parser.rs | 286 ------------------ .../move-core-types/src/unit_tests/mod.rs | 1 + .../src/unit_tests/parsing_test.rs | 282 +++++++++++++++++ 3 files changed, 283 insertions(+), 286 deletions(-) create mode 100644 external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs diff --git a/external-crates/move/crates/move-core-types/src/parsing/parser.rs b/external-crates/move/crates/move-core-types/src/parsing/parser.rs index 307fbe59b4d33..7361b0fcc3272 100644 --- a/external-crates/move/crates/move-core-types/src/parsing/parser.rs +++ b/external-crates/move/crates/move-core-types/src/parsing/parser.rs @@ -457,289 +457,3 @@ pub fn parse_address_number(s: &str) -> Option<([u8; AccountAddress::LENGTH], Nu result[(AccountAddress::LENGTH - bytes.len())..].clone_from_slice(&bytes); Some((result, base)) } - -#[cfg(test)] -mod tests { - use crate::parsing::{ - address::{NumericalAddress, ParsedAddress}, - types::{ParsedStructType, ParsedType}, - values::ParsedValue, - }; - use crate::{account_address::AccountAddress, identifier::Identifier, u256::U256}; - use proptest::prelude::*; - use proptest::proptest; - - #[allow(clippy::unreadable_literal)] - #[test] - fn tests_parse_value_positive() { - use ParsedValue as V; - let cases: &[(&str, V)] = &[ - (" 0u8", V::U8(0)), - ("0u8", V::U8(0)), - ("0xF_Fu8", V::U8(255)), - ("0xF__FF__Eu16", V::U16(u16::MAX - 1)), - ("0xFFF_FF__FF_Cu32", V::U32(u32::MAX - 3)), - ("255u8", V::U8(255)), - ("255u256", V::U256(U256::from(255u64))), - ("0", V::InferredNum(U256::from(0u64))), - ("0123", V::InferredNum(U256::from(123u64))), - ("0xFF", V::InferredNum(U256::from(0xFFu64))), - ("0xF_F", V::InferredNum(U256::from(0xFFu64))), - ("0xFF__", V::InferredNum(U256::from(0xFFu64))), - ( - "0x12_34__ABCD_FF", - V::InferredNum(U256::from(0x1234ABCDFFu64)), - ), - ("0u64", V::U64(0)), - ("0x0u64", V::U64(0)), - ( - "18446744073709551615", - V::InferredNum(U256::from(18446744073709551615u128)), - ), - ("18446744073709551615u64", V::U64(18446744073709551615)), - ("0u128", V::U128(0)), - ("1_0u8", V::U8(1_0)), - ("10_u8", V::U8(10)), - ("1_000u64", V::U64(1_000)), - ("1_000", V::InferredNum(U256::from(1_000u32))), - ("1_0_0_0u64", V::U64(1_000)), - ("1_000_000u128", V::U128(1_000_000)), - ( - "340282366920938463463374607431768211455u128", - V::U128(340282366920938463463374607431768211455), - ), - ("true", V::Bool(true)), - ("false", V::Bool(false)), - ( - "@0x0", - V::Address(ParsedAddress::Numerical(NumericalAddress::new( - AccountAddress::from_hex_literal("0x0") - .unwrap() - .into_bytes(), - crate::parsing::parser::NumberFormat::Hex, - ))), - ), - ( - "@0", - V::Address(ParsedAddress::Numerical(NumericalAddress::new( - AccountAddress::from_hex_literal("0x0") - .unwrap() - .into_bytes(), - crate::parsing::parser::NumberFormat::Hex, - ))), - ), - ( - "@0x54afa3526", - V::Address(ParsedAddress::Numerical(NumericalAddress::new( - AccountAddress::from_hex_literal("0x54afa3526") - .unwrap() - .into_bytes(), - crate::parsing::parser::NumberFormat::Hex, - ))), - ), - ( - "b\"hello\"", - V::Vector("hello".as_bytes().iter().copied().map(V::U8).collect()), - ), - ("x\"7fff\"", V::Vector(vec![V::U8(0x7f), V::U8(0xff)])), - ("x\"\"", V::Vector(vec![])), - ("x\"00\"", V::Vector(vec![V::U8(0x00)])), - ( - "x\"deadbeef\"", - V::Vector(vec![V::U8(0xde), V::U8(0xad), V::U8(0xbe), V::U8(0xef)]), - ), - ]; - - for (s, expected) in cases { - assert_eq!(&ParsedValue::parse(s).unwrap(), expected) - } - } - - #[test] - fn tests_parse_value_negative() { - /// Test cases for the parser that should always fail. - const PARSE_VALUE_NEGATIVE_TEST_CASES: &[&str] = &[ - "-3", - "0u42", - "0u645", - "0u64x", - "0u6 4", - "0u", - "_10", - "_10_u8", - "_10__u8", - "10_u8__", - "0xFF_u8_", - "0xF_u8__", - "0x_F_u8__", - "_", - "__", - "__4", - "_u8", - "5_bool", - "256u8", - "4294967296u32", - "65536u16", - "18446744073709551616u64", - "340282366920938463463374607431768211456u128", - "340282366920938463463374607431768211456340282366920938463463374607431768211456340282366920938463463374607431768211456340282366920938463463374607431768211456u256", - "0xg", - "0x00g0", - "0x", - "0x_", - "", - "@@", - "()", - "x\"ffff", - "x\"a \"", - "x\" \"", - "x\"0g\"", - "x\"0\"", - "garbage", - "true3", - "3false", - "3 false", - "", - "0XFF", - "0X0", - ]; - - for s in PARSE_VALUE_NEGATIVE_TEST_CASES { - assert!( - ParsedValue::<()>::parse(s).is_err(), - "Unexpectedly succeeded in parsing: {}", - s - ) - } - } - - #[test] - fn test_parse_type_negative() { - for s in &[ - "_", - "_::_::_", - "0x1::_", - "0x1::__::_", - "0x1::_::__", - "0x1::_::foo", - "0x1::foo::_", - "0x1::_::_", - "0x1::bar::foo<0x1::_::foo>", - ] { - assert!( - ParsedType::parse(s).is_err(), - "Parsed type {s} but should have failed" - ); - } - } - - #[test] - fn test_parse_struct_negative() { - for s in &[ - "_", - "_::_::_", - "0x1::_", - "0x1::__::_", - "0x1::_::__", - "0x1::_::foo", - "0x1::foo::_", - "0x1::_::_", - "0x1::bar::foo<0x1::_::foo>", - ] { - assert!( - ParsedStructType::parse(s).is_err(), - "Parsed type {s} but should have failed" - ); - } - } - - #[test] - fn test_type_type() { - for s in &[ - "u64", - "bool", - "vector", - "vector>", - "address", - "signer", - "0x1::M::S", - "0x2::M::S_", - "0x3::M_::S", - "0x4::M_::S_", - "0x00000000004::M::S", - "0x1::M::S", - "0x1::M::S<0x2::P::Q>", - "vector<0x1::M::S>", - "vector<0x1::M_::S_>", - "vector>", - "0x1::M::S>", - "0x1::_bar::_BAR", - "0x1::__::__", - "0x1::_bar::_BAR<0x2::_____::______fooo______>", - "0x1::__::__<0x2::_____::______fooo______, 0xff::Bar____::_______foo>", - ] { - assert!(ParsedType::parse(s).is_ok(), "Failed to parse type {}", s); - } - } - - #[test] - fn test_parse_valid_struct_type() { - let valid = vec![ - "0x1::Foo::Foo", - "0x1::Foo_Type::Foo", - "0x1::Foo_::Foo", - "0x1::X_123::X32_", - "0x1::Foo::Foo_Type", - "0x1::Foo::Foo<0x1::ABC::ABC>", - "0x1::Foo::Foo<0x1::ABC::ABC_Type>", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo
", - "0x1::Foo::Foo", - "0x1::Foo::Foo>", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo", - "0x1::Foo::Foo,address,signer>", - "0x1::Foo::Foo>>", - "0x1::Foo::Foo<0x1::Foo::Struct, 0x1::Foo::Foo>>>>", - "0x1::_bar::_BAR", - "0x1::__::__", - "0x1::_bar::_BAR<0x2::_____::______fooo______>", - "0x1::__::__<0x2::_____::______fooo______, 0xff::Bar____::_______foo>", - ]; - for s in valid { - assert!( - ParsedStructType::parse(s).is_ok(), - "Failed to parse struct {}", - s - ); - } - } - - fn struct_type_gen() -> impl Strategy { - ( - any::(), - any::(), - any::(), - ) - .prop_map(|(address, module, name)| format!("0x{}::{}::{}", address, module, name)) - } - - proptest! { - #[test] - fn test_parse_valid_struct_type_proptest(s in struct_type_gen()) { - prop_assert!(ParsedStructType::parse(&s).is_ok()); - } - - #[test] - fn test_parse_valid_type_struct_only_proptest(s in struct_type_gen()) { - prop_assert!(ParsedStructType::parse(&s).is_ok()); - } - } -} diff --git a/external-crates/move/crates/move-core-types/src/unit_tests/mod.rs b/external-crates/move/crates/move-core-types/src/unit_tests/mod.rs index 237660ea9a80a..64e54f71b241d 100644 --- a/external-crates/move/crates/move-core-types/src/unit_tests/mod.rs +++ b/external-crates/move/crates/move-core-types/src/unit_tests/mod.rs @@ -5,5 +5,6 @@ mod extractor_test; mod identifier_test; mod language_storage_test; +mod parsing_test; mod value_test; mod visitor_test; diff --git a/external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs b/external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs new file mode 100644 index 0000000000000..b3d251cf3a5c8 --- /dev/null +++ b/external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs @@ -0,0 +1,282 @@ +use crate::parsing::{ + address::{NumericalAddress, ParsedAddress}, + types::{ParsedStructType, ParsedType}, + values::ParsedValue, +}; +use crate::{account_address::AccountAddress, identifier::Identifier, u256::U256}; +use proptest::prelude::*; +use proptest::proptest; + +#[allow(clippy::unreadable_literal)] +#[test] +fn tests_parse_value_positive() { + use ParsedValue as V; + let cases: &[(&str, V)] = &[ + (" 0u8", V::U8(0)), + ("0u8", V::U8(0)), + ("0xF_Fu8", V::U8(255)), + ("0xF__FF__Eu16", V::U16(u16::MAX - 1)), + ("0xFFF_FF__FF_Cu32", V::U32(u32::MAX - 3)), + ("255u8", V::U8(255)), + ("255u256", V::U256(U256::from(255u64))), + ("0", V::InferredNum(U256::from(0u64))), + ("0123", V::InferredNum(U256::from(123u64))), + ("0xFF", V::InferredNum(U256::from(0xFFu64))), + ("0xF_F", V::InferredNum(U256::from(0xFFu64))), + ("0xFF__", V::InferredNum(U256::from(0xFFu64))), + ( + "0x12_34__ABCD_FF", + V::InferredNum(U256::from(0x1234ABCDFFu64)), + ), + ("0u64", V::U64(0)), + ("0x0u64", V::U64(0)), + ( + "18446744073709551615", + V::InferredNum(U256::from(18446744073709551615u128)), + ), + ("18446744073709551615u64", V::U64(18446744073709551615)), + ("0u128", V::U128(0)), + ("1_0u8", V::U8(1_0)), + ("10_u8", V::U8(10)), + ("1_000u64", V::U64(1_000)), + ("1_000", V::InferredNum(U256::from(1_000u32))), + ("1_0_0_0u64", V::U64(1_000)), + ("1_000_000u128", V::U128(1_000_000)), + ( + "340282366920938463463374607431768211455u128", + V::U128(340282366920938463463374607431768211455), + ), + ("true", V::Bool(true)), + ("false", V::Bool(false)), + ( + "@0x0", + V::Address(ParsedAddress::Numerical(NumericalAddress::new( + AccountAddress::from_hex_literal("0x0") + .unwrap() + .into_bytes(), + crate::parsing::parser::NumberFormat::Hex, + ))), + ), + ( + "@0", + V::Address(ParsedAddress::Numerical(NumericalAddress::new( + AccountAddress::from_hex_literal("0x0") + .unwrap() + .into_bytes(), + crate::parsing::parser::NumberFormat::Hex, + ))), + ), + ( + "@0x54afa3526", + V::Address(ParsedAddress::Numerical(NumericalAddress::new( + AccountAddress::from_hex_literal("0x54afa3526") + .unwrap() + .into_bytes(), + crate::parsing::parser::NumberFormat::Hex, + ))), + ), + ( + "b\"hello\"", + V::Vector("hello".as_bytes().iter().copied().map(V::U8).collect()), + ), + ("x\"7fff\"", V::Vector(vec![V::U8(0x7f), V::U8(0xff)])), + ("x\"\"", V::Vector(vec![])), + ("x\"00\"", V::Vector(vec![V::U8(0x00)])), + ( + "x\"deadbeef\"", + V::Vector(vec![V::U8(0xde), V::U8(0xad), V::U8(0xbe), V::U8(0xef)]), + ), + ]; + + for (s, expected) in cases { + assert_eq!(&ParsedValue::parse(s).unwrap(), expected) + } +} + +#[test] +fn tests_parse_value_negative() { + /// Test cases for the parser that should always fail. + const PARSE_VALUE_NEGATIVE_TEST_CASES: &[&str] = &[ + "-3", + "0u42", + "0u645", + "0u64x", + "0u6 4", + "0u", + "_10", + "_10_u8", + "_10__u8", + "10_u8__", + "0xFF_u8_", + "0xF_u8__", + "0x_F_u8__", + "_", + "__", + "__4", + "_u8", + "5_bool", + "256u8", + "4294967296u32", + "65536u16", + "18446744073709551616u64", + "340282366920938463463374607431768211456u128", + "340282366920938463463374607431768211456340282366920938463463374607431768211456340282366920938463463374607431768211456340282366920938463463374607431768211456u256", + "0xg", + "0x00g0", + "0x", + "0x_", + "", + "@@", + "()", + "x\"ffff", + "x\"a \"", + "x\" \"", + "x\"0g\"", + "x\"0\"", + "garbage", + "true3", + "3false", + "3 false", + "", + "0XFF", + "0X0", + ]; + + for s in PARSE_VALUE_NEGATIVE_TEST_CASES { + assert!( + ParsedValue::<()>::parse(s).is_err(), + "Unexpectedly succeeded in parsing: {}", + s + ) + } +} + +#[test] +fn test_parse_type_negative() { + for s in &[ + "_", + "_::_::_", + "0x1::_", + "0x1::__::_", + "0x1::_::__", + "0x1::_::foo", + "0x1::foo::_", + "0x1::_::_", + "0x1::bar::foo<0x1::_::foo>", + ] { + assert!( + ParsedType::parse(s).is_err(), + "Parsed type {s} but should have failed" + ); + } +} + +#[test] +fn test_parse_struct_negative() { + for s in &[ + "_", + "_::_::_", + "0x1::_", + "0x1::__::_", + "0x1::_::__", + "0x1::_::foo", + "0x1::foo::_", + "0x1::_::_", + "0x1::bar::foo<0x1::_::foo>", + ] { + assert!( + ParsedStructType::parse(s).is_err(), + "Parsed type {s} but should have failed" + ); + } +} + +#[test] +fn test_type_type() { + for s in &[ + "u64", + "bool", + "vector", + "vector>", + "address", + "signer", + "0x1::M::S", + "0x2::M::S_", + "0x3::M_::S", + "0x4::M_::S_", + "0x00000000004::M::S", + "0x1::M::S", + "0x1::M::S<0x2::P::Q>", + "vector<0x1::M::S>", + "vector<0x1::M_::S_>", + "vector>", + "0x1::M::S>", + "0x1::_bar::_BAR", + "0x1::__::__", + "0x1::_bar::_BAR<0x2::_____::______fooo______>", + "0x1::__::__<0x2::_____::______fooo______, 0xff::Bar____::_______foo>", + ] { + assert!(ParsedType::parse(s).is_ok(), "Failed to parse type {}", s); + } +} + +#[test] +fn test_parse_valid_struct_type() { + let valid = vec![ + "0x1::Foo::Foo", + "0x1::Foo_Type::Foo", + "0x1::Foo_::Foo", + "0x1::X_123::X32_", + "0x1::Foo::Foo_Type", + "0x1::Foo::Foo<0x1::ABC::ABC>", + "0x1::Foo::Foo<0x1::ABC::ABC_Type>", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo
", + "0x1::Foo::Foo", + "0x1::Foo::Foo>", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo", + "0x1::Foo::Foo,address,signer>", + "0x1::Foo::Foo>>", + "0x1::Foo::Foo<0x1::Foo::Struct, 0x1::Foo::Foo>>>>", + "0x1::_bar::_BAR", + "0x1::__::__", + "0x1::_bar::_BAR<0x2::_____::______fooo______>", + "0x1::__::__<0x2::_____::______fooo______, 0xff::Bar____::_______foo>", + ]; + for s in valid { + assert!( + ParsedStructType::parse(s).is_ok(), + "Failed to parse struct {}", + s + ); + } +} + +fn struct_type_gen() -> impl Strategy { + ( + any::(), + any::(), + any::(), + ) + .prop_map(|(address, module, name)| format!("0x{}::{}::{}", address, module, name)) +} + +proptest! { + #[test] + fn test_parse_valid_struct_type_proptest(s in struct_type_gen()) { + prop_assert!(ParsedStructType::parse(&s).is_ok()); + } + + #[test] + fn test_parse_valid_type_struct_only_proptest(s in struct_type_gen()) { + prop_assert!(ParsedStructType::parse(&s).is_ok()); + } +} From 15450e03ed13f1bff1a057f9747e294f898ebe1b Mon Sep 17 00:00:00 2001 From: Tim Zakian <2895723+tzakian@users.noreply.github.com> Date: Thu, 24 Oct 2024 09:58:51 -0700 Subject: [PATCH 2/2] [move] Add additional tests for parsing (#19996) ## Description Adds additional tests and fixes a couple small issues around type lists. Also removes the `num_bigint` usage and instead uses `num::bigint` (which are the same as far as I am aware). This will get moved to a u256 in a PR above this. ## Test plan New tests + CI --- Cargo.lock | 2 - .../sui-transactional-test-runner/src/args.rs | 9 +- .../parser.rs | 2 +- .../token.rs | 2 +- .../src/test_adapter.rs | 5 +- crates/sui-types/src/lib.rs | 10 +- crates/sui/src/client_ptb/ast.rs | 2 +- crates/sui/src/client_ptb/builder.rs | 2 +- crates/sui/src/client_ptb/parser.rs | 2 +- external-crates/move/Cargo.lock | 2 - .../move/crates/move-cli/src/sandbox/cli.rs | 2 +- .../move-command-line-common/Cargo.toml | 7 - .../move-command-line-common/src/lib.rs | 5 - .../move-compiler/src/expansion/translate.rs | 2 +- .../crates/move-compiler/src/shared/ide.rs | 2 +- .../crates/move-compiler/src/shared/mod.rs | 4 +- .../move/crates/move-core-types/Cargo.toml | 1 - .../move-core-types/src/language_storage.rs | 9 +- .../move-core-types/src/parsing/address.rs | 2 +- .../move-core-types/src/parsing/parser.rs | 15 +- .../src/unit_tests/parsing_test.rs | 340 +++++++++++++++++- .../move/crates/move-model/src/model.rs | 3 +- .../move/crates/move-stdlib/src/lib.rs | 6 +- .../src/framework.rs | 8 +- .../src/tasks.rs | 8 +- .../src/vm_test_harness.rs | 5 +- 26 files changed, 382 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9cd2740ee029..a2aebd353d6e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7416,7 +7416,6 @@ dependencies = [ "hex", "move-binary-format", "move-core-types", - "num-bigint 0.4.4", "once_cell", "serde", "sha2 0.9.9", @@ -7469,7 +7468,6 @@ dependencies = [ "leb128", "move-proc-macros", "num", - "num-bigint 0.4.4", "once_cell", "primitive-types 0.10.1", "proptest", diff --git a/crates/sui-transactional-test-runner/src/args.rs b/crates/sui-transactional-test-runner/src/args.rs index 2d73a54ea99d9..5e0e12299942d 100644 --- a/crates/sui-transactional-test-runner/src/args.rs +++ b/crates/sui-transactional-test-runner/src/args.rs @@ -5,10 +5,13 @@ use crate::test_adapter::{FakeID, SuiTestAdapter}; use anyhow::{bail, ensure}; use clap; use clap::{Args, Parser}; -use move_command_line_common::parser::{parse_u256, parse_u64}; -use move_command_line_common::values::{ParsableValue, ParsedValue}; -use move_command_line_common::{parser::Parser as MoveCLParser, values::ValueToken}; use move_compiler::editions::Flavor; +use move_core_types::parsing::{ + parser::Parser as MoveCLParser, + parser::{parse_u256, parse_u64}, + values::ValueToken, + values::{ParsableValue, ParsedValue}, +}; use move_core_types::runtime_value::{MoveStruct, MoveValue}; use move_core_types::u256::U256; use move_symbol_pool::Symbol; diff --git a/crates/sui-transactional-test-runner/src/programmable_transaction_test_parser/parser.rs b/crates/sui-transactional-test-runner/src/programmable_transaction_test_parser/parser.rs index 3dfd6ec45ce6e..eb9397e40e5ea 100644 --- a/crates/sui-transactional-test-runner/src/programmable_transaction_test_parser/parser.rs +++ b/crates/sui-transactional-test-runner/src/programmable_transaction_test_parser/parser.rs @@ -3,7 +3,7 @@ use std::{borrow::BorrowMut, marker::PhantomData, str::FromStr}; -use move_command_line_common::{ +use move_core_types::parsing::{ parser::{Parser, Token}, types::{ParsedType, TypeToken}, }; diff --git a/crates/sui-transactional-test-runner/src/programmable_transaction_test_parser/token.rs b/crates/sui-transactional-test-runner/src/programmable_transaction_test_parser/token.rs index 145bc5347c499..d4d03475881ad 100644 --- a/crates/sui-transactional-test-runner/src/programmable_transaction_test_parser/token.rs +++ b/crates/sui-transactional-test-runner/src/programmable_transaction_test_parser/token.rs @@ -4,8 +4,8 @@ use std::fmt::{self, Display}; use anyhow::bail; -use move_command_line_common::parser::Token; use move_core_types::identifier; +use move_core_types::parsing::parser::Token; #[derive(Eq, PartialEq, Debug, Clone, Copy)] pub enum CommandToken { diff --git a/crates/sui-transactional-test-runner/src/test_adapter.rs b/crates/sui-transactional-test-runner/src/test_adapter.rs index 6ee27e331e740..f9113bb41b8da 100644 --- a/crates/sui-transactional-test-runner/src/test_adapter.rs +++ b/crates/sui-transactional-test-runner/src/test_adapter.rs @@ -15,15 +15,14 @@ use fastcrypto::encoding::{Base64, Encoding}; use fastcrypto::traits::ToFromBytes; use move_binary_format::CompiledModule; use move_bytecode_utils::module_cache::GetModule; -use move_command_line_common::{ - address::ParsedAddress, files::verify_and_create_named_address_mapping, -}; +use move_command_line_common::files::verify_and_create_named_address_mapping; use move_compiler::{ editions::{Edition, Flavor}, shared::{NumberFormat, NumericalAddress, PackageConfig, PackagePaths}, Flags, FullyCompiledProgram, }; use move_core_types::ident_str; +use move_core_types::parsing::address::ParsedAddress; use move_core_types::{ account_address::AccountAddress, identifier::IdentStr, diff --git a/crates/sui-types/src/lib.rs b/crates/sui-types/src/lib.rs index 4823253ab985f..b956b6a38de6c 100644 --- a/crates/sui-types/src/lib.rs +++ b/crates/sui-types/src/lib.rs @@ -153,7 +153,7 @@ pub fn sui_framework_address_concat_string(suffix: &str) -> String { /// Parsing succeeds if and only if `s` matches one of these formats exactly, with no remaining /// suffix. This function is intended for use within the authority codebases. pub fn parse_sui_address(s: &str) -> anyhow::Result { - use move_command_line_common::address::ParsedAddress; + use move_core_types::parsing::address::ParsedAddress; Ok(ParsedAddress::parse(s)? .into_account_address(&resolve_address)? .into()) @@ -163,7 +163,7 @@ pub fn parse_sui_address(s: &str) -> anyhow::Result { /// module name (an identifier). Parsing succeeds if and only if `s` matches this format exactly, /// with no remaining input. This function is intended for use within the authority codebases. pub fn parse_sui_module_id(s: &str) -> anyhow::Result { - use move_command_line_common::types::ParsedModuleId; + use move_core_types::parsing::types::ParsedModuleId; ParsedModuleId::parse(s)?.into_module_id(&resolve_address) } @@ -172,7 +172,7 @@ pub fn parse_sui_module_id(s: &str) -> anyhow::Result { /// format exactly, with no remaining input. This function is intended for use within the authority /// codebases. pub fn parse_sui_fq_name(s: &str) -> anyhow::Result<(ModuleId, String)> { - use move_command_line_common::types::ParsedFqName; + use move_core_types::parsing::types::ParsedFqName; ParsedFqName::parse(s)?.into_fq_name(&resolve_address) } @@ -181,7 +181,7 @@ pub fn parse_sui_fq_name(s: &str) -> anyhow::Result<(ModuleId, String)> { /// brackets). Parsing succeeds if and only if `s` matches this format exactly, with no remaining /// input. This function is intended for use within the authority codebase. pub fn parse_sui_struct_tag(s: &str) -> anyhow::Result { - use move_command_line_common::types::ParsedStructType; + use move_core_types::parsing::types::ParsedStructType; ParsedStructType::parse(s)?.into_struct_tag(&resolve_address) } @@ -189,7 +189,7 @@ pub fn parse_sui_struct_tag(s: &str) -> anyhow::Result { /// vector with a type parameter. Parsing succeeds if and only if `s` matches this format exactly, /// with no remaining input. This function is intended for use within the authority codebase. pub fn parse_sui_type_tag(s: &str) -> anyhow::Result { - use move_command_line_common::types::ParsedType; + use move_core_types::parsing::types::ParsedType; ParsedType::parse(s)?.into_type_tag(&resolve_address) } diff --git a/crates/sui/src/client_ptb/ast.rs b/crates/sui/src/client_ptb/ast.rs index 762c34fd64b49..94eb9c23a5dc9 100644 --- a/crates/sui/src/client_ptb/ast.rs +++ b/crates/sui/src/client_ptb/ast.rs @@ -3,7 +3,7 @@ use std::fmt; -use move_command_line_common::{ +use move_core_types::parsing::{ address::{NumericalAddress, ParsedAddress}, types::{ParsedFqName, ParsedModuleId, ParsedStructType, ParsedType}, }; diff --git a/crates/sui/src/client_ptb/builder.rs b/crates/sui/src/client_ptb/builder.rs index 3737437b24a48..8df2dbf90dd7e 100644 --- a/crates/sui/src/client_ptb/builder.rs +++ b/crates/sui/src/client_ptb/builder.rs @@ -16,7 +16,7 @@ use miette::Severity; use move_binary_format::{ binary_config::BinaryConfig, file_format::SignatureToken, CompiledModule, }; -use move_command_line_common::{ +use move_core_types::parsing::{ address::{NumericalAddress, ParsedAddress}, parser::NumberFormat, }; diff --git a/crates/sui/src/client_ptb/parser.rs b/crates/sui/src/client_ptb/parser.rs index 7f442e0c96614..e9e769a39cfa3 100644 --- a/crates/sui/src/client_ptb/parser.rs +++ b/crates/sui/src/client_ptb/parser.rs @@ -3,7 +3,7 @@ use std::iter::Peekable; -use move_command_line_common::{ +use move_core_types::parsing::{ address::{NumericalAddress, ParsedAddress}, parser::{parse_u128, parse_u16, parse_u256, parse_u32, parse_u64, parse_u8}, types::{ParsedFqName, ParsedModuleId, ParsedStructType, ParsedType}, diff --git a/external-crates/move/Cargo.lock b/external-crates/move/Cargo.lock index c456637b99402..375412d050dda 100644 --- a/external-crates/move/Cargo.lock +++ b/external-crates/move/Cargo.lock @@ -1804,7 +1804,6 @@ dependencies = [ "hex", "move-binary-format", "move-core-types", - "num-bigint", "once_cell", "proptest", "serde", @@ -1868,7 +1867,6 @@ dependencies = [ "leb128", "move-proc-macros", "num", - "num-bigint", "once_cell", "primitive-types", "proptest", diff --git a/external-crates/move/crates/move-cli/src/sandbox/cli.rs b/external-crates/move/crates/move-cli/src/sandbox/cli.rs index e346d5292269e..e8aee6887e169 100644 --- a/external-crates/move/crates/move-cli/src/sandbox/cli.rs +++ b/external-crates/move/crates/move-cli/src/sandbox/cli.rs @@ -11,7 +11,7 @@ use crate::{ }; use anyhow::Result; use clap::Parser; -use move_command_line_common::values::ParsedValue; +use move_core_types::parsing::values::ParsedValue; use move_core_types::{language_storage::TypeTag, transaction_argument::TransactionArgument}; use move_package::compilation::package_layout::CompiledPackageLayout; use move_vm_test_utils::gas_schedule::CostTable; diff --git a/external-crates/move/crates/move-command-line-common/Cargo.toml b/external-crates/move/crates/move-command-line-common/Cargo.toml index 08679ba8a6e31..83aa969a204af 100644 --- a/external-crates/move/crates/move-command-line-common/Cargo.toml +++ b/external-crates/move/crates/move-command-line-common/Cargo.toml @@ -15,7 +15,6 @@ difference.workspace = true walkdir.workspace = true sha2.workspace = true hex.workspace = true -num-bigint.workspace = true once_cell.workspace = true serde.workspace = true dirs-next.workspace = true @@ -27,9 +26,3 @@ move-binary-format.workspace = true [dev-dependencies] proptest.workspace = true -# Ok to do this since: -# edition = 2021 ==> resolver = 2 -# * https://doc.rust-lang.org/edition-guide/rust-2021/default-cargo-resolver.html#summary -# resolver = 2 ==> feature-resolver-version-2 which allows dev-dependencies to set features -# * https://doc.rust-lang.org/cargo/reference/resolver.html#feature-resolver-version-2 -move-core-types = { workspace = true, features = ["fuzzing"] } diff --git a/external-crates/move/crates/move-command-line-common/src/lib.rs b/external-crates/move/crates/move-command-line-common/src/lib.rs index 17024fcc20f87..6014194ab13ef 100644 --- a/external-crates/move/crates/move-command-line-common/src/lib.rs +++ b/external-crates/move/crates/move-command-line-common/src/lib.rs @@ -11,8 +11,3 @@ pub mod error_bitset; pub mod files; pub mod interactive; pub mod testing; - -pub use move_core_types::parsing::address; -pub use move_core_types::parsing::parser; -pub use move_core_types::parsing::types; -pub use move_core_types::parsing::values; diff --git a/external-crates/move/crates/move-compiler/src/expansion/translate.rs b/external-crates/move/crates/move-compiler/src/expansion/translate.rs index 40eb01fe7a98c..e9f7e1d47534f 100644 --- a/external-crates/move/crates/move-compiler/src/expansion/translate.rs +++ b/external-crates/move/crates/move-compiler/src/expansion/translate.rs @@ -40,8 +40,8 @@ use crate::{ }, FullyCompiledProgram, }; -use move_command_line_common::parser::{parse_u16, parse_u256, parse_u32}; use move_core_types::account_address::AccountAddress; +use move_core_types::parsing::parser::{parse_u16, parse_u256, parse_u32}; use move_ir_types::location::*; use move_proc_macros::growing_stack; use move_symbol_pool::Symbol; diff --git a/external-crates/move/crates/move-compiler/src/shared/ide.rs b/external-crates/move/crates/move-compiler/src/shared/ide.rs index 6816278d34ed8..895f57da06985 100644 --- a/external-crates/move/crates/move-compiler/src/shared/ide.rs +++ b/external-crates/move/crates/move-compiler/src/shared/ide.rs @@ -16,7 +16,7 @@ use crate::{ unit_test::filter_test_members::UNIT_TEST_POISON_FUN_NAME, }; -use move_command_line_common::address::NumericalAddress; +use move_core_types::parsing::address::NumericalAddress; use move_ir_types::location::Loc; use move_symbol_pool::Symbol; diff --git a/external-crates/move/crates/move-compiler/src/shared/mod.rs b/external-crates/move/crates/move-compiler/src/shared/mod.rs index a242bcb7565ef..b0609c6f4fd93 100644 --- a/external-crates/move/crates/move-compiler/src/shared/mod.rs +++ b/external-crates/move/crates/move-compiler/src/shared/mod.rs @@ -62,7 +62,7 @@ pub use ast_debug::AstDebug; // Numbers //************************************************************************************************** -pub use move_command_line_common::parser::{ +pub use move_core_types::parsing::parser::{ parse_address_number as parse_address, parse_u128, parse_u16, parse_u256, parse_u32, parse_u64, parse_u8, NumberFormat, }; @@ -71,7 +71,7 @@ pub use move_command_line_common::parser::{ // Address //************************************************************************************************** -pub use move_command_line_common::address::NumericalAddress; +pub use move_core_types::parsing::address::NumericalAddress; pub fn parse_named_address(s: &str) -> anyhow::Result<(String, NumericalAddress)> { let before_after = s.split('=').collect::>(); diff --git a/external-crates/move/crates/move-core-types/Cargo.toml b/external-crates/move/crates/move-core-types/Cargo.toml index 8fe59b4168b61..feffa24db30b2 100644 --- a/external-crates/move/crates/move-core-types/Cargo.toml +++ b/external-crates/move/crates/move-core-types/Cargo.toml @@ -30,7 +30,6 @@ bcs.workspace = true leb128.workspace = true thiserror.workspace = true serde_with.workspace = true -num-bigint.workspace = true [dev-dependencies] proptest.workspace = true diff --git a/external-crates/move/crates/move-core-types/src/language_storage.rs b/external-crates/move/crates/move-core-types/src/language_storage.rs index 6edb196ce9675..bbf597fc5d326 100644 --- a/external-crates/move/crates/move-core-types/src/language_storage.rs +++ b/external-crates/move/crates/move-core-types/src/language_storage.rs @@ -6,7 +6,7 @@ use crate::{ account_address::AccountAddress, gas_algebra::{AbstractMemorySize, BOX_ABSTRACT_SIZE, ENUM_BASE_ABSTRACT_SIZE}, identifier::{IdentStr, Identifier}, - parsing::types::{ParsedStructType, ParsedType}, + parsing::types::{ParsedModuleId, ParsedStructType, ParsedType}, }; use move_proc_macros::test_variant_order; use once_cell::sync::Lazy; @@ -327,6 +327,13 @@ impl Display for ModuleId { } } +impl FromStr for ModuleId { + type Err = anyhow::Error; + fn from_str(s: &str) -> Result { + ParsedModuleId::parse(s)?.into_module_id(&|_| None) + } +} + impl ModuleId { pub fn short_str_lossless(&self) -> String { format!("0x{}::{}", self.address.short_str_lossless(), self.name) diff --git a/external-crates/move/crates/move-core-types/src/parsing/address.rs b/external-crates/move/crates/move-core-types/src/parsing/address.rs index 04720ff63b7dc..b479e76dcf23c 100644 --- a/external-crates/move/crates/move-core-types/src/parsing/address.rs +++ b/external-crates/move/crates/move-core-types/src/parsing/address.rs @@ -4,7 +4,7 @@ use crate::account_address::AccountAddress; use crate::parsing::parser::{parse_address_number, NumberFormat}; use anyhow::anyhow; -use num_bigint::BigUint; +use num::BigUint; use std::{fmt, hash::Hash}; // Parsed Address, either a name or a numerical address diff --git a/external-crates/move/crates/move-core-types/src/parsing/parser.rs b/external-crates/move/crates/move-core-types/src/parsing/parser.rs index 7361b0fcc3272..1245c34239d54 100644 --- a/external-crates/move/crates/move-core-types/src/parsing/parser.rs +++ b/external-crates/move/crates/move-core-types/src/parsing/parser.rs @@ -11,7 +11,7 @@ use crate::{ u256::{U256FromStrError, U256}, }; use anyhow::{anyhow, bail, Result}; -use num_bigint::BigUint; +use num::BigUint; use std::{fmt::Display, iter::Peekable, num::ParseIntError}; const MAX_TYPE_DEPTH: u64 = 128; @@ -76,7 +76,7 @@ impl ParsedValue { } } -fn parse<'a, Tok: Token, R>( +pub(crate) fn parse<'a, Tok: Token, R>( s: &'a str, f: impl FnOnce(&mut Parser<'a, Tok, std::vec::IntoIter<(Tok, &'a str)>>) -> Result, ) -> Result { @@ -139,8 +139,12 @@ impl<'a, Tok: Token, I: Iterator> Parser<'a, Tok, I> { break; } self.advance(delim)?; - if is_end(self.peek_tok()) && allow_trailing_delim { - break; + if is_end(self.peek_tok()) { + if allow_trailing_delim { + break; + } else { + bail!("Invalid type list: trailing delimiter '{}'", delim) + } } } Ok(v) @@ -225,6 +229,9 @@ impl<'a, I: Iterator> Parser<'a, TypeToken, I> { true, )?; self.advance(TypeToken::Gt)?; + if type_args.is_empty() { + bail!("expected at least one type argument") + } type_args } _ => vec![], diff --git a/external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs b/external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs index b3d251cf3a5c8..426d03abc92a4 100644 --- a/external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs +++ b/external-crates/move/crates/move-core-types/src/unit_tests/parsing_test.rs @@ -1,11 +1,18 @@ -use crate::parsing::{ - address::{NumericalAddress, ParsedAddress}, - types::{ParsedStructType, ParsedType}, - values::ParsedValue, +use crate::{ + account_address::AccountAddress, + identifier::Identifier, + language_storage::{ModuleId, StructTag, TypeTag}, + parsing::{ + address::{NumericalAddress, ParsedAddress}, + parser::parse, + types::{ParsedFqName, ParsedType, TypeToken}, + values::ParsedValue, + }, + u256::U256, }; -use crate::{account_address::AccountAddress, identifier::Identifier, u256::U256}; -use proptest::prelude::*; -use proptest::proptest; +use anyhow::bail; +use proptest::{prelude::*, proptest}; +use std::str::FromStr; #[allow(clippy::unreadable_literal)] #[test] @@ -163,9 +170,10 @@ fn test_parse_type_negative() { "0x1::foo::_", "0x1::_::_", "0x1::bar::foo<0x1::_::foo>", + "0X1::bar::bar", ] { assert!( - ParsedType::parse(s).is_err(), + TypeTag::from_str(s).is_err(), "Parsed type {s} but should have failed" ); } @@ -183,9 +191,20 @@ fn test_parse_struct_negative() { "0x1::foo::_", "0x1::_::_", "0x1::bar::foo<0x1::_::foo>", + "0x1::bar::bar::foo", + "0x1::Foo::Foo<", + "0x1::Foo::Foo<0x1::ABC::ABC", + "0x1::Foo::Foo<0x1::ABC::ABC::>", + "0x1::Foo::Foo<0x1::ABC::ABC::A>", + "0x1::Foo::Foo<>", + "0x1::Foo::Foo<,>", + "0x1::Foo::Foo<,", + "0x1::Foo::Foo,>", + "0x1::Foo::Foo>", + "0x1::Foo::Foo,", ] { assert!( - ParsedStructType::parse(s).is_err(), + TypeTag::from_str(s).is_err(), "Parsed type {s} but should have failed" ); } @@ -216,7 +235,7 @@ fn test_type_type() { "0x1::_bar::_BAR<0x2::_____::______fooo______>", "0x1::__::__<0x2::_____::______fooo______, 0xff::Bar____::_______foo>", ] { - assert!(ParsedType::parse(s).is_ok(), "Failed to parse type {}", s); + assert!(TypeTag::from_str(s).is_ok(), "Failed to parse type {}", s); } } @@ -253,14 +272,76 @@ fn test_parse_valid_struct_type() { ]; for s in valid { assert!( - ParsedStructType::parse(s).is_ok(), + StructTag::from_str(s).is_ok(), "Failed to parse struct {}", s ); } } -fn struct_type_gen() -> impl Strategy { +#[test] +fn test_parse_type_list() { + let valid_with_trails = vec![ + "", + "", + ",>", + ]; + let valid_no_trails = vec![ + "", + "", + ">", + ]; + let invalid = vec![ + "<>", + "<,>", + "", + "<,u64>", + "<,u64,>", + ",", + "", + "<", + "<<", + "><", + ">,<", + ">,", + ",>", + ",,", + ">>", + "", + "u64,>", + "u64, u64,>", + "u64, u64,", + "u64, u64", + "u64 u64", + "", + "", + "u64 u64,", + "", + ",", + ",,>", + ]; + + for t in valid_no_trails.iter().chain(valid_with_trails.iter()) { + assert!(parse_type_tags(t, true).is_ok()); + } + + for t in &valid_no_trails { + assert!(parse_type_tags(t, false).is_ok()); + } + + for t in &valid_with_trails { + assert!(parse_type_tags(t, false).is_err()); + } + + for t in &invalid { + assert!(parse_type_tags(t, true).is_err(), "parsed type {}", t); + assert!(parse_type_tags(t, false).is_err(), "parsed type {}", t); + } +} + +fn struct_type_gen0() -> impl Strategy { ( any::(), any::(), @@ -269,14 +350,241 @@ fn struct_type_gen() -> impl Strategy { .prop_map(|(address, module, name)| format!("0x{}::{}::{}", address, module, name)) } +fn struct_type_gen1() -> impl Strategy { + (any::(), any::(), any::()) + .prop_map(|(address, module, name)| format!("{}::{}::{}", address, module, name)) +} + +fn module_id_gen0() -> impl Strategy { + (any::(), any::()) + .prop_map(|(address, module)| format!("0x{address}::{module}")) +} + +fn module_id_gen1() -> impl Strategy { + (any::(), any::()) + .prop_map(|(address, module)| format!("{address}::{module}")) +} + +fn fq_id_gen0() -> impl Strategy { + ( + any::(), + any::(), + any::(), + ) + .prop_map(|(address, module, name)| format!("0x{address}::{module}::{name}")) +} + +fn fq_id_gen1() -> impl Strategy { + (any::(), any::(), any::()) + .prop_map(|(address, module, name)| format!("{address}::{module}::{name}")) +} + +fn parse_type_tags(s: &str, allow_trailing_delim: bool) -> anyhow::Result> { + parse(s, |parser| { + parser.advance(TypeToken::Lt)?; + let parsed = parser.parse_list( + |parser| parser.parse_type(), + TypeToken::Comma, + TypeToken::Gt, + allow_trailing_delim, + )?; + parser.advance(TypeToken::Gt)?; + if parsed.is_empty() { + bail!("expected at least one type argument") + } + Ok(parsed) + }) +} + proptest! { #[test] - fn test_parse_valid_struct_type_proptest(s in struct_type_gen()) { - prop_assert!(ParsedStructType::parse(&s).is_ok()); + fn parse_type_tag_list(t in struct_type_gen0(), args in proptest::collection::vec(struct_type_gen0(), 1..=100)) { + let s_no_trail = format!("<{}>", args.join(",")); + let s_with_trail = format!("<{},>", args.join(",")); + let s_no_trail_no_trail = parse_type_tags(&s_no_trail, false); + let s_no_trail_allow_trail = parse_type_tags(&s_no_trail, true); + let s_with_trail_no_trail = parse_type_tags(&s_with_trail, false); + let s_with_trail_allow_trail = parse_type_tags(&s_with_trail, true); + prop_assert!(s_no_trail_no_trail.is_ok()); + prop_assert!(s_no_trail_allow_trail.is_ok()); + prop_assert!(s_with_trail_no_trail.is_err()); + prop_assert!(s_with_trail_allow_trail.is_ok()); + let t_with_trail = format!("{t}{s_no_trail}"); + let t_no_trail = format!("{t}{s_with_trail}"); + let t_with_trail = TypeTag::from_str(&t_with_trail); + let t_no_trail = TypeTag::from_str(&t_no_trail); + prop_assert!(t_with_trail.is_ok()); + prop_assert!(t_no_trail.is_ok()); + prop_assert_eq!(t_with_trail.unwrap(), t_no_trail.unwrap()); + } + + #[test] + fn test_parse_valid_struct_type_proptest0(s in struct_type_gen0(), x in r#"(::foo)[^a-zA-Z0-9_\s]+"#) { + prop_assert!(StructTag::from_str(&s).is_ok()); + prop_assert!(TypeTag::from_str(&s).is_ok()); + prop_assert!(ParsedFqName::parse(&s).is_ok()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + + // Add remainder string + let s = s + &x; + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + + } + + #[test] + fn test_parse_valid_struct_type_proptest1(s in struct_type_gen1(), x in r#"(::foo)[^a-zA-Z0-9_\s]+"#) { + prop_assert!(StructTag::from_str(&s).is_ok()); + prop_assert!(TypeTag::from_str(&s).is_ok()); + prop_assert!(ParsedFqName::parse(&s).is_ok()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + // add remainder string + let s = s + &x; + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + } + + #[test] + fn test_parse_valid_module_id_proptest0(s in module_id_gen0(), x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(ModuleId::from_str(&s).is_ok()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + // add remainder string + let s = s + &x; + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + } + + #[test] + fn test_parse_valid_module_id_proptest1(s in module_id_gen1(), x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(ModuleId::from_str(&s).is_ok()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + // add remainder String + let s = s + &x; + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + + } + + #[test] + fn test_parse_valid_fq_id_proptest0(s in fq_id_gen0(), x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(ParsedFqName::parse(&s).is_ok()); + prop_assert!(StructTag::from_str(&s).is_ok()); + prop_assert!(TypeTag::from_str(&s).is_ok()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + // add remainder string + let s = s + &x; + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + } + + #[test] + fn test_parse_valid_fq_id_proptest1(s in fq_id_gen1(), x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(ParsedFqName::parse(&s).is_ok()); + prop_assert!(StructTag::from_str(&s).is_ok()); + prop_assert!(TypeTag::from_str(&s).is_ok()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + let s = s + &x; + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + } + + #[test] + fn test_parse_valid_numeric_address(s in "[0-9]{64}", x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(AccountAddress::from_str(&s).is_ok()); + prop_assert!(ParsedAddress::parse(&s).is_ok()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + // add remainder string + let s = s + &x; + prop_assert!(AccountAddress::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + } + + #[test] + fn test_parse_different_length_numeric_addresses(s in "[0-9]{1,63}", x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(AccountAddress::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_ok()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + // add remainder string + let s = s + &x; + prop_assert!(AccountAddress::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + } + + #[test] + fn test_parse_valid_hex_address(s in "0x[0-9a-fA-F]{64}", x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(AccountAddress::from_str(&s).is_ok()); + prop_assert!(ParsedAddress::parse(&s).is_ok()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + // add remainder string + let s = s + &x; + prop_assert!(AccountAddress::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); } #[test] - fn test_parse_valid_type_struct_only_proptest(s in struct_type_gen()) { - prop_assert!(ParsedStructType::parse(&s).is_ok()); + fn test_parse_invalid_hex_address(s in "[0-9]{63}[a-fA-F]{1}", x in r#"[^a-zA-Z0-9_\s]+"#) { + prop_assert!(AccountAddress::from_str(&s).is_ok()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); + // add remainder string + let s = s + &x; + prop_assert!(AccountAddress::from_str(&s).is_err()); + prop_assert!(ParsedAddress::parse(&s).is_err()); + prop_assert!(ParsedFqName::parse(&s).is_err()); + prop_assert!(ModuleId::from_str(&s).is_err()); + prop_assert!(StructTag::from_str(&s).is_err()); + prop_assert!(TypeTag::from_str(&s).is_err()); } } diff --git a/external-crates/move/crates/move-model/src/model.rs b/external-crates/move/crates/move-model/src/model.rs index f80c4c15b9ba1..40d0391f2a456 100644 --- a/external-crates/move/crates/move-model/src/model.rs +++ b/external-crates/move/crates/move-model/src/model.rs @@ -47,7 +47,8 @@ use move_binary_format::{ CompiledModule, }; use move_bytecode_source_map::{mapping::SourceMapping, source_map::SourceMap}; -use move_command_line_common::{address::NumericalAddress, files::FileHash}; +use move_command_line_common::files::FileHash; +use move_core_types::parsing::address::NumericalAddress; use move_core_types::{ account_address::AccountAddress, identifier::{IdentStr, Identifier}, diff --git a/external-crates/move/crates/move-stdlib/src/lib.rs b/external-crates/move/crates/move-stdlib/src/lib.rs index 5d714e3d3acd1..a823dca9fefe4 100644 --- a/external-crates/move/crates/move-stdlib/src/lib.rs +++ b/external-crates/move/crates/move-stdlib/src/lib.rs @@ -3,10 +3,8 @@ // SPDX-License-Identifier: Apache-2.0 use log::LevelFilter; -use move_command_line_common::{ - address::NumericalAddress, - files::{extension_equals, find_filenames, MOVE_EXTENSION}, -}; +use move_command_line_common::files::{extension_equals, find_filenames, MOVE_EXTENSION}; +use move_core_types::parsing::address::NumericalAddress; use std::{collections::BTreeMap, path::PathBuf}; #[cfg(test)] diff --git a/external-crates/move/crates/move-transactional-test-runner/src/framework.rs b/external-crates/move/crates/move-transactional-test-runner/src/framework.rs index 54f935d88d65c..ac38bdfbe78cd 100644 --- a/external-crates/move/crates/move-transactional-test-runner/src/framework.rs +++ b/external-crates/move/crates/move-transactional-test-runner/src/framework.rs @@ -14,12 +14,9 @@ use clap::Parser; use move_binary_format::file_format::CompiledModule; use move_bytecode_source_map::{mapping::SourceMapping, source_map::SourceMap}; use move_command_line_common::{ - address::ParsedAddress, env::read_bool_env_var, files::{MOVE_EXTENSION, MOVE_IR_EXTENSION}, testing::{add_update_baseline_fix, format_diff, read_env_update_baseline, EXP_EXT}, - types::ParsedType, - values::{ParsableValue, ParsedValue}, }; use move_compiler::{ compiled_unit::AnnotatedCompiledUnit, @@ -28,6 +25,11 @@ use move_compiler::{ shared::{files::MappedFiles, NumericalAddress, PackageConfig}, FullyCompiledProgram, }; +use move_core_types::parsing::{ + address::ParsedAddress, + types::ParsedType, + values::{ParsableValue, ParsedValue}, +}; use move_core_types::{ account_address::AccountAddress, identifier::{IdentStr, Identifier}, diff --git a/external-crates/move/crates/move-transactional-test-runner/src/tasks.rs b/external-crates/move/crates/move-transactional-test-runner/src/tasks.rs index c1e62c544f60b..f5247de2c86a7 100644 --- a/external-crates/move/crates/move-transactional-test-runner/src/tasks.rs +++ b/external-crates/move/crates/move-transactional-test-runner/src/tasks.rs @@ -6,14 +6,14 @@ use anyhow::{anyhow, bail, Result}; use clap::*; -use move_command_line_common::{ +use move_command_line_common::files::{MOVE_EXTENSION, MOVE_IR_EXTENSION}; +use move_compiler::shared::NumericalAddress; +use move_core_types::identifier::Identifier; +use move_core_types::parsing::{ address::ParsedAddress, - files::{MOVE_EXTENSION, MOVE_IR_EXTENSION}, types::ParsedType, values::{ParsableValue, ParsedValue}, }; -use move_compiler::shared::NumericalAddress; -use move_core_types::identifier::Identifier; use std::{convert::TryInto, fmt::Debug, path::Path, str::FromStr}; use tempfile::NamedTempFile; diff --git a/external-crates/move/crates/move-transactional-test-runner/src/vm_test_harness.rs b/external-crates/move/crates/move-transactional-test-runner/src/vm_test_harness.rs index f04769afce091..05b3b5d281926 100644 --- a/external-crates/move/crates/move-transactional-test-runner/src/vm_test_harness.rs +++ b/external-crates/move/crates/move-transactional-test-runner/src/vm_test_harness.rs @@ -15,10 +15,9 @@ use move_binary_format::{ errors::{Location, VMError, VMResult}, CompiledModule, }; -use move_command_line_common::{ - address::ParsedAddress, files::verify_and_create_named_address_mapping, -}; +use move_command_line_common::files::verify_and_create_named_address_mapping; use move_compiler::{editions::Edition, shared::PackagePaths, FullyCompiledProgram}; +use move_core_types::parsing::address::ParsedAddress; use move_core_types::{ account_address::AccountAddress, identifier::IdentStr,