mirror of
https://github.com/swc-project/swc.git
synced 2024-12-23 21:54:36 +03:00
Use FileMap as an input.
This commit is contained in:
parent
e2f75ec0a2
commit
9b2a5880bb
@ -7,5 +7,4 @@ authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
swc_ecma_ast = { path = "./ast" }
|
||||
swc_ecma_parser = { path = "./parser" }
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -1,5 +1,5 @@
|
||||
use std::str;
|
||||
use swc_common::BytePos;
|
||||
use swc_common::{BytePos, FileMap};
|
||||
|
||||
/// Used inside lexer.
|
||||
pub(super) struct LexerInput<I: Input> {
|
||||
@ -8,7 +8,7 @@ pub(super) struct LexerInput<I: Input> {
|
||||
input: I,
|
||||
}
|
||||
|
||||
impl<'a, I: Input> LexerInput<I> {
|
||||
impl<I: Input> LexerInput<I> {
|
||||
pub const fn new(input: I) -> Self {
|
||||
LexerInput {
|
||||
input,
|
||||
@ -57,9 +57,37 @@ impl<'a, I: Input> LexerInput<I> {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CharIndices<'a>(pub str::CharIndices<'a>);
|
||||
pub struct FileMapInput<'a> {
|
||||
fm: &'a FileMap,
|
||||
start_pos: BytePos,
|
||||
iter: str::CharIndices<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Input for CharIndices<'a> {
|
||||
impl<'a> From<&'a FileMap> for FileMapInput<'a> {
|
||||
fn from(fm: &'a FileMap) -> Self {
|
||||
let src = match fm.src {
|
||||
Some(ref s) => s,
|
||||
None => unreachable!("Cannot lex filemap without source: {}", fm.name),
|
||||
};
|
||||
|
||||
FileMapInput {
|
||||
start_pos: fm.start_pos,
|
||||
iter: src.char_indices(),
|
||||
fm,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for FileMapInput<'a> {
|
||||
type Item = (BytePos, char);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.iter
|
||||
.next()
|
||||
.map(|(i, c)| (BytePos(i as u32 + self.start_pos.0), c))
|
||||
}
|
||||
}
|
||||
impl<'a> Input for FileMapInput<'a> {
|
||||
fn peek(&mut self) -> Option<(BytePos, char)> {
|
||||
self.clone().nth(0)
|
||||
}
|
||||
@ -75,13 +103,6 @@ impl<'a> Input for CharIndices<'a> {
|
||||
None
|
||||
}
|
||||
}
|
||||
impl<'a> Iterator for CharIndices<'a> {
|
||||
type Item = (BytePos, char);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.0.next().map(|(i, c)| (BytePos(i as _), c))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Input: Iterator<Item = (BytePos, char)> {
|
||||
fn peek(&mut self) -> Option<(BytePos, char)>;
|
||||
@ -94,23 +115,3 @@ pub trait Input: Iterator<Item = (BytePos, char)> {
|
||||
where
|
||||
F: FnMut(char) -> bool;
|
||||
}
|
||||
|
||||
impl<'a, I> Input for &'a mut I
|
||||
where
|
||||
I: Input,
|
||||
{
|
||||
fn peek(&mut self) -> Option<(BytePos, char)> {
|
||||
<I as Input>::peek(*self)
|
||||
}
|
||||
|
||||
fn peek_ahead(&mut self) -> Option<(BytePos, char)> {
|
||||
<I as Input>::peek_ahead(*self)
|
||||
}
|
||||
|
||||
fn uncons_while<F>(&mut self, f: F) -> Option<&str>
|
||||
where
|
||||
F: FnMut(char) -> bool,
|
||||
{
|
||||
<I as Input>::uncons_while(self, f)
|
||||
}
|
||||
}
|
||||
|
@ -267,16 +267,16 @@ impl<'a, I: Input> Lexer<'a, I> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use lexer::input::CharIndices;
|
||||
use super::input::FileMapInput;
|
||||
use std::f64::INFINITY;
|
||||
use std::panic;
|
||||
|
||||
fn lex<F, Ret>(s: &'static str, f: F) -> Ret
|
||||
where
|
||||
F: FnOnce(&mut Lexer<CharIndices>) -> Ret,
|
||||
F: FnOnce(&mut Lexer<FileMapInput>) -> Ret,
|
||||
{
|
||||
::with_test_sess(s, |sess| {
|
||||
let mut l = Lexer::new(sess, CharIndices(s.char_indices()));
|
||||
::with_test_sess(s, |sess, fm| {
|
||||
let mut l = Lexer::new(sess, fm.into());
|
||||
f(&mut l)
|
||||
})
|
||||
}
|
||||
@ -369,9 +369,8 @@ mod tests {
|
||||
.or_else(|_| case.parse::<f64>())
|
||||
.expect("failed to parse `expected` as float using str.parse()");
|
||||
|
||||
let input = CharIndices(case.char_indices());
|
||||
let vec = panic::catch_unwind(|| {
|
||||
::with_test_sess(case, |mut sess| {
|
||||
::with_test_sess(case, |mut sess, input| {
|
||||
sess.cfg.strict = strict;
|
||||
Lexer::new(sess, input)
|
||||
.map(|ts| ts.token)
|
||||
|
@ -1,14 +1,14 @@
|
||||
use super::*;
|
||||
use super::input::CharIndices;
|
||||
use super::input::FileMapInput;
|
||||
use std::ops::Range;
|
||||
use std::str;
|
||||
|
||||
fn with_lexer<F, Ret>(s: &'static str, f: F) -> Ret
|
||||
where
|
||||
F: FnOnce(&mut Lexer<CharIndices>) -> Ret,
|
||||
F: FnOnce(&mut Lexer<FileMapInput>) -> Ret,
|
||||
{
|
||||
::with_test_sess(s, |sess| {
|
||||
let mut l = Lexer::new(sess, CharIndices(s.char_indices()));
|
||||
::with_test_sess(s, |sess, fm| {
|
||||
let mut l = Lexer::new(sess, fm);
|
||||
f(&mut l)
|
||||
})
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ pub extern crate swc_macros;
|
||||
#[macro_use]
|
||||
extern crate testing;
|
||||
extern crate unicode_xid;
|
||||
pub use self::lexer::input::{CharIndices, Input};
|
||||
pub use self::lexer::input::{FileMapInput, Input};
|
||||
pub use self::parser::*;
|
||||
use slog::Logger;
|
||||
use swc_common::errors::Handler;
|
||||
@ -61,19 +61,30 @@ pub struct Session<'a> {
|
||||
#[cfg(test)]
|
||||
fn with_test_sess<F, Ret>(src: &'static str, f: F) -> Ret
|
||||
where
|
||||
F: FnOnce(Session) -> Ret,
|
||||
F: FnOnce(Session, FileMapInput) -> Ret,
|
||||
{
|
||||
use std::rc::Rc;
|
||||
use swc_common::FileName;
|
||||
use swc_common::errors::{CodeMap, FilePathMapping};
|
||||
|
||||
let cm = Rc::new(CodeMap::new(FilePathMapping::empty()));
|
||||
let fm = cm.new_filemap(FileName::Real("testing".into()), src.into());
|
||||
|
||||
let handler = ::swc_common::errors::Handler::with_tty_emitter(
|
||||
::swc_common::errors::ColorConfig::Never,
|
||||
::swc_common::errors::ColorConfig::Auto,
|
||||
true,
|
||||
false,
|
||||
None,
|
||||
Some(cm),
|
||||
);
|
||||
|
||||
let logger = ::testing::logger().new(o!("src" => src));
|
||||
|
||||
f(Session {
|
||||
handler: &handler,
|
||||
logger: &logger,
|
||||
cfg: Default::default(),
|
||||
})
|
||||
f(
|
||||
Session {
|
||||
handler: &handler,
|
||||
logger: &logger,
|
||||
cfg: Default::default(),
|
||||
},
|
||||
(&*fm).into(),
|
||||
)
|
||||
}
|
||||
|
@ -81,11 +81,9 @@ impl<'a, I: Input> Parser<'a, I> {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn test_parser<F, Ret>(s: &'static str, f: F) -> Ret
|
||||
pub fn test_parser<F, Ret>(s: &'static str, f: F) -> Ret
|
||||
where
|
||||
F: FnOnce(&mut Parser<::CharIndices>) -> Ret,
|
||||
F: FnOnce(&mut Parser<::FileMapInput>) -> Ret,
|
||||
{
|
||||
::with_test_sess(s, |session| {
|
||||
f(&mut Parser::new(session, ::CharIndices(s.char_indices())))
|
||||
})
|
||||
::with_test_sess(s, |sess, input| f(&mut Parser::new(sess, input)))
|
||||
}
|
||||
|
@ -16,11 +16,13 @@ use std::fs::read_dir;
|
||||
use std::io::{self, Read};
|
||||
use std::panic::{catch_unwind, resume_unwind};
|
||||
use std::path::Path;
|
||||
use std::rc::Rc;
|
||||
use swc_common::{FoldWith, Folder};
|
||||
use swc_common::FileName;
|
||||
use swc_common::Span;
|
||||
use swc_common::errors::{CodeMap, FilePathMapping};
|
||||
use swc_common::errors::Handler;
|
||||
|
||||
use swc_ecma_parser::{CharIndices, PResult, Parser, Session};
|
||||
use swc_ecma_parser::{FileMapInput, PResult, Parser, Session};
|
||||
use swc_ecma_parser::ast::*;
|
||||
use test::{test_main, Options, TestDesc, TestDescAndFn, TestFn, TestName};
|
||||
use test::ShouldPanic::No;
|
||||
@ -179,19 +181,23 @@ fn logger(file_name: &str, src: &str) -> Logger {
|
||||
}
|
||||
|
||||
struct TestSess {
|
||||
cm: Rc<CodeMap>,
|
||||
handler: Handler,
|
||||
logger: Logger,
|
||||
}
|
||||
|
||||
impl TestSess {
|
||||
fn new() -> Self {
|
||||
let cm = Rc::new(CodeMap::new(FilePathMapping::empty()));
|
||||
|
||||
let handler = ::swc_common::errors::Handler::with_tty_emitter(
|
||||
::swc_common::errors::ColorConfig::Never,
|
||||
true,
|
||||
false,
|
||||
None,
|
||||
Some(cm.clone()),
|
||||
);
|
||||
TestSess {
|
||||
cm,
|
||||
handler,
|
||||
logger: ::testing::logger(),
|
||||
}
|
||||
@ -205,16 +211,19 @@ impl TestSess {
|
||||
|
||||
fn with_parser<'a, F, Ret>(&'a mut self, file_name: &str, src: &str, f: F) -> PResult<'a, Ret>
|
||||
where
|
||||
F: FnOnce(&mut Parser<'a, CharIndices>) -> PResult<'a, Ret>,
|
||||
F: FnOnce(&mut Parser<'a, FileMapInput>) -> PResult<'a, Ret>,
|
||||
{
|
||||
self.logger = logger(file_name, src);
|
||||
let fm = self.cm
|
||||
.new_filemap(FileName::Real(file_name.into()), src.into());
|
||||
|
||||
f(&mut Parser::new(
|
||||
Session {
|
||||
logger: &self.logger,
|
||||
handler: &self.handler,
|
||||
cfg: Default::default(),
|
||||
},
|
||||
::CharIndices(src.char_indices()),
|
||||
(&*fm).into(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,9 @@ pub extern crate swc_macros;
|
||||
use slog::Logger;
|
||||
use std::path::Path;
|
||||
use std::rc::Rc;
|
||||
use swc_common::errors::{CodeMap, FilePathMapping, Handler};
|
||||
use swc_common::errors::{CodeMap, Handler};
|
||||
use swc_ecmascript::ast::Module;
|
||||
use swc_ecmascript::parser::{CharIndices, PResult, Parser, Session as ParseSess};
|
||||
use swc_ecmascript::parser::{FileMapInput, PResult, Parser, Session as ParseSess};
|
||||
|
||||
pub struct Compiler {
|
||||
codemap: Rc<CodeMap>,
|
||||
@ -35,10 +35,9 @@ impl Compiler {
|
||||
|
||||
/// TODO
|
||||
pub fn parse_js(&self, path: &Path) -> PResult<Module> {
|
||||
let file = self.codemap
|
||||
let fm = self.codemap
|
||||
.load_file_and_lines(path)
|
||||
.expect("failed to load file");
|
||||
let src = file.src.clone().expect("we loaded this right before");
|
||||
|
||||
Parser::new(
|
||||
ParseSess {
|
||||
@ -46,7 +45,7 @@ impl Compiler {
|
||||
logger: &self.logger,
|
||||
cfg: Default::default(),
|
||||
},
|
||||
CharIndices(src.char_indices()),
|
||||
FileMapInput::from(&*fm),
|
||||
).parse_module()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user