Need type information or cross-file analysis?
├── YES → Use Semantic Tools (find-*)
└── NO → Need complex pattern matching?
├── YES → Use Syntactic Tools (query-syntax, navigate, get-ast)
└── NO → Use Semantic Tools for simplicity
Best for: Type information, symbol resolution, cross-file references, inheritance relationships Speed: Slower (requires compilation) Pattern matching: Simple wildcards only Returns: Rich metadata with types and relationships
Best for: Code patterns, structural queries, expression-level analysis, code style checks Speed: Fast (no compilation needed) Pattern matching: Complex XPath-style queries Returns: AST nodes with optional semantic enrichment
Use: spelunk-find-method (semantic)
{
"tool": "spelunk-find-method",
"pattern": "*",
"includeOverrides": true
}Why: Requires understanding inheritance relationships across files
Use: spelunk-query-syntax (syntactic)
{
"tool": "spelunk-query-syntax",
"roslynPath": "//if-statement//binary-expression[@operator='==' and @right-text='null']"
}Why: Pattern-based search within syntax structure
Use: spelunk-find-implementations (semantic)
{
"tool": "spelunk-find-implementations",
"interfaceName": "IDisposable"
}Why: Requires type resolution and inheritance analysis
Use: spelunk-query-syntax (syntactic)
{
"tool": "spelunk-query-syntax",
"roslynPath": "//method[@async]//await-expression[not(invocation[@name='ConfigureAwait'])]"
}Why: Structural pattern within method bodies
Use: spelunk-query-syntax with semantic enrichment
{
"tool": "spelunk-query-syntax",
"roslynPath": "//variable[@name='customer']",
"includeSemanticInfo": true
}Why: Need syntax location but also type information
- First-time analysis of a project
- Type information is essential
- Cross-file relationships matter
- Working with compiled, stable code
- Repeated queries on same codebase
- Analyzing code style or patterns
- Working with code that might not compile
- Need sub-second response times
Both languages work with all tools through Roslyn:
- Semantic tools abstract language differences
- SpelunkPath queries use language-agnostic node types where possible
Currently requires special handling:
- Semantic tools route to F#-specific implementations
- Use FSharpPath syntax instead of SpelunkPath
- Some cross-language features limited
- Use semantic tool to find symbols
- Use syntactic tool to analyze usage patterns
Example: Find all ToString() overrides that don't call base
// Step 1: Find overrides
{
"tool": "spelunk-find-method",
"pattern": "ToString",
"includeOverrides": true
}
// Step 2: Check implementation
{
"tool": "spelunk-query-syntax",
"file": "result.file",
"roslynPath": "//method[ToString]/block[not(.//base-expression)]"
}When you need both syntax patterns and type info:
{
"tool": "spelunk-query-syntax",
"roslynPath": "//invocation[@name='Process']",
"includeSemanticInfo": true
}Returns syntax nodes with added semantic data:
{
"node": { "type": "InvocationExpression", "text": "Process(order)" },
"semanticInfo": {
"symbol": "OrderService.Process(Order)",
"returnType": "ProcessResult",
"isAsync": false
}
}| Task | Recommended Tool | Reasoning |
|---|---|---|
| Find method by name | find-method | Simple, returns rich metadata |
| Find complex patterns | query-syntax | XPath flexibility needed |
| Find type references | find-type-references | Cross-file semantic analysis |
| Check code style | query-syntax | Pattern-based, no compilation |
| Find unused code | find-references + analysis | Semantic understanding required |
| Navigate from position | navigate | Position-based with XPath nav |
| Understand code structure | get-ast | Syntax tree visualization |
| Find inheritance chain | find-type | Semantic relationships |
| Find string literals | query-syntax | Simple syntax pattern |
| Find API usage | find-references | Semantic symbol resolution |
- Compilation errors: Tool returns partial results or fails
- Missing references: May not resolve external types
- Solution: Fix compilation or use syntactic tools
- No type info: Can't distinguish overloads
- No cross-file: Can't follow references
- Solution: Use includeSemanticInfo or switch to semantic tools
- Start with intent: What information does the user actually need?
- Consider compilation state: Is the code likely to compile?
- Optimize for speed: Use syntactic when semantic isn't required
- Cache patterns: Reuse SpelunkPath queries for similar requests
- Fail gracefully: Have fallback from semantic to syntactic
spelunk-find-method- Methods with full signaturesspelunk-find-property- Properties with typesspelunk-find-class- Classes with inheritancespelunk-find-interface- Interfaces with membersspelunk-find-type- Any type definitionspelunk-find-implementations- Interface/abstract implementationsspelunk-find-references- Symbol usage across filesspelunk-find-type-references- Type usage locations
spelunk-query-syntax- XPath queries on ASTspelunk-navigate- Navigate from position using axesspelunk-get-ast- Get syntax tree structurespelunk-find-in-project- Text search (fallback)
All syntactic tools support includeSemanticInfo: true for enriched results combining syntax patterns with semantic data.