vize_l2 0.507.0

L2 - the Davinci semantic IR (codename Disegno): the neutral op family every input dialect lowers into
Documentation
use super::{ForHeadInput, NativeForInput};
use oxc_ast::ast::BindingPattern;
use oxc_span::GetSpan;
use vize_l0::{Allocator, SourceRoot, Span};
use vize_l1::embed::syntax::{NativeForHead, NativeForInput as SourceForInput, NativeForRefusal};
use vize_l1::embed::{Embed, EmbedSource, Grammar, Lang, Shape, SourceError};

fn observe<'a>(arena: &'a Allocator, source: &'a str, lang: Lang) -> NativeForHead<'a> {
    SourceForInput::attribute_in(
        arena,
        SourceRoot::new(source).unwrap().whole_block(),
        source,
        lang,
    )
    .unwrap()
    .observe()
}

#[test]
fn complete_two_observations_profiles_and_roots_survive_movement() {
    let arena = Allocator::default();
    for lang in [Lang::Js, Lang::Ts] {
        let text = "(α, key) in β";
        let syntax = observe(&arena, text, lang);
        let aliases = syntax
            .aliases()
            .unwrap()
            .unwrap()
            .parameters()
            .unwrap()
            .as_ptr();
        let collection = syntax.collection().unwrap().unwrap().expression().unwrap() as *const _;
        let input = ForHeadInput::new(syntax).unwrap();
        assert!(core::mem::needs_drop::<ForHeadInput<'_>>());
        let mut pending = alloc::vec::Vec::new();
        pending.push(input);
        pending.reserve(32);
        let input = pending.pop().unwrap();
        assert_eq!(input.aliases().as_ptr(), aliases);
        assert_eq!(input.collection() as *const _, collection);
        assert!(core::ptr::eq(input.source().text(), text));
        assert_eq!(
            input.syntax().grammar(),
            Grammar {
                lang,
                shape: Shape::ForHead
            }
        );
        let admitted = input.syntax().admitted_dense().unwrap();
        for profile in [
            admitted.aliases().source_type(),
            admitted.collection().source_type(),
        ] {
            assert!(profile.is_module());
            assert!(!profile.is_jsx());
            assert_eq!(profile.is_typescript(), lang == Lang::Ts);
        }
        let aliases = input.aliases();
        let collection = input.collection();
        drop(input);
        assert_eq!(aliases.len(), 2);
        assert!(matches!(
            collection,
            oxc_ast::ast::Expression::Identifier(_)
        ));
    }
}

#[test]
fn unicode_alias_and_collection_namespaces_have_independent_exact_goldens() {
    let arena = Allocator::default();
    let file = "頭(α, key) in β尾";
    let value = file.get(3..file.len() - 3).unwrap();
    let syntax = SourceForInput::attribute_in(
        &arena,
        SourceRoot::new(file).unwrap().whole_block(),
        value,
        Lang::Ts,
    )
    .unwrap()
    .observe();
    let input = ForHeadInput::new(syntax).unwrap();
    let BindingPattern::BindingIdentifier(first) = &input.aliases()[0].pattern else {
        panic!("original alias")
    };
    let BindingPattern::BindingIdentifier(second) = &input.aliases()[1].pattern else {
        panic!("original alias")
    };
    assert_eq!(input.alias_decoded_span(first.span), Ok(Span::new(0, 2)));
    assert_eq!(input.alias_decoded_span(second.span), Ok(Span::new(4, 7)));
    assert_eq!(input.alias_authored_span(first.span), Ok(Span::new(4, 6)));
    assert_eq!(input.alias_authored_span(second.span), Ok(Span::new(8, 11)));
    assert_eq!(
        input.collection_decoded_span(input.collection().span()),
        Ok(Span::new(0, 2))
    );
    assert_eq!(
        input.collection_authored_span(input.collection().span()),
        Ok(Span::new(16, 18))
    );
    assert_eq!(
        input.alias_decoded_span(oxc_span::Span::new(0, 1)),
        Err(SourceError::InvalidDecodedSpan)
    );
    assert_eq!(
        input.collection_decoded_span(oxc_span::Span::new(0, 1)),
        Err(SourceError::InvalidDecodedSpan)
    );
    assert_eq!(
        input.collection_decoded_span(oxc_span::Span::new(3, 2)),
        Err(SourceError::InvalidDecodedSpan)
    );
    assert_eq!(
        input.alias_authored_span(oxc_span::Span::new(1, 2)),
        Err(SourceError::InvalidDecodedSpan)
    );
}

#[test]
fn neutral_dense_roots_do_not_establish_the_original_source_capability() {
    let arena = Allocator::default();
    let text = "item in items";
    let syntax = vize_l1::embed::syntax::parse_vue_for_head_once(
        &arena,
        Embed {
            grammar: Grammar {
                lang: Lang::Js,
                shape: Shape::ForHead,
            },
            source: EmbedSource::authored(text, Span::new(0, text.len() as u32)).unwrap(),
        },
    );
    assert!(syntax.dense().is_some());
    let aliases = syntax
        .aliases()
        .unwrap()
        .unwrap()
        .parameters()
        .unwrap()
        .as_ptr();
    let rejected = ForHeadInput::new(syntax).unwrap_err();
    assert_eq!(rejected.kind, NativeForRefusal::UnpreparedSource);
    assert_eq!(
        rejected
            .syntax()
            .aliases()
            .unwrap()
            .unwrap()
            .parameters()
            .unwrap()
            .as_ptr(),
        aliases
    );
    assert!(core::ptr::eq(rejected.into_syntax().source().text(), text));
}

mod refusal;
mod selected;