java_lang/tree/parser/
import.rs1use super::{super::ImportDeclaration, identifier};
2use crate::{ts, Token, TokenStream};
3use nom::{
4 bytes::tag,
5 combinator::{complete, opt},
6 error::Error,
7 multi::{many0, separated_list1},
8 IResult, Parser,
9};
10use std::borrow::Cow;
11
12pub fn import_declaration<'a>(tokens: TokenStream) -> IResult<TokenStream, ImportDeclaration<'a>> {
39 let (tokens, _) = tag(ts![Import]).parse(tokens)?;
40 let (tokens, r#static) = opt(tag(ts![Static])).parse(tokens)?;
41 let (tokens, idents) = separated_list1(complete(tag(ts![Dot])), identifier).parse(tokens)?;
42 let name = idents
43 .into_iter()
44 .map(|i| i.to_string())
45 .collect::<Vec<_>>()
46 .join(Token::DOT);
47
48 let Ok((tokens, _)) = tag::<_, _, Error<TokenStream>>(ts![Dot, Star]).parse(tokens.clone())
49 else {
50 let (tokens, _) = tag(ts![SemiColon]).parse(tokens)?;
51 let import_declaration = if r#static.is_none() {
52 ImportDeclaration::SimpleType(Cow::Owned(name))
53 } else {
54 ImportDeclaration::SingleStatic(Cow::Owned(name))
55 };
56 return Ok((tokens, import_declaration));
57 };
58
59 let (tokens, _) = tag(ts![SemiColon]).parse(tokens)?;
60 let import_declaration = if r#static.is_none() {
61 ImportDeclaration::TypeOnDemand(Cow::Owned(name))
62 } else {
63 ImportDeclaration::StaticOnDemand(Cow::Owned(name))
64 };
65 Ok((tokens, import_declaration))
66}
67
68pub fn import_declarations<'a>(
95 tokens: TokenStream,
96) -> IResult<TokenStream, Vec<ImportDeclaration<'a>>> {
97 many0(complete(import_declaration)).parse(tokens)
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 const IMPORTS: &str = "
105 import java.util.List;
106 import java.io.*;
107 import static java.util.Collections.emptyList;
108 import static java.util.Collections.*;
109 ";
110
111 #[test]
112 fn test_import_declaration() -> anyhow::Result<()> {
113 let (_, tokens) = TokenStream::from_str(IMPORTS)?;
114 assert!(!tokens.is_empty());
115
116 let (tokens, import) = import_declaration(tokens)?;
117 assert!(matches!(import, ImportDeclaration::SimpleType(_)));
118
119 let (tokens, import) = import_declaration(tokens)?;
120 assert!(matches!(import, ImportDeclaration::TypeOnDemand(_)));
121
122 let (tokens, import) = import_declaration(tokens)?;
123 assert!(matches!(import, ImportDeclaration::SingleStatic(_)));
124
125 let (tokens, import) = import_declaration(tokens)?;
126 assert!(matches!(import, ImportDeclaration::StaticOnDemand(_)));
127
128 assert!(tokens.is_empty());
129
130 Ok(())
131 }
132
133 #[test]
134 fn test_import_declarations() -> anyhow::Result<()> {
135 let (_, tokens) = TokenStream::from_str(IMPORTS)?;
136 assert!(!tokens.is_empty());
137
138 let (tokens, imports) = import_declarations(tokens)?;
139 assert_eq!(imports.len(), 4);
140
141 assert!(tokens.is_empty());
142
143 Ok(())
144 }
145}