alixinne / glsl-lang

LALR parser for GLSL
https://alixinne.github.io/glsl-lang/glsl_lang/
BSD 3-Clause "New" or "Revised" License
23 stars 4 forks source link

How to resolve a FileId to a file path? #12

Closed ennis closed 2 years ago

ennis commented 2 years ago

I am trying to obtain the file path of an AST Node from its NodeSpan::file_id(). I found the FileIdResolver trait, implemented by lang_pp::Processor, but I'm having trouble using that while there's an AST node in scope:

   let mut pp = Preprocessor::new_with_fs(&aux_sources);
    // setup preprocessor and construct the lexer input
    let input_file = pp.open_source(source, "").with_state(
        ProcessorState::builder()
            .extension(ext_name!("GL_GOOGLE_include_directive"), ExtensionBehavior::Enable)
            .finish(),
    );

    // parse the GLSL into a translation unit
    let mut translation_unit = TranslationUnit::parse_with_options::<Lexer<&SourceFiles>>(
        input_file,
        &ParseOptions {
            target_vulkan: true,
            ..Default::default()
        },
    )
    .unwrap();

    let diag_config = term::Config::default();
    let mut diag_sink = DiagnosticSink::new(diag_writer, diag_config, &aux_sources, &pp);
    translate_translation_unit(module, &mut diag_sink, &translation_unit.0);

This fails with:

error[E0502]: cannot borrow `pp` as immutable because it is also borrowed as mutable
    --> ashley\src\glsl.rs:1524:85
     |
1507 |     let input_file = pp.open_source(source, "").with_state(
     |                      -------------------------- mutable borrow occurs here
...
1524 |     let mut diag_sink = DiagnosticSink::new(diag_writer, diag_config, &aux_sources, &pp);
     |                                                                                     ^^^ immutable borrow occurs here
1525 |     translate_translation_unit(module, &mut diag_sink, &translation_unit.0);
     |                                                        ------------------- mutable borrow later used here

It seems that AST nodes produced from a preprocessor-produced File mutably borrow the preprocessor, which means that I can't call FileIdResolver::resolve while I am processing the AST, which I need to do to output diagnostics (that's what DiagnosticSink does internally).

ennis commented 2 years ago

Never mind, the issue was that translation_unit was actually a tuple containing the AST node and some extra stuff which I didn't need but kept the borrow alive for too long.