Skip to content

Commit

Permalink
Merge pull request #70 from rusty-ecma/source-location
Browse files Browse the repository at this point in the history
Source location
  • Loading branch information
FreeMasen committed Nov 24, 2022
2 parents a176ecc + 1ebb72f commit 83fbdab
Show file tree
Hide file tree
Showing 31 changed files with 74,779 additions and 11,474 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
# - name: clone Test262
# run: git clone https://github.com/tc39/test262 ./test262_full && mv ./test262_full/test ./test262
- name: Run tests
run: cargo test --features=moz_central
run: cargo test --release --features=moz_central
env:
RUST_MIN_STACK: 9999999
- name: rust-tarpaulin
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ moz-central
/failures
!tests/test262/hilight.js
test262_full
*.zip
*.zip
bench.sh
20 changes: 11 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[package]
name = "ressa"
version = "0.7.6"
version = "0.8.0"
authors = ["Robert Masen <r@robertmasen.pizza>"]
repository = "https://github.com/FreeMasen/RESSA"
repository = "https://github.com/rusty-ecma/RESSA"
description = "An ECMAscript parser"
license = "MIT"
readme = "./README.md"
Expand All @@ -13,14 +13,15 @@ edition = "2018"
[dependencies]
backtrace = "0.3"
ress = "0.11"
resast = "0.4"
resast = "0.5"
log = "0.4"
walkdir = { version = "2", optional = true }
indicatif = { version = "0.12", optional = true, features = ["with_rayon"] }
rayon = { version = "1", optional = true }
pulldown-cmark = { version = "0.7", optional = true }
res-regex = "0.1"
hash-chain = "0.3"
tracing = "0.1"

[features]
default = []
Expand All @@ -34,16 +35,17 @@ test_262 = ["indicatif", "rayon", "pulldown-cmark"]
test_262_parser = ["indicatif", "rayon", "pulldown-cmark"]

[dev-dependencies]
term-painter = "0.2.4"
docopt = "1"
walkdir = "2"
serde = { version = "1", features = ["derive"] }
lazy_static = "1"
criterion = "0.3"
docopt = "1"
env_logger = "0.6"
term = "0.6"
insta = "1.19"
lazy_static = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yaml = "0.9"
term = "0.6"
term-painter = "0.2.4"
walkdir = "2"

[[bench]]
name = "major_libs"
Expand Down
233 changes: 233 additions & 0 deletions benches/major_libs_spanned.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
#![cfg(test)]
// #![feature(test)]
//! This benchmarking suite is extremely naive
//! I use it internally to determine if I have
//! been able to make large impact performance
//! improvements in both this crate
//! and `ress`
//! If you want to full output please run
//! `node ./bencher.js` in the crate root
//! this will collect the results and
//! build a table that will be written to
//! benchmark.md
//! This will include information about
//! the parser overhead above the scanner
//! and a naive comparison against
//! [esprima](https://github.com/jquery/esprima)
extern crate ress;
extern crate ressa;
// extern crate test;
#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate criterion;

use std::{fs::read_to_string, path::PathBuf};

use criterion::{black_box, Criterion};
use ressa::spanned::Parser;

lazy_static! {
static ref NG: String = get_js(Lib::Angular).unwrap();
static ref NG_MIN: String = get_min_js(Lib::Angular).unwrap();
static ref JQ: String = get_js(Lib::Jquery).unwrap();
static ref JQ_MIN: String = get_min_js(Lib::Jquery).unwrap();
static ref REACT: String = get_js(Lib::React).unwrap();
static ref REACT_MIN: String = get_min_js(Lib::React).unwrap();
static ref REACT_DOM: String = get_js(Lib::ReactDom).unwrap();
static ref REACT_DOM_MIN: String = get_min_js(Lib::ReactDom).unwrap();
static ref VUE: String = get_js(Lib::Vue).unwrap();
static ref VUE_MIN: String = get_min_js(Lib::Vue).unwrap();
static ref EV5: String = get_js(Lib::Es5).unwrap();
static ref EV2015: String = get_js(Lib::Es2015S).unwrap();
static ref EVMOD: String = get_js(Lib::Es2015M).unwrap();
}

fn angular1(c: &mut Criterion) {
bench(c, &NG, "angular1", false);
}

fn angular1_min(c: &mut Criterion) {
bench(c, &NG_MIN, "angular1_min", false);
}

fn jquery(c: &mut Criterion) {
bench(c, &JQ, "jquery", false);
}

fn jquery_min(c: &mut Criterion) {
bench(c, &JQ_MIN, "jquery_min", false);
}

fn react(c: &mut Criterion) {
bench(c, &REACT, "react", false);
}

fn react_min(c: &mut Criterion) {
bench(c, &REACT_MIN, "react_min", false);
}

fn react_dom(c: &mut Criterion) {
bench(c, &REACT_DOM, "react_dom", false);
}

fn react_dom_min(c: &mut Criterion) {
bench(c, &REACT_DOM_MIN, "react_dom_min", false);
}

fn vue(c: &mut Criterion) {
bench(c, &VUE, "vue", false);
}

fn vue_min(c: &mut Criterion) {
bench(c, &VUE_MIN, "vue_min", false);
}

fn es5(c: &mut Criterion) {
bench(c, &EV5, "es5", false);
}

fn es2015(c: &mut Criterion) {
bench(c, &EV2015, "es2015", false);
}

fn es_module(c: &mut Criterion) {
bench(c, &EVMOD, "es_module", true);
}

fn bench(c: &mut Criterion, js: &str, name: &'static str, module: bool) {
c.bench_function(name, |b| {
b.iter(|| {
let p = Parser::builder()
.js(&js)
.module(module)
.build()
.expect("Unable to crate new parser for es2015-module.js");
for i in p {
match i {
Ok(p) => {
black_box(p);
}
Err(e) => {
if let Some(text) = format_error(js, &e) {
panic!("{}:\n{}", e, text);
} else {
panic!("{}", e);
}
}
}
}
})
});
}

fn format_error(js: &str, e: &ressa::Error) -> Option<String> {
let pos = e.position()?;
let line_count = js.lines().count();
if line_count < 5 {
return Some(js.to_string());
}
let skip = pos.line.saturating_sub(2);
Some(
js.lines()
.enumerate()
.skip(skip)
.take(5)
.map(|(i, l)| {
if i + 1 == pos.line {
let whitespace = " ".repeat(pos.column);
let tail_ct = l.len() - pos.column;
let arrows = "^".repeat(tail_ct);
format!("{}\n{}{}\n", l, whitespace, arrows)
} else {
format!("{}\n", l)
}
})
.collect(),
)
}

fn npm_install() -> Result<(), ::std::io::Error> {
let mut c = ::std::process::Command::new("npm");
c.arg("i");
c.output()?;
Ok(())
}

enum Lib {
Jquery,
Angular,
React,
ReactDom,
Vue,
Es5,
Es2015S,
Es2015M,
}

impl Lib {
pub fn path(&self) -> String {
match self {
Lib::Jquery => "node_modules/jquery/dist/jquery.js".into(),
Lib::Angular => "node_modules/angular/angular.js".into(),
Lib::React => "node_modules/react/umd/react.development.js".into(),
Lib::ReactDom => "node_modules/react-dom/umd/react-dom.development.js".into(),
Lib::Vue => "node_modules/vue/dist/vue.js".into(),
Lib::Es5 => "node_modules/everything.js/es5.js".into(),
Lib::Es2015S => "node_modules/everything.js/es2015-script.js".into(),
Lib::Es2015M => "node_modules/everything.js/es2015-module.js".into(),
}
}

pub fn min_path(&self) -> String {
match self {
Lib::Jquery => "node_modules/jquery/dist/jquery.min.js".into(),
Lib::Angular => "node_modules/angular/angular.min.js".into(),
Lib::React => "node_modules/react/umd/react.production.min.js".into(),
Lib::ReactDom => "node_modules/react-dom/umd/react-dom.production.min.js".into(),
Lib::Vue => "node_modules/vue/dist/vue.min.js".into(),
_ => unreachable!(),
}
}
}

fn get_js(l: Lib) -> Result<String, ::std::io::Error> {
let path = PathBuf::from(l.path());
if !path.exists() {
npm_install()?;
if !path.exists() {
panic!("npm install failed to make {} available", path.display());
}
}
read_to_string(path)
}

fn get_min_js(l: Lib) -> Result<String, ::std::io::Error> {
let path = PathBuf::from(l.min_path());
if !path.exists() {
npm_install()?;
if !path.exists() {
panic!("npm install failed to make {} available", path.display());
}
}
read_to_string(path)
}

criterion_group!(
benches,
angular1,
angular1_min,
jquery,
jquery_min,
react,
react_min,
react_dom,
react_dom_min,
vue,
vue_min,
es5,
es2015,
es_module
);
criterion_main!(benches);
9 changes: 9 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
coverage:
status:
project:
default:
informational: true
patch:
default:
enabled: no
if_not_found: success
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
{
"devDependencies": {
"acorn": "^6.4.0",
"angular": "^1.5.6",
"dexie": "^2.0.4",
"acorn": "^8.7.0",
"angular": "^1.6.10",
"dexie": "^3.2.2",
"esprima": "^4.0.1",
"everything.js": "^1.0.3",
"jquery": "^3.3.1",
"moment": "^2.22.2",
"react": "^16.4.2",
"react-dom": "^16.4.2",
"vue": "^2.5.17"
},
"dependencies": {}
}
}
2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub enum Error {
ContinueOfNotIterationLabel(Position, String),
Scanner(ress::error::Error),
Other(Box<dyn ::std::error::Error>),
Misc(String),
}

impl Display for Error {
Expand Down Expand Up @@ -91,6 +92,7 @@ impl Display for Error {
Error::ContinueOfNotIterationLabel(ref pos, ref token) => write!(f, "Label `{}` is does not label a loop, continue is invalid at {}", token, pos),
Error::Scanner(ref e) => write!(f, "Error when tokenizing {}", e),
Error::Other(ref e) => write!(f, "{}", e),
Error::Misc(ref e) => write!(f, "{}", e),
}
}
}
Expand Down
Loading

0 comments on commit 83fbdab

Please sign in to comment.