Skip to content

Commit 4353a66

Browse files
authored
feat: support identifier enum variant (#70)
This adds support for enum variant which includes identifier as its member. - Literal variant > Member will always be treated as string value. This matches the LLS behavior. ```lua ---| '<literal>' [# description] ``` - Identifier variant ```lua ---| `<identifier>` [# description] ```
1 parent 3a180f8 commit 4353a66

File tree

6 files changed

+59
-23
lines changed

6 files changed

+59
-23
lines changed

emmylua.md

+7-6
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,8 @@ You can define a (pseudo) enum using [`---@alias`](#alias).
645645

646646
```lua
647647
---@alias <name> <type>
648-
---| '<value>' [# description]
648+
---| '<literal>' [# description]
649+
---| `<identifier>` [# description]
649650
```
650651

651652
- Input
@@ -660,7 +661,7 @@ local U = {}
660661
---| '"line"' # Vertical motion
661662
---| '"char"' # Horizontal motion
662663
---| 'v'
663-
---| 'V' # Visual Line Mode
664+
---| `some.ident` # Some identifier
664665

665666
---Global vim mode
666667
---@type VMode
@@ -678,10 +679,10 @@ VMode *VMode*
678679
Read `:h map-operator`
679680
680681
Variants: ~
681-
("line") Vertical motion
682-
("char") Horizontal motion
683-
(v)
684-
(V) Visual Line Mode
682+
("line") Vertical motion
683+
("char") Horizontal motion
684+
("v")
685+
(some.ident) Some identifier
685686
686687
687688
U.VMODE *U.VMODE*

src/lexer.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,18 @@ impl Lexer {
4848
)))
4949
.ignored();
5050

51-
let union_literal = just('\'')
52-
.ignore_then(filter(|c| c != &'\'').repeated())
53-
.then_ignore(just('\''))
54-
.collect();
51+
let union_literal = choice((
52+
just('\'')
53+
.ignore_then(filter(|c| c != &'\'').repeated())
54+
.then_ignore(just('\''))
55+
.collect()
56+
.map(Member::Literal),
57+
just('`')
58+
.ignore_then(filter(|c| c != &'`').repeated())
59+
.then_ignore(just('`'))
60+
.collect()
61+
.map(Member::Ident),
62+
));
5563

5664
let variant = just('|')
5765
.then_ignore(space)
@@ -149,7 +157,7 @@ impl Lexer {
149157
.delimited_by(just('(').padded(), just(')').padded());
150158

151159
// Union of string literals: '"g@"'|'"g@$"'
152-
let string_literal = union_literal.map(Ty::Ref);
160+
let string_literal = union_literal.map(Ty::Member);
153161

154162
choice((
155163
array_union(any, inner.clone()),

src/lexer/token.rs

+26-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
use std::fmt::Display;
22

3+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4+
pub enum Member {
5+
Literal(String),
6+
Ident(String),
7+
}
8+
9+
impl Display for Member {
10+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11+
match self {
12+
Self::Literal(lit) => f.write_str(&format!(
13+
r#""{}""#,
14+
lit.trim_start_matches('"').trim_end_matches('"')
15+
)),
16+
Self::Ident(ident) => f.write_str(ident),
17+
}
18+
}
19+
}
20+
321
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
422
pub enum TagType {
523
/// ```lua
@@ -63,9 +81,13 @@ pub enum TagType {
6381
/// ```
6482
Alias(String, Option<Ty>),
6583
/// ```lua
66-
/// ---| '<value>' [# description]
84+
/// ---| '<literal>' [# description]
85+
///
86+
/// -- or
87+
///
88+
/// ---| `<ident>` [# description]
6789
/// ```
68-
Variant(String, Option<String>),
90+
Variant(Member, Option<String>),
6991
/// ```lua
7092
/// ---@type <type> [desc]
7193
/// ```
@@ -166,6 +188,7 @@ pub enum Ty {
166188
Userdata,
167189
Lightuserdata,
168190
Ref(String),
191+
Member(Member),
169192
Array(Box<Ty>),
170193
Table(Option<(Box<Ty>, Box<Ty>)>),
171194
Fun(Vec<(Name, Ty)>, Option<Vec<Ty>>),
@@ -234,6 +257,7 @@ impl Display for Ty {
234257
f.write_str("|")?;
235258
f.write_str(&lhs.to_string())
236259
}
260+
Self::Member(mem) => mem.fmt(f),
237261
}
238262
}
239263
}

src/parser/tags/alias.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use chumsky::{prelude::choice, select, Parser};
22

33
use crate::{
4-
lexer::{TagType, Ty},
4+
lexer::{Member, TagType, Ty},
55
parser::{impl_parse, Prefix},
66
};
77

88
#[derive(Debug, Clone)]
99
pub enum AliasKind {
1010
Type(Ty),
11-
Enum(Vec<(String, Option<String>)>),
11+
Enum(Vec<(Member, Option<String>)>),
1212
}
1313

1414
#[derive(Debug, Clone)]

tests/basic.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ fn alias_and_type() {
576576
---| '"line"' # Vertical motion
577577
---| '"char"' # Horizontal motion
578578
---| 'v'
579-
---| 'V' # Visual Line Mode
579+
---| `some.ident` # Some identifier
580580
581581
---Returns all the content of the buffer
582582
---@return Lines
@@ -619,10 +619,10 @@ VMode *VMode*
619619
Read `:h map-operator`
620620
621621
Variants: ~
622-
("line") Vertical motion
623-
("char") Horizontal motion
624-
(v)
625-
(V) Visual Line Mode
622+
("line") Vertical motion
623+
("char") Horizontal motion
624+
("v")
625+
(some.ident) Some identifier
626626
627627
628628
U.get_all() *U.get_all*

tests/types.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use chumsky::Parser;
2-
use lemmy_help::lexer::{Lexer, Name, Ty};
2+
use lemmy_help::lexer::{Lexer, Member, Name, Ty};
33

44
macro_rules! b {
55
($t:expr) => {
@@ -201,10 +201,13 @@ fn types() {
201201
check!(
202202
r#"'"g@"'|string[]|'"g@$"'|number"#,
203203
Ty::Union(
204-
b!(Ty::Ref(r#""g@""#.into())),
204+
b!(Ty::Member(Member::Literal(r#""g@""#.into()))),
205205
b!(Ty::Union(
206206
b!(Ty::Array(b!(Ty::String))),
207-
b!(Ty::Union(b!(Ty::Ref(r#""g@$""#.into())), b!(Ty::Number)))
207+
b!(Ty::Union(
208+
b!(Ty::Member(Member::Literal(r#""g@$""#.into()))),
209+
b!(Ty::Number)
210+
))
208211
))
209212
)
210213
);

0 commit comments

Comments
 (0)