pub struct SemanticAnalyzer {
pub class_models: Vec<ClassModel>,
/* private fields */
}Expand description
Semantic analysis types for hover, tokens, and code understanding. 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.