pub struct SemanticAnalyzer {
pub class_models: Vec<ClassModel>,
/* private fields */
}Expand description
Semantic analyzer providing comprehensive IDE features for Perl code.
Central component for LSP semantic analysis, combining symbol table construction, semantic token generation, and hover information extraction with enterprise-grade performance characteristics.
§Performance Characteristics
- Analysis time: O(n) where n is AST node count
- Memory usage: ~1MB per 10K lines of Perl code
- Incremental updates: ≤1ms for typical changes
- Symbol resolution: <50μs average lookup time
§LSP Workflow Integration
Core pipeline component:
- Parse: AST generation from Perl source
- Index: Symbol table and semantic token construction
- Navigate: Symbol resolution for go-to-definition
- Complete: Context-aware completion suggestions
- Analyze: Cross-reference analysis and diagnostics
§Perl Language Support
- Full Perl 5 syntax coverage with modern idioms
- Package-qualified symbol resolution
- Lexical scoping with
my,our,local,state - Object-oriented method dispatch
- Regular expression and heredoc analysis
§Examples
use perl_parser::{Parser, SemanticAnalyzer};
let code = "my $greeting = 'hello'; sub say_hi { print $greeting; }";
let mut parser = Parser::new(code);
let ast = parser.parse()?;
let analyzer = SemanticAnalyzer::analyze_with_source(&ast, code);
let symbols = analyzer.symbol_table();
let tokens = analyzer.semantic_tokens();Fields§
§class_models: Vec<ClassModel>Class models extracted from the same file (for same-file inheritance resolution)
Implementations§
Source§impl SemanticAnalyzer
impl SemanticAnalyzer
Sourcepub fn infer_type(&self, node: &Node) -> Option<String>
pub fn infer_type(&self, node: &Node) -> Option<String>
Infer the type of a node based on its context and initialization.
Provides basic type inference for Perl expressions to enhance hover information with derived type information. Supports common patterns:
- Literal values (numbers, strings, arrays, hashes)
- Variable references (looks up declaration)
- Function calls (basic return type hints)
In the semantic workflow (Parse -> Index -> Analyze), this method runs during the Analyze stage and consumes symbols produced during Index.
§Arguments
node- The AST node to infer type for
§Returns
A string describing the inferred type, or None if type cannot be determined
Source§impl SemanticAnalyzer
impl SemanticAnalyzer
Sourcepub fn analyze(ast: &Node) -> SemanticAnalyzer
pub fn analyze(ast: &Node) -> SemanticAnalyzer
Create a new semantic analyzer from an AST.
Equivalent to analyze_with_source with an empty
source string. Use this when you only need symbol-table and token analysis
without source-text-dependent features like hover documentation.
§Examples
use perl_parser::{Parser, SemanticAnalyzer};
let mut parser = Parser::new("my $x = 42;");
let ast = parser.parse()?;
let analyzer = SemanticAnalyzer::analyze(&ast);
assert!(!analyzer.symbol_table().symbols.is_empty());Sourcepub fn analyze_with_source(ast: &Node, source: &str) -> SemanticAnalyzer
pub fn analyze_with_source(ast: &Node, source: &str) -> SemanticAnalyzer
Create a new semantic analyzer from an AST and source text.
The source text enables richer analysis including hover documentation extraction and precise text-range lookups.
§Examples
use perl_parser::{Parser, SemanticAnalyzer};
let code = "sub greet { print \"Hello\\n\"; }";
let mut parser = Parser::new(code);
let ast = parser.parse()?;
let analyzer = SemanticAnalyzer::analyze_with_source(&ast, code);
let tokens = analyzer.semantic_tokens();
// tokens contains semantic highlighting data for the parsed codeSourcepub fn symbol_table(&self) -> &SymbolTable
pub fn symbol_table(&self) -> &SymbolTable
Get the symbol table.
Sourcepub fn semantic_tokens(&self) -> &[SemanticToken]
pub fn semantic_tokens(&self) -> &[SemanticToken]
Get semantic tokens for syntax highlighting.
Sourcepub fn hover_at(&self, location: ByteSpan) -> Option<&HoverInfo>
pub fn hover_at(&self, location: ByteSpan) -> Option<&HoverInfo>
Get hover information at a location for Navigate/Analyze stages.
Sourcepub fn all_hover_entries(&self) -> impl Iterator<Item = &HoverInfo>
pub fn all_hover_entries(&self) -> impl Iterator<Item = &HoverInfo>
Iterate over all hover entries collected during analysis.
Sourcepub fn symbol_at(&self, location: ByteSpan) -> Option<&Symbol>
pub fn symbol_at(&self, location: ByteSpan) -> Option<&Symbol>
Find the symbol at a given location for Navigate workflows.
Returns the most specific (smallest range) symbol that contains the location. This ensures that when hovering inside a subroutine body, we return the variable at the cursor rather than the enclosing subroutine.
Sourcepub fn find_definition(&self, position: usize) -> Option<&Symbol>
pub fn find_definition(&self, position: usize) -> Option<&Symbol>
Find the definition of a symbol at a given position for Navigate workflows.
Sourcepub fn is_file_test_operator(op: &str) -> bool
pub fn is_file_test_operator(op: &str) -> bool
Check if an operator is a file test operator.
File test operators in Perl are unary operators that test file properties: -e (exists), -d (directory), -f (file), -r (readable), -w (writable), etc.
Delegates to builtins::is_file_test_operator.
Sourcepub fn resolve_inherited_method_hover(
&self,
receiver_class: &str,
method_name: &str,
) -> Option<HoverInfo>
pub fn resolve_inherited_method_hover( &self, receiver_class: &str, method_name: &str, ) -> Option<HoverInfo>
Resolve hover info for a method by walking the same-file parent chain.
Given a receiver package name and a method name, walks the parents of
each ClassModel in self.class_models (BFS) and returns HoverInfo for
the first class in the chain that defines the method.
For packages not in class_models (plain packages with no OO indicators),
falls back to the symbol table looking for PackageName::method_name.
Returns None when no ancestor in the same file defines the method.
Cross-file inheritance is out of scope — tracked as a follow-up issue.