- 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:
강동윤 2019-02-11 11:39:20 +09:00 committed by GitHub
parent c2142bc225
commit 7fe2245a3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 422 additions and 546 deletions

View File

@ -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"

View File

@ -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},

View File

@ -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,

View File

@ -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),

View File

@ -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()
}
}

View File

@ -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(

View File

@ -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;

View File

@ -1,4 +1,2 @@
pub use crate::sync;
pub extern crate fxhash as fx;
pub mod sip128;
pub mod stable_hasher;

View File

@ -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,

View File

@ -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
}
}

View File

@ -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

View File

@ -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

View File

@ -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>,
}

View File

@ -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

View File

@ -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,

View File

@ -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> {

View File

@ -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';",
);
}
}

View File

@ -15,7 +15,7 @@ impl Handlers for Noop {}
struct Builder {
cfg: Config,
cm: Lrc<SourceMap>,
cm: Arc<SourceMap>,
comments: Comments,
}

View File

@ -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,

View File

@ -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
}

View File

@ -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 {

View File

@ -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'")
}]
);
}

View File

@ -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()));
//!

View File

@ -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
}

View File

@ -0,0 +1 @@
(foo ? 1 : 2)

View File

@ -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
}
)
)
}
)
}
)
)
)
]
}

View File

@ -0,0 +1 @@
foo ? 1 : 2

View File

@ -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
}
)
)
}
)
)
)
]
}

View File

@ -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" }

View File

@ -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 {

View File

@ -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,

View File

@ -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 {

View File

@ -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,

View File

@ -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 };

View File

@ -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>,

View File

@ -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 };

View File

@ -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(),)
}

View File

@ -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,
}

View File

@ -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)
}

View File

@ -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!(

View File

@ -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,
}

View File

@ -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)
}

View File

@ -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();

View File

@ -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));