Skip to content

Commit 6885eb7

Browse files
committed
Add version of ct_token_map that doesn't insert #[allow(unused)]
This helps spotting errors in custom lexers where some of the tokens are never emitted.
1 parent f7397a7 commit 6885eb7

File tree

3 files changed

+36
-7
lines changed

3 files changed

+36
-7
lines changed

lrlex/examples/calc_manual_lex/build.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use lrlex::{DefaultLexerTypes, ct_token_map};
1+
use lrlex::{DefaultLexerTypes, ct_token_map_require_usage};
22
use lrpar::CTParserBuilder;
33

44
// Some of the token names in the parser do not lead to valid Rust identifiers, so we map them to
@@ -16,10 +16,11 @@ fn main() {
1616
.unwrap()
1717
.build()
1818
.unwrap();
19-
ct_token_map::<u8>(
19+
ct_token_map_require_usage::<u8>(
2020
"token_map",
2121
ctp.token_map(),
2222
Some(&TOKENS_MAP.iter().cloned().collect()),
23+
true,
2324
)
2425
.unwrap();
2526
}

lrlex/src/lib/ctbuilder.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,10 +1192,11 @@ impl CTLexer {
11921192
/// `HashMap{"ID": 0, "INT": 1}` the generated module will look roughly as follows:
11931193
///
11941194
/// ```rust,ignore
1195+
/// #[allow(dead_code)]
11951196
/// mod x {
11961197
/// pub const T_ID: u8 = 0;
11971198
/// pub const T_INT: u8 = 1;
1198-
/// pub const TOK_IDS: &[u8] = &[T_ID, T_INT];
1199+
/// pub const TOK_IDS: &[u8] = &[0, 1];
11991200
/// }
12001201
/// ```
12011202
///
@@ -1205,16 +1206,34 @@ impl CTLexer {
12051206
/// module will look roughly as follows:
12061207
///
12071208
/// ```rust,ignore
1209+
/// #[allow(dead_code)]
12081210
/// mod x {
12091211
/// pub const T_PLUS: u8 = 0;
12101212
/// pub const T_ID: u8 = 1;
1211-
/// pub const TOK_IDS: &[u8] = &[T_PLUS, T_ID];
1213+
/// pub const TOK_IDS: &[u8] = &[0, 1];
12121214
/// }
12131215
/// ```
1216+
///
1217+
/// You can also use [`ct_token_map_require_usage`] to disable the `#[allow(dead_code)]` annotation.
1218+
/// This will help you to ensure that a custom lexer can produce every token used in a parser.
12141219
pub fn ct_token_map<StorageT: Display + ToTokens>(
12151220
mod_name: &str,
12161221
token_map: impl Borrow<HashMap<String, StorageT>>,
12171222
rename_map: Option<&HashMap<&str, &str>>,
1223+
) -> Result<(), Box<dyn Error>> {
1224+
ct_token_map_require_usage(mod_name, token_map, rename_map, false)
1225+
}
1226+
1227+
/// Same as [`ct_token_map`], but allows disabling `#[allow(dead_code)]` annotation
1228+
/// for generated constants.
1229+
///
1230+
/// This function can help you to ensure that a custom lexer can produce
1231+
/// every token used in a parser.
1232+
pub fn ct_token_map_require_usage<StorageT: Display + ToTokens>(
1233+
mod_name: &str,
1234+
token_map: impl Borrow<HashMap<String, StorageT>>,
1235+
rename_map: Option<&HashMap<&str, &str>>,
1236+
require_usage: bool,
12181237
) -> Result<(), Box<dyn Error>> {
12191238
// Record the time that this version of lrlex was built. If the source code changes and rustc
12201239
// forces a recompile, this will change this value, causing anything which depends on this
@@ -1237,21 +1256,30 @@ pub fn ct_token_map<StorageT: Display + ToTokens>(
12371256
};
12381257
let tok_ident = format_ident!("T_{}", name.to_ascii_uppercase());
12391258
(
1259+
// Note: the array of all tokens can't use `tok_ident` because
1260+
// it will confuse the dead code checker. For this reason,
1261+
// we use `id` here.
12401262
quote! {
1241-
#tok_ident,
1263+
#id,
12421264
},
12431265
quote! {
12441266
pub const #tok_ident: #storaget = #id;
12451267
},
12461268
)
12471269
})
12481270
.unzip();
1271+
let unused_annotation = if require_usage {
1272+
quote! {}
1273+
} else {
1274+
quote! {#[allow(dead_code)]}
1275+
};
12491276
// Since the formatter doesn't preserve comments and we don't want to lose build time,
12501277
// just format the module contents.
12511278
let unformatted = quote! {
1279+
#unused_annotation
12521280
mod #mod_ident {
1253-
#![allow(dead_code)]
12541281
#tokens
1282+
#[allow(dead_code)]
12551283
pub const TOK_IDS: &[#storaget] = &[#token_array];
12561284
}
12571285
}

lrlex/src/lib/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ mod lexer;
2121
mod parser;
2222

2323
pub use crate::{
24-
ctbuilder::{CTLexer, CTLexerBuilder, LexerKind, RustEdition, Visibility, ct_token_map},
24+
ctbuilder::{CTLexer, CTLexerBuilder, LexerKind, RustEdition, Visibility, ct_token_map, ct_token_map_require_usage},
2525
defaults::{DefaultLexeme, DefaultLexerTypes},
2626
lexer::{
2727
DEFAULT_LEX_FLAGS, LRNonStreamingLexer, LRNonStreamingLexerDef, LexFlags, LexerDef, Rule,

0 commit comments

Comments
 (0)