diff --git a/full-moon/Cargo.toml b/full-moon/Cargo.toml index 2b411160..bbb07fd8 100644 --- a/full-moon/Cargo.toml +++ b/full-moon/Cargo.toml @@ -11,9 +11,9 @@ keywords = ["lua", "parser", "lua51", "lua52", "luau"] edition = "2021" [package.metadata.docs.rs] -# Build Locally: RUSTDOCFLAGS="--cfg doc_cfg" cargo +nightly doc --features luau,lua52,lua53,lua54,luajit --no-deps --open +# Build Locally: RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --features luau,lua52,lua53,lua54,luajit --no-deps --open features = ["luau", "lua52", "lua53", "lua54", "luajit"] -rustdoc-args = ["--cfg", "doc_cfg"] +rustdoc-args = ["--cfg", "docsrs"] [features] default = ["serde"] @@ -28,19 +28,19 @@ no-source-tests = [] [dependencies] bytecount = "0.6" cfg-if = "1.0" -derive_more = "0.99" +derive_more = { version = "1.0", features = ["display"] } full_moon_derive = { path = "../full-moon-derive", version = "=0.11.0" } paste = "1.0" serde = { version = "1.0", features = ["derive", "rc"], optional = true } -smol_str = { version = "0.1.23", features = ["serde"] } +smol_str = { version = "0.3.1", features = ["serde"] } [dev-dependencies] codespan = "0.11.1" codespan-reporting = "0.11.1" criterion = "0.5.1" -insta = { version = "1.26.0", features = ["glob", "yaml"] } -pretty_assertions = "1.3.0" -termcolor = "1.2.0" +insta = { version = "1.40.0", features = ["glob", "yaml"] } +pretty_assertions = "1.4.1" +termcolor = "1.4.1" [[bench]] name = "date" diff --git a/full-moon/src/ast/lua52.rs b/full-moon/src/ast/lua52.rs index 7a2f395d..e83bdcf6 100644 --- a/full-moon/src/ast/lua52.rs +++ b/full-moon/src/ast/lua52.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; /// A goto statement, such as `goto label`. #[derive(Clone, Debug, Display, PartialEq, Eq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{goto_token}{label_name}")] +#[display("{goto_token}{label_name}")] pub struct Goto { pub(crate) goto_token: TokenReference, pub(crate) label_name: TokenReference, @@ -50,7 +50,7 @@ impl Goto { /// A label, such as `::label::`. #[derive(Clone, Debug, Display, PartialEq, Eq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{left_colons}{name}{right_colons}")] +#[display("{left_colons}{name}{right_colons}")] pub struct Label { pub(crate) left_colons: TokenReference, pub(crate) name: TokenReference, diff --git a/full-moon/src/ast/lua54.rs b/full-moon/src/ast/lua54.rs index 87645542..2512015f 100644 --- a/full-moon/src/ast/lua54.rs +++ b/full-moon/src/ast/lua54.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; /// An attribute on a local variable, `` in `local x ` #[derive(Clone, Debug, Display, PartialEq, Eq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{}{}{}", "brackets.tokens().0", "name", "brackets.tokens().1")] +#[display("{}{}{}", brackets.tokens().0, name, brackets.tokens().1)] pub struct Attribute { #[node(full_range)] #[visit(contains = "name")] diff --git a/full-moon/src/ast/luau.rs b/full-moon/src/ast/luau.rs index 5c170bf0..2ffa4fc1 100644 --- a/full-moon/src/ast/luau.rs +++ b/full-moon/src/ast/luau.rs @@ -15,7 +15,7 @@ use derive_more::Display; #[non_exhaustive] pub enum TypeInfo { /// A shorthand type annotating the structure of an array: { number } - #[display(fmt = "{}{}{}", "braces.tokens().0", "type_info", "braces.tokens().1")] + #[display("{}{}{}", braces.tokens().0, type_info, braces.tokens().1)] Array { /// The braces (`{}`) containing the type info. braces: ContainedSpan, @@ -24,23 +24,23 @@ pub enum TypeInfo { }, /// A standalone type, such as `string` or `Foo`. - #[display(fmt = "{_0}")] + #[display("{_0}")] Basic(TokenReference), /// A singleton string type, such as `"hello"` - #[display(fmt = "{_0}")] + #[display("{_0}")] String(TokenReference), /// A singleton boolean type, such as `true` - #[display(fmt = "{_0}")] + #[display("{_0}")] Boolean(TokenReference), /// A callback type, such as `(string, number) => boolean`. #[display( - fmt = "{}{}{arguments}{}{arrow}{return_type}", - "display_option(generics)", - "parentheses.tokens().0", - "parentheses.tokens().1" + "{}{}{arguments}{}{arrow}{return_type}", + display_option(generics), + parentheses.tokens().0, + parentheses.tokens().1 )] Callback { /// Optional generics provided for the arguments, such as in `(T) -> string` @@ -57,11 +57,11 @@ pub enum TypeInfo { /// A type using generics, such as `map`. #[display( - fmt = "{}{}{}{}", - "base", - "arrows.tokens().0", - "generics", - "arrows.tokens().1" + "{}{}{}{}", + base, + arrows.tokens().0, + generics, + arrows.tokens().1 )] Generic { /// The type that has generics: `map`. @@ -74,7 +74,7 @@ pub enum TypeInfo { /// A generic pack: `T...`. /// Note, these are only available as return types, when annotating a vararg (`...`) in a function parameter, or as a generic type argument. - #[display(fmt = "{name}{ellipsis}")] + #[display("{name}{ellipsis}")] GenericPack { /// The name of the type that is generic: `T`. name: TokenReference, @@ -83,11 +83,11 @@ pub enum TypeInfo { }, /// An intersection type, such as `string & number`. - #[display(fmt = "{_0}")] + #[display("{_0}")] Intersection(TypeIntersection), /// A type coming from a module, such as `module.Foo` - #[display(fmt = "{module}{punctuation}{type_info}")] + #[display("{module}{punctuation}{type_info}")] Module { /// The module the type is coming from: `module`. module: TokenReference, @@ -98,7 +98,7 @@ pub enum TypeInfo { }, /// An optional type, such as `string?`. - #[display(fmt = "{base}{question_mark}")] + #[display("{base}{question_mark}")] Optional { /// The type that is optional: `string`. base: Box, @@ -107,7 +107,7 @@ pub enum TypeInfo { }, /// A type annotating the structure of a table: { foo: number, bar: string } - #[display(fmt = "{}{}{}", "braces.tokens().0", "fields", "braces.tokens().1")] + #[display("{}{}{}", braces.tokens().0, fields, braces.tokens().1)] Table { /// The braces (`{}`) containing the fields. braces: ContainedSpan, @@ -117,11 +117,11 @@ pub enum TypeInfo { /// A type in the form of `typeof(foo)`. #[display( - fmt = "{}{}{}{}", - "typeof_token", - "parentheses.tokens().0", - "inner", - "parentheses.tokens().1" + "{}{}{}{}", + typeof_token, + parentheses.tokens().0, + inner, + parentheses.tokens().1 )] Typeof { /// The token `typeof`. @@ -134,10 +134,10 @@ pub enum TypeInfo { /// A tuple expression: `(string, number)`. #[display( - fmt = "{}{}{}", - "parentheses.tokens().0", - "types", - "parentheses.tokens().1" + "{}{}{}", + parentheses.tokens().0, + types, + parentheses.tokens().1 )] Tuple { /// The parentheses used to contain the types @@ -147,11 +147,11 @@ pub enum TypeInfo { }, /// A union type, such as `string | number`. - #[display(fmt = "{_0}")] + #[display("{_0}")] Union(TypeUnion), /// A variadic type: `...number`. - #[display(fmt = "{ellipsis}{type_info}")] + #[display("{ellipsis}{type_info}")] Variadic { /// The ellipsis: `...`. ellipsis: TokenReference, @@ -160,7 +160,7 @@ pub enum TypeInfo { }, /// A variadic type pack: `...T` in `Function<...T>` - #[display(fmt = "{ellipsis}{name}")] + #[display("{ellipsis}{name}")] VariadicPack { /// The ellipsis: `...` ellipsis: TokenReference, @@ -172,7 +172,7 @@ pub enum TypeInfo { /// A union type, such as `string | number`. #[derive(Clone, Debug, Display, PartialEq, Node)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{}{types}", "display_option(leading)")] +#[display("{}{types}", display_option(leading))] pub struct TypeUnion { pub(crate) leading: Option, pub(crate) types: Punctuated, @@ -208,7 +208,7 @@ impl TypeUnion { /// An intersection type, such as `string & number`. #[derive(Clone, Debug, Display, PartialEq, Node)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{}{types}", "display_option(leading)")] +#[display("{}{types}", display_option(leading))] pub struct TypeIntersection { pub(crate) leading: Option, pub(crate) types: Punctuated, @@ -247,11 +247,11 @@ impl TypeIntersection { #[non_exhaustive] pub enum IndexedTypeInfo { /// A standalone type, such as `string` or `Foo`. - #[display(fmt = "{_0}")] + #[display("{_0}")] Basic(TokenReference), /// A type using generics, such as `map`. - #[display(fmt = "{base}{}{generics}{}", "arrows.tokens().0", "arrows.tokens().1")] + #[display("{base}{}{generics}{}", arrows.tokens().0, arrows.tokens().1)] Generic { /// The type that has generics: `map`. base: TokenReference, @@ -266,7 +266,7 @@ pub enum IndexedTypeInfo { /// The `foo: number` in `{ foo: number }`. #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{key}{colon}{value}")] +#[display("{key}{colon}{value}")] pub struct TypeField { pub(crate) key: TypeFieldKey, pub(crate) colon: TokenReference, @@ -323,11 +323,11 @@ impl TypeField { #[non_exhaustive] pub enum TypeFieldKey { /// A name, such as `foo`. - #[display(fmt = "{_0}")] + #[display("{_0}")] Name(TokenReference), /// An index signature, such as `[number]`. - #[display(fmt = "{}{}{}", "brackets.tokens().0", "inner", "brackets.tokens().1")] + #[display("{}{}{}", brackets.tokens().0, inner, brackets.tokens().1)] IndexSignature { /// The brackets (`[]`) used to contain the type. brackets: ContainedSpan, @@ -340,7 +340,7 @@ pub enum TypeFieldKey { /// A type assertion using `::`, such as `:: number`. #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{assertion_op}{cast_to}")] +#[display("{assertion_op}{cast_to}")] pub struct TypeAssertion { pub(crate) assertion_op: TokenReference, pub(crate) cast_to: TypeInfo, @@ -383,12 +383,12 @@ impl TypeAssertion { #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[display( - fmt = "{}{}{}{}{}", - "type_token", - "base", - "display_option(generics)", - "equal_token", - "declare_as" + "{}{}{}{}{}", + type_token, + base, + display_option(generics), + equal_token, + declare_as )] pub struct TypeDeclaration { pub(crate) type_token: TokenReference, @@ -482,11 +482,11 @@ impl TypeDeclaration { #[non_exhaustive] pub enum GenericParameterInfo { /// A name, such as `foo`. - #[display(fmt = "{_0}")] + #[display("{_0}")] Name(TokenReference), /// A variadic type pack: `T...`. - #[display(fmt = "{name}{ellipsis}")] + #[display("{name}{ellipsis}")] Variadic { /// The name of the type that is variadic: `T`. name: TokenReference, @@ -498,10 +498,10 @@ pub enum GenericParameterInfo { #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[display( - fmt = "{}{}{}", - "parameter", - "display_option(self.equals())", - "display_option(self.default_type())" + "{}{}{}", + parameter, + display_option(self.equals()), + display_option(self.default_type()) )] pub struct GenericDeclarationParameter { pub(crate) parameter: GenericParameterInfo, @@ -546,7 +546,7 @@ impl GenericDeclarationParameter { /// The generics used in a [`TypeDeclaration`]. #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{}{}{}", "arrows.tokens().0", "generics", "arrows.tokens().1")] +#[display("{}{}{}", arrows.tokens().0, generics, arrows.tokens().1)] pub struct GenericDeclaration { #[visit(contains = "generics")] pub(crate) arrows: ContainedSpan, @@ -595,7 +595,7 @@ impl Default for GenericDeclaration { /// A type specifier, the `: number` in `local foo: number` #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{punctuation}{type_info}")] +#[display("{punctuation}{type_info}")] pub struct TypeSpecifier { pub(crate) punctuation: TokenReference, pub(crate) type_info: TypeInfo, @@ -686,7 +686,7 @@ impl fmt::Display for TypeArgument { /// An exported type declaration, such as `export type Meters = number` #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{export_token}{type_declaration}")] +#[display("{export_token}{type_declaration}")] pub struct ExportedTypeDeclaration { pub(crate) export_token: TokenReference, pub(crate) type_declaration: TypeDeclaration, @@ -738,7 +738,7 @@ impl ExportedTypeDeclaration { #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[non_exhaustive] #[allow(missing_docs)] -#[display(fmt = "{}")] +#[display("{_0}")] /// Compound operators, such as X += Y or X -= Y pub enum CompoundOp { PlusEqual(TokenReference), @@ -792,7 +792,7 @@ impl CompoundOp { /// A Compound Assignment statement, such as `x += 1` or `x -= 1` #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{lhs}{compound_operator}{rhs}")] +#[display("{lhs}{compound_operator}{rhs}")] pub struct CompoundAssignment { pub(crate) lhs: Var, pub(crate) compound_operator: CompoundOp, @@ -847,14 +847,14 @@ impl CompoundAssignment { #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[display( - fmt = "{}{}{}{}{}{}{}", - "if_token", - "condition", - "then_token", - "if_expression", - "display_option(else_if_expressions.as_ref().map(join_vec))", - "else_token", - "else_expression" + "{}{}{}{}{}{}{}", + if_token, + condition, + then_token, + if_expression, + display_option(else_if_expressions.as_ref().map(join_vec)), + else_token, + else_expression )] pub struct IfExpression { pub(crate) if_token: TokenReference, @@ -971,7 +971,7 @@ impl IfExpression { /// An elseif expression in a bigger [`IfExpression`] expression #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{else_if_token}{condition}{then_token}{expression}")] +#[display("{else_if_token}{condition}{then_token}{expression}")] pub struct ElseIfExpression { pub(crate) else_if_token: TokenReference, pub(crate) condition: Expression, @@ -1044,7 +1044,7 @@ impl ElseIfExpression { /// The `last_string` would be the literal 3, with a backtick afterwards. #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{}{}", "join_vec(segments)", "last_string")] +#[display("{}{}", join_vec(segments), last_string)] pub struct InterpolatedString { pub(crate) segments: Vec, pub(crate) last_string: TokenReference, @@ -1095,7 +1095,7 @@ impl InterpolatedString { /// Read the documentation for [`InterpolatedString`] for more information. #[derive(Clone, Debug, Display, PartialEq, Node)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{literal}{expression}")] +#[display("{literal}{expression}")] pub struct InterpolatedStringSegment { /// The literal part of the segment. Guaranteed to be of TokenType::InterpolatedString pub literal: TokenReference, diff --git a/full-moon/src/ast/mod.rs b/full-moon/src/ast/mod.rs index b80892a2..04e423e8 100644 --- a/full-moon/src/ast/mod.rs +++ b/full-moon/src/ast/mod.rs @@ -45,9 +45,9 @@ pub mod lua54; #[derive(Clone, Debug, Default, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[display( - fmt = "{}{}", - "display_optional_punctuated_vec(stmts)", - "display_option(&last_stmt.as_ref().map(display_optional_punctuated))" + "{}{}", + display_optional_punctuated_vec(stmts), + display_option(last_stmt.as_ref().map(display_optional_punctuated)) )] pub struct Block { stmts: Vec<(Stmt, Option)>, @@ -127,7 +127,7 @@ pub enum LastStmt { /// A `return` statement #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{token}{returns}")] +#[display("{token}{returns}")] pub struct Return { token: TokenReference, returns: Punctuated, @@ -177,12 +177,12 @@ impl Default for Return { pub enum Field { /// A key in the format of `[expression] = value` #[display( - fmt = "{}{}{}{}{}", - "brackets.tokens().0", - "key", - "brackets.tokens().1", - "equal", - "value" + "{}{}{}{}{}", + brackets.tokens().0, + key, + brackets.tokens().1, + equal, + value )] ExpressionKey { /// The `[...]` part of `[expression] = value` @@ -196,7 +196,7 @@ pub enum Field { }, /// A key in the format of `name = value` - #[display(fmt = "{key}{equal}{value}")] + #[display("{key}{equal}{value}")] NameKey { /// The `name` part of `name = value` key: TokenReference, @@ -207,14 +207,14 @@ pub enum Field { }, /// A field with no key, just a value (such as `"a"` in `{ "a" }`) - #[display(fmt = "{_0}")] + #[display("{_0}")] NoKey(Expression), } /// A table being constructed, such as `{ 1, 2, 3 }` or `{ a = 1 }` #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{}{}{}", "braces.tokens().0", "fields", "braces.tokens().1")] +#[display("{}{}{}", braces.tokens().0, fields, braces.tokens().1)] pub struct TableConstructor { #[node(full_range)] #[visit(contains = "fields")] @@ -268,7 +268,7 @@ impl Default for TableConstructor { #[non_exhaustive] pub enum Expression { /// A binary operation, such as `1 + 3` - #[display(fmt = "{lhs}{binop}{rhs}")] + #[display("{lhs}{binop}{rhs}")] BinaryOperator { /// The left hand side of the binary operation, the `1` part of `1 + 3` lhs: Box, @@ -279,12 +279,7 @@ pub enum Expression { }, /// A statement in parentheses, such as `(#list)` - #[display( - fmt = "{}{}{}", - "contained.tokens().0", - "expression", - "contained.tokens().1" - )] + #[display("{}{}{}", contained.tokens().0, expression, contained.tokens().1)] Parentheses { /// The parentheses of the expression #[node(full_range)] @@ -294,7 +289,7 @@ pub enum Expression { }, /// A unary operation, such as `#list` - #[display(fmt = "{unop}{expression}")] + #[display("{unop}{expression}")] UnaryOperator { /// The unary operation, the `#` part of `#list` unop: UnOp, @@ -303,45 +298,45 @@ pub enum Expression { }, /// An anonymous function, such as `function() end` - #[display(fmt = "{}{}", "_0.0", "_0.1")] + #[display("{}{}", _0.0, _0.1)] Function(Box<(TokenReference, FunctionBody)>), /// A call of a function, such as `call()` - #[display(fmt = "{_0}")] + #[display("{_0}")] FunctionCall(FunctionCall), /// An if expression, such as `if foo then true else false`. /// Only available when the "luau" feature flag is enabled. #[cfg(feature = "luau")] - #[display(fmt = "{_0}")] + #[display("{_0}")] IfExpression(IfExpression), /// An interpolated string, such as `` `hello {"world"}` `` /// Only available when the "luau" feature flag is enabled. #[cfg(feature = "luau")] - #[display(fmt = "{_0}")] + #[display("{_0}")] InterpolatedString(InterpolatedString), /// A table constructor, such as `{ 1, 2, 3 }` - #[display(fmt = "{_0}")] + #[display("{_0}")] TableConstructor(TableConstructor), /// A number token, such as `3.3` - #[display(fmt = "{_0}")] + #[display("{_0}")] Number(TokenReference), /// A string token, such as `"hello"` - #[display(fmt = "{_0}")] + #[display("{_0}")] String(TokenReference), /// A symbol, such as `true` - #[display(fmt = "{_0}")] + #[display("{_0}")] Symbol(TokenReference), /// A value that has been asserted for a particular type, for use in Luau. /// Only available when the "luau" feature flag is enabled. #[cfg(feature = "luau")] - #[display(fmt = "{expression}{type_assertion}")] + #[display("{expression}{type_assertion}")] TypeAssertion { /// The expression being asserted expression: Box, @@ -351,7 +346,7 @@ pub enum Expression { }, /// A more complex value, such as `call().x` - #[display(fmt = "{_0}")] + #[display("{_0}")] Var(Var), } @@ -361,43 +356,43 @@ pub enum Expression { #[non_exhaustive] pub enum Stmt { /// An assignment, such as `x = 1` - #[display(fmt = "{_0}")] + #[display("{_0}")] Assignment(Assignment), /// A do block, `do end` - #[display(fmt = "{_0}")] + #[display("{_0}")] Do(Do), /// A function call on its own, such as `call()` - #[display(fmt = "{_0}")] + #[display("{_0}")] FunctionCall(FunctionCall), /// A function declaration, such as `function x() end` - #[display(fmt = "{_0}")] + #[display("{_0}")] FunctionDeclaration(FunctionDeclaration), /// A generic for loop, such as `for index, value in pairs(list) do end` - #[display(fmt = "{_0}")] + #[display("{_0}")] GenericFor(GenericFor), /// An if statement - #[display(fmt = "{_0}")] + #[display("{_0}")] If(If), /// A local assignment, such as `local x = 1` - #[display(fmt = "{_0}")] + #[display("{_0}")] LocalAssignment(LocalAssignment), /// A local function declaration, such as `local function x() end` - #[display(fmt = "{_0}")] + #[display("{_0}")] LocalFunction(LocalFunction), /// A numeric for loop, such as `for index = 1, 10 do end` - #[display(fmt = "{_0}")] + #[display("{_0}")] NumericFor(NumericFor), /// A repeat loop - #[display(fmt = "{_0}")] + #[display("{_0}")] Repeat(Repeat), /// A while loop - #[display(fmt = "{_0}")] + #[display("{_0}")] While(While), /// A compound assignment, such as `+=` /// Only available when the "luau" feature flag is enabled #[cfg(feature = "luau")] - #[display(fmt = "{_0}")] + #[display("{_0}")] CompoundAssignment(CompoundAssignment), /// An exported type declaration, such as `export type Meters = number` /// Only available when the "luau" feature flag is enabled. @@ -424,10 +419,10 @@ pub enum Stmt { #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[non_exhaustive] pub enum Prefix { - #[display(fmt = "{_0}")] + #[display("{_0}")] /// A complicated expression, such as `("foo")` Expression(Box), - #[display(fmt = "{_0}")] + #[display("{_0}")] /// Just a name, such as `foo` Name(TokenReference), } @@ -439,12 +434,7 @@ pub enum Prefix { #[non_exhaustive] pub enum Index { /// Indexing in the form of `x["y"]` - #[display( - fmt = "{}{}{}", - "brackets.tokens().0", - "expression", - "brackets.tokens().1" - )] + #[display("{}{}{}", brackets.tokens().0, expression, brackets.tokens().1)] Brackets { /// The `[...]` part of `["y"]` brackets: ContainedSpan, @@ -453,7 +443,7 @@ pub enum Index { }, /// Indexing in the form of `x.y` - #[display(fmt = "{dot}{name}")] + #[display("{dot}{name}")] Dot { /// The `.` part of `.y` dot: TokenReference, @@ -469,10 +459,10 @@ pub enum Index { pub enum FunctionArgs { /// Used when a function is called in the form of `call(1, 2, 3)` #[display( - fmt = "{}{}{}", - "parentheses.tokens().0", - "arguments", - "parentheses.tokens().1" + "{}{}{}", + parentheses.tokens().0, + arguments, + parentheses.tokens().1 )] Parentheses { /// The `(...) part of (1, 2, 3)` @@ -482,10 +472,10 @@ pub enum FunctionArgs { arguments: Punctuated, }, /// Used when a function is called in the form of `call "foobar"` - #[display(fmt = "{_0}")] + #[display("{_0}")] String(TokenReference), /// Used when a function is called in the form of `call { 1, 2, 3 }` - #[display(fmt = "{_0}")] + #[display("{_0}")] TableConstructor(TableConstructor), } @@ -888,15 +878,15 @@ impl fmt::Display for GenericFor { #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[display( - fmt = "{}{}{}{}{}{}{}{}", - "if_token", - "condition", - "then_token", - "block", - "display_option(else_if.as_ref().map(join_vec))", - "display_option(else_token)", - "display_option(r#else)", - "end_token" + "{}{}{}{}{}{}{}{}", + if_token, + condition, + then_token, + block, + display_option(else_if.as_ref().map(join_vec)), + display_option(else_token), + display_option(r#else), + end_token )] pub struct If { if_token: TokenReference, @@ -1011,7 +1001,7 @@ impl If { /// An elseif block in a bigger [`If`] statement #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{else_if_token}{condition}{then_token}{block}")] +#[display("{else_if_token}{condition}{then_token}{block}")] pub struct ElseIf { else_if_token: TokenReference, condition: Expression, @@ -1077,7 +1067,7 @@ impl ElseIf { /// A while loop #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{while_token}{condition}{do_token}{block}{end_token}")] +#[display("{while_token}{condition}{do_token}{block}{end_token}")] pub struct While { while_token: TokenReference, condition: Expression, @@ -1155,7 +1145,7 @@ impl While { /// A repeat loop #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{repeat_token}{block}{until_token}{until}")] +#[display("{repeat_token}{block}{until_token}{until}")] pub struct Repeat { repeat_token: TokenReference, block: Block, @@ -1224,7 +1214,7 @@ impl Repeat { /// A method call, such as `x:y()` #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{colon_token}{name}{args}")] +#[display("{colon_token}{name}{args}")] pub struct MethodCall { colon_token: TokenReference, name: TokenReference, @@ -1280,10 +1270,10 @@ impl MethodCall { #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[non_exhaustive] pub enum Call { - #[display(fmt = "{_0}")] + #[display("{_0}")] /// A function being called directly, such as `x(1)` AnonymousCall(FunctionArgs), - #[display(fmt = "{_0}")] + #[display("{_0}")] /// A method call, such as `x:y()` MethodCall(MethodCall), } @@ -1478,10 +1468,10 @@ pub enum Parameter { #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[non_exhaustive] pub enum Suffix { - #[display(fmt = "{_0}")] + #[display("{_0}")] /// A call, including method calls and direct calls Call(Call), - #[display(fmt = "{_0}")] + #[display("{_0}")] /// An index, such as `x.y` Index(Index), } @@ -1489,7 +1479,7 @@ pub enum Suffix { /// A complex expression used by [`Var`], consisting of both a prefix and suffixes #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{}{}", "prefix", "join_vec(suffixes)")] +#[display("{}{}", prefix, join_vec(suffixes))] pub struct VarExpression { prefix: Prefix, suffixes: Vec, @@ -1531,17 +1521,17 @@ impl VarExpression { #[non_exhaustive] pub enum Var { /// An expression, such as `x.y.z` or `x()` - #[display(fmt = "{_0}")] + #[display("{_0}")] Expression(Box), /// A literal identifier, such as `x` - #[display(fmt = "{_0}")] + #[display("{_0}")] Name(TokenReference), } /// An assignment, such as `x = y`. Not used for [`LocalAssignment`s](LocalAssignment) #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{var_list}{equal_token}{expr_list}")] +#[display("{var_list}{equal_token}{expr_list}")] pub struct Assignment { var_list: Punctuated, equal_token: TokenReference, @@ -1599,12 +1589,9 @@ impl Assignment { #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[cfg_attr( not(feature = "luau"), - display(fmt = "{local_token}{function_token}{name}{body}") -)] -#[cfg_attr( - feature = "luau", - display(fmt = "{local_token}{function_token}{name}{body}") + display("{local_token}{function_token}{name}{body}") )] +#[cfg_attr(feature = "luau", display("{local_token}{function_token}{name}{body}"))] pub struct LocalFunction { local_token: TokenReference, function_token: TokenReference, @@ -1815,7 +1802,7 @@ impl fmt::Display for LocalAssignment { /// This is not used for things like `while true do end`, only those on their own #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{do_token}{block}{end_token}")] +#[display("{do_token}{block}{end_token}")] pub struct Do { do_token: TokenReference, block: Block, @@ -1872,7 +1859,7 @@ impl Default for Do { /// A function being called, such as `call()` #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{}{}", "prefix", "join_vec(suffixes)")] +#[display("{}{}", prefix, join_vec(suffixes))] pub struct FunctionCall { prefix: Prefix, suffixes: Vec, @@ -1921,10 +1908,10 @@ impl FunctionCall { #[derive(Clone, Debug, Display, PartialEq, Eq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[display( - fmt = "{}{}{}", - "names", - "display_option(self.method_colon())", - "display_option(self.method_name())" + "{}{}{}", + names, + display_option(self.method_colon()), + display_option(self.method_name()) )] pub struct FunctionName { names: Punctuated, @@ -1975,8 +1962,8 @@ impl FunctionName { /// as well as complicated declarations such as `function x.y.z:a() end` #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[cfg_attr(not(feature = "luau"), display(fmt = "{function_token}{name}{body}"))] -#[cfg_attr(feature = "luau", display(fmt = "{function_token}{name}{body}"))] +#[cfg_attr(not(feature = "luau"), display("{function_token}{name}{body}"))] +#[cfg_attr(feature = "luau", display("{function_token}{name}{body}"))] pub struct FunctionDeclaration { function_token: TokenReference, name: FunctionName, @@ -2038,7 +2025,7 @@ macro_rules! make_bin_op { #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[non_exhaustive] $(#[$outer])* - #[display(fmt = "{}")] + #[display("{_0}")] pub enum BinOp { $( #[allow(missing_docs)] @@ -2183,7 +2170,7 @@ impl BinOp { #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[allow(missing_docs)] #[non_exhaustive] -#[display(fmt = "{}")] +#[display("{_0}")] pub enum UnOp { Minus(TokenReference), Not(TokenReference), diff --git a/full-moon/src/ast/parsers.rs b/full-moon/src/ast/parsers.rs index 18a2d8cd..a40c764a 100644 --- a/full-moon/src/ast/parsers.rs +++ b/full-moon/src/ast/parsers.rs @@ -2345,7 +2345,7 @@ fn parse_simple_type( TokenType::Identifier { .. } => { let name = state.consume().unwrap(); - if name.to_string() == "typeof" { + if name.token.to_string() == "typeof" { let left_parenthesis = match state.require(Symbol::LeftParen, "expected `(` after `typeof`") { Some(token) => token, diff --git a/full-moon/src/ast/punctuated.rs b/full-moon/src/ast/punctuated.rs index 598ffedd..74e114c5 100644 --- a/full-moon/src/ast/punctuated.rs +++ b/full-moon/src/ast/punctuated.rs @@ -21,7 +21,7 @@ use crate::{ util, visitors::{Visit, VisitMut, Visitor, VisitorMut}, }; -use derive_more::Display; +use derive_more::Display as DeriveDisplay; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use std::{fmt::Display, iter::FromIterator}; @@ -29,10 +29,10 @@ use std::{fmt::Display, iter::FromIterator}; /// A punctuated sequence of node `T` separated by /// [`TokenReference`](crate::tokenizer::TokenReference). /// Refer to the [module documentation](index.html) for more details. -#[derive(Clone, Debug, Display, PartialEq, Eq)] +#[derive(Clone, Debug, DeriveDisplay, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(bound = "T: Display")] -#[display(fmt = "{}", "util::join_vec(pairs)")] +#[display(bound(T: Display))] +#[display("{}", util::join_vec(pairs))] pub struct Punctuated { pairs: Vec>, } @@ -335,17 +335,17 @@ impl<'a, T> Iterator for IterMut<'a, T> { /// A node `T` followed by the possible trailing /// [`TokenReference`](crate::tokenizer::TokenReference). /// Refer to the [module documentation](index.html) for more details. -#[derive(Clone, Debug, Display, PartialEq, Eq)] -#[display(bound = "T: Display")] +#[derive(Clone, Debug, DeriveDisplay, PartialEq, Eq)] +#[display(bound(T: Display))] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub enum Pair { /// A node `T` with no trailing punctuation - #[display(fmt = "{_0}")] + #[display("{_0}")] End(T), /// A node `T` followed by punctuation (in the form of a /// [`TokenReference`](crate::tokenizer::TokenReference)) - #[display(fmt = "{_0}{_1}")] + #[display("{_0}{_1}")] Punctuated(T, TokenReference), } diff --git a/full-moon/src/lib.rs b/full-moon/src/lib.rs index a0b7b518..6c42b295 100644 --- a/full-moon/src/lib.rs +++ b/full-moon/src/lib.rs @@ -1,6 +1,6 @@ #![warn(missing_docs)] #![allow(clippy::large_enum_variant)] -#![cfg_attr(doc_cfg, feature(doc_auto_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] //! # Full Moon //! //! `full_moon` is a lossless parser for Lua, supporting Lua 5.1, 5.2, 5.3, 5.4 and Luau @@ -95,16 +95,17 @@ pub fn parse(code: &str) -> Result> { /// Given code and a pinned Lua version, will produce an [`ast::AstResult`]. /// This AstResult always produces some [`Ast`](ast::Ast), regardless of errors. -/// If a partial Ast is produced (i.e. if there are any errors), a few guarantees are lost. +/// If a partial Ast is produced (i.e. if there are any errors), a few guarantees are lost: +/// /// 1. Tokens may be produced that aren't in the code itself. For example, `if x == 2 code()` -/// will produce a phantom `then` token in order to produce a usable [`If`](ast::If) struct. -/// These phantom tokens will have a null position. If you need accurate positions from the -/// phantom tokens, you can call [`Ast::update_positions`](ast::Ast::update_positions). +/// will produce a phantom `then` token in order to produce a usable [`If`](ast::If) struct. +/// These phantom tokens will have a null position. If you need accurate positions from the +/// phantom tokens, you can call [`Ast::update_positions`](ast::Ast::update_positions). /// 2. The code, when printed, is not guaranteed to be valid Lua. -/// This can happen in the case of something like `local x = if`, which will produce a -/// [`LocalAssignment`](ast::LocalAssignment) that would print to `local x =`. +/// This can happen in the case of something like `local x = if`, which will produce a +/// [`LocalAssignment`](ast::LocalAssignment) that would print to `local x =`. /// 3. There are no stability guarantees for partial Ast results, but they are consistent -/// within the same exact version of full-moon. +/// within the same exact version of full-moon. pub fn parse_fallible(code: &str, lua_version: LuaVersion) -> ast::AstResult { ast::AstResult::parse_fallible(code, lua_version) } diff --git a/full-moon/src/short_string.rs b/full-moon/src/short_string.rs index 1638b26e..d297a00c 100644 --- a/full-moon/src/short_string.rs +++ b/full-moon/src/short_string.rs @@ -14,7 +14,7 @@ pub struct ShortString(SmolStr); impl ShortString { /// Creates a new ShortString from the given text. pub fn new + AsRef>(text: T) -> Self { - ShortString(SmolStr::from(text)) + ShortString(SmolStr::new(text)) } /// Returns a `&str` representation of the ShortString. @@ -49,7 +49,7 @@ impl Deref for ShortString { impl + AsRef> From for ShortString { fn from(value: T) -> Self { - ShortString(SmolStr::from(value)) + ShortString(SmolStr::new(value)) } } diff --git a/full-moon/src/tokenizer/structs.rs b/full-moon/src/tokenizer/structs.rs index 59de04aa..70079082 100644 --- a/full-moon/src/tokenizer/structs.rs +++ b/full-moon/src/tokenizer/structs.rs @@ -914,8 +914,9 @@ impl fmt::Display for TokenizerError { impl std::error::Error for TokenizerError {} -// #[cfg(test)] -#[cfg(feature = "rewrite todo: tokenizer tests")] +/* +// rewrite TODO: tokenizer tests + mod tests { use crate::tokenizer::*; use pretty_assertions::assert_eq; @@ -1193,3 +1194,4 @@ mod tests { let _ = tokens("ยน;"); } } +*/ diff --git a/full-moon/tests/fail_cases.rs b/full-moon/tests/fail_cases.rs index 7f96331e..7f252f13 100644 --- a/full-moon/tests/fail_cases.rs +++ b/full-moon/tests/fail_cases.rs @@ -6,7 +6,7 @@ use full_moon::{ ast::{AstResult, LuaVersion}, tokenizer::{self, LexerResult}, }; -use insta::{assert_display_snapshot, assert_yaml_snapshot}; +use insta::{assert_snapshot, assert_yaml_snapshot}; use std::{fs, path::Path}; mod common; @@ -53,7 +53,7 @@ fn process_codespan_display(source: &str, result: &AstResult) { codespan_reporting::term::emit(&mut output, &config, &files, &diagnostic).unwrap(); } - assert_display_snapshot!( + assert_snapshot!( "error_display", String::from_utf8(output.into_inner()).unwrap() ); diff --git a/full-moon/tests/roblox_cases/pass/multiline_typeof_regression/ast.snap b/full-moon/tests/roblox_cases/pass/multiline_typeof_regression/ast.snap new file mode 100644 index 00000000..c818214b --- /dev/null +++ b/full-moon/tests/roblox_cases/pass/multiline_typeof_regression/ast.snap @@ -0,0 +1,190 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/roblox_cases/pass/multiline_typeof_regression +--- +stmts: + - - TypeDeclaration: + type_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: TypeOf + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + generics: ~ + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: "\n" + declare_as: + Typeof: + typeof_token: + leading_trivia: + - start_position: + bytes: 14 + line: 2 + character: 1 + end_position: + bytes: 18 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 18 + line: 2 + character: 5 + end_position: + bytes: 24 + line: 2 + character: 11 + token_type: + type: Identifier + identifier: typeof + trailing_trivia: [] + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 24 + line: 2 + character: 11 + end_position: + bytes: 25 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 27 + line: 2 + character: 14 + end_position: + bytes: 28 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 28 + line: 2 + character: 15 + end_position: + bytes: 29 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: "\n" + inner: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 25 + line: 2 + character: 12 + end_position: + bytes: 26 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 26 + line: 2 + character: 13 + end_position: + bytes: 27 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: [] + - ~ diff --git a/full-moon/tests/roblox_cases/pass/multiline_typeof_regression/source.lua b/full-moon/tests/roblox_cases/pass/multiline_typeof_regression/source.lua new file mode 100644 index 00000000..918ba268 --- /dev/null +++ b/full-moon/tests/roblox_cases/pass/multiline_typeof_regression/source.lua @@ -0,0 +1,2 @@ +type TypeOf = + typeof({}) diff --git a/full-moon/tests/roblox_cases/pass/multiline_typeof_regression/tokens.snap b/full-moon/tests/roblox_cases/pass/multiline_typeof_regression/tokens.snap new file mode 100644 index 00000000..b2697c3c --- /dev/null +++ b/full-moon/tests/roblox_cases/pass/multiline_typeof_regression/tokens.snap @@ -0,0 +1,158 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/roblox_cases/pass/multiline_typeof_regression +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: TypeOf +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 14 + line: 2 + character: 1 + end_position: + bytes: 18 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 2 + character: 5 + end_position: + bytes: 24 + line: 2 + character: 11 + token_type: + type: Identifier + identifier: typeof +- start_position: + bytes: 24 + line: 2 + character: 11 + end_position: + bytes: 25 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 25 + line: 2 + character: 12 + end_position: + bytes: 26 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 26 + line: 2 + character: 13 + end_position: + bytes: 27 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 27 + line: 2 + character: 14 + end_position: + bytes: 28 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 28 + line: 2 + character: 15 + end_position: + bytes: 29 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 29 + line: 3 + character: 1 + end_position: + bytes: 29 + line: 3 + character: 1 + token_type: + type: Eof