Skip to main content

luaparse_rs/ast/
common.rs

1//! Shared types used across the syntax tree: identifiers, blocks, comments, and parameters.
2
3use alloc::{string::String, vec::Vec};
4
5use crate::Span;
6use super::stmt::Stmt;
7
8/// A name in the source code, like a variable or function name.
9#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10pub struct Identifier {
11    /// The actual text of the name.
12    pub name: String,
13    /// Where it appears in the source.
14    pub span: Span,
15}
16
17impl Identifier {
18    pub fn new(name: String, span: Span) -> Self {
19        Self { name, span }
20    }
21}
22
23/// A variable name that may have an attribute attached.
24///
25/// In Lua 5.4, local variables can have attributes like `<const>` or `<close>`.
26/// For example: `local f <close> = io.open("file")`.
27#[derive(Debug, Clone, PartialEq)]
28pub struct VariableName {
29    /// The variable's name.
30    pub name: Identifier,
31    /// An optional attribute (e.g. `const` or `close` in Lua 5.4).
32    pub attribute: Option<Identifier>,
33}
34
35impl VariableName {
36    pub fn new(name: Identifier, attribute: Option<Identifier>) -> Self {
37        Self { name, attribute }
38    }
39    
40    pub fn simple(name: Identifier) -> Self {
41        Self { name, attribute: None }
42    }
43}
44
45/// A sequence of statements, like the body of a function or loop.
46#[derive(Debug, Clone, PartialEq)]
47pub struct Block {
48    /// The statements in this block, in order.
49    pub statements: Vec<Stmt>,
50    /// The span covering the entire block.
51    pub span: Span,
52}
53
54impl Block {
55    pub fn new(statements: Vec<Stmt>, span: Span) -> Self {
56        Self { statements, span }
57    }
58    
59    pub fn empty(span: Span) -> Self {
60        Self {
61            statements: Vec::new(),
62            span,
63        }
64    }
65}
66
67/// A comment found in the source code.
68///
69/// Both line comments (`-- hello`) and block comments (`--[[ hello ]]`) are captured.
70#[derive(Debug, Clone, PartialEq)]
71pub struct Comment {
72    /// The text of the comment (without the `--` prefix or block delimiters).
73    pub content: String,
74    /// `true` for block comments (`--[[ ]]`), `false` for line comments (`--`).
75    pub is_block: bool,
76    /// Where it appears in the source.
77    pub span: Span,
78}
79
80impl Comment {
81    pub fn new(content: String, is_block: bool, span: Span) -> Self {
82        Self { content, is_block, span }
83    }
84}
85
86/// A type annotation's source location.
87///
88/// This is a lightweight marker that just records where the annotation is
89/// in the source. The actual type expression lives in the Luau type system;
90/// see [`TypeExpr`](super::types::TypeExpr) for the full representation.
91#[derive(Debug, Clone, PartialEq)]
92pub struct TypeAnnotation {
93    /// The span covering the entire type annotation.
94    pub span: Span,
95}
96
97impl TypeAnnotation {
98    pub fn new(span: Span) -> Self {
99        Self { span }
100    }
101}
102
103/// A function parameter.
104///
105/// Can be a named parameter, a variadic (`...`), or (in Luau) a typed parameter.
106#[derive(Debug, Clone, PartialEq)]
107pub struct Parameter {
108    /// The parameter name, if it has one. Varargs (`...`) have no name.
109    pub name: Option<Identifier>,
110    /// An optional attribute on the parameter.
111    pub attribute: Option<Identifier>,
112    /// An optional Luau type annotation (e.g. `: string`).
113    pub type_annotation: Option<TypeAnnotation>,
114    /// `true` if this is a `...` vararg parameter.
115    pub is_vararg: bool,
116    /// Where it appears in the source.
117    pub span: Span,
118}
119
120impl Parameter {
121    pub fn new(
122        name: Option<Identifier>,
123        attribute: Option<Identifier>,
124        type_annotation: Option<TypeAnnotation>,
125        is_vararg: bool,
126        span: Span,
127    ) -> Self {
128        Self {
129            name,
130            attribute,
131            type_annotation,
132            is_vararg,
133            span,
134        }
135    }
136    
137    pub fn vararg(span: Span) -> Self {
138        Self {
139            name: None,
140            attribute: None,
141            type_annotation: None,
142            is_vararg: true,
143            span,
144        }
145    }
146    
147    pub fn identifier(name: Identifier) -> Self {
148        let span = name.span.clone();
149        Self {
150            name: Some(name),
151            attribute: None,
152            type_annotation: None,
153            is_vararg: false,
154            span,
155        }
156    }
157}