mirror of
https://github.com/swc-project/swc.git
synced 2024-12-25 06:36:08 +03:00
Cleanup (#152)
- replace Lrc with std::sync::Arc swc_common: - make swc_common::sync private - improve MoveMap swc_ecma_codegen: - fix codegen of import. swc_ecma_transforms: - properly detect valid identifier. swc_ecma_parser: - Fix parsing of cond expr inside paren.
This commit is contained in:
parent
c2142bc225
commit
7fe2245a3d
@ -25,6 +25,3 @@ atty = "0.2"
|
||||
parking_lot = "0.7.1"
|
||||
fxhash = "0.2"
|
||||
termcolor = "1.0"
|
||||
rayon = "1"
|
||||
rayon-core = "1"
|
||||
owning_ref = "0.4"
|
||||
|
@ -9,6 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
use super::{Applicability, Diagnostic, DiagnosticId, DiagnosticStyledString, Handler, Level};
|
||||
use log::debug;
|
||||
use std::{
|
||||
fmt::{self, Debug},
|
||||
ops::{Deref, DerefMut},
|
||||
|
@ -15,12 +15,13 @@ use super::{
|
||||
CodeSuggestion, DiagnosticBuilder, DiagnosticId, Level, SourceMapperDyn, SubDiagnostic,
|
||||
};
|
||||
use atty;
|
||||
use rustc_data_structures::{fx::FxHashMap, sync::Lrc};
|
||||
use fxhash::FxHashMap;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
cmp::{min, Reverse},
|
||||
io::{self, prelude::*},
|
||||
ops::Range,
|
||||
sync::Arc,
|
||||
};
|
||||
use syntax_pos::{MultiSpan, SourceFile, Span};
|
||||
use termcolor::{Buffer, BufferWriter, Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||
@ -128,14 +129,14 @@ impl ColorConfig {
|
||||
|
||||
pub struct EmitterWriter {
|
||||
dst: Destination,
|
||||
sm: Option<Lrc<SourceMapperDyn>>,
|
||||
sm: Option<Arc<SourceMapperDyn>>,
|
||||
short_message: bool,
|
||||
teach: bool,
|
||||
ui_testing: bool,
|
||||
}
|
||||
|
||||
struct FileWithAnnotatedLines {
|
||||
file: Lrc<SourceFile>,
|
||||
file: Arc<SourceFile>,
|
||||
lines: Vec<Line>,
|
||||
multiline_depth: usize,
|
||||
}
|
||||
@ -143,7 +144,7 @@ struct FileWithAnnotatedLines {
|
||||
impl EmitterWriter {
|
||||
pub fn stderr(
|
||||
color_config: ColorConfig,
|
||||
source_map: Option<Lrc<SourceMapperDyn>>,
|
||||
source_map: Option<Arc<SourceMapperDyn>>,
|
||||
short_message: bool,
|
||||
teach: bool,
|
||||
) -> EmitterWriter {
|
||||
@ -159,7 +160,7 @@ impl EmitterWriter {
|
||||
|
||||
pub fn new(
|
||||
dst: Box<dyn Write + Send>,
|
||||
source_map: Option<Lrc<SourceMapperDyn>>,
|
||||
source_map: Option<Arc<SourceMapperDyn>>,
|
||||
short_message: bool,
|
||||
teach: bool,
|
||||
) -> EmitterWriter {
|
||||
@ -188,7 +189,7 @@ impl EmitterWriter {
|
||||
fn preprocess_annotations(&mut self, msp: &MultiSpan) -> Vec<FileWithAnnotatedLines> {
|
||||
fn add_annotation_to_file(
|
||||
file_vec: &mut Vec<FileWithAnnotatedLines>,
|
||||
file: Lrc<SourceFile>,
|
||||
file: Arc<SourceFile>,
|
||||
line_index: usize,
|
||||
ann: Annotation,
|
||||
) {
|
||||
@ -316,7 +317,7 @@ impl EmitterWriter {
|
||||
fn render_source_line(
|
||||
&self,
|
||||
buffer: &mut StyledBuffer,
|
||||
file: Lrc<SourceFile>,
|
||||
file: Arc<SourceFile>,
|
||||
line: &Line,
|
||||
width_offset: usize,
|
||||
code_offset: usize,
|
||||
|
@ -15,15 +15,19 @@ pub use self::{
|
||||
emitter::{ColorConfig, Emitter, EmitterWriter},
|
||||
};
|
||||
use crate::{
|
||||
rustc_data_structures::{fx::FxHashSet, stable_hasher::StableHasher},
|
||||
sync::{self, Lock, LockCell, Lrc},
|
||||
rustc_data_structures::stable_hasher::StableHasher,
|
||||
sync::{Lock, LockCell},
|
||||
syntax_pos::{BytePos, FileLinesResult, FileName, Loc, MultiSpan, Span, NO_EXPANSION},
|
||||
};
|
||||
use fxhash::FxHashSet;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
cell::Cell,
|
||||
error, fmt, panic,
|
||||
sync::atomic::{AtomicUsize, Ordering::SeqCst},
|
||||
sync::{
|
||||
atomic::{AtomicUsize, Ordering::SeqCst},
|
||||
Arc,
|
||||
},
|
||||
};
|
||||
use termcolor::{Color, ColorSpec};
|
||||
|
||||
@ -31,7 +35,6 @@ mod diagnostic;
|
||||
mod diagnostic_builder;
|
||||
pub mod emitter;
|
||||
mod lock;
|
||||
pub mod registry;
|
||||
mod snippet;
|
||||
mod styled_buffer;
|
||||
|
||||
@ -97,7 +100,7 @@ pub struct SubstitutionPart {
|
||||
pub snippet: String,
|
||||
}
|
||||
|
||||
pub type SourceMapperDyn = dyn SourceMapper + sync::Send + sync::Sync;
|
||||
pub type SourceMapperDyn = dyn SourceMapper + Send + Sync;
|
||||
|
||||
pub trait SourceMapper {
|
||||
fn lookup_char_pos(&self, pos: BytePos) -> Loc;
|
||||
@ -270,7 +273,7 @@ pub struct Handler {
|
||||
pub flags: HandlerFlags,
|
||||
|
||||
err_count: AtomicUsize,
|
||||
emitter: Lock<Box<dyn Emitter + sync::Send>>,
|
||||
emitter: Lock<Box<dyn Emitter + Send>>,
|
||||
continue_after_error: LockCell<bool>,
|
||||
delayed_span_bugs: Lock<Vec<Diagnostic>>,
|
||||
|
||||
@ -332,7 +335,7 @@ impl Handler {
|
||||
color_config: ColorConfig,
|
||||
can_emit_warnings: bool,
|
||||
treat_err_as_bug: bool,
|
||||
cm: Option<Lrc<SourceMapperDyn>>,
|
||||
cm: Option<Arc<SourceMapperDyn>>,
|
||||
) -> Handler {
|
||||
Handler::with_tty_emitter_and_flags(
|
||||
color_config,
|
||||
@ -347,7 +350,7 @@ impl Handler {
|
||||
|
||||
pub fn with_tty_emitter_and_flags(
|
||||
color_config: ColorConfig,
|
||||
cm: Option<Lrc<SourceMapperDyn>>,
|
||||
cm: Option<Arc<SourceMapperDyn>>,
|
||||
flags: HandlerFlags,
|
||||
) -> Handler {
|
||||
let emitter = Box::new(EmitterWriter::stderr(color_config, cm, false, false));
|
||||
@ -357,7 +360,7 @@ impl Handler {
|
||||
pub fn with_emitter(
|
||||
can_emit_warnings: bool,
|
||||
treat_err_as_bug: bool,
|
||||
e: Box<dyn Emitter + sync::Send>,
|
||||
e: Box<dyn Emitter + Send>,
|
||||
) -> Handler {
|
||||
Handler::with_emitter_and_flags(
|
||||
e,
|
||||
@ -369,10 +372,7 @@ impl Handler {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn with_emitter_and_flags(
|
||||
e: Box<dyn Emitter + sync::Send>,
|
||||
flags: HandlerFlags,
|
||||
) -> Handler {
|
||||
pub fn with_emitter_and_flags(e: Box<dyn Emitter + Send>, flags: HandlerFlags) -> Handler {
|
||||
Handler {
|
||||
flags,
|
||||
err_count: AtomicUsize::new(0),
|
||||
|
@ -1,28 +0,0 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Registry {
|
||||
descriptions: FxHashMap<&'static str, &'static str>,
|
||||
}
|
||||
|
||||
impl Registry {
|
||||
pub fn new(descriptions: &[(&'static str, &'static str)]) -> Registry {
|
||||
Registry {
|
||||
descriptions: descriptions.iter().cloned().collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_description(&self, code: &str) -> Option<&'static str> {
|
||||
self.descriptions.get(code).cloned()
|
||||
}
|
||||
}
|
@ -47,7 +47,7 @@ fn test() {
|
||||
let end_pos = file_map.end_pos - BytePos(1);
|
||||
let full = Span::new(start_pos, end_pos, Default::default());
|
||||
|
||||
let handler = Handler::with_tty_emitter(ColorConfig::Always, false, false, Some(Lrc::new(cm)));
|
||||
let handler = Handler::with_tty_emitter(ColorConfig::Always, false, false, Some(Arc::new(cm)));
|
||||
|
||||
::syntax_pos::GLOBALS.set(&::syntax_pos::Globals::new(), || {
|
||||
DiagnosticBuilder::new_with_code(
|
||||
|
@ -2,20 +2,15 @@
|
||||
|
||||
extern crate ast_node;
|
||||
extern crate atty;
|
||||
extern crate cfg_if;
|
||||
extern crate either;
|
||||
extern crate fxhash;
|
||||
extern crate owning_ref;
|
||||
extern crate log;
|
||||
extern crate parking_lot;
|
||||
extern crate rayon;
|
||||
extern crate rayon_core;
|
||||
extern crate scoped_tls;
|
||||
extern crate string_cache;
|
||||
extern crate termcolor;
|
||||
extern crate unicode_width;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate cfg_if;
|
||||
extern crate scoped_tls;
|
||||
|
||||
#[cfg(feature = "fold")]
|
||||
pub use self::fold::{Fold, FoldWith, Visit, VisitWith};
|
||||
@ -40,6 +35,6 @@ pub mod macros;
|
||||
mod pos;
|
||||
mod rustc_data_structures;
|
||||
mod source_map;
|
||||
pub mod sync;
|
||||
mod sync;
|
||||
mod syntax_pos;
|
||||
pub mod util;
|
||||
|
@ -1,4 +1,2 @@
|
||||
pub use crate::sync;
|
||||
pub extern crate fxhash as fx;
|
||||
pub mod sip128;
|
||||
pub mod stable_hasher;
|
||||
|
@ -16,16 +16,18 @@
|
||||
//! `spans` and used pervasively in the compiler. They are absolute positions
|
||||
//! within the SourceMap, which upon request can be converted to line and column
|
||||
//! information, source code snippets, etc.
|
||||
|
||||
use crate::sync::{Lock, LockGuard, Lrc, MappedLockGuard};
|
||||
use crate::sync::{Lock, LockGuard, MappedLockGuard};
|
||||
pub use crate::syntax_pos::{hygiene::ExpnInfo, *};
|
||||
use errors::SourceMapper;
|
||||
use rustc_data_structures::{fx::FxHashMap, stable_hasher::StableHasher};
|
||||
use fxhash::FxHashMap;
|
||||
use log::debug;
|
||||
use rustc_data_structures::stable_hasher::StableHasher;
|
||||
use std::{
|
||||
cmp, env, fs,
|
||||
hash::Hash,
|
||||
io::{self, Read},
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
// _____________________________________________________________________________
|
||||
@ -91,8 +93,8 @@ impl StableSourceFileId {
|
||||
|
||||
#[derive(Default)]
|
||||
pub(super) struct SourceMapFiles {
|
||||
pub(super) source_files: Vec<Lrc<SourceFile>>,
|
||||
stable_id_to_source_file: FxHashMap<StableSourceFileId, Lrc<SourceFile>>,
|
||||
pub(super) source_files: Vec<Arc<SourceFile>>,
|
||||
stable_id_to_source_file: FxHashMap<StableSourceFileId, Arc<SourceFile>>,
|
||||
}
|
||||
|
||||
pub struct SourceMap {
|
||||
@ -143,7 +145,7 @@ impl SourceMap {
|
||||
self.file_loader.file_exists(path)
|
||||
}
|
||||
|
||||
pub fn load_file(&self, path: &Path) -> io::Result<Lrc<SourceFile>> {
|
||||
pub fn load_file(&self, path: &Path) -> io::Result<Arc<SourceFile>> {
|
||||
let src = self.file_loader.read_file(path)?;
|
||||
let filename = if let Some((ref name, _)) = self.doctest_offset {
|
||||
name.clone()
|
||||
@ -153,14 +155,14 @@ impl SourceMap {
|
||||
Ok(self.new_source_file(filename, src))
|
||||
}
|
||||
|
||||
pub fn files(&self) -> MappedLockGuard<Vec<Lrc<SourceFile>>> {
|
||||
pub fn files(&self) -> MappedLockGuard<Vec<Arc<SourceFile>>> {
|
||||
LockGuard::map(self.files.borrow(), |files| &mut files.source_files)
|
||||
}
|
||||
|
||||
pub fn source_file_by_stable_id(
|
||||
&self,
|
||||
stable_id: StableSourceFileId,
|
||||
) -> Option<Lrc<SourceFile>> {
|
||||
) -> Option<Arc<SourceFile>> {
|
||||
self.files
|
||||
.borrow()
|
||||
.stable_id_to_source_file
|
||||
@ -179,7 +181,7 @@ impl SourceMap {
|
||||
|
||||
/// Creates a new source_file.
|
||||
/// This does not ensure that only one SourceFile exists per file name.
|
||||
pub fn new_source_file(&self, filename: FileName, src: String) -> Lrc<SourceFile> {
|
||||
pub fn new_source_file(&self, filename: FileName, src: String) -> Arc<SourceFile> {
|
||||
let start_pos = self.next_start_pos();
|
||||
|
||||
// The path is used to determine the directory for loading submodules and
|
||||
@ -196,7 +198,7 @@ impl SourceMap {
|
||||
}
|
||||
other => (other, false),
|
||||
};
|
||||
let source_file = Lrc::new(SourceFile::new(
|
||||
let source_file = Arc::new(SourceFile::new(
|
||||
filename,
|
||||
was_remapped,
|
||||
unmapped_path,
|
||||
@ -302,7 +304,7 @@ impl SourceMap {
|
||||
}
|
||||
|
||||
// If the relevant source_file is empty, we don't return a line number.
|
||||
pub fn lookup_line(&self, pos: BytePos) -> Result<SourceFileAndLine, Lrc<SourceFile>> {
|
||||
pub fn lookup_line(&self, pos: BytePos) -> Result<SourceFileAndLine, Arc<SourceFile>> {
|
||||
let idx = self.lookup_source_file_idx(pos);
|
||||
|
||||
let f = (*self.files.borrow().source_files)[idx].clone();
|
||||
@ -756,7 +758,7 @@ impl SourceMap {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_source_file(&self, filename: &FileName) -> Option<Lrc<SourceFile>> {
|
||||
pub fn get_source_file(&self, filename: &FileName) -> Option<Arc<SourceFile>> {
|
||||
for sf in self.files.borrow().source_files.iter() {
|
||||
if *filename == sf.name {
|
||||
return Some(sf.clone());
|
||||
@ -979,7 +981,7 @@ impl FilePathMapping {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use std::sync::Arc;
|
||||
|
||||
fn init_source_map() -> SourceMap {
|
||||
let sm = SourceMap::new(FilePathMapping::empty());
|
||||
@ -1177,7 +1179,7 @@ mod tests {
|
||||
trait SourceMapExtension {
|
||||
fn span_substr(
|
||||
&self,
|
||||
file: &Lrc<SourceFile>,
|
||||
file: &Arc<SourceFile>,
|
||||
source_text: &str,
|
||||
substring: &str,
|
||||
n: usize,
|
||||
@ -1187,7 +1189,7 @@ mod tests {
|
||||
impl SourceMapExtension for SourceMap {
|
||||
fn span_substr(
|
||||
&self,
|
||||
file: &Lrc<SourceFile>,
|
||||
file: &Arc<SourceFile>,
|
||||
source_text: &str,
|
||||
substring: &str,
|
||||
n: usize,
|
||||
|
@ -33,92 +33,18 @@
|
||||
//! `rustc_erase_owner!` erases a OwningRef owner into Erased or Erased + Send +
|
||||
//! Sync depending on the value of cfg!(parallel_queries).
|
||||
|
||||
use owning_ref::{Erased, OwningRef};
|
||||
pub use parking_lot::{
|
||||
MappedMutexGuard as MappedLockGuard, MappedRwLockReadGuard as MappedReadGuard,
|
||||
MappedRwLockWriteGuard as MappedWriteGuard, MutexGuard as LockGuard,
|
||||
RwLockReadGuard as ReadGuard, RwLockWriteGuard as WriteGuard,
|
||||
};
|
||||
use parking_lot::{Mutex as InnerLock, RwLock as InnerRwLock};
|
||||
use rayon::iter::IntoParallelIterator;
|
||||
pub use rayon::{iter::ParallelIterator, join, scope};
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
collections::HashMap,
|
||||
fmt::{self, Debug, Formatter},
|
||||
hash::{BuildHasher, Hash},
|
||||
marker::PhantomData,
|
||||
ops::{Deref, DerefMut},
|
||||
thread,
|
||||
};
|
||||
pub use std::{
|
||||
marker::{Send, Sync},
|
||||
sync::{Arc as Lrc, Weak},
|
||||
};
|
||||
|
||||
pub fn serial_join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
|
||||
where
|
||||
A: FnOnce() -> RA,
|
||||
B: FnOnce() -> RB,
|
||||
{
|
||||
(oper_a(), oper_b())
|
||||
}
|
||||
|
||||
pub struct SerialScope;
|
||||
|
||||
impl SerialScope {
|
||||
pub fn spawn<F>(&self, f: F)
|
||||
where
|
||||
F: FnOnce(&SerialScope),
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn serial_scope<F, R>(f: F) -> R
|
||||
where
|
||||
F: FnOnce(&SerialScope) -> R,
|
||||
{
|
||||
f(&SerialScope)
|
||||
}
|
||||
|
||||
pub type MTRef<'a, T> = &'a T;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct MTLock<T>(Lock<T>);
|
||||
|
||||
impl<T> MTLock<T> {
|
||||
#[inline(always)]
|
||||
pub fn new(inner: T) -> Self {
|
||||
MTLock(Lock::new(inner))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn into_inner(self) -> T {
|
||||
self.0.into_inner()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
self.0.get_mut()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn lock(&self) -> LockGuard<T> {
|
||||
self.0.lock()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn lock_mut(&self) -> LockGuard<T> {
|
||||
self.lock()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn par_iter<T: IntoParallelIterator>(t: T) -> T::Iter {
|
||||
t.into_par_iter()
|
||||
}
|
||||
|
||||
pub type MetadataRef = OwningRef<Box<dyn Erased + Send + Sync>, [u8]>;
|
||||
|
||||
/// This makes locks panic if they are already held.
|
||||
/// It is only useful when you are running in a single thread
|
||||
@ -141,11 +67,6 @@ impl<T> LockCell<T> {
|
||||
LockCell(Lock::new(inner))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn into_inner(self) -> T {
|
||||
self.0.into_inner()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn set(&self, new_inner: T) {
|
||||
*self.0.lock() = new_inner;
|
||||
@ -158,32 +79,8 @@ impl<T> LockCell<T> {
|
||||
{
|
||||
*self.0.lock()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn set_mut(&mut self, new_inner: T) {
|
||||
*self.0.get_mut() = new_inner;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get_mut(&mut self) -> T
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
*self.0.get_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> LockCell<Option<T>> {
|
||||
#[inline(always)]
|
||||
pub fn take(&self) -> Option<T> {
|
||||
self.0.lock().take()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn assert_sync<T: ?Sized + Sync>() {}
|
||||
pub fn assert_send_val<T: ?Sized + Send>(_t: &T) {}
|
||||
pub fn assert_send_sync_val<T: ?Sized + Sync + Send>(_t: &T) {}
|
||||
|
||||
pub trait HashMapExt<K, V> {
|
||||
/// Same as HashMap::insert, but it may panic if there's already an
|
||||
/// entry for `key` with a value not equal to `value`
|
||||
@ -198,151 +95,6 @@ impl<K: Eq + Hash, V: Eq, S: BuildHasher> HashMapExt<K, V> for HashMap<K, V, S>
|
||||
}
|
||||
}
|
||||
|
||||
/// A type whose inner value can be written once and then will stay read-only
|
||||
// This contains a PhantomData<T> since this type conceptually owns a T outside
|
||||
// the Mutex once initialized. This ensures that Once<T> is Sync only if T is.
|
||||
// If we did not have PhantomData<T> we could send a &Once<Cell<bool>> to
|
||||
// multiple threads and call `get` on it to get access to &Cell<bool> on those
|
||||
// threads.
|
||||
pub struct Once<T>(Lock<Option<T>>, PhantomData<T>);
|
||||
|
||||
impl<T> Once<T> {
|
||||
/// Creates an Once value which is uninitialized
|
||||
#[inline(always)]
|
||||
pub fn new() -> Self {
|
||||
Once(Lock::new(None), PhantomData)
|
||||
}
|
||||
|
||||
/// Consumes the value and returns Some(T) if it was initialized
|
||||
#[inline(always)]
|
||||
pub fn into_inner(self) -> Option<T> {
|
||||
self.0.into_inner()
|
||||
}
|
||||
|
||||
/// Tries to initialize the inner value to `value`.
|
||||
/// Returns `None` if the inner value was uninitialized and `value` was
|
||||
/// consumed setting it otherwise if the inner value was already set it
|
||||
/// returns `value` back to the caller
|
||||
#[inline]
|
||||
pub fn try_set(&self, value: T) -> Option<T> {
|
||||
let mut lock = self.0.lock();
|
||||
if lock.is_some() {
|
||||
return Some(value);
|
||||
}
|
||||
*lock = Some(value);
|
||||
None
|
||||
}
|
||||
|
||||
/// Tries to initialize the inner value to `value`.
|
||||
/// Returns `None` if the inner value was uninitialized and `value` was
|
||||
/// consumed setting it otherwise if the inner value was already set it
|
||||
/// asserts that `value` is equal to the inner value and then returns
|
||||
/// `value` back to the caller
|
||||
#[inline]
|
||||
pub fn try_set_same(&self, value: T) -> Option<T>
|
||||
where
|
||||
T: Eq,
|
||||
{
|
||||
let mut lock = self.0.lock();
|
||||
if let Some(ref inner) = *lock {
|
||||
assert!(*inner == value);
|
||||
return Some(value);
|
||||
}
|
||||
*lock = Some(value);
|
||||
None
|
||||
}
|
||||
|
||||
/// Tries to initialize the inner value to `value` and panics if it was
|
||||
/// already initialized
|
||||
#[inline]
|
||||
pub fn set(&self, value: T) {
|
||||
assert!(self.try_set(value).is_none());
|
||||
}
|
||||
|
||||
/// Tries to initialize the inner value by calling the closure while
|
||||
/// ensuring that no-one else can access the value in the mean time by
|
||||
/// holding a lock for the duration of the closure. If the value was
|
||||
/// already initialized the closure is not called and `false` is returned,
|
||||
/// otherwise if the value from the closure initializes the inner value,
|
||||
/// `true` is returned
|
||||
#[inline]
|
||||
pub fn init_locking<F: FnOnce() -> T>(&self, f: F) -> bool {
|
||||
let mut lock = self.0.lock();
|
||||
if lock.is_some() {
|
||||
return false;
|
||||
}
|
||||
*lock = Some(f());
|
||||
true
|
||||
}
|
||||
|
||||
/// Tries to initialize the inner value by calling the closure without
|
||||
/// ensuring that no-one else can access it. This mean when this is
|
||||
/// called from multiple threads, multiple closures may concurrently be
|
||||
/// computing a value which the inner value should take. Only one of
|
||||
/// these closures are used to actually initialize the value.
|
||||
/// If some other closure already set the value,
|
||||
/// we return the value our closure computed wrapped in a `Option`.
|
||||
/// If our closure set the value, `None` is returned.
|
||||
/// If the value is already initialized, the closure is not called and
|
||||
/// `None` is returned.
|
||||
#[inline]
|
||||
pub fn init_nonlocking<F: FnOnce() -> T>(&self, f: F) -> Option<T> {
|
||||
if self.0.lock().is_some() {
|
||||
None
|
||||
} else {
|
||||
self.try_set(f())
|
||||
}
|
||||
}
|
||||
|
||||
/// Tries to initialize the inner value by calling the closure without
|
||||
/// ensuring that no-one else can access it. This mean when this is
|
||||
/// called from multiple threads, multiple closures may concurrently be
|
||||
/// computing a value which the inner value should take. Only one of
|
||||
/// these closures are used to actually initialize the value.
|
||||
/// If some other closure already set the value, we assert that it our
|
||||
/// closure computed a value equal to the value already set and then
|
||||
/// we return the value our closure computed wrapped in a `Option`.
|
||||
/// If our closure set the value, `None` is returned.
|
||||
/// If the value is already initialized, the closure is not called and
|
||||
/// `None` is returned.
|
||||
#[inline]
|
||||
pub fn init_nonlocking_same<F: FnOnce() -> T>(&self, f: F) -> Option<T>
|
||||
where
|
||||
T: Eq,
|
||||
{
|
||||
if self.0.lock().is_some() {
|
||||
None
|
||||
} else {
|
||||
self.try_set_same(f())
|
||||
}
|
||||
}
|
||||
|
||||
/// Tries to get a reference to the inner value, returns `None` if it is not
|
||||
/// yet initialized
|
||||
#[inline(always)]
|
||||
pub fn try_get(&self) -> Option<&T> {
|
||||
let lock = &*self.0.lock();
|
||||
if let Some(ref inner) = *lock {
|
||||
// This is safe since we won't mutate the inner value
|
||||
unsafe { Some(&*(inner as *const T)) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets reference to the inner value, panics if it is not yet initialized
|
||||
#[inline(always)]
|
||||
pub fn get(&self) -> &T {
|
||||
self.try_get().expect("value was not set")
|
||||
}
|
||||
|
||||
/// Gets reference to the inner value, panics if it is not yet initialized
|
||||
#[inline(always)]
|
||||
pub fn borrow(&self) -> &T {
|
||||
self.get()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Debug> Debug for LockCell<T> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
f.debug_struct("LockCell")
|
||||
@ -411,21 +163,6 @@ impl<T> Lock<T> {
|
||||
Lock(InnerLock::new(inner))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn into_inner(self) -> T {
|
||||
self.0.into_inner()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
self.0.get_mut()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn try_lock(&self) -> Option<LockGuard<T>> {
|
||||
self.0.try_lock()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn lock(&self) -> LockGuard<T> {
|
||||
if ERROR_CHECKING {
|
||||
@ -435,11 +172,6 @@ impl<T> Lock<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn with_lock<F: FnOnce(&mut T) -> R, R>(&self, f: F) -> R {
|
||||
f(&mut *self.lock())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn borrow(&self) -> LockGuard<T> {
|
||||
self.lock()
|
||||
@ -475,16 +207,6 @@ impl<T> RwLock<T> {
|
||||
RwLock(InnerRwLock::new(inner))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn into_inner(self) -> T {
|
||||
self.0.into_inner()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
self.0.get_mut()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn read(&self) -> ReadGuard<T> {
|
||||
if ERROR_CHECKING {
|
||||
@ -494,39 +216,10 @@ impl<T> RwLock<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn with_read_lock<F: FnOnce(&T) -> R, R>(&self, f: F) -> R {
|
||||
f(&*self.read())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn try_write(&self) -> Result<WriteGuard<T>, ()> {
|
||||
self.0.try_write().ok_or(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn write(&self) -> WriteGuard<T> {
|
||||
if ERROR_CHECKING {
|
||||
self.0.try_write().expect("lock was already held")
|
||||
} else {
|
||||
self.0.write()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn with_write_lock<F: FnOnce(&mut T) -> R, R>(&self, f: F) -> R {
|
||||
f(&mut *self.write())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn borrow(&self) -> ReadGuard<T> {
|
||||
self.read()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn borrow_mut(&self) -> WriteGuard<T> {
|
||||
self.write()
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Probably a bad idea
|
||||
@ -536,51 +229,3 @@ impl<T: Clone> Clone for RwLock<T> {
|
||||
RwLock::new(self.borrow().clone())
|
||||
}
|
||||
}
|
||||
|
||||
/// A type which only allows its inner value to be used in one thread.
|
||||
/// It will panic if it is used on multiple threads.
|
||||
#[derive(Copy, Clone, Hash, Debug, Eq, PartialEq)]
|
||||
pub struct OneThread<T> {
|
||||
thread: thread::ThreadId,
|
||||
inner: T,
|
||||
}
|
||||
|
||||
unsafe impl<T> std::marker::Sync for OneThread<T> {}
|
||||
unsafe impl<T> std::marker::Send for OneThread<T> {}
|
||||
|
||||
impl<T> OneThread<T> {
|
||||
#[inline(always)]
|
||||
fn check(&self) {
|
||||
assert_eq!(thread::current().id(), self.thread);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn new(inner: T) -> Self {
|
||||
OneThread {
|
||||
thread: thread::current().id(),
|
||||
inner,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn into_inner(value: Self) -> T {
|
||||
value.check();
|
||||
value.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for OneThread<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &T {
|
||||
self.check();
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for OneThread<T> {
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
self.check();
|
||||
&mut self.inner
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,8 @@
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::*;
|
||||
use cfg_if::cfg_if;
|
||||
use unicode_width::UnicodeWidthChar;
|
||||
|
||||
/// Find all newlines, multi-byte characters, and non-narrow characters in a
|
||||
|
@ -16,7 +16,7 @@
|
||||
//! DOI=10.1017/S0956796812000093 <https://doi.org/10.1017/S0956796812000093>
|
||||
|
||||
use super::{Span, GLOBALS};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use fxhash::{FxHashMap, FxHashSet};
|
||||
use std::fmt;
|
||||
|
||||
/// A SyntaxContext represents a chain of macro expansions (represented by
|
||||
|
@ -2,10 +2,8 @@ pub use self::{
|
||||
hygiene::{ExpnInfo, Mark, SyntaxContext},
|
||||
span_encoding::{Span, DUMMY_SP},
|
||||
};
|
||||
use rustc_data_structures::{
|
||||
stable_hasher::StableHasher,
|
||||
sync::{Lock, Lrc},
|
||||
};
|
||||
use crate::sync::Lock;
|
||||
use rustc_data_structures::stable_hasher::StableHasher;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
cell::Cell,
|
||||
@ -14,6 +12,7 @@ use std::{
|
||||
hash::{Hash, Hasher},
|
||||
ops::{Add, Sub},
|
||||
path::PathBuf,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
mod analyze_source_file;
|
||||
@ -662,7 +661,7 @@ pub struct SourceFile {
|
||||
/// Indicates which crate this SourceFile was imported from.
|
||||
pub crate_of_origin: u32,
|
||||
/// The complete source code
|
||||
pub src: Lrc<String>,
|
||||
pub src: Arc<String>,
|
||||
/// The source code's hash
|
||||
pub src_hash: u128,
|
||||
/// The start position of this source in the SourceMap
|
||||
@ -715,7 +714,7 @@ impl SourceFile {
|
||||
name_was_remapped,
|
||||
unmapped_path: Some(unmapped_path),
|
||||
crate_of_origin: 0,
|
||||
src: Lrc::new(src),
|
||||
src: Arc::new(src),
|
||||
src_hash,
|
||||
start_pos,
|
||||
end_pos: Pos::from_usize(end_pos),
|
||||
@ -927,7 +926,7 @@ impl Sub for CharPos {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Loc {
|
||||
/// Information about the original source
|
||||
pub file: Lrc<SourceFile>,
|
||||
pub file: Arc<SourceFile>,
|
||||
/// The (1-based) line number
|
||||
pub line: usize,
|
||||
/// The (0-based) column offset
|
||||
@ -944,18 +943,18 @@ pub struct LocWithOpt {
|
||||
pub filename: FileName,
|
||||
pub line: usize,
|
||||
pub col: CharPos,
|
||||
pub file: Option<Lrc<SourceFile>>,
|
||||
pub file: Option<Arc<SourceFile>>,
|
||||
}
|
||||
|
||||
// used to be structural records. Better names, anyone?
|
||||
#[derive(Debug)]
|
||||
pub struct SourceFileAndLine {
|
||||
pub sf: Lrc<SourceFile>,
|
||||
pub sf: Arc<SourceFile>,
|
||||
pub line: usize,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct SourceFileAndBytePos {
|
||||
pub sf: Lrc<SourceFile>,
|
||||
pub sf: Arc<SourceFile>,
|
||||
pub pos: BytePos,
|
||||
}
|
||||
|
||||
@ -972,7 +971,7 @@ pub struct LineInfo {
|
||||
}
|
||||
|
||||
pub struct FileLines {
|
||||
pub file: Lrc<SourceFile>,
|
||||
pub file: Arc<SourceFile>,
|
||||
pub lines: Vec<LineInfo>,
|
||||
}
|
||||
|
||||
|
@ -14,14 +14,13 @@
|
||||
// The encoding format for inline spans were obtained by optimizing over crates
|
||||
// in rustc/libstd. See https://internals.rust-lang.org/t/rfc-compiler-refactoring-spans/1357/28
|
||||
|
||||
use hygiene::SyntaxContext;
|
||||
use super::hygiene::SyntaxContext;
|
||||
use fxhash::FxHashMap;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use BytePos;
|
||||
use SpanData;
|
||||
use GLOBALS;
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
/// A compressed span.
|
||||
/// Contains either fields of `SpanData` inline if they are small, or index into
|
||||
/// span interner. The primary goal of `Span` is to be as small as possible and
|
||||
|
@ -15,6 +15,36 @@ pub trait MoveMap<T>: Sized {
|
||||
}
|
||||
|
||||
impl<T> MoveMap<T> for Vec<T> {
|
||||
/// This reduces binary size.
|
||||
fn move_map<F>(mut self, mut f: F) -> Self
|
||||
where
|
||||
F: FnMut(T) -> T,
|
||||
{
|
||||
let mut read_i = 0;
|
||||
let mut write_i = 0;
|
||||
unsafe {
|
||||
let old_len = self.len();
|
||||
self.set_len(0); // make sure we just leak elements in case of panic
|
||||
|
||||
while read_i < old_len {
|
||||
// move the read_i'th item out of the vector and map it
|
||||
// to an iterator
|
||||
let e = ptr::read(self.get_unchecked(read_i));
|
||||
let e = f(e);
|
||||
read_i += 1;
|
||||
|
||||
assert!(write_i < read_i);
|
||||
ptr::write(self.get_unchecked_mut(write_i), e);
|
||||
write_i += 1;
|
||||
}
|
||||
|
||||
// write_i tracks the number of actually written new items.
|
||||
self.set_len(write_i);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn move_flat_map<F, I>(mut self, mut f: F) -> Self
|
||||
where
|
||||
F: FnMut(T) -> I,
|
||||
|
@ -20,11 +20,9 @@ use self::{
|
||||
util::{SourceMapperExt, SpanExt, StartsWithAlphaNum},
|
||||
};
|
||||
use fxhash::FxHashSet;
|
||||
use std::io;
|
||||
use std::{io, sync::Arc};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{
|
||||
comments::Comments, sync::Lrc, BytePos, SourceMap, Span, Spanned, SyntaxContext, DUMMY_SP,
|
||||
};
|
||||
use swc_common::{comments::Comments, BytePos, SourceMap, Span, Spanned, SyntaxContext, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_codegen_macros::emitter;
|
||||
|
||||
@ -66,7 +64,7 @@ impl<'a, N: Node> Node for &'a N {
|
||||
|
||||
pub struct Emitter<'a> {
|
||||
pub cfg: config::Config,
|
||||
pub cm: Lrc<SourceMap>,
|
||||
pub cm: Arc<SourceMap>,
|
||||
pub comments: Option<Comments>,
|
||||
pub wr: Box<('a + WriteJs)>,
|
||||
pub handlers: Box<('a + Handlers)>,
|
||||
@ -159,6 +157,7 @@ impl<'a> Emitter<'a> {
|
||||
space!();
|
||||
|
||||
let mut specifiers = vec![];
|
||||
let mut emitted_default = false;
|
||||
for specifier in &node.specifiers {
|
||||
match specifier {
|
||||
ImportSpecifier::Specific(ref s) => {
|
||||
@ -166,7 +165,7 @@ impl<'a> Emitter<'a> {
|
||||
}
|
||||
ImportSpecifier::Default(ref s) => {
|
||||
emit!(s.local);
|
||||
space!();
|
||||
emitted_default = true;
|
||||
}
|
||||
ImportSpecifier::Namespace(ref ns) => {
|
||||
assert!(node.specifiers.len() <= 2);
|
||||
@ -180,7 +179,14 @@ impl<'a> Emitter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
if !specifiers.is_empty() {
|
||||
if specifiers.is_empty() {
|
||||
space!();
|
||||
} else if !specifiers.is_empty() {
|
||||
if emitted_default {
|
||||
punct!(",");
|
||||
formatting_space!();
|
||||
}
|
||||
|
||||
punct!("{");
|
||||
self.emit_list(
|
||||
node.span(),
|
||||
@ -188,10 +194,11 @@ impl<'a> Emitter<'a> {
|
||||
ListFormat::NamedImportsOrExportsElements,
|
||||
)?;
|
||||
punct!("}");
|
||||
formatting_space!();
|
||||
}
|
||||
|
||||
keyword!("from");
|
||||
space!();
|
||||
formatting_space!();
|
||||
emit!(node.src);
|
||||
semi!();
|
||||
}
|
||||
@ -1806,7 +1813,7 @@ impl<'a> Emitter<'a> {
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn get_text_of_node<T: Spanned>(
|
||||
cm: &Lrc<SourceMap>,
|
||||
cm: &Arc<SourceMap>,
|
||||
node: &T,
|
||||
_include_travia: bool,
|
||||
) -> Option<String> {
|
||||
|
@ -3,7 +3,7 @@
|
||||
/// [ratel]:https://github.com/ratel-rust/ratel-core
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::tests::assert_min;
|
||||
use crate::tests::{assert_min, assert_pretty};
|
||||
|
||||
#[test]
|
||||
fn block_statement() {
|
||||
@ -74,4 +74,16 @@ mod tests {
|
||||
assert_min("for (foo of bar){}", "for(foo of bar){}");
|
||||
assert_min("for (let foo of bar){}", "for(let foo of bar){}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import() {
|
||||
assert_min(
|
||||
"import colors, { color } from 'patterns/colors';",
|
||||
"import colors,{color}from'patterns/colors';",
|
||||
);
|
||||
assert_pretty(
|
||||
"import colors, { color } from 'patterns/colors';",
|
||||
"import colors, { color } from 'patterns/colors';",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ impl Handlers for Noop {}
|
||||
|
||||
struct Builder {
|
||||
cfg: Config,
|
||||
cm: Lrc<SourceMap>,
|
||||
cm: Arc<SourceMap>,
|
||||
comments: Comments,
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
use super::{Result, WriteJs};
|
||||
use sourcemap::SourceMapBuilder;
|
||||
use std::io::{self, Write};
|
||||
use swc_common::{sync::Lrc, SourceMap, Span};
|
||||
use std::{
|
||||
io::{self, Write},
|
||||
sync::Arc,
|
||||
};
|
||||
use swc_common::{SourceMap, Span};
|
||||
|
||||
///
|
||||
/// -----
|
||||
@ -10,7 +13,7 @@ use swc_common::{sync::Lrc, SourceMap, Span};
|
||||
///
|
||||
/// https://github.com/Microsoft/TypeScript/blob/45eaf42006/src/compiler/utilities.ts#L2548
|
||||
pub struct JsWriter<'a, W: Write> {
|
||||
cm: Lrc<SourceMap>,
|
||||
cm: Arc<SourceMap>,
|
||||
indent: usize,
|
||||
line_start: bool,
|
||||
line_count: usize,
|
||||
@ -23,7 +26,7 @@ pub struct JsWriter<'a, W: Write> {
|
||||
|
||||
impl<'a, W: Write> JsWriter<'a, W> {
|
||||
pub fn new(
|
||||
cm: Lrc<SourceMap>,
|
||||
cm: Arc<SourceMap>,
|
||||
new_line: &'a str,
|
||||
wr: W,
|
||||
srcmap: &'a mut SourceMapBuilder,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::list::ListFormat;
|
||||
use std::sync::Arc;
|
||||
use swc_common::{
|
||||
errors::SourceMapper, sync::Lrc, BytePos, SourceMap, SourceMapperDyn, Span, Spanned,
|
||||
SyntaxContext,
|
||||
errors::SourceMapper, BytePos, SourceMap, SourceMapperDyn, Span, Spanned, SyntaxContext,
|
||||
};
|
||||
use swc_ecma_ast::*;
|
||||
|
||||
@ -127,13 +127,13 @@ impl SourceMapperExt for SourceMapper {
|
||||
self
|
||||
}
|
||||
}
|
||||
impl SourceMapperExt for Lrc<SourceMapperDyn> {
|
||||
impl SourceMapperExt for Arc<SourceMapperDyn> {
|
||||
fn get_code_map(&self) -> &SourceMapper {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
impl SourceMapperExt for Lrc<SourceMap> {
|
||||
impl SourceMapperExt for Arc<SourceMap> {
|
||||
fn get_code_map(&self) -> &SourceMapper {
|
||||
&**self
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use std::{
|
||||
path::Path,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
use swc_common::{comments::Comments, sync::Lrc};
|
||||
use swc_common::comments::Comments;
|
||||
use swc_ecma_codegen::Emitter;
|
||||
use swc_ecma_parser::{Parser, Session, SourceFileInput, Syntax};
|
||||
use test::{test_main, Options, ShouldPanic::No, TestDesc, TestDescAndFn, TestFn, TestName};
|
||||
@ -154,7 +154,7 @@ fn error_tests(tests: &mut Vec<TestDescAndFn>) -> Result<(), io::Error> {
|
||||
Some(Comments::default()),
|
||||
);
|
||||
|
||||
let s: Lrc<String> = src.src.clone();
|
||||
let s: Arc<String> = src.src.clone();
|
||||
let mut src_map_builder = SourceMapBuilder::new(Some(&s));
|
||||
{
|
||||
let mut emitter = Emitter {
|
||||
|
@ -154,6 +154,7 @@ fn module_legacy_comment_2() {
|
||||
#[test]
|
||||
fn test262_lexer_error_0001() {
|
||||
assert_eq!(
|
||||
lex(Syntax::default(), "123..a(1)"),
|
||||
vec![
|
||||
123f64.span(0..4).lb(),
|
||||
Dot.span(4..5),
|
||||
@ -162,13 +163,13 @@ fn test262_lexer_error_0001() {
|
||||
1.span(7..8),
|
||||
RParen.span(8..9),
|
||||
],
|
||||
lex(Syntax::default(), "123..a(1)")
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test262_lexer_error_0002() {
|
||||
assert_eq!(
|
||||
lex(Syntax::default(), r#"'use\x20strict';"#),
|
||||
vec![
|
||||
Token::Str {
|
||||
value: "use strict".into(),
|
||||
@ -177,45 +178,44 @@ fn test262_lexer_error_0002() {
|
||||
.span(0..15)
|
||||
.lb(),
|
||||
Semi.span(15..16),
|
||||
],
|
||||
lex(Syntax::default(), r#"'use\x20strict';"#)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test262_lexer_error_0003() {
|
||||
assert_eq!(
|
||||
vec!["a".span(0..6).lb()],
|
||||
lex(Syntax::default(), r#"\u0061"#)
|
||||
lex(Syntax::default(), r#"\u0061"#),
|
||||
vec!["a".span(0..6).lb()]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test262_lexer_error_0004() {
|
||||
assert_eq!(
|
||||
vec![tok!('+'), tok!('{'), tok!('}'), tok!('/'), 1.into_token()],
|
||||
lex_tokens(Syntax::default(), "+{} / 1")
|
||||
lex_tokens(Syntax::default(), "+{} / 1"),
|
||||
vec![tok!('+'), tok!('{'), tok!('}'), tok!('/'), 1.into_token()]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ident_escape_unicode() {
|
||||
assert_eq!(
|
||||
vec!["aa".span(0..7).lb()],
|
||||
lex(Syntax::default(), r#"a\u0061"#)
|
||||
lex(Syntax::default(), r#"a\u0061"#),
|
||||
vec!["aa".span(0..7).lb()]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ident_escape_unicode_2() {
|
||||
assert_eq!(
|
||||
vec!["℘℘".span(0..6).lb()],
|
||||
lex(Syntax::default(), "℘℘")
|
||||
lex(Syntax::default(), "℘℘"),
|
||||
vec!["℘℘".span(0..6).lb()]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
vec!["℘℘".span(0..9).lb()],
|
||||
lex(Syntax::default(), r#"℘\u2118"#)
|
||||
lex(Syntax::default(), r#"℘\u2118"#),
|
||||
vec!["℘℘".span(0..9).lb()]
|
||||
);
|
||||
}
|
||||
|
||||
@ -372,30 +372,30 @@ fn non_regexp_unary_plus() {
|
||||
#[test]
|
||||
fn paren_semi() {
|
||||
assert_eq!(
|
||||
vec![LParen.span(0).lb(), RParen.span(1), Semi.span(2)],
|
||||
lex(Syntax::default(), "();")
|
||||
lex(Syntax::default(), "();"),
|
||||
vec![LParen.span(0).lb(), RParen.span(1), Semi.span(2)]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ident_paren() {
|
||||
assert_eq!(
|
||||
lex(Syntax::default(), "a(bc);"),
|
||||
vec![
|
||||
"a".span(0).lb(),
|
||||
LParen.span(1),
|
||||
"bc".span(2..4),
|
||||
RParen.span(4),
|
||||
Semi.span(5),
|
||||
],
|
||||
lex(Syntax::default(), "a(bc);")
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_word() {
|
||||
assert_eq!(
|
||||
vec!["a".span(0).lb(), "b".span(2), "c".span(4)],
|
||||
lex(Syntax::default(), "a b c"),
|
||||
vec!["a".span(0).lb(), "b".span(2), "c".span(4)]
|
||||
)
|
||||
}
|
||||
|
||||
@ -440,6 +440,7 @@ fn simple_regex() {
|
||||
#[test]
|
||||
fn complex_regex() {
|
||||
assert_eq_ignore_span!(
|
||||
lex_tokens(Syntax::default(), "f(); function foo() {} /42/i"),
|
||||
vec![
|
||||
Word(Word::Ident("f".into())),
|
||||
LParen,
|
||||
@ -463,22 +464,22 @@ fn complex_regex() {
|
||||
has_escape: false,
|
||||
}),
|
||||
),
|
||||
],
|
||||
lex_tokens(Syntax::default(), "f(); function foo() {} /42/i")
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple_div() {
|
||||
assert_eq!(
|
||||
lex(Syntax::default(), "a / b"),
|
||||
vec!["a".span(0).lb(), Div.span(2), "b".span(4)],
|
||||
lex(Syntax::default(), "a / b")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn complex_divide() {
|
||||
assert_eq!(
|
||||
lex_tokens(Syntax::default(), "x = function foo() {} /a/i"),
|
||||
vec![
|
||||
Word(Word::Ident("x".into())),
|
||||
AssignOp(Assign),
|
||||
@ -493,7 +494,6 @@ fn complex_divide() {
|
||||
BinOp(Div),
|
||||
Word(Word::Ident("i".into())),
|
||||
],
|
||||
lex_tokens(Syntax::default(), "x = function foo() {} /a/i"),
|
||||
"/ should be parsed as div operator"
|
||||
)
|
||||
}
|
||||
@ -524,16 +524,16 @@ fn spec_001() {
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
expected,
|
||||
lex_tokens(
|
||||
Syntax::default(),
|
||||
"a = b
|
||||
/hi/g.exec(c).map(d);"
|
||||
)
|
||||
),
|
||||
expected
|
||||
);
|
||||
assert_eq!(
|
||||
expected,
|
||||
lex_tokens(Syntax::default(), "a = b / hi / g.exec(c).map(d);")
|
||||
lex_tokens(Syntax::default(), "a = b / hi / g.exec(c).map(d);"),
|
||||
expected
|
||||
);
|
||||
}
|
||||
|
||||
@ -603,6 +603,7 @@ fn empty() {
|
||||
#[test]
|
||||
fn migrated_0002() {
|
||||
assert_eq!(
|
||||
lex(Syntax::default(), "tokenize(/42/)"),
|
||||
vec![
|
||||
"tokenize".span(0..8).lb(),
|
||||
LParen.span(8),
|
||||
@ -617,13 +618,13 @@ fn migrated_0002() {
|
||||
.span(9..13),
|
||||
RParen.span(13),
|
||||
],
|
||||
lex(Syntax::default(), "tokenize(/42/)")
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn migrated_0003() {
|
||||
assert_eq!(
|
||||
lex(Syntax::default(), "(false) /42/"),
|
||||
vec![
|
||||
LParen.span(0).lb(),
|
||||
Word::False.span(1..6),
|
||||
@ -632,13 +633,13 @@ fn migrated_0003() {
|
||||
42.span(9..11),
|
||||
Div.span(11),
|
||||
],
|
||||
lex(Syntax::default(), "(false) /42/"),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn migrated_0004() {
|
||||
assert_eq!(
|
||||
lex(Syntax::default(), "function f(){} /42/"),
|
||||
vec![
|
||||
Function.span(0..8).lb(),
|
||||
"f".span(9),
|
||||
@ -655,8 +656,7 @@ fn migrated_0004() {
|
||||
None,
|
||||
)
|
||||
.span(15..19),
|
||||
],
|
||||
lex(Syntax::default(), "function f(){} /42/")
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@ -687,6 +687,7 @@ fn migrated_0006() {
|
||||
// )
|
||||
|
||||
assert_eq!(
|
||||
lex(Syntax::default(), "{} /42/"),
|
||||
vec![
|
||||
LBrace.span(0).lb(),
|
||||
RBrace.span(1),
|
||||
@ -700,25 +701,24 @@ fn migrated_0006() {
|
||||
)
|
||||
.span(3..7),
|
||||
],
|
||||
lex(Syntax::default(), "{} /42/")
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_lit() {
|
||||
assert_eq!(
|
||||
lex_tokens(Syntax::default(), "'abcde'"),
|
||||
vec![Token::Str {
|
||||
value: "abcde".into(),
|
||||
has_escape: false,
|
||||
}],
|
||||
lex_tokens(Syntax::default(), "'abcde'")
|
||||
);
|
||||
assert_eq_ignore_span!(
|
||||
lex_tokens(Syntax::default(), "'\\\nabc'"),
|
||||
vec![Token::Str {
|
||||
value: "abc".into(),
|
||||
has_escape: true,
|
||||
}],
|
||||
lex_tokens(Syntax::default(), "'\\\nabc'")
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
//!
|
||||
//! fn main() {
|
||||
//! swc_common::GLOBALS.set(&swc_common::Globals::new(), || {
|
||||
//! let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
//! let cm = Arc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
//! let handler =
|
||||
//! Handler::with_tty_emitter(ColorConfig::Auto, true, false, Some(cm.clone()));
|
||||
//!
|
||||
|
@ -1001,8 +1001,9 @@ impl<'a, I: Input> Parser<'a, I> {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let start = cur_pos!();
|
||||
|
||||
let arg = {
|
||||
let mut arg = {
|
||||
if self.input.syntax().typescript()
|
||||
&& (is!(IdentRef) || (is!("...") && peeked_is!(IdentRef)))
|
||||
{
|
||||
@ -1026,12 +1027,43 @@ impl<'a, I: Input> Parser<'a, I> {
|
||||
}
|
||||
};
|
||||
let optional = if self.input.syntax().typescript() {
|
||||
if eat!('?') {
|
||||
match *arg.expr {
|
||||
Expr::Ident(..) => {}
|
||||
_ => syntax_error!(arg.span(), SyntaxError::TsBindingPatCannotBeOptional),
|
||||
if is!('?') {
|
||||
if peeked_is!(',') || peeked_is!(':') || peeked_is!(')') || peeked_is!('=') {
|
||||
bump!();
|
||||
let _ = cur!(false);
|
||||
match *arg.expr {
|
||||
Expr::Ident(..) => {}
|
||||
_ => {
|
||||
syntax_error!(arg.span(), SyntaxError::TsBindingPatCannotBeOptional)
|
||||
}
|
||||
}
|
||||
true
|
||||
} else if match arg {
|
||||
ExprOrSpread { spread: None, .. } => true,
|
||||
_ => false,
|
||||
} {
|
||||
expect!('?');
|
||||
|
||||
let test = arg.expr;
|
||||
let cons = self.include_in_expr(true).parse_assignment_expr()?;
|
||||
expect!(':');
|
||||
let alt = self.parse_assignment_expr()?;
|
||||
|
||||
arg = ExprOrSpread {
|
||||
spread: None,
|
||||
expr: Box::new(Expr::Cond(CondExpr {
|
||||
span: span!(start),
|
||||
|
||||
test,
|
||||
cons,
|
||||
alt,
|
||||
})),
|
||||
};
|
||||
|
||||
false
|
||||
} else {
|
||||
false
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
(foo ? 1 : 2)
|
@ -0,0 +1,91 @@
|
||||
Module {
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
0
|
||||
),
|
||||
hi: BytePos(
|
||||
13
|
||||
),
|
||||
ctxt: #0
|
||||
},
|
||||
body: [
|
||||
Stmt(
|
||||
Expr(
|
||||
Paren(
|
||||
ParenExpr {
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
0
|
||||
),
|
||||
hi: BytePos(
|
||||
13
|
||||
),
|
||||
ctxt: #0
|
||||
},
|
||||
expr: Cond(
|
||||
CondExpr {
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
1
|
||||
),
|
||||
hi: BytePos(
|
||||
12
|
||||
),
|
||||
ctxt: #0
|
||||
},
|
||||
test: Ident(
|
||||
Ident {
|
||||
sym: foo,
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
1
|
||||
),
|
||||
hi: BytePos(
|
||||
4
|
||||
),
|
||||
ctxt: #0
|
||||
},
|
||||
type_ann: None,
|
||||
optional: false
|
||||
}
|
||||
),
|
||||
cons: Lit(
|
||||
Num(
|
||||
Number {
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
7
|
||||
),
|
||||
hi: BytePos(
|
||||
8
|
||||
),
|
||||
ctxt: #0
|
||||
},
|
||||
value: 1.0
|
||||
}
|
||||
)
|
||||
),
|
||||
alt: Lit(
|
||||
Num(
|
||||
Number {
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
11
|
||||
),
|
||||
hi: BytePos(
|
||||
12
|
||||
),
|
||||
ctxt: #0
|
||||
},
|
||||
value: 2.0
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
]
|
||||
}
|
@ -0,0 +1 @@
|
||||
foo ? 1 : 2
|
@ -0,0 +1,78 @@
|
||||
Module {
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
0
|
||||
),
|
||||
hi: BytePos(
|
||||
11
|
||||
),
|
||||
ctxt: #0
|
||||
},
|
||||
body: [
|
||||
Stmt(
|
||||
Expr(
|
||||
Cond(
|
||||
CondExpr {
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
0
|
||||
),
|
||||
hi: BytePos(
|
||||
11
|
||||
),
|
||||
ctxt: #0
|
||||
},
|
||||
test: Ident(
|
||||
Ident {
|
||||
sym: foo,
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
0
|
||||
),
|
||||
hi: BytePos(
|
||||
3
|
||||
),
|
||||
ctxt: #0
|
||||
},
|
||||
type_ann: None,
|
||||
optional: false
|
||||
}
|
||||
),
|
||||
cons: Lit(
|
||||
Num(
|
||||
Number {
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
6
|
||||
),
|
||||
hi: BytePos(
|
||||
7
|
||||
),
|
||||
ctxt: #0
|
||||
},
|
||||
value: 1.0
|
||||
}
|
||||
)
|
||||
),
|
||||
alt: Lit(
|
||||
Num(
|
||||
Number {
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
10
|
||||
),
|
||||
hi: BytePos(
|
||||
11
|
||||
),
|
||||
ctxt: #0
|
||||
},
|
||||
value: 2.0
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
]
|
||||
}
|
@ -22,6 +22,7 @@ indexmap = "1"
|
||||
ordered-float = "1.0.1"
|
||||
Inflector = { version = "0.11.4", default-features = false }
|
||||
scoped-tls = { version = "0.1", features = ["nightly"] }
|
||||
unicode-xid = "0.1"
|
||||
|
||||
[dev-dependencies]
|
||||
testing = { path ="../../testing" }
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::util::is_valid_ident;
|
||||
use ast::*;
|
||||
use swc_common::{Fold, FoldWith};
|
||||
|
||||
@ -30,7 +31,7 @@ impl Fold<MemberExpr> for MemberExprLit {
|
||||
value: sym, span, ..
|
||||
}))
|
||||
| Expr::Ident(Ident { sym, span, .. }) => {
|
||||
if sym.is_reserved_for_es3() || sym.contains("-") || sym.contains(".") {
|
||||
if sym.is_reserved_for_es3() || !is_valid_ident(&sym) {
|
||||
return MemberExpr {
|
||||
computed: true,
|
||||
prop: box Expr::Lit(Lit::Str(Str {
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::util::is_valid_ident;
|
||||
use ast::*;
|
||||
use swc_common::{Fold, FoldWith};
|
||||
|
||||
@ -39,7 +40,7 @@ impl Fold<PropName> for PropertyLiteral {
|
||||
PropName::Str(Str {
|
||||
value: sym, span, ..
|
||||
}) => {
|
||||
if sym.is_reserved_for_es3() || sym.contains('-') || sym.contains('.') {
|
||||
if sym.is_reserved_for_es3() || !is_valid_ident(&sym) {
|
||||
return PropName::Str(Str {
|
||||
span,
|
||||
value: sym,
|
||||
|
@ -1,15 +1,17 @@
|
||||
use ast::*;
|
||||
use scoped_tls::scoped_thread_local;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
};
|
||||
use swc_common::{
|
||||
errors::{ColorConfig, Handler},
|
||||
sync::Lrc,
|
||||
FileName, FilePathMapping, Fold, FoldWith, SourceMap, Span, DUMMY_SP,
|
||||
};
|
||||
use swc_ecma_parser::{Parser, Session, SourceFileInput, Syntax};
|
||||
|
||||
lazy_static! {
|
||||
static ref CM: Lrc<SourceMap> = { Lrc::new(SourceMap::new(FilePathMapping::empty())) };
|
||||
static ref CM: Arc<SourceMap> = { Arc::new(SourceMap::new(FilePathMapping::empty())) };
|
||||
static ref HANDLER: Handler =
|
||||
{ Handler::with_tty_emitter(ColorConfig::Always, false, true, Some(CM.clone())) };
|
||||
static ref SESSION: Session<'static> = { Session { handler: &*HANDLER } };
|
||||
@ -182,7 +184,7 @@ define_helpers!(Helpers {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InjectHelpers {
|
||||
pub cm: Lrc<SourceMap>,
|
||||
pub cm: Arc<SourceMap>,
|
||||
}
|
||||
|
||||
impl Fold<Module> for InjectHelpers {
|
||||
|
@ -38,6 +38,7 @@ extern crate testing;
|
||||
extern crate either;
|
||||
extern crate objekt;
|
||||
extern crate serde;
|
||||
extern crate unicode_xid;
|
||||
|
||||
pub use self::{
|
||||
fixer::fixer, hygiene::hygiene, inline_globals::InlineGlobals, simplify::simplifier,
|
||||
|
@ -2,10 +2,10 @@ use ast::Expr;
|
||||
use fxhash::FxHashMap;
|
||||
use inflector::Inflector;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{
|
||||
errors::{ColorConfig, Handler},
|
||||
sync::Lrc,
|
||||
FileName, SourceMap,
|
||||
};
|
||||
use swc_ecma_parser::{Parser, Session, SourceFileInput, Syntax};
|
||||
@ -18,7 +18,7 @@ pub struct Config {
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub(super) fn build(self, cm: Lrc<SourceMap>) -> BuiltConfig {
|
||||
pub(super) fn build(self, cm: Arc<SourceMap>) -> BuiltConfig {
|
||||
let handler = Handler::with_tty_emitter(ColorConfig::Always, false, true, Some(cm.clone()));
|
||||
|
||||
let session = Session { handler: &handler };
|
||||
|
@ -10,14 +10,14 @@ use crate::{
|
||||
};
|
||||
use ast::*;
|
||||
use fxhash::FxHashSet;
|
||||
use std::{collections::hash_map::Entry, iter};
|
||||
use swc_common::{sync::Lrc, Fold, FoldWith, Mark, SourceMap, VisitWith, DUMMY_SP};
|
||||
use std::{collections::hash_map::Entry, iter, sync::Arc};
|
||||
use swc_common::{Fold, FoldWith, Mark, SourceMap, VisitWith, DUMMY_SP};
|
||||
|
||||
mod config;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub fn umd(cm: Lrc<SourceMap>, config: Config) -> impl Pass + Clone {
|
||||
pub fn umd(cm: Arc<SourceMap>, config: Config) -> impl Pass + Clone {
|
||||
Umd {
|
||||
config: config.build(cm.clone()),
|
||||
cm,
|
||||
@ -29,7 +29,7 @@ pub fn umd(cm: Lrc<SourceMap>, config: Config) -> impl Pass + Clone {
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Umd {
|
||||
cm: Lrc<SourceMap>,
|
||||
cm: Arc<SourceMap>,
|
||||
config: BuiltConfig,
|
||||
scope: State<Scope>,
|
||||
exports: State<Exports>,
|
||||
|
@ -1,11 +1,10 @@
|
||||
use crate::{pass::Pass, util::ExprFactory};
|
||||
use ast::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{iter, mem};
|
||||
use std::{iter, mem, sync::Arc};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{
|
||||
errors::{ColorConfig, Handler},
|
||||
sync::Lrc,
|
||||
FileName, Fold, FoldWith, SourceMap, Spanned, DUMMY_SP,
|
||||
};
|
||||
use swc_ecma_parser::{Parser, Session, SourceFileInput, Syntax};
|
||||
@ -58,7 +57,7 @@ fn default_throw_if_namespace() -> bool {
|
||||
/// `@babel/plugin-transform-react-jsx`
|
||||
///
|
||||
/// Turn JSX into React function calls
|
||||
pub fn jsx(cm: Lrc<SourceMap>, options: Options) -> impl Pass + Clone {
|
||||
pub fn jsx(cm: Arc<SourceMap>, options: Options) -> impl Pass + Clone {
|
||||
let handler = Handler::with_tty_emitter(ColorConfig::Always, false, true, Some(cm.clone()));
|
||||
|
||||
let session = Session { handler: &handler };
|
||||
|
@ -7,7 +7,7 @@ use crate::{
|
||||
react::display_name,
|
||||
};
|
||||
|
||||
fn tr(cm: Lrc<SourceMap>, options: Options) -> impl Fold<Module> {
|
||||
fn tr(cm: Arc<SourceMap>, options: Options) -> impl Fold<Module> {
|
||||
chain!(jsx(cm.clone(), options), display_name(), Classes, arrow(),)
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,19 @@
|
||||
use crate::pass::Pass;
|
||||
use ast::*;
|
||||
use swc_common::{sync::Lrc, FileName, Fold, SourceMap, DUMMY_SP};
|
||||
use std::sync::Arc;
|
||||
use swc_common::{FileName, Fold, SourceMap, DUMMY_SP};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
/// `@babel/plugin-transform-react-jsx-source`
|
||||
pub fn jsx_src(dev: bool, cm: Lrc<SourceMap>) -> impl Pass + Clone {
|
||||
pub fn jsx_src(dev: bool, cm: Arc<SourceMap>) -> impl Pass + Clone {
|
||||
JsxSrc { cm, dev }
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct JsxSrc {
|
||||
cm: Lrc<SourceMap>,
|
||||
cm: Arc<SourceMap>,
|
||||
dev: bool,
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ use super::*;
|
||||
use swc_common::FilePathMapping;
|
||||
|
||||
fn tr() -> impl Fold<Module> {
|
||||
let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let cm = Arc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
jsx_src(true, cm)
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,8 @@ pub use self::{
|
||||
jsx_src::jsx_src,
|
||||
};
|
||||
use crate::pass::Pass;
|
||||
use swc_common::{sync::Lrc, SourceMap};
|
||||
use std::sync::Arc;
|
||||
use swc_common::SourceMap;
|
||||
|
||||
mod display_name;
|
||||
mod jsx;
|
||||
@ -15,7 +16,7 @@ mod jsx_src;
|
||||
/// `@babel/preset-react`
|
||||
///
|
||||
/// Preset for all React plugins.
|
||||
pub fn react(cm: Lrc<SourceMap>, options: Options) -> impl Pass + Clone {
|
||||
pub fn react(cm: Arc<SourceMap>, options: Options) -> impl Pass + Clone {
|
||||
let Options { development, .. } = options;
|
||||
|
||||
chain!(
|
||||
|
@ -9,7 +9,7 @@ use std::{
|
||||
process::Command,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
use swc_common::{errors::Handler, sync::Lrc, FileName, Fold, FoldWith, SourceMap};
|
||||
use swc_common::{errors::Handler, FileName, Fold, FoldWith, SourceMap};
|
||||
use swc_ecma_codegen::Emitter;
|
||||
use swc_ecma_parser::{Parser, Session, SourceFileInput, Syntax};
|
||||
use tempfile::tempdir_in;
|
||||
@ -19,7 +19,7 @@ struct MyHandlers;
|
||||
impl swc_ecma_codegen::Handlers for MyHandlers {}
|
||||
|
||||
pub(crate) struct Tester<'a> {
|
||||
pub cm: Lrc<SourceMap>,
|
||||
pub cm: Arc<SourceMap>,
|
||||
pub handler: &'a Handler,
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ use std::{
|
||||
};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{Mark, Span, Spanned, Visit, VisitWith, DUMMY_SP};
|
||||
use unicode_xid::UnicodeXID;
|
||||
|
||||
pub(crate) mod constructor;
|
||||
mod factory;
|
||||
@ -932,3 +933,11 @@ impl<'a> Visit<Ident> for DestructuringFinder<'a> {
|
||||
self.found.push((i.sym.clone(), i.span));
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_valid_ident(s: &JsWord) -> bool {
|
||||
if s.len() == 0 {
|
||||
return false;
|
||||
}
|
||||
let first = s.chars().next().unwrap();
|
||||
UnicodeXID::is_xid_start(first) && s.chars().skip(1).all(UnicodeXID::is_xid_continue)
|
||||
}
|
||||
|
@ -3,14 +3,11 @@ use std::{
|
||||
io::{self, Write},
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
use swc_common::{
|
||||
errors::{EmitterWriter, Handler, HandlerFlags, SourceMapperDyn},
|
||||
sync::Lrc,
|
||||
};
|
||||
use swc_common::errors::{EmitterWriter, Handler, HandlerFlags, SourceMapperDyn};
|
||||
|
||||
/// Creates a new handler for testing.
|
||||
pub(crate) fn new_handler(
|
||||
cm: Lrc<SourceMapperDyn>,
|
||||
cm: Arc<SourceMapperDyn>,
|
||||
treat_err_as_bug: bool,
|
||||
) -> (Handler, BufferedError) {
|
||||
let buf: BufferedError = Default::default();
|
||||
|
@ -17,11 +17,10 @@ use std::{
|
||||
fs::{create_dir_all, File},
|
||||
io::Write,
|
||||
path::Path,
|
||||
sync::Arc,
|
||||
thread,
|
||||
};
|
||||
use swc_common::{
|
||||
errors::Handler, sync::Lrc, FilePathMapping, Fold, FoldWith, SourceMap, Span, DUMMY_SP,
|
||||
};
|
||||
use swc_common::{errors::Handler, FilePathMapping, Fold, FoldWith, SourceMap, Span, DUMMY_SP};
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
@ -31,9 +30,9 @@ mod paths;
|
||||
|
||||
pub fn run_test<F, Ret>(treat_err_as_bug: bool, op: F) -> Result<Ret, StdErr>
|
||||
where
|
||||
F: FnOnce(Lrc<SourceMap>, &Handler) -> Result<Ret, ()>,
|
||||
F: FnOnce(Arc<SourceMap>, &Handler) -> Result<Ret, ()>,
|
||||
{
|
||||
let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let cm = Arc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let (handler, errors) = self::errors::new_handler(cm.clone(), treat_err_as_bug);
|
||||
let result = swc_common::GLOBALS.set(&swc_common::Globals::new(), || op(cm, &handler));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user