infiniloom_engine/index/
patterns.rs

1//! Shared regex patterns for import extraction across index modules.
2//!
3//! These patterns are used by both the full index builder and the lazy context builder
4//! to extract import statements from source code.
5
6use once_cell::sync::Lazy;
7use regex::Regex;
8
9/// Python: `import module` or `import module.submodule`
10pub static PYTHON_IMPORT: Lazy<Regex> =
11    Lazy::new(|| Regex::new(r"^\s*import\s+(\S+)").expect("PYTHON_IMPORT: invalid regex pattern"));
12
13/// Python: `from module import name`
14pub static PYTHON_FROM_IMPORT: Lazy<Regex> = Lazy::new(|| {
15    Regex::new(r"^\s*from\s+(\S+)\s+import").expect("PYTHON_FROM_IMPORT: invalid regex pattern")
16});
17
18/// JavaScript/TypeScript: `import ... from 'module'` or `import ... from "module"`
19pub static JS_IMPORT: Lazy<Regex> = Lazy::new(|| {
20    Regex::new(r#"import\s+.*\s+from\s+['"]([^'"]+)['"]"#)
21        .expect("JS_IMPORT: invalid regex pattern")
22});
23
24/// JavaScript/TypeScript: multi-line import statements
25pub static JS_IMPORT_MULTILINE: Lazy<Regex> = Lazy::new(|| {
26    Regex::new(r#"(?s)import\s+.*?\s+from\s+['"]([^'"]+)['"]"#)
27        .expect("JS_IMPORT_MULTILINE: invalid regex pattern")
28});
29
30/// JavaScript/TypeScript: `require('module')` or `require("module")`
31pub static JS_REQUIRE: Lazy<Regex> = Lazy::new(|| {
32    Regex::new(r#"require\s*\(\s*['"]([^'"]+)['"]\s*\)"#)
33        .expect("JS_REQUIRE: invalid regex pattern")
34});
35
36/// Rust: `use crate::module;` or `use std::collections::HashMap;`
37pub static RUST_USE: Lazy<Regex> =
38    Lazy::new(|| Regex::new(r"^\s*use\s+([^;]+);").expect("RUST_USE: invalid regex pattern"));
39
40/// Go: `import "module"` or `import alias "module"` or `import ( "module" )`
41pub static GO_IMPORT: Lazy<Regex> = Lazy::new(|| {
42    Regex::new(r#"import\s+(?:\(\s*)?(?:[\w.]+\s+)?["']([^"']+)["']"#)
43        .expect("GO_IMPORT: invalid regex pattern")
44});
45
46/// Java: `import package.Class;`
47pub static JAVA_IMPORT: Lazy<Regex> = Lazy::new(|| {
48    Regex::new(r"^\s*import\s+([\w.]+);").expect("JAVA_IMPORT: invalid regex pattern")
49});
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn test_python_import() {
57        assert!(PYTHON_IMPORT.is_match("import os"));
58        assert!(PYTHON_IMPORT.is_match("import os.path"));
59        assert!(PYTHON_IMPORT.is_match("  import json"));
60    }
61
62    #[test]
63    fn test_python_from_import() {
64        assert!(PYTHON_FROM_IMPORT.is_match("from os import path"));
65        assert!(PYTHON_FROM_IMPORT.is_match("from typing import List"));
66    }
67
68    #[test]
69    fn test_js_import() {
70        assert!(JS_IMPORT.is_match("import { foo } from 'module'"));
71        assert!(JS_IMPORT.is_match("import foo from \"module\""));
72    }
73
74    #[test]
75    fn test_js_require() {
76        assert!(JS_REQUIRE.is_match("require('module')"));
77        assert!(JS_REQUIRE.is_match("const x = require(\"module\")"));
78    }
79
80    #[test]
81    fn test_rust_use() {
82        assert!(RUST_USE.is_match("use std::collections::HashMap;"));
83        assert!(RUST_USE.is_match("  use crate::module;"));
84    }
85
86    #[test]
87    fn test_go_import() {
88        assert!(GO_IMPORT.is_match("import \"fmt\""));
89        assert!(GO_IMPORT.is_match("import f \"fmt\""));
90    }
91
92    #[test]
93    fn test_java_import() {
94        assert!(JAVA_IMPORT.is_match("import java.util.List;"));
95        assert!(JAVA_IMPORT.is_match("import com.example.MyClass;"));
96    }
97}