Skip to content

Commit

Permalink
Parser: Error recovery (#449)
Browse files Browse the repository at this point in the history
Implement some error recovery logic to parser
  • Loading branch information
kdy1 authored Nov 17, 2019
1 parent 716bfe0 commit d074063
Show file tree
Hide file tree
Showing 190 changed files with 3,839 additions and 875 deletions.
41 changes: 22 additions & 19 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
{
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/*.bk": true,
},
"[rust]": {
"editor.formatOnSave": true
},
"rust.rustflags": "--cfg procmacro2_semver_exempt",
// Important
"rust.cfg_test": false,
"rust-client.revealOutputChannelOn": "warn",
"rust-client.logToFile": true,
"editor.formatOnSave": true,

}
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/*.bk": true
},
"[rust]": {
"editor.formatOnSave": true
},
"[typescript]": {
"editor.formatOnSave": false
},
"rust.rustflags": "--cfg procmacro2_semver_exempt",
// Important
"rust.cfg_test": false,
"rust-client.revealOutputChannelOn": "warn",
"rust-client.logToFile": true,
"editor.formatOnSave": true,
"git.ignoreLimitWarning": true
}
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ swc_common = { path ="./common" }
swc_ecmascript = { path ="./ecmascript" }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sourcemap = "2"
failure = "0.1"
path-clean = "0.1"
lazy_static = "1"
hashbrown = "0.5"
regex = "1"
chashmap = "2.2.2"
sourcemap = "2.2"

[[example]]
name = "usage"
Expand All @@ -34,6 +34,7 @@ name = "usage"
lto = true

[profile.release]
codegen-units = 1
lto = true

[patch.crates-io]
Expand Down
15 changes: 14 additions & 1 deletion atoms/words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ BiquadFilterNode
Blob
BlobEvent
Boolean
Bottom line
BroadcastChannel
BudgetService
ByteLengthQueuingStrategy
Expand Down Expand Up @@ -113,6 +114,8 @@ EvalError
Event
EventSource
EventTarget
Exclude
Extract
File
FileList
FileReader
Expand Down Expand Up @@ -289,6 +292,7 @@ Node
NodeFilter
NodeIterator
NodeList
NonNullable
Notification
Number
Object
Expand All @@ -299,6 +303,7 @@ Option
OscillatorNode
PageTransitionEvent
PannerNode
Partial
Path2D
PaymentAddress
PaymentRequest
Expand All @@ -320,6 +325,7 @@ PeriodicWave
PermissionStatus
Permissions
PhotoCapabilities
Pick
Plugin
PluginArray
PointerEvent
Expand Down Expand Up @@ -361,14 +367,19 @@ Range
RangeError
React
ReadableStream
Readonly
ReadonlyArray
Record
ReferenceError
Reflect
RegExp
RemotePlayback
Request
Required
ResizeObserver
ResizeObserverEntry
Response
ReturnType
SVGAElement
SVGAngle
SVGAnimateElement
Expand Down Expand Up @@ -565,6 +576,7 @@ abstract
any
apply
arguments
arguments
as
async
await
Expand All @@ -590,6 +602,7 @@ do
else
enum
env
eval
export
extends
false
Expand Down Expand Up @@ -635,8 +648,8 @@ switch
symbol
target
this
this
throw
toString
true
try
type
Expand Down
8 changes: 4 additions & 4 deletions common/src/errors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
use hashbrown::HashSet;
use std::{
borrow::Cow,
cell::Cell,
cell::RefCell,
error, fmt, panic,
sync::{
atomic::{AtomicUsize, Ordering::SeqCst},
Expand Down Expand Up @@ -293,8 +293,8 @@ pub struct Handler {

fn default_track_diagnostic(_: &Diagnostic) {}

thread_local!(pub static TRACK_DIAGNOSTICS: Cell<fn(&Diagnostic)> =
Cell::new(default_track_diagnostic));
thread_local!(pub static TRACK_DIAGNOSTICS: RefCell<Box<dyn Fn(&Diagnostic)>> =
RefCell::new(Box::new(default_track_diagnostic)));

#[derive(Default)]
pub struct HandlerFlags {
Expand Down Expand Up @@ -716,7 +716,7 @@ impl Handler {
let diagnostic = &**db;

TRACK_DIAGNOSTICS.with(|track_diagnostics| {
track_diagnostics.get()(diagnostic);
track_diagnostics.borrow()(diagnostic);
});

if let Some(ref code) = diagnostic.code {
Expand Down
31 changes: 31 additions & 0 deletions common/src/fold/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use self::and_then::AndThen;
use crate::util::{map::Map, move_map::MoveMap};
use either::Either;
use std::{borrow::Cow, sync::Arc};
use string_cache::{Atom, StaticAtomSet};

pub mod and_then;
Expand Down Expand Up @@ -282,3 +283,33 @@ where
}
}
}

impl<T, F> VisitWith<F> for Arc<T>
where
T: ?Sized,
F: Visit<T>,
{
fn visit_children(&self, f: &mut F) {
f.visit(&**self)
}
}

impl<'a, A, F> FoldWith<F> for Cow<'a, A>
where
A: Clone + FoldWith<F>,
{
/// `#[inline(always)]`: To optimize .into_owned()
#[inline(always)]
fn fold_children(self, f: &mut F) -> Self {
Cow::Owned(self.into_owned().fold_with(f))
}
}

impl<A, F> VisitWith<F> for Cow<'_, A>
where
A: Clone + VisitWith<F>,
{
fn visit_children(&self, f: &mut F) {
(**self).visit_children(f)
}
}
20 changes: 20 additions & 0 deletions common/src/pos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub use crate::syntax_pos::{
SourceFile, SourceFileAndBytePos, SourceFileAndLine, Span, SpanData, SpanLinesError,
SyntaxContext, CM, DUMMY_SP, GLOBALS, NO_EXPANSION,
};
use std::{borrow::Cow, sync::Arc};

///
/// # Derive
Expand All @@ -14,6 +15,16 @@ pub trait Spanned {
fn span(&self) -> Span;
}

impl<'a, T> Spanned for Cow<'a, T>
where
T: Spanned + Clone,
{
#[inline(always)]
fn span(&self) -> Span {
(**self).span()
}
}

impl Spanned for Span {
#[inline(always)]
fn span(&self) -> Span {
Expand Down Expand Up @@ -41,6 +52,15 @@ where
}
}

impl<S> Spanned for Arc<S>
where
S: ?Sized + Spanned,
{
fn span(&self) -> Span {
<S as Spanned>::span(&*self)
}
}

impl<S> Spanned for Box<S>
where
S: ?Sized + Spanned,
Expand Down
48 changes: 48 additions & 0 deletions common/src/util/iter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
pub trait IteratorExt: Iterator {
/// Copied from https://stackoverflow.com/a/49456265/6193633
fn chain_with<F, I>(self, f: F) -> ChainWith<Self, F, I::IntoIter>
where
Self: Sized,
F: FnOnce() -> I,
I: IntoIterator<Item = Self::Item>,
{
ChainWith {
base: self,
factory: Some(f),
iterator: None,
}
}
}

impl<I: Iterator> IteratorExt for I {}

pub struct ChainWith<B, F, I> {
base: B,
factory: Option<F>,
iterator: Option<I>,
}

impl<B, F, I> Iterator for ChainWith<B, F, I::IntoIter>
where
B: Iterator,
F: FnOnce() -> I,
I: IntoIterator<Item = B::Item>,
{
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
if let Some(b) = self.base.next() {
return Some(b);
}

// Exhausted the first, generate the second

if let Some(f) = self.factory.take() {
self.iterator = Some(f().into_iter());
}

self.iterator
.as_mut()
.expect("There must be an iterator")
.next()
}
}
1 change: 1 addition & 0 deletions common/src/util/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod iter;
pub mod map;
pub mod move_map;
1 change: 0 additions & 1 deletion ecmascript/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,5 @@ swc_ecma_ast = { path ="./ast" }
swc_ecma_codegen = { path ="./codegen" }
swc_ecma_parser = { path ="./parser", features = ["verify"] }
swc_ecma_transforms = { path ="./transforms" }
swc_ecma_lints = { path ="./lints" }

[dev-dependencies]
4 changes: 4 additions & 0 deletions ecmascript/ast/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::{
TsAsExpr, TsConstAssertion, TsNonNullExpr, TsOptChain, TsTypeAnn, TsTypeAssertion,
TsTypeCastExpr, TsTypeParamDecl, TsTypeParamInstantiation,
},
Invalid,
};
use serde::{self, Deserialize, Serialize};
#[cfg(feature = "fold")]
Expand Down Expand Up @@ -144,6 +145,9 @@ pub enum Expr {

#[tag("TsOptionalChainingExpression")]
TsOptChain(TsOptChain),

#[tag("Invalid")]
Invalid(Invalid),
}

#[ast_node("ThisExpression")]
Expand Down
13 changes: 12 additions & 1 deletion ecmascript/ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ pub use self::{
pat::{
ArrayPat, AssignPat, AssignPatProp, KeyValuePatProp, ObjectPat, ObjectPatProp, Pat, RestPat,
},
prop::{AssignProp, GetterProp, KeyValueProp, MethodProp, Prop, PropName, SetterProp},
prop::{
AssignProp, ComputedPropName, GetterProp, KeyValueProp, MethodProp, Prop, PropName,
SetterProp,
},
stmt::{
BlockStmt, BreakStmt, CatchClause, ContinueStmt, DebuggerStmt, DoWhileStmt, EmptyStmt,
ForInStmt, ForOfStmt, ForStmt, IfStmt, LabeledStmt, ReturnStmt, Stmt, SwitchCase,
Expand All @@ -64,6 +67,7 @@ pub use self::{
TsUnionOrIntersectionType, TsUnionType,
},
};
use swc_common::{ast_node, Span};

#[macro_use]
mod macros;
Expand All @@ -81,3 +85,10 @@ mod pat;
mod prop;
mod stmt;
mod typescript;

/// Represents a invalid node.
#[ast_node("Invalid")]
#[derive(Copy)]
pub struct Invalid {
pub span: Span,
}
5 changes: 4 additions & 1 deletion ecmascript/ast/src/pat.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{expr::Expr, ident::Ident, prop::PropName, typescript::TsTypeAnn};
use crate::{expr::Expr, ident::Ident, prop::PropName, typescript::TsTypeAnn, Invalid};
use swc_common::{ast_node, Span};

#[ast_node]
Expand All @@ -18,6 +18,9 @@ pub enum Pat {
#[tag("AssignmentPattern")]
Assign(AssignPat),

#[tag("Invalid")]
Invalid(Invalid),

/// Only for for-in / for-of loops. This is *syntatically* valid.
#[tag("*")]
Expr(Box<Expr>),
Expand Down
Loading

0 comments on commit d074063

Please sign in to comment.