vize_l2 0.532.0

L2 - the Davinci semantic IR (codename Disegno): the neutral op family every input dialect lowers into
Documentation
use super::{
    Allocator, Error, FileProducer, ProgramScope, SourceRoot, SourceType, Span, append, offset,
};

#[test]
fn authored_utf8_boundaries_nonzero_origins_and_half_open_ends_are_checked() {
    let arena = Allocator::default();
    let source = "😀 opaque\nconst é = 1; é;\nopaque";
    let start = offset(source, "const");
    let end = offset(source, "\nopaque");
    let block = SourceRoot::new(source)
        .unwrap()
        .block(source.get(start as usize..end as usize).unwrap(), start)
        .unwrap();
    let mut producer = FileProducer::new(&arena, source).unwrap();
    append(
        &arena,
        &mut producer,
        block,
        7,
        SourceType::mjs(),
        ProgramScope::Nested,
    );
    let owner = producer.finish().unwrap();
    assert!(owner.is_complete());
    let name = offset(source, "é =");
    let declaration = owner.binding_at_offset(name).unwrap().unwrap();
    assert_eq!(
        declaration.declaration().unwrap().span,
        Span::new(name, name + 2)
    );
    assert!(matches!(
        owner.binding_at_offset(name + 1),
        Err(Error::NotCharBoundary)
    ));
    assert!(matches!(
        owner.reference_at_offset(1),
        Err(Error::NotCharBoundary)
    ));
    assert!(owner.binding_at_offset(name + 2).unwrap().is_none());
    let use_at = source.rfind('é').unwrap() as u32;
    assert_eq!(
        owner
            .reference_at_offset(use_at)
            .unwrap()
            .unwrap()
            .reference()
            .span,
        Span::new(use_at, use_at + 2)
    );
    assert!(owner.reference_at_offset(use_at + 2).unwrap().is_none());
    assert!(owner.scope_at_offset(start).unwrap().is_some());
    for at in [0, start - 1, end, source.len() as u32] {
        assert!(owner.scope_at_offset(at).unwrap().is_none());
        assert!(owner.binding_at_offset(at).unwrap().is_none());
        assert!(owner.reference_at_offset(at).unwrap().is_none());
    }
    let invalid = source.len() as u32 + 1;
    assert!(matches!(
        owner.scope_at_offset(invalid),
        Err(Error::OutOfBounds)
    ));
    assert!(matches!(
        owner.binding_at_offset(invalid),
        Err(Error::OutOfBounds)
    ));
    assert!(matches!(
        owner.reference_at_offset(invalid),
        Err(Error::OutOfBounds)
    ));
}

#[test]
fn units_can_be_recorded_in_reverse_source_order_without_crossing_opaque_gaps() {
    let arena = Allocator::default();
    let source = "const earlier = 1; earlier;\nopaque\nconst later = 2; later;";
    let root = SourceRoot::new(source).unwrap();
    let first_end = offset(source, "\nopaque");
    let second_start = offset(source, "const later");
    let mut producer = FileProducer::new(&arena, source).unwrap();
    for (start, end, index) in [(second_start, source.len() as u32, 9), (0, first_end, 4)] {
        append(
            &arena,
            &mut producer,
            root.block(source.get(start as usize..end as usize).unwrap(), start)
                .unwrap(),
            index,
            SourceType::mjs(),
            ProgramScope::Nested,
        );
    }
    let owner = producer.finish().unwrap();
    assert!(owner.is_complete());
    for (needle, unit) in [("earlier =", 4), ("later =", 9)] {
        let binding = owner
            .binding_at_offset(offset(source, needle))
            .unwrap()
            .unwrap();
        assert_eq!(binding.declaration().unwrap().unit.index(), unit);
        assert_eq!(
            owner
                .scope_at_offset(offset(source, needle))
                .unwrap()
                .unwrap()
                .scope()
                .id,
            binding.declaration().unwrap().scope
        );
    }
    assert!(
        owner
            .scope_at_offset(offset(source, "opaque"))
            .unwrap()
            .is_none()
    );
}

#[test]
fn overlapping_original_unit_observations_are_ambiguous_even_on_a_non_name_byte() {
    let arena = Allocator::default();
    let source = "const local = 1; local;";
    let block = SourceRoot::new(source).unwrap().whole_block();
    let mut producer = FileProducer::new(&arena, source).unwrap();
    for index in [3, 8] {
        append(
            &arena,
            &mut producer,
            block,
            index,
            SourceType::mjs(),
            ProgramScope::Nested,
        );
    }
    let owner = producer.finish().unwrap();
    assert!(owner.is_complete());
    assert_eq!(owner.units().len(), 2);
    for at in [
        0,
        offset(source, "local ="),
        source.rfind("local").unwrap() as u32,
    ] {
        assert!(matches!(
            owner.scope_at_offset(at),
            Err(Error::AmbiguousSite)
        ));
        assert!(matches!(
            owner.binding_at_offset(at),
            Err(Error::AmbiguousSite)
        ));
        assert!(matches!(
            owner.reference_at_offset(at),
            Err(Error::AmbiguousSite)
        ));
    }
}