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_macros_common/.cargo-checksum.json
vendored
Normal file
1
third-party/vendor/swc_macros_common/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{"Cargo.toml":"27da963292e1a6f42284beb6f3f484b9244fbc4e63d4647ccf13ed74eb5552cf","src/binder.rs":"6b0c34594bef5e61f6e9fc1d048ab389fe606dbbe577a1b9039a599ccc02f88f","src/derive.rs":"61d95d1cfe13c4c91f49b130771e5dfddca46d999ff75a4d784bbe39584f2eef","src/derive/generics.rs":"3333a2dbb3c3e95b4a0010666de8a951574a72a6d8e8ce90cf29944399016d11","src/lib.rs":"f654efe689a11157cbc97c5b6e679cb764459c9d883601283f540f11dfa975da","src/prelude.rs":"c5b2fde7a5e6b7feb425fff02fb0c6dd81c19c5308e5e83ae4d28dfd929b33fe","src/syn_ext.rs":"0f4f7736ea3c5549016cf1821137c488f6c033211a6febd656a90ab18186a62e"},"package":"7a273205ccb09b51fabe88c49f3b34c5a4631c4c00a16ae20e03111d6a42e832"}
|
||||
44
third-party/vendor/swc_macros_common/Cargo.toml
vendored
Normal file
44
third-party/vendor/swc_macros_common/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# 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_macros_common"
|
||||
version = "0.3.8"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
description = "Common utilities for swc macros."
|
||||
documentation = "https://rustdoc.swc.rs/swc_macros_common/"
|
||||
license = "Apache-2.0"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
resolver = "1"
|
||||
|
||||
[lib]
|
||||
bench = false
|
||||
|
||||
[dependencies.pmutil]
|
||||
version = "0.6.1"
|
||||
|
||||
[dependencies.proc-macro2]
|
||||
version = "1"
|
||||
|
||||
[dependencies.quote]
|
||||
version = "1"
|
||||
|
||||
[dependencies.syn]
|
||||
version = "2"
|
||||
features = [
|
||||
"derive",
|
||||
"visit",
|
||||
"parsing",
|
||||
"full",
|
||||
"printing",
|
||||
"extra-traits",
|
||||
]
|
||||
306
third-party/vendor/swc_macros_common/src/binder.rs
vendored
Normal file
306
third-party/vendor/swc_macros_common/src/binder.rs
vendored
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
//! # Example
|
||||
//!
|
||||
//! `_binded_a`, `_binded_b` and `_binded_0` in below example are
|
||||
//! `BindedField`.
|
||||
//!
|
||||
//! ```rust
|
||||
//! struct S {
|
||||
//! a: u8,
|
||||
//! b: u16,
|
||||
//! }
|
||||
//! let s = S { a: 0, b: 0 };
|
||||
//! match s {
|
||||
//! S {
|
||||
//! a: _binded_a,
|
||||
//! b: _binded_b,
|
||||
//! } => {}
|
||||
//! }
|
||||
//! enum E {
|
||||
//! V1 { a: u8 },
|
||||
//! V2(u16),
|
||||
//! V3,
|
||||
//! }
|
||||
//! let e = E::V1 { a: 0 };
|
||||
//! match e {
|
||||
//! E::V1 { a: _binded_a } => {}
|
||||
//! E::V2(_binded_0) => {}
|
||||
//! E::V3 => {}
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! -----
|
||||
//!
|
||||
//! Adopted from `synstructure`.
|
||||
use pmutil::{prelude::*, *};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::ToTokens;
|
||||
use syn::{
|
||||
punctuated::Pair,
|
||||
token::{Mut, Ref},
|
||||
*,
|
||||
};
|
||||
|
||||
use crate::{def_site, is_attr_name, syn_ext::PairExt};
|
||||
|
||||
/// Used to bind whole struct or enum.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Binder<'a> {
|
||||
ident: &'a Ident,
|
||||
body: &'a Data,
|
||||
attrs: &'a [Attribute],
|
||||
}
|
||||
|
||||
impl<'a> Binder<'a> {
|
||||
///
|
||||
/// - `attrs`: Attributes of the type.
|
||||
pub const fn new(ident: &'a Ident, body: &'a Data, attrs: &'a [Attribute]) -> Self {
|
||||
Binder { ident, body, attrs }
|
||||
}
|
||||
|
||||
pub fn new_from(input: &'a DeriveInput) -> Self {
|
||||
Self::new(&input.ident, &input.data, &input.attrs)
|
||||
}
|
||||
|
||||
///
|
||||
pub fn variants(&self) -> Vec<VariantBinder<'a>> {
|
||||
match *self.body {
|
||||
Data::Enum(DataEnum { ref variants, .. }) => {
|
||||
let enum_name = &self.ident;
|
||||
variants
|
||||
.iter()
|
||||
.map(|v| VariantBinder::new(Some(enum_name), &v.ident, &v.fields, &v.attrs))
|
||||
.collect()
|
||||
}
|
||||
Data::Struct(DataStruct { ref fields, .. }) => {
|
||||
vec![VariantBinder::new(None, self.ident, fields, self.attrs)]
|
||||
}
|
||||
Data::Union(_) => unimplemented!("Binder for union type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Variant.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VariantBinder<'a> {
|
||||
/// None for struct.
|
||||
enum_name: Option<&'a Ident>,
|
||||
/// Name of variant.
|
||||
name: &'a Ident,
|
||||
data: &'a Fields,
|
||||
attrs: &'a [Attribute],
|
||||
}
|
||||
|
||||
impl<'a> VariantBinder<'a> {
|
||||
pub const fn new(
|
||||
enum_name: Option<&'a Ident>,
|
||||
name: &'a Ident,
|
||||
data: &'a Fields,
|
||||
attrs: &'a [Attribute],
|
||||
) -> Self {
|
||||
VariantBinder {
|
||||
enum_name,
|
||||
name,
|
||||
data,
|
||||
attrs,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn variant_name(&self) -> &Ident {
|
||||
self.name
|
||||
}
|
||||
|
||||
pub const fn data(&self) -> &Fields {
|
||||
self.data
|
||||
}
|
||||
|
||||
pub const fn attrs(&self) -> &[Attribute] {
|
||||
self.attrs
|
||||
}
|
||||
|
||||
/// `EnumName::VariantName` for enum, and `StructName` for struct.
|
||||
pub fn qual_path(&self) -> Path {
|
||||
match self.enum_name {
|
||||
Some(enum_name) => Quote::new(def_site::<Span>())
|
||||
.quote_with(smart_quote!(
|
||||
Vars {
|
||||
EnumName: enum_name,
|
||||
VariantName: self.name,
|
||||
},
|
||||
{ EnumName::VariantName }
|
||||
))
|
||||
.parse(),
|
||||
None => self.name.clone().into(),
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// - `prefix`: prefix of field binding.
|
||||
pub fn bind(
|
||||
&self,
|
||||
prefix: &str,
|
||||
by_ref: Option<Ref>,
|
||||
mutability: Option<Mut>,
|
||||
) -> (Pat, Vec<BindedField<'a>>) {
|
||||
let path = self.qual_path();
|
||||
|
||||
let (pat, bindings) = match *self.data {
|
||||
Fields::Unit => {
|
||||
// EnumName::VariantName
|
||||
let pat = Pat::Path(PatPath {
|
||||
qself: None,
|
||||
path,
|
||||
attrs: Default::default(),
|
||||
});
|
||||
|
||||
// Unit struct does not have any field to bind
|
||||
(pat, vec![])
|
||||
}
|
||||
Fields::Named(FieldsNamed {
|
||||
named: ref fields,
|
||||
brace_token,
|
||||
}) => {
|
||||
let mut bindings = vec![];
|
||||
|
||||
let fields = fields
|
||||
.pairs()
|
||||
.map(|e| {
|
||||
let (t, p) = e.into_tuple();
|
||||
Pair::new(t, p.cloned())
|
||||
})
|
||||
.enumerate()
|
||||
.map(|(idx, f)| {
|
||||
f.map_item(|f| {
|
||||
let ident = f
|
||||
.ident
|
||||
.clone()
|
||||
.expect("field of struct-like variants should have name");
|
||||
|
||||
let binded_ident = ident.new_ident_with(|s| format!("{}{}", prefix, s));
|
||||
bindings.push(BindedField {
|
||||
idx,
|
||||
binded_ident: binded_ident.clone(),
|
||||
field: f,
|
||||
});
|
||||
FieldPat {
|
||||
attrs: f
|
||||
.attrs
|
||||
.iter()
|
||||
.filter(|attr| is_attr_name(attr, "cfg"))
|
||||
.cloned()
|
||||
.collect(),
|
||||
colon_token: f.colon_token,
|
||||
member: Member::Named(ident),
|
||||
pat: Box::new(Pat::Ident(PatIdent {
|
||||
by_ref,
|
||||
mutability,
|
||||
ident: binded_ident,
|
||||
subpat: None,
|
||||
attrs: Default::default(),
|
||||
})),
|
||||
}
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
// EnumName::VariantName { fields }
|
||||
let pat = Pat::Struct(PatStruct {
|
||||
attrs: Default::default(),
|
||||
qself: None,
|
||||
path,
|
||||
brace_token,
|
||||
fields,
|
||||
rest: None,
|
||||
});
|
||||
(pat, bindings)
|
||||
}
|
||||
Fields::Unnamed(FieldsUnnamed {
|
||||
unnamed: ref fields,
|
||||
paren_token,
|
||||
}) => {
|
||||
// TODO
|
||||
let mut bindings = vec![];
|
||||
|
||||
let pats = fields
|
||||
.pairs()
|
||||
.map(|e| {
|
||||
let (t, p) = e.into_tuple();
|
||||
Pair::new(t, p.cloned())
|
||||
})
|
||||
.enumerate()
|
||||
.map(|(idx, f)| {
|
||||
f.map_item(|f| {
|
||||
let binded_ident =
|
||||
def_site::<Span>().new_ident(format!("{}{}", prefix, idx));
|
||||
bindings.push(BindedField {
|
||||
idx,
|
||||
binded_ident: binded_ident.clone(),
|
||||
field: f,
|
||||
});
|
||||
|
||||
Pat::Ident(PatIdent {
|
||||
by_ref,
|
||||
mutability,
|
||||
ident: binded_ident,
|
||||
subpat: None,
|
||||
attrs: Default::default(),
|
||||
})
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
// EnumName::VariantName ( fields )
|
||||
let pat = Pat::TupleStruct(PatTupleStruct {
|
||||
attrs: Default::default(),
|
||||
qself: None,
|
||||
path,
|
||||
paren_token,
|
||||
elems: pats,
|
||||
});
|
||||
(pat, bindings)
|
||||
}
|
||||
};
|
||||
|
||||
// if we don't need to move fields, we should match on reference to make tuple
|
||||
// work.
|
||||
|
||||
// let pat = match by_ref {
|
||||
// Some(ref_token) => Pat::Ref(PatRef {
|
||||
// pat: box pat,
|
||||
// and_token: ref_token.0.as_token(),
|
||||
// mutability,
|
||||
// }),
|
||||
// None => pat,
|
||||
// };
|
||||
|
||||
(pat, bindings)
|
||||
}
|
||||
}
|
||||
|
||||
/// Binded field. Note that this struct acts like a binded variable for
|
||||
/// `quote!`.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BindedField<'a> {
|
||||
binded_ident: Ident,
|
||||
idx: usize,
|
||||
field: &'a Field,
|
||||
}
|
||||
|
||||
impl<'a> BindedField<'a> {
|
||||
pub const fn idx(&self) -> usize {
|
||||
self.idx
|
||||
}
|
||||
|
||||
/// Name of field binding.
|
||||
pub const fn name(&self) -> &Ident {
|
||||
&self.binded_ident
|
||||
}
|
||||
|
||||
pub const fn field(&self) -> &Field {
|
||||
self.field
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToTokens for BindedField<'a> {
|
||||
fn to_tokens(&self, t: &mut TokenStream) {
|
||||
self.binded_ident.to_tokens(t)
|
||||
}
|
||||
}
|
||||
107
third-party/vendor/swc_macros_common/src/derive.rs
vendored
Normal file
107
third-party/vendor/swc_macros_common/src/derive.rs
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
use std::iter;
|
||||
|
||||
use pmutil::ToTokensExt;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::ToTokens;
|
||||
use syn::{punctuated::Pair, *};
|
||||
|
||||
use crate::def_site;
|
||||
|
||||
mod generics;
|
||||
|
||||
/// Generics of derived impl item.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Derive<'a> {
|
||||
input: &'a DeriveInput,
|
||||
out: ItemImpl,
|
||||
}
|
||||
|
||||
impl<'a> Derive<'a> {
|
||||
pub fn new(input: &'a DeriveInput) -> Self {
|
||||
let (generics, self_ty) = {
|
||||
// Generics for impl cannot have default.
|
||||
let params = input
|
||||
.generics
|
||||
.params
|
||||
.clone()
|
||||
.into_pairs()
|
||||
.map(|mut pair| {
|
||||
if let GenericParam::Type(ref mut t) = *pair.value_mut() {
|
||||
t.eq_token = None;
|
||||
t.default = None;
|
||||
}
|
||||
|
||||
pair
|
||||
})
|
||||
.collect();
|
||||
|
||||
let generics = Generics {
|
||||
params,
|
||||
gt_token: input.generics.gt_token,
|
||||
lt_token: input.generics.lt_token,
|
||||
where_clause: input.generics.where_clause.clone(),
|
||||
};
|
||||
|
||||
// Handle generic declared on type.
|
||||
let ty: Box<Type> = {
|
||||
let (_, ty_generics, _) = input.generics.split_for_impl();
|
||||
let mut t = TokenStream::new();
|
||||
input.ident.to_tokens(&mut t);
|
||||
ty_generics.to_tokens(&mut t);
|
||||
Box::new(parse(t.dump().into()).unwrap_or_else(|err| {
|
||||
panic!("failed to parse type: {}\nType: {}", err, t.dump())
|
||||
}))
|
||||
};
|
||||
|
||||
(generics, ty)
|
||||
};
|
||||
|
||||
Derive {
|
||||
input,
|
||||
out: ItemImpl {
|
||||
attrs: vec![],
|
||||
impl_token: def_site(),
|
||||
brace_token: def_site(),
|
||||
defaultness: None,
|
||||
unsafety: None,
|
||||
generics,
|
||||
trait_: None,
|
||||
self_ty,
|
||||
items: Default::default(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Set `defaultness`
|
||||
pub fn defaultness(&mut self, defaultness: Option<token::Default>) {
|
||||
self.out.defaultness = defaultness;
|
||||
}
|
||||
|
||||
/// Set `unsafety`
|
||||
pub fn unsafety(&mut self, unsafety: Option<token::Unsafe>) {
|
||||
self.out.unsafety = unsafety;
|
||||
}
|
||||
|
||||
pub fn input(&self) -> &DeriveInput {
|
||||
self.input
|
||||
}
|
||||
|
||||
pub fn append_to(mut self, item: ItemImpl) -> ItemImpl {
|
||||
assert_eq!(self.out.trait_, None);
|
||||
if !self.out.generics.params.empty_or_trailing() {
|
||||
self.out.generics.params.push_punct(def_site());
|
||||
}
|
||||
|
||||
self.out
|
||||
.generics
|
||||
.params
|
||||
.extend(item.generics.params.into_pairs());
|
||||
|
||||
self.out.trait_ = item.trait_;
|
||||
|
||||
self.out.attrs.extend(item.attrs);
|
||||
self.out.items.extend(item.items);
|
||||
|
||||
self.out
|
||||
}
|
||||
}
|
||||
122
third-party/vendor/swc_macros_common/src/derive/generics.rs
vendored
Normal file
122
third-party/vendor/swc_macros_common/src/derive/generics.rs
vendored
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
use std::collections::BTreeSet;
|
||||
|
||||
use quote::quote;
|
||||
use syn::visit::{self, Visit};
|
||||
|
||||
use super::*;
|
||||
|
||||
impl<'a> Derive<'a> {
|
||||
pub fn all_generic_fields(&self) -> Vec<&'a Field> {
|
||||
struct TypeVisitor<'a> {
|
||||
params: &'a BTreeSet<Ident>,
|
||||
is_generic: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'b> Visit<'a> for TypeVisitor<'b> {
|
||||
fn visit_path(&mut self, path: &Path) {
|
||||
if let Some(seg) = path.segments.last() {
|
||||
if seg.ident == "PhantomData" {
|
||||
// Hardcoded exception.
|
||||
// This assumes name of the associated type is not PhantomData.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if path.leading_colon.is_none() {
|
||||
if let Some(seg) = path.segments.first() {
|
||||
let id = &seg.ident;
|
||||
if self.params.contains(id) {
|
||||
self.is_generic = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visit::visit_path(self, path)
|
||||
}
|
||||
|
||||
fn visit_macro(&mut self, _: &Macro) {}
|
||||
}
|
||||
|
||||
struct FieldVisitor<'a> {
|
||||
/// Type parameters defined on type.
|
||||
params: BTreeSet<Ident>,
|
||||
fields: Vec<&'a Field>,
|
||||
}
|
||||
|
||||
impl<'a: 'b, 'b> Visit<'a> for FieldVisitor<'b> {
|
||||
fn visit_field(&mut self, field: &'a Field) {
|
||||
let mut vis = TypeVisitor {
|
||||
params: &self.params,
|
||||
is_generic: false,
|
||||
};
|
||||
vis.visit_type(&field.ty);
|
||||
if vis.is_generic {
|
||||
self.fields.push(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut vis = FieldVisitor {
|
||||
params: self
|
||||
.input
|
||||
.generics
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|p| match *p {
|
||||
GenericParam::Type(TypeParam { ref ident, .. }) => Some(ident.clone()),
|
||||
_ => None,
|
||||
})
|
||||
.collect(),
|
||||
fields: vec![],
|
||||
};
|
||||
|
||||
vis.visit_derive_input(self.input);
|
||||
vis.fields
|
||||
}
|
||||
|
||||
pub fn add_where_predicates<I>(&mut self, preds: I)
|
||||
where
|
||||
I: IntoIterator<Item = WherePredicate>,
|
||||
{
|
||||
let preds = preds.into_iter().map(|t| Pair::Punctuated(t, def_site()));
|
||||
|
||||
match self.out.generics.where_clause {
|
||||
Some(WhereClause {
|
||||
ref mut predicates, ..
|
||||
}) => {
|
||||
if !predicates.empty_or_trailing() {
|
||||
predicates.push_punct(def_site());
|
||||
}
|
||||
|
||||
predicates.extend(preds)
|
||||
}
|
||||
None => {
|
||||
self.out.generics.where_clause = Some(WhereClause {
|
||||
where_token: def_site(),
|
||||
predicates: preds.collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Add `Self: #trait_`.
|
||||
pub fn bound_self(&mut self, trait_: Path) {
|
||||
let self_ty: Type = parse(quote!(Self).into()).unwrap();
|
||||
|
||||
let bound = WherePredicate::Type(PredicateType {
|
||||
lifetimes: None,
|
||||
bounded_ty: self_ty,
|
||||
colon_token: def_site(),
|
||||
// `Trait` in `Self: Trait`
|
||||
bounds: iter::once(Pair::End(TypeParamBound::Trait(TraitBound {
|
||||
modifier: TraitBoundModifier::None,
|
||||
lifetimes: None,
|
||||
path: trait_,
|
||||
paren_token: None,
|
||||
})))
|
||||
.collect(),
|
||||
});
|
||||
|
||||
self.add_where_predicates(iter::once(bound))
|
||||
}
|
||||
}
|
||||
126
third-party/vendor/swc_macros_common/src/lib.rs
vendored
Normal file
126
third-party/vendor/swc_macros_common/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
//! Internal crate for the swc project.
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
#[cfg(procmacro2_semver_exempt)]
|
||||
use pmutil::SpanExt;
|
||||
use pmutil::{prelude::*, synom_ext::FromSpan, Quote, SpanExt};
|
||||
use proc_macro2::Span;
|
||||
use quote::ToTokens;
|
||||
use syn::*;
|
||||
|
||||
pub mod binder;
|
||||
pub mod derive;
|
||||
pub mod prelude;
|
||||
mod syn_ext;
|
||||
|
||||
pub fn call_site<T: FromSpan>() -> T {
|
||||
T::from_span(Span::call_site())
|
||||
}
|
||||
|
||||
/// `Span::def_site().located_at(Span::call_site()).as_token()`
|
||||
#[cfg(not(procmacro2_semver_exempt))]
|
||||
pub fn def_site<T: FromSpan>() -> T {
|
||||
call_site()
|
||||
}
|
||||
|
||||
/// `Span::def_site().located_at(Span::call_site()).as_token()`
|
||||
#[cfg(procmacro2_semver_exempt)]
|
||||
pub fn def_site<T: FromSpan>() -> T {
|
||||
Span::def_site().located_at(Span::call_site()).as_token()
|
||||
}
|
||||
|
||||
/// `attr` - tokens inside `#[]`. e.g. `derive(EqIgnoreSpan)`, ast_node
|
||||
pub fn print(attr: &'static str, tokens: proc_macro2::TokenStream) -> proc_macro::TokenStream {
|
||||
use std::env;
|
||||
|
||||
match env::var("PRINT_GENERATED") {
|
||||
Ok(ref s) if s == "1" || attr == s => {}
|
||||
_ => return tokens.into(),
|
||||
}
|
||||
|
||||
println!("\n\tOutput of #[{}]:\n\t {}", attr, tokens);
|
||||
tokens.into()
|
||||
}
|
||||
|
||||
pub fn is_attr_name(attr: &Attribute, name: &str) -> bool {
|
||||
attr.path().is_ident(name)
|
||||
}
|
||||
|
||||
/// Returns `None` if `attr` is not a doc attribute.
|
||||
pub fn doc_str(attr: &Attribute) -> Option<String> {
|
||||
fn parse_tts(attr: &Attribute) -> String {
|
||||
match &attr.meta {
|
||||
Meta::NameValue(MetaNameValue {
|
||||
value:
|
||||
Expr::Lit(ExprLit {
|
||||
lit: Lit::Str(s), ..
|
||||
}),
|
||||
..
|
||||
}) => s.value(),
|
||||
_ => panic!("failed to parse {:?}", attr.meta),
|
||||
}
|
||||
}
|
||||
|
||||
if !is_attr_name(attr, "doc") {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(parse_tts(attr))
|
||||
}
|
||||
|
||||
/// Creates a doc comment.
|
||||
pub fn make_doc_attr(s: &str) -> Attribute {
|
||||
comment(s)
|
||||
}
|
||||
|
||||
pub fn access_field(obj: &dyn ToTokens, idx: usize, f: &Field) -> Expr {
|
||||
Expr::Field(ExprField {
|
||||
attrs: Default::default(),
|
||||
base: syn::parse2(obj.to_token_stream())
|
||||
.expect("swc_macros_common::access_field: failed to parse object"),
|
||||
dot_token: Span::call_site().as_token(),
|
||||
member: match &f.ident {
|
||||
Some(id) => Member::Named(id.clone()),
|
||||
_ => Member::Unnamed(Index {
|
||||
index: idx as _,
|
||||
span: Span::call_site(),
|
||||
}),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
pub fn join_stmts(stmts: &[Stmt]) -> Quote {
|
||||
let mut q = Quote::new_call_site();
|
||||
|
||||
for s in stmts {
|
||||
q.push_tokens(s);
|
||||
}
|
||||
|
||||
q
|
||||
}
|
||||
|
||||
/// fail! is a panic! with location reporting.
|
||||
#[macro_export]
|
||||
macro_rules! fail {
|
||||
($($args:tt)+) => {{
|
||||
panic!("{}\n --> {}:{}:{}", format_args!($($args)*), file!(), line!(), column!());
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! unimplemented {
|
||||
($($args:tt)+) => {{
|
||||
fail!("not yet implemented: {}", format_args!($($args)*));
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! unreachable {
|
||||
() => {{
|
||||
fail!("internal error: unreachable");
|
||||
}};
|
||||
($($args:tt)+) => {{
|
||||
fail!("internal error: unreachable\n{}", format_args!($($args)*));
|
||||
}};
|
||||
}
|
||||
11
third-party/vendor/swc_macros_common/src/prelude.rs
vendored
Normal file
11
third-party/vendor/swc_macros_common/src/prelude.rs
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
pub use proc_macro2::{Delimiter, Group, Literal, Punct, Span, TokenStream, TokenTree};
|
||||
pub use quote::ToTokens;
|
||||
pub use syn::punctuated::{Pair as Element, Punctuated};
|
||||
|
||||
pub use super::{
|
||||
binder::{BindedField, Binder, VariantBinder},
|
||||
call_site, def_site,
|
||||
derive::Derive,
|
||||
doc_str, is_attr_name, print,
|
||||
syn_ext::{ItemImplExt, PairExt},
|
||||
};
|
||||
95
third-party/vendor/swc_macros_common/src/syn_ext.rs
vendored
Normal file
95
third-party/vendor/swc_macros_common/src/syn_ext.rs
vendored
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
use quote::quote;
|
||||
use syn::{punctuated::Pair, *};
|
||||
|
||||
use crate::def_site;
|
||||
|
||||
/// Extension trait for `ItemImpl` (impl block).
|
||||
pub trait ItemImplExt {
|
||||
/// Instead of
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
|
||||
///
|
||||
/// let item: Item = Quote::new(def_site::<Span>())
|
||||
/// .quote_with(smart_quote!(
|
||||
/// Vars {
|
||||
/// Type: type_name,
|
||||
/// impl_generics,
|
||||
/// ty_generics,
|
||||
/// where_clause,
|
||||
/// },
|
||||
/// {
|
||||
/// impl impl_generics ::swc_common::AstNode for Type ty_generics
|
||||
/// where_clause {}
|
||||
/// }
|
||||
/// )).parse();
|
||||
/// ```
|
||||
///
|
||||
/// You can use this like
|
||||
///
|
||||
/// ```rust,ignore
|
||||
// let item = Quote::new(def_site::<Span>())
|
||||
/// .quote_with(smart_quote!(Vars { Type: type_name }, {
|
||||
/// impl ::swc_common::AstNode for Type {}
|
||||
/// }))
|
||||
/// .parse::<ItemImpl>()
|
||||
/// .with_generics(input.generics);
|
||||
/// ```
|
||||
fn with_generics(self, generics: Generics) -> Self;
|
||||
}
|
||||
|
||||
impl ItemImplExt for ItemImpl {
|
||||
fn with_generics(mut self, mut generics: Generics) -> Self {
|
||||
// TODO: Check conflicting name
|
||||
|
||||
let need_new_punct = !generics.params.empty_or_trailing();
|
||||
if need_new_punct {
|
||||
generics.params.push_punct(def_site());
|
||||
}
|
||||
|
||||
// Respan
|
||||
if let Some(t) = generics.lt_token {
|
||||
self.generics.lt_token = Some(t)
|
||||
}
|
||||
if let Some(t) = generics.gt_token {
|
||||
self.generics.gt_token = Some(t)
|
||||
}
|
||||
|
||||
let ty = self.self_ty;
|
||||
|
||||
// Handle generics defined on struct, enum, or union.
|
||||
let mut item: ItemImpl = {
|
||||
let (_, ty_generics, _) = generics.split_for_impl();
|
||||
let item = quote! {
|
||||
#ty #ty_generics
|
||||
};
|
||||
|
||||
ItemImpl {
|
||||
generics,
|
||||
self_ty: parse2(item).unwrap(),
|
||||
..self
|
||||
}
|
||||
};
|
||||
|
||||
// Handle generics added by proc-macro.
|
||||
item.generics
|
||||
.params
|
||||
.extend(self.generics.params.into_pairs());
|
||||
|
||||
item
|
||||
}
|
||||
}
|
||||
|
||||
pub trait PairExt<T, P>: Sized + Into<Pair<T, P>> {
|
||||
fn map_item<F, NewItem>(self, op: F) -> Pair<NewItem, P>
|
||||
where
|
||||
F: FnOnce(T) -> NewItem,
|
||||
{
|
||||
match self.into() {
|
||||
Pair::Punctuated(t, p) => Pair::Punctuated(op(t), p),
|
||||
Pair::End(t) => Pair::End(op(t)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, P> PairExt<T, P> for Pair<T, P> {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue