Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions crates/oxc_semantic/examples/semantic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,23 @@
//!
//! Create a `test.js` file and run:
//! ```bash
//! cargo run -p oxc_semantic --example semantic [filename] [--symbols]
//! cargo run -p oxc_semantic --example semantic [filename] [--symbols] [--symbol-references]
//! ```
//!
//! ## Options
//!
//! - `--symbols`: Display symbol table and reference information
//! - `--symbol-references`: Display detailed reference information for each symbol

use std::{env, path::Path, sync::Arc};

use itertools::Itertools;

use oxc_allocator::Allocator;
use oxc_diagnostics::{GraphicalReportHandler, OxcDiagnostic};
use oxc_parser::Parser;
use oxc_semantic::SemanticBuilder;
use oxc_span::SourceType;
use oxc_span::{GetSpan, SourceType};

// Instruction:
// create a `test.js`,
Expand All @@ -33,6 +35,7 @@ use oxc_span::SourceType;
fn main() -> std::io::Result<()> {
let name = env::args().nth(1).unwrap_or_else(|| "test.js".to_string());
let show_symbols = env::args().skip(1).any(|arg| arg == "--symbols");
let show_symbol_references = env::args().skip(1).any(|arg| arg == "--symbol-references");
let path = Path::new(&name);
let source_text = Arc::new(std::fs::read_to_string(path)?);
let source_type = SourceType::from_path(path).unwrap();
Expand Down Expand Up @@ -83,5 +86,42 @@ fn main() -> std::io::Result<()> {
}
}

if show_symbol_references {
let reporter = GraphicalReportHandler::new();

for sym in semantic.semantic.scoping().symbol_ids() {
let symbol_name = semantic.semantic.scoping().symbol_name(sym);
let declaration_node_id = semantic.semantic.scoping().symbol_declaration(sym);
let declaration_span =
semantic.semantic.nodes().get_node(declaration_node_id).kind().span();

let reference_spans = semantic.semantic.symbol_references(sym).map(|reference| {
(
semantic.semantic.nodes().get_node(reference.node_id()).kind().span(),
reference.flags(),
)
});

let has_zero_references = semantic.semantic.symbol_references(sym).next().is_none();

let mut info = OxcDiagnostic::warn(format!("References for symbol `{symbol_name}`"))
.with_label(declaration_span.primary_label("declared here"))
.and_labels(
reference_spans
.map(|(span, flags)| span.label(format!("referenced here: ({flags:?})"))),
);

if has_zero_references {
info = info.with_note("This symbol has no references.");
}

let info = info.with_source_code(Arc::clone(&source_text));

let mut s = String::new();
reporter.render_report(&mut s, info.as_ref()).unwrap();
println!("{s}");
}
}

Ok(())
}
Loading