Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
1
third-party/vendor/swc_visit/.cargo-checksum.json
vendored
Normal file
1
third-party/vendor/swc_visit/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{"Cargo.toml":"b58a7da59f2d67a7de54402c08eba6428bbdf4c63a3f31a68d69b38f16b35216","scripts/expand.sh":"e8c632aece0ecc2de8f749a4ec6d8cb67471262c94ca502ab916627c0def2fb1","src/lib.rs":"4428d85f285fa41fc489526c139712d7243bddd60f6e7b907008ff9309a936dc","src/util/map.rs":"ecdb7ca6b1882067e3092bcc90ff520d269b3a094231b1515a984d780dfd219f","src/util/mod.rs":"b153b511e652daf68555d14b993c1a77f7061301ea2980f70848fd998ade2421","src/util/move_map.rs":"e9354adcfd940d23e901e9017919cbb7aeafd53c82376ad10f1a7be5942dd461","tests/arc.rs":"28ca501546ffa58c88d78f6b8b06fd3620984228b7d58b5136c1d77a9e295400","tests/fold.rs":"a62021212884b0a6ba27024a5c79abf9b5088911a0d5db12bf95fa635bad587e","tests/opt_vec.rs":"4e5de21bd20c4cdc0233b05bf1196e2850857c26ad9d83f285235dff7ed11d01","tests/vec_opt.rs":"179723c2687964e00b8f456755eb43b053210291fd71a9b0fb2b3581ccc4e54c"},"package":"e87c337fbb2d191bf371173dea6a957f01899adb8f189c6c31b122a6cfc98fc3"}
|
||||
32
third-party/vendor/swc_visit/Cargo.toml
vendored
Normal file
32
third-party/vendor/swc_visit/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2021"
|
||||
name = "swc_visit"
|
||||
version = "0.5.7"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
description = "Visitor generator for stable rustc"
|
||||
license = "Apache-2.0"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
resolver = "1"
|
||||
|
||||
[lib]
|
||||
bench = false
|
||||
|
||||
[dependencies.either]
|
||||
version = "1.5.3"
|
||||
|
||||
[dependencies.swc_visit_macros]
|
||||
version = "0.5.8"
|
||||
|
||||
[features]
|
||||
path = []
|
||||
7
third-party/vendor/swc_visit/scripts/expand.sh
vendored
Executable file
7
third-party/vendor/swc_visit/scripts/expand.sh
vendored
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
|
||||
|
||||
export DBG_DUMP=1
|
||||
|
||||
cargo expand --features path --test vec_opt > tests/expanded.rs
|
||||
544
third-party/vendor/swc_visit/src/lib.rs
vendored
Normal file
544
third-party/vendor/swc_visit/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,544 @@
|
|||
//! Visitor generator for the rust language.
|
||||
//!
|
||||
//!
|
||||
//! There are three variants of visitor in swc. Those are `Fold`, `VisitMut`,
|
||||
//! `Visit`.
|
||||
//!
|
||||
//! # Comparisons
|
||||
//!
|
||||
//! ## `Fold` vs `VisitMut`
|
||||
//!
|
||||
//! `Fold` and `VisitMut` do almost identical tasks, but `Fold` is easier to use
|
||||
//! while being slower and weak to stack overflow for very deep asts. `Fold` is
|
||||
//! fast enough for almost all cases so it would be better to start with `Fold`.
|
||||
//!
|
||||
//! By very deep asts, I meant code like thousands of `a + a + a + a + ...`.
|
||||
//!
|
||||
//!
|
||||
//! # `Fold`
|
||||
//!
|
||||
//! > WARNING: `Fold` is slow, and it's recommended to use VisitMut if you are
|
||||
//! experienced.
|
||||
//!
|
||||
//!
|
||||
//! `Fold` takes ownership of value, which means you have to return the new
|
||||
//! value. Returning new value means returning ownership of the value. But you
|
||||
//! don't have to care about ownership or about managing memories while using
|
||||
//! such visitors. `rustc` handles them automatically and all allocations will
|
||||
//! be freed when it goes out of the scope.
|
||||
//!
|
||||
//! You can invoke your `Fold` implementation like `node.fold_with(&mut
|
||||
//! visitor)` where `visitor` is your visitor. Note that as it takes ownership
|
||||
//! of value, you have to call `node.fold_children_with(self)` in e.g. `fn
|
||||
//! fold_module(&mut self, m: Module) -> Module` if you override the default
|
||||
//! behavior. Also you have to store return value from `fold_children_with`,
|
||||
//! like `let node = node.fold_children_with(self)`. Order of execution can be
|
||||
//! controlled using this. If there is some logic that should be applied to the
|
||||
//! parent first, you can call `fold_children_with` after such logic.
|
||||
//!
|
||||
//! # `VisitMut`
|
||||
//!
|
||||
//! `VisitMut` uses a mutable reference to AST nodes (e.g. `&mut Expr`). You can
|
||||
//! use `Take` from `swc_common::util::take::Take` to get owned value from a
|
||||
//! mutable reference.
|
||||
//!
|
||||
//! You will typically use code like
|
||||
//!
|
||||
//! ```ignore
|
||||
//! *e = return_value.take();
|
||||
//! ```
|
||||
//!
|
||||
//! where `e = &mut Expr` and `return_value` is also `&mut Expr`. `take()` is an
|
||||
//! extension method defined on `MapWithMut`. It's almost identical to `Fold`,
|
||||
//! so I'll skip memory management.
|
||||
//!
|
||||
//! You can invoke your `VisitMut` implementation like `node.visit_mut_with(&mut
|
||||
//! visitor)` where `visitor` is your visitor. Again, you need to call
|
||||
//! `node.visit_mut_children_with(self)` in visitor implementation if you want
|
||||
//! to modify children nodes. You don't need to store the return value in this
|
||||
//! case.
|
||||
//!
|
||||
//!
|
||||
//! # `Visit`
|
||||
//!
|
||||
//!`Visit` uses non-mutable references to AST nodes. It can be used to see if
|
||||
//! an AST node contains a specific node nested deeply in the AST. This is
|
||||
//! useful for checking if AST node contains `this`. This is useful for lots of
|
||||
//! cases - `this` in arrow expressions are special and we need to generate
|
||||
//! different code if a `this` expression is used.
|
||||
//!
|
||||
//! You can use your `Visit` implementation like `node.visit_with(&Invalid{
|
||||
//! span: DUMMY_SP, }, &mut visitor`. I think API is mis-designed, but it works
|
||||
//! and there are really lots of code using `Visit` already.
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//! # Cargo features
|
||||
//!
|
||||
//! You should add
|
||||
//! ```toml
|
||||
//! [features]
|
||||
//! path = []
|
||||
//! ```
|
||||
//!
|
||||
//! If you want to allow using path-aware visitor.
|
||||
//!
|
||||
//!
|
||||
//! # Path-aware visitor
|
||||
//!
|
||||
//! Path-aware visitor is a visitor that can be used to visit AST nodes with
|
||||
//! current path from the entrypoint.
|
||||
//!
|
||||
//! `VisitMutAstPath` and `FoldAstPath` can be used to transform AST nodes with
|
||||
//! the path to the node.
|
||||
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
pub use either::Either;
|
||||
pub use swc_visit_macros::define;
|
||||
|
||||
pub mod util;
|
||||
|
||||
/// Visit all children nodes. This converts `VisitAll` to `Visit`. The type
|
||||
/// parameter `V` should implement `VisitAll` and `All<V>` implements `Visit`.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct All<V> {
|
||||
pub visitor: V,
|
||||
}
|
||||
|
||||
/// A visitor which visits node only if `enabled` is true.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Optional<V> {
|
||||
pub enabled: bool,
|
||||
pub visitor: V,
|
||||
}
|
||||
|
||||
impl<V> Optional<V> {
|
||||
pub const fn new(visitor: V, enabled: bool) -> Self {
|
||||
Self { enabled, visitor }
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for a pass which is designed to invoked multiple time to same input.
|
||||
///
|
||||
/// See [Repeat].
|
||||
pub trait Repeated {
|
||||
/// Should run again?
|
||||
fn changed(&self) -> bool;
|
||||
|
||||
/// Reset.
|
||||
fn reset(&mut self);
|
||||
}
|
||||
|
||||
/// A visitor which applies `A` and then `B`.
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct AndThen<A, B> {
|
||||
pub first: A,
|
||||
pub second: B,
|
||||
}
|
||||
|
||||
/// Chains multiple visitor.
|
||||
#[macro_export]
|
||||
macro_rules! chain {
|
||||
($a:expr, $b:expr) => {{
|
||||
use $crate::AndThen;
|
||||
|
||||
AndThen {
|
||||
first: $a,
|
||||
second: $b,
|
||||
}
|
||||
}};
|
||||
|
||||
($a:expr, $b:expr,) => {
|
||||
chain!($a, $b)
|
||||
};
|
||||
|
||||
($a:expr, $b:expr, $($rest:tt)+) => {{
|
||||
use $crate::AndThen;
|
||||
|
||||
AndThen{
|
||||
first: $a,
|
||||
second: chain!($b, $($rest)*),
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// A visitor which applies `V` again and again if `V` modifies the node.
|
||||
///
|
||||
/// # Note
|
||||
/// `V` should return `true` from `changed()` to make the pass run multiple
|
||||
/// time.
|
||||
///
|
||||
/// See: [Repeated]
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Repeat<V>
|
||||
where
|
||||
V: Repeated,
|
||||
{
|
||||
pub pass: V,
|
||||
}
|
||||
|
||||
impl<V> Repeat<V>
|
||||
where
|
||||
V: Repeated,
|
||||
{
|
||||
pub fn new(pass: V) -> Self {
|
||||
Self { pass }
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> Repeated for Repeat<V>
|
||||
where
|
||||
V: Repeated,
|
||||
{
|
||||
fn changed(&self) -> bool {
|
||||
self.pass.changed()
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
self.pass.reset()
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, B> Repeated for AndThen<A, B>
|
||||
where
|
||||
A: Repeated,
|
||||
B: Repeated,
|
||||
{
|
||||
fn changed(&self) -> bool {
|
||||
self.first.changed() || self.second.changed()
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
self.first.reset();
|
||||
self.second.reset();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct AstKindPath<K>
|
||||
where
|
||||
K: ParentKind,
|
||||
{
|
||||
path: Vec<K>,
|
||||
}
|
||||
|
||||
impl<K> std::ops::Deref for AstKindPath<K>
|
||||
where
|
||||
K: ParentKind,
|
||||
{
|
||||
type Target = Vec<K>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.path
|
||||
}
|
||||
}
|
||||
|
||||
impl<K> Default for AstKindPath<K>
|
||||
where
|
||||
K: ParentKind,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
path: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K> AstKindPath<K>
|
||||
where
|
||||
K: ParentKind,
|
||||
{
|
||||
pub fn new(path: Vec<K>) -> Self {
|
||||
Self { path }
|
||||
}
|
||||
|
||||
pub fn with_guard(&mut self, kind: K) -> AstKindPathGuard<K> {
|
||||
self.path.push(kind);
|
||||
|
||||
AstKindPathGuard { path: self }
|
||||
}
|
||||
|
||||
pub fn with_index_guard(&mut self, index: usize) -> AstKindPathIndexGuard<K> {
|
||||
self.path.last_mut().unwrap().set_index(index);
|
||||
|
||||
AstKindPathIndexGuard { path: self }
|
||||
}
|
||||
|
||||
#[deprecated = "Use with_guard instead"]
|
||||
pub fn with<Ret>(&mut self, path: K, op: impl FnOnce(&mut Self) -> Ret) -> Ret {
|
||||
self.path.push(path);
|
||||
let ret = op(self);
|
||||
self.path.pop();
|
||||
ret
|
||||
}
|
||||
|
||||
#[deprecated = "Use with_index_guard instead"]
|
||||
pub fn with_index<Ret>(&mut self, index: usize, op: impl FnOnce(&mut Self) -> Ret) -> Ret {
|
||||
self.path.last_mut().unwrap().set_index(index);
|
||||
let res = op(self);
|
||||
self.path.last_mut().unwrap().set_index(usize::MAX);
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AstKindPathGuard<'a, K>
|
||||
where
|
||||
K: ParentKind,
|
||||
{
|
||||
path: &'a mut AstKindPath<K>,
|
||||
}
|
||||
|
||||
impl<K> Deref for AstKindPathGuard<'_, K>
|
||||
where
|
||||
K: ParentKind,
|
||||
{
|
||||
type Target = AstKindPath<K>;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.path
|
||||
}
|
||||
}
|
||||
|
||||
impl<K> DerefMut for AstKindPathGuard<'_, K>
|
||||
where
|
||||
K: ParentKind,
|
||||
{
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.path
|
||||
}
|
||||
}
|
||||
|
||||
impl<K> Drop for AstKindPathGuard<'_, K>
|
||||
where
|
||||
K: ParentKind,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
self.path.path.pop();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AstKindPathIndexGuard<'a, K>
|
||||
where
|
||||
K: ParentKind,
|
||||
{
|
||||
path: &'a mut AstKindPath<K>,
|
||||
}
|
||||
|
||||
impl<K> Deref for AstKindPathIndexGuard<'_, K>
|
||||
where
|
||||
K: ParentKind,
|
||||
{
|
||||
type Target = AstKindPath<K>;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.path
|
||||
}
|
||||
}
|
||||
|
||||
impl<K> DerefMut for AstKindPathIndexGuard<'_, K>
|
||||
where
|
||||
K: ParentKind,
|
||||
{
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.path
|
||||
}
|
||||
}
|
||||
|
||||
impl<K> Drop for AstKindPathIndexGuard<'_, K>
|
||||
where
|
||||
K: ParentKind,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
self.path.path.last_mut().unwrap().set_index(usize::MAX);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct AstNodePath<N>
|
||||
where
|
||||
N: NodeRef,
|
||||
{
|
||||
kinds: AstKindPath<N::ParentKind>,
|
||||
path: Vec<N>,
|
||||
}
|
||||
|
||||
impl<N> std::ops::Deref for AstNodePath<N>
|
||||
where
|
||||
N: NodeRef,
|
||||
{
|
||||
type Target = Vec<N>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.path
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> Default for AstNodePath<N>
|
||||
where
|
||||
N: NodeRef,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
kinds: Default::default(),
|
||||
path: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> AstNodePath<N>
|
||||
where
|
||||
N: NodeRef,
|
||||
{
|
||||
pub fn new(kinds: AstKindPath<N::ParentKind>, path: Vec<N>) -> Self {
|
||||
Self { kinds, path }
|
||||
}
|
||||
|
||||
pub fn kinds(&self) -> &AstKindPath<N::ParentKind> {
|
||||
&self.kinds
|
||||
}
|
||||
|
||||
pub fn with_guard(&mut self, node: N) -> AstNodePathGuard<N> {
|
||||
self.kinds.path.push(node.kind());
|
||||
self.path.push(node);
|
||||
|
||||
AstNodePathGuard { path: self }
|
||||
}
|
||||
|
||||
pub fn with_index_guard(&mut self, index: usize) -> AstNodePathIndexGuard<N> {
|
||||
self.kinds.path.last_mut().unwrap().set_index(index);
|
||||
self.path.last_mut().unwrap().set_index(index);
|
||||
|
||||
AstNodePathIndexGuard { path: self }
|
||||
}
|
||||
|
||||
#[deprecated = "Use with_guard instead"]
|
||||
pub fn with<F, Ret>(&mut self, node: N, op: F) -> Ret
|
||||
where
|
||||
F: for<'aa> FnOnce(&'aa mut AstNodePath<N>) -> Ret,
|
||||
{
|
||||
let kind = node.kind();
|
||||
|
||||
self.kinds.path.push(kind);
|
||||
self.path.push(node);
|
||||
let ret = op(self);
|
||||
self.path.pop();
|
||||
self.kinds.path.pop();
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
#[deprecated = "Use with_index_guard instead"]
|
||||
pub fn with_index<F, Ret>(&mut self, index: usize, op: F) -> Ret
|
||||
where
|
||||
F: for<'aa> FnOnce(&'aa mut AstNodePath<N>) -> Ret,
|
||||
{
|
||||
self.kinds.path.last_mut().unwrap().set_index(index);
|
||||
self.path.last_mut().unwrap().set_index(index);
|
||||
|
||||
let res = op(self);
|
||||
|
||||
self.path.last_mut().unwrap().set_index(usize::MAX);
|
||||
self.kinds.path.last_mut().unwrap().set_index(usize::MAX);
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
pub trait NodeRef: Copy {
|
||||
type ParentKind: ParentKind;
|
||||
|
||||
fn kind(&self) -> Self::ParentKind;
|
||||
|
||||
fn set_index(&mut self, index: usize);
|
||||
}
|
||||
|
||||
pub trait ParentKind: Copy {
|
||||
fn set_index(&mut self, index: usize);
|
||||
}
|
||||
|
||||
pub struct AstNodePathGuard<'a, N>
|
||||
where
|
||||
N: NodeRef,
|
||||
{
|
||||
path: &'a mut AstNodePath<N>,
|
||||
}
|
||||
|
||||
impl<N> Deref for AstNodePathGuard<'_, N>
|
||||
where
|
||||
N: NodeRef,
|
||||
{
|
||||
type Target = AstNodePath<N>;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.path
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> DerefMut for AstNodePathGuard<'_, N>
|
||||
where
|
||||
N: NodeRef,
|
||||
{
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.path
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> Drop for AstNodePathGuard<'_, N>
|
||||
where
|
||||
N: NodeRef,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
self.path.path.pop();
|
||||
self.path.kinds.path.pop();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AstNodePathIndexGuard<'a, N>
|
||||
where
|
||||
N: NodeRef,
|
||||
{
|
||||
path: &'a mut AstNodePath<N>,
|
||||
}
|
||||
|
||||
impl<N> Deref for AstNodePathIndexGuard<'_, N>
|
||||
where
|
||||
N: NodeRef,
|
||||
{
|
||||
type Target = AstNodePath<N>;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.path
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> DerefMut for AstNodePathIndexGuard<'_, N>
|
||||
where
|
||||
N: NodeRef,
|
||||
{
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.path
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> Drop for AstNodePathIndexGuard<'_, N>
|
||||
where
|
||||
N: NodeRef,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
self.path.path.last_mut().unwrap().set_index(usize::MAX);
|
||||
self.path
|
||||
.kinds
|
||||
.path
|
||||
.last_mut()
|
||||
.unwrap()
|
||||
.set_index(usize::MAX);
|
||||
}
|
||||
}
|
||||
35
third-party/vendor/swc_visit/src/util/map.rs
vendored
Normal file
35
third-party/vendor/swc_visit/src/util/map.rs
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
use std::{mem, ptr};
|
||||
|
||||
/// Copied from `syntax::ptr::P` of rustc.
|
||||
pub trait Map<T> {
|
||||
/// Transform the inner value, consuming `self` and producing a new `P<T>`.
|
||||
///
|
||||
/// # Memory leak
|
||||
///
|
||||
/// This will leak `self` if the given closure panics.
|
||||
fn map<F>(self, f: F) -> Self
|
||||
where
|
||||
F: FnOnce(T) -> T;
|
||||
}
|
||||
|
||||
impl<T> Map<T> for Box<T> {
|
||||
fn map<F>(mut self, f: F) -> Self
|
||||
where
|
||||
F: FnOnce(T) -> T,
|
||||
{
|
||||
let p: *mut T = &mut *self;
|
||||
|
||||
// Leak self in case of panic.
|
||||
// FIXME(eddyb) Use some sort of "free guard" that
|
||||
// only deallocates, without dropping the pointee,
|
||||
// in case the call the `f` below ends in a panic.
|
||||
mem::forget(self);
|
||||
|
||||
unsafe {
|
||||
ptr::write(p, f(ptr::read(p)));
|
||||
|
||||
// Recreate self from the raw pointer.
|
||||
Box::from_raw(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
3
third-party/vendor/swc_visit/src/util/mod.rs
vendored
Normal file
3
third-party/vendor/swc_visit/src/util/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
//! Some utilities for generated visitors.
|
||||
pub mod map;
|
||||
pub mod move_map;
|
||||
99
third-party/vendor/swc_visit/src/util/move_map.rs
vendored
Normal file
99
third-party/vendor/swc_visit/src/util/move_map.rs
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
use std::{iter, ptr};
|
||||
|
||||
/// Modifiers vector in-place.
|
||||
pub trait MoveMap<T>: Sized {
|
||||
/// Map in place.
|
||||
fn move_map<F>(self, mut f: F) -> Self
|
||||
where
|
||||
F: FnMut(T) -> T,
|
||||
{
|
||||
self.move_flat_map(|e| iter::once(f(e)))
|
||||
}
|
||||
|
||||
/// This will be very slow if you try to extend vector using this method.
|
||||
///
|
||||
/// This method exists to drop useless nodes. You can return Option to do
|
||||
/// such shortening.
|
||||
fn move_flat_map<F, I>(self, f: F) -> Self
|
||||
where
|
||||
F: FnMut(T) -> I,
|
||||
I: IntoIterator<Item = T>;
|
||||
}
|
||||
|
||||
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.as_ptr().add(read_i));
|
||||
let e = f(e);
|
||||
read_i += 1;
|
||||
|
||||
assert!(write_i < read_i);
|
||||
ptr::write(self.as_mut_ptr().add(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,
|
||||
I: IntoIterator<Item = T>,
|
||||
{
|
||||
let mut read_i = 0;
|
||||
let mut write_i = 0;
|
||||
unsafe {
|
||||
let mut 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.as_ptr().add(read_i));
|
||||
let iter = f(e).into_iter();
|
||||
read_i += 1;
|
||||
|
||||
for e in iter {
|
||||
if write_i < read_i {
|
||||
ptr::write(self.as_mut_ptr().add(write_i), e);
|
||||
write_i += 1;
|
||||
} else {
|
||||
// If this is reached we ran out of space
|
||||
// in the middle of the vector.
|
||||
// However, the vector is in a valid state here,
|
||||
// so we just do a somewhat inefficient insert.
|
||||
self.set_len(old_len);
|
||||
self.insert(write_i, e);
|
||||
|
||||
old_len = self.len();
|
||||
self.set_len(0);
|
||||
|
||||
read_i += 1;
|
||||
write_i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write_i tracks the number of actually written new items.
|
||||
self.set_len(write_i);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
49
third-party/vendor/swc_visit/tests/arc.rs
vendored
Normal file
49
third-party/vendor/swc_visit/tests/arc.rs
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#![allow(clippy::ptr_arg)]
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use swc_visit::define;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Item {
|
||||
pub item: Option<Arc<Item>>,
|
||||
pub ref_to_enum: Option<Arc<Enum>>,
|
||||
}
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Enum {
|
||||
Item(Arc<Item>),
|
||||
Items(Arc<Vec<Item>>),
|
||||
Enum(Arc<Enum>),
|
||||
Enums(Arc<Vec<Enum>>),
|
||||
}
|
||||
|
||||
define!({
|
||||
pub struct Item {
|
||||
pub item: Option<Arc<Item>>,
|
||||
pub ref_to_enum: Option<Arc<Enum>>,
|
||||
}
|
||||
pub enum Enum {
|
||||
Item(Arc<Item>),
|
||||
Items(Arc<Vec<Item>>),
|
||||
Enum(Arc<Enum>),
|
||||
Enums(Arc<Vec<Enum>>),
|
||||
}
|
||||
});
|
||||
|
||||
struct Panic;
|
||||
|
||||
impl Visit for Panic {
|
||||
fn visit_item(&mut self, _: &Item) {
|
||||
panic!("Success")
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Success")]
|
||||
fn test_panic() {
|
||||
Enum::Item(Arc::new(Item {
|
||||
item: None,
|
||||
ref_to_enum: None,
|
||||
}))
|
||||
.visit_children_with(&mut Panic)
|
||||
}
|
||||
40
third-party/vendor/swc_visit/tests/fold.rs
vendored
Normal file
40
third-party/vendor/swc_visit/tests/fold.rs
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#![allow(clippy::ptr_arg)]
|
||||
|
||||
use std::any::Any;
|
||||
|
||||
use swc_visit::define;
|
||||
|
||||
/// Visitable nodes.
|
||||
pub trait Node: Any {}
|
||||
|
||||
impl<T: ?Sized> Node for T where T: Any {}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Item {
|
||||
// pub field: usize,
|
||||
// pub inner: Option<Box<Item>>,
|
||||
pub opt_vec: Option<Vec<Item>>,
|
||||
pub vec_opt: Vec<Option<Item>>,
|
||||
|
||||
pub value: f64,
|
||||
}
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Enum {
|
||||
Item(Item),
|
||||
Boxed(Box<Enum>),
|
||||
}
|
||||
|
||||
define!({
|
||||
pub struct Item {
|
||||
// pub field: usize,
|
||||
// pub inner: Option<Box<Item>>,
|
||||
pub opt_vec: Option<Vec<Item>>,
|
||||
pub vec_opt: Vec<Option<Item>>,
|
||||
|
||||
pub value: f64,
|
||||
}
|
||||
pub enum Enum {
|
||||
Item(Item),
|
||||
Boxed(Box<Enum>),
|
||||
}
|
||||
});
|
||||
30
third-party/vendor/swc_visit/tests/opt_vec.rs
vendored
Normal file
30
third-party/vendor/swc_visit/tests/opt_vec.rs
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#![allow(clippy::ptr_arg)]
|
||||
|
||||
use std::any::Any;
|
||||
|
||||
use swc_visit::define;
|
||||
|
||||
/// Visitable nodes.
|
||||
pub trait Node: Any {}
|
||||
|
||||
impl<T: ?Sized> Node for T where T: Any {}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Item {
|
||||
pub opt_vec1: Option<Vec<Item>>,
|
||||
pub opt_vec2: Option<Vec<Enum>>,
|
||||
}
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Enum {
|
||||
Item(Item),
|
||||
}
|
||||
|
||||
define!({
|
||||
pub struct Item {
|
||||
pub opt_vec1: Option<Vec<Item>>,
|
||||
pub opt_vec2: Option<Vec<Enum>>,
|
||||
}
|
||||
pub enum Enum {
|
||||
Item(Item),
|
||||
}
|
||||
});
|
||||
23
third-party/vendor/swc_visit/tests/vec_opt.rs
vendored
Normal file
23
third-party/vendor/swc_visit/tests/vec_opt.rs
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#![allow(clippy::ptr_arg)]
|
||||
|
||||
use swc_visit::define;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Item {
|
||||
pub vec_opt1: Vec<Option<Item>>,
|
||||
pub vec_opt2: Vec<Option<Enum>>,
|
||||
}
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Enum {
|
||||
Item(Item),
|
||||
}
|
||||
|
||||
define!({
|
||||
pub struct Item {
|
||||
pub vec_opt1: Vec<Option<Item>>,
|
||||
pub vec_opt2: Vec<Option<Enum>>,
|
||||
}
|
||||
pub enum Enum {
|
||||
Item(Item),
|
||||
}
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue