Skip to content

Commit

Permalink
Rework import & export statements parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
werediver committed Sep 3, 2023
1 parent 231be5d commit ae3c4d3
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 46 deletions.
23 changes: 16 additions & 7 deletions dart-parser/src/dart/directive.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,48 @@
#[derive(PartialEq, Eq, Debug)]
pub enum Directive<'s> {
Export(&'s str),
Export(Export<'s>),
Import(Import<'s>),
Part(&'s str),
PartOf(PartOf<'s>),
}

#[derive(PartialEq, Eq, Debug)]
pub struct Export<'s> {
pub target: &'s str,
pub filters: Vec<Filter<'s>>,
}

#[derive(PartialEq, Eq, Debug)]
pub struct Import<'s> {
pub target: &'s str,
pub prefix: Option<&'s str>,
pub show: Vec<&'s str>,
pub hide: Vec<&'s str>,
pub filters: Vec<Filter<'s>>,
}

impl<'s> Import<'s> {
pub fn target(target: &'s str) -> Self {
Import {
target,
prefix: None,
show: Vec::default(),
hide: Vec::default(),
filters: Vec::default(),
}
}

pub fn target_as(target: &'s str, prefix: &'s str) -> Self {
Import {
target,
prefix: Some(prefix),
show: Vec::default(),
hide: Vec::default(),
filters: Vec::default(),
}
}
}

#[derive(PartialEq, Eq, Debug)]
pub enum Filter<'s> {
Show(Vec<&'s str>),
Hide(Vec<&'s str>),
}

#[derive(PartialEq, Eq, Debug)]
pub enum PartOf<'s> {
LibPath(&'s str),
Expand Down
89 changes: 54 additions & 35 deletions dart-parser/src/parser/directive.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
use nom::{
branch::alt,
bytes::complete::tag,
combinator::{cut, opt, success},
combinator::{cut, opt},
error::{context, ContextError, ParseError},
multi::separated_list1,
sequence::{pair, preceded, terminated, tuple},
Parser,
};

use crate::dart::directive::{Directive, Import, PartOf};
use crate::dart::directive::{Directive, Export, Filter, Import, PartOf};

use super::{common::spbr, string::string, ty::identifier, PResult};
use super::{
common::{sep_list, spbr, spbrc, SepMode},
string::string,
ty::identifier,
PResult,
};

pub fn directive<'s, E>(s: &'s str) -> PResult<Directive, E>
where
Expand All @@ -27,16 +32,20 @@ where
)(s)
}

fn export<'s, E>(s: &'s str) -> PResult<&str, E>
fn export<'s, E>(s: &'s str) -> PResult<Export, E>
where
E: ParseError<&'s str> + ContextError<&'s str>,
{
context(
"export",
preceded(
pair(tag("export"), spbr),
cut(terminated(terminated(string, opt(spbr)), tag(";"))),
),
cut(terminated(
pair(terminated(string, opt(spbr)), import_filters),
tag(";"),
)),
)
.map(|(target, filters)| Export { target, filters }),
)(s)
}

Expand All @@ -55,40 +64,42 @@ where
pair(tag("as"), spbr),
terminated(identifier, opt(spbr)),
)),
alt((
terminated(
pair(show_clause, opt(preceded(opt(spbr), hide_clause)))
.map(|(show, hide)| (Some(show), hide)),
opt(spbr),
),
terminated(
pair(hide_clause, opt(preceded(opt(spbr), show_clause)))
.map(|(hide, show)| (show, Some(hide))),
opt(spbr),
),
success((None, None)),
)),
import_filters,
)),
tag(";"),
)),
)
.map(|(target, prefix, (show, hide))| Import {
.map(|(target, prefix, filters)| Import {
target,
prefix,
show: show.unwrap_or(Vec::new()),
hide: hide.unwrap_or(Vec::new()),
filters,
}),
)
.parse(s)
}

fn import_filters<'s, E>(s: &'s str) -> PResult<Vec<Filter>, E>
where
E: ParseError<&'s str> + ContextError<&'s str>,
{
context(
"import_filters",
sep_list(
0,
SepMode::NoTrailing,
spbrc,
alt((show_clause.map(Filter::Show), hide_clause.map(Filter::Hide))),
),
)(s)
}

fn show_clause<'s, E>(s: &'s str) -> PResult<Vec<&str>, E>
where
E: ParseError<&'s str> + ContextError<&'s str>,
{
preceded(
pair(tag("show"), spbr),
separated_list1(tuple((opt(spbr), tag(","), opt(spbr))), identifier),
pair(tag("show"), spbrc),
separated_list1(tuple((opt(spbrc), tag(","), opt(spbrc))), identifier),
)(s)
}

Expand All @@ -97,8 +108,8 @@ where
E: ParseError<&'s str> + ContextError<&'s str>,
{
preceded(
pair(tag("hide"), spbr),
separated_list1(tuple((opt(spbr), tag(","), opt(spbr))), identifier),
pair(tag("hide"), spbrc),
separated_list1(tuple((opt(spbrc), tag(","), opt(spbrc))), identifier),
)(s)
}

Expand Down Expand Up @@ -141,7 +152,13 @@ mod tests {
fn export_test() {
assert_eq!(
export::<VerboseError<_>>("export 'src/utils.dart';x"),
Ok(("x", "src/utils.dart"))
Ok((
"x",
Export {
target: "src/utils.dart",
filters: Vec::new()
}
))
);
}

Expand Down Expand Up @@ -170,8 +187,7 @@ mod tests {
Import {
target: "package:path/path.dart",
prefix: None,
show: vec!["join"],
hide: Vec::default(),
filters: vec![Filter::Show(vec!["join"])],
}
))
);
Expand All @@ -186,8 +202,7 @@ mod tests {
Import {
target: "package:path/path.dart",
prefix: None,
show: Vec::default(),
hide: vec!["join", "basename"],
filters: vec![Filter::Hide(vec!["join", "basename"])],
}
))
);
Expand All @@ -204,8 +219,10 @@ mod tests {
Import {
target: "package:path/path.dart",
prefix: Some("p"),
show: vec!["join", "basename"],
hide: vec!["dirname"],
filters: vec![
Filter::Show(vec!["join", "basename"]),
Filter::Hide(vec!["dirname"])
],
}
))
);
Expand All @@ -222,8 +239,10 @@ mod tests {
Import {
target: "package:path/path.dart",
prefix: Some("p"),
show: vec!["join", "basename"],
hide: vec!["dirname"],
filters: vec![
Filter::Hide(vec!["dirname"]),
Filter::Show(vec!["join", "basename"])
],
}
))
);
Expand Down
19 changes: 15 additions & 4 deletions dart-parser/src/parser/extension.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use nom::{
branch::alt,
bytes::complete::tag,
combinator::{cut, opt},
combinator::{cut, opt, success},
error::{context, ContextError, ParseError},
multi::many0,
sequence::{pair, preceded, terminated, tuple},
Expand All @@ -28,14 +28,25 @@ where
"extension",
tuple((
alt((
tuple((tag("extension"), spbr, tag("on"), spbr)).map(|_| (None, Vec::new())),
tuple((
pair(tag("extension"), opt(spbr)),
alt((
terminated(type_params, opt(spbr)),
success(()).map(|_| Vec::new()),
)),
pair(tag("on"), spbr),
))
.map(|(_, type_params, _)| (None, type_params)),
tuple((
terminated(tag("extension"), spbr),
terminated(identifier, opt(spbr)),
opt(terminated(type_params, opt(spbr))),
alt((
terminated(type_params, opt(spbr)),
success(()).map(|_| Vec::new()),
)),
terminated(tag("on"), spbr),
))
.map(|(_, name, type_params, _)| (Some(name), type_params.unwrap_or(Vec::new()))),
.map(|(_, name, type_params, _)| (Some(name), type_params)),
)),
terminated(ty, opt(spbr)),
extension_body,
Expand Down

0 comments on commit ae3c4d3

Please sign in to comment.