riptc 0.1.7

Rust implementation of the InertiaJS protocol compatible with `riptc` for generating strong TypeScript bindings.
//! SWC requires tracked spans to correlate to comments, so this module
//! provides a way to provision comments and tether them to the emitter.

// TODO(@lazkindness): fix this module it just doesn't work

use std::{cell::RefCell, rc::Rc, sync::atomic::AtomicU32};

use swc_common::{
    BytePos, DUMMY_SP, Span,
    comments::{Comment, CommentKind, Comments, SingleThreadedComments},
};

static COMMENT_TICKER: AtomicU32 = AtomicU32::new(0);

thread_local! {
    static COMMENTS_MANAGER: RefCell<Rc<SingleThreadedComments>> = RefCell::new(Rc::new(SingleThreadedComments::default()));
}

/// Create a span that contains a comment.
///
/// For ease of use, this accepts an optional comment and will fall back
/// to the dummy span if one is not provided
pub fn create_comment_span(
    // this is not an atom because then `maybe_comment` will require
    // a type annotation every time
    comment: Option<&str>,
) -> Span {
    let Some(comment) = comment else {
        return DUMMY_SP;
    };

    let id = COMMENT_TICKER.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
    let span = Span::new(BytePos(id), BytePos(id + 1));

    COMMENTS_MANAGER.with_borrow_mut(|comments| {
        comments.add_leading(
            span.lo,
            Comment {
                kind: CommentKind::Line,
                span,
                text: comment.into(),
            },
        );
    });

    span
}

/// Gets all comments and returns them.
pub fn get_comments() -> Rc<SingleThreadedComments> {
    COMMENTS_MANAGER.with_borrow(Rc::clone)
}