diff --git a/Cargo.toml b/Cargo.toml index 28d909aaf3..8b8cd5f994 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,6 @@ members = [ "c2rust", "c2rust-transpile", - "c2rust-refactor", "c2rust-ast-builder", "c2rust-ast-exporter", "c2rust-ast-printer", diff --git a/LICENSE b/LICENSE index 3c28b39d79..47983398f5 100644 --- a/LICENSE +++ b/LICENSE @@ -14,3 +14,4 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND Portions of C2Rust are derived from packages written by third parties. The following third party packages are included, and carry their own copyright notices and license terms: * c2rust-ast-printer. Dual-licensed under Apache 2.0 and MIT, see c2rust-ast-printer/COPYRIGHT for details. +* prettyplease. Dual-licensed under Apache 2.0 and MIT, see prettyplease/LICENSE-* for details. diff --git a/c2rust-ast-builder/Cargo.toml b/c2rust-ast-builder/Cargo.toml index bb71722cce..0c45c56610 100644 --- a/c2rust-ast-builder/Cargo.toml +++ b/c2rust-ast-builder/Cargo.toml @@ -11,3 +11,5 @@ repository = "https://github.com/immunant/c2rust" description = "Rust AST builder support crate for the C2Rust project" [dependencies] +proc-macro2 = { version = "1.0", features = ["span-locations"]} +syn = { version = "1.0", features = ["full", "proc-macro", "printing"] } diff --git a/c2rust-ast-builder/src/builder.rs b/c2rust-ast-builder/src/builder.rs index c7e54a725b..f9cd8598f5 100644 --- a/c2rust-ast-builder/src/builder.rs +++ b/c2rust-ast-builder/src/builder.rs @@ -1,17 +1,157 @@ //! Helpers for building AST nodes. Normally used by calling `mk().some_node(args...)`. -use rustc::hir; -use rustc_target::spec::abi::{self, Abi}; -use std::rc::Rc; use std::str; -use syntax::ast::*; -use syntax::attr::mk_attr_inner; -use syntax::token::{self, TokenKind, Token}; -use syntax::ptr::P; -use syntax::source_map::{dummy_spanned, Span, Spanned, DUMMY_SP}; -use syntax::tokenstream::{DelimSpan, TokenStream, TokenStreamBuilder, TokenTree}; -use syntax::ThinVec; -use into_symbol::IntoSymbol; +use proc_macro2::{Span, TokenStream, TokenTree}; +use std::default::Default; +use syn::{*, __private::ToTokens, punctuated::Punctuated}; +use std::iter::FromIterator; + +/// a MetaItem that has already been turned into tokens in preparation for being added as an attribute +pub struct PreparedMetaItem { + pub path: Path, + pub tokens: TokenStream, +} + +pub mod properties { + pub trait ToToken { + type Token; + fn to_token(&self) -> Option; + } + +#[derive(Debug, Clone)] + pub enum Mutability { + Mutable, + Immutable, + } + impl ToToken for Mutability { + type Token = syn::token::Mut; + fn to_token(&self) -> Option { + match self { + Mutability::Mutable => Some(Default::default()), + Mutability::Immutable => None, + } + } + } + + #[derive(Debug, Clone)] + pub enum Unsafety { + Normal, + Unsafe, + } + impl ToToken for Unsafety { + type Token = syn::token::Unsafe; + fn to_token(&self) -> Option { + match self { + Unsafety::Normal => None, + Unsafety::Unsafe => Some(Default::default()), + } + } + } + + #[derive(Debug, Clone)] + pub enum Constness { + Const, + NotConst, + } + impl ToToken for Constness { + type Token = syn::token::Const; + fn to_token(&self) -> Option { + match self { + Constness::NotConst => None, + Constness::Const => Some(Default::default()), + } + } + } + + #[derive(Debug, Clone)] + pub enum Movability { + Movable, + Immovable, + } + impl ToToken for Movability { + type Token = syn::token::Static; + fn to_token(&self) -> Option { + match self { + Movability::Immovable => Some(Default::default()), + Movability::Movable => None, + } + } + } + + #[derive(Debug, Clone)] + pub enum IsAsync { + Async, + NotAsync, + } + impl ToToken for IsAsync { + type Token = syn::token::Async; + fn to_token(&self) -> Option { + match self { + IsAsync::NotAsync => None, + IsAsync::Async => Some(Default::default()), + } + } + } + + #[derive(Debug, Clone)] + pub enum Defaultness { + Final, + Default, + } + impl ToToken for Defaultness { + type Token = syn::token::Default; + fn to_token(&self) -> Option { + match self { + Defaultness::Final => None, + Defaultness::Default => Some(Default::default()), + } + } + } +} + +use self::properties::*; + +pub type FnDecl = (Ident, Vec, Option, ReturnType); +pub type BareFnTyParts = (Vec, Option, ReturnType); + +pub enum CaptureBy { + Value, + Ref, +} + +#[derive(Debug, Clone)] +pub enum Extern { + None, + Implicit, + Explicit(String), +} + +//const Async : IsAsync = Some(Default::default()); + +pub enum SelfKind { + Value(Mutability), + Region(Lifetime, Mutability), +} + +fn use_tree_with_prefix(prefix: Path, leaf: UseTree) -> UseTree { + let mut out = leaf; + for seg in prefix.segments.into_iter().rev() { + out = UseTree::Path(UsePath { + ident: seg.ident, + colon2_token: Default::default(), + tree: Box::new(out), + }); + } + out +} + +fn punct(x: Vec) -> Punctuated { + Punctuated::from_iter(x.into_iter()) +} + +fn punct_box(x: Vec>) -> Punctuated { + Punctuated::from_iter(x.into_iter().map(|x| *x)) +} pub trait Make { fn make(self, mk: &Builder) -> T; @@ -29,58 +169,90 @@ impl<'a, T: Clone> Make for &'a T { } } -impl Make for S { - fn make(self, _mk: &Builder) -> Ident { - Ident::with_dummy_span(self.into_symbol()) +impl Make for &str { + fn make(self, mk: &Builder) -> Ident { + Ident::new(self, mk.span) + } +} + +impl Make for String { + fn make(self, mk: &Builder) -> Ident { + Ident::new(&*self, mk.span) + } +} + +impl Make for &String { + fn make(self, mk: &Builder) -> Ident { + Ident::new(&*self, mk.span) } } impl> Make