use crate::types::{InheritanceGraph, Language};
use crate::TldrResult;
use std::path::Path;
pub const PYTHON_STDLIB_CLASSES: &[&str] = &[
"Exception",
"BaseException",
"ValueError",
"TypeError",
"RuntimeError",
"KeyError",
"IndexError",
"AttributeError",
"NotImplementedError",
"StopIteration",
"GeneratorExit",
"SystemExit",
"KeyboardInterrupt",
"AssertionError",
"ImportError",
"ModuleNotFoundError",
"OSError",
"IOError",
"FileNotFoundError",
"PermissionError",
"TimeoutError",
"ConnectionError",
"BrokenPipeError",
"ChildProcessError",
"FileExistsError",
"InterruptedError",
"IsADirectoryError",
"NotADirectoryError",
"ProcessLookupError",
"ABC",
"ABCMeta",
"Protocol",
"Generic",
"TypedDict",
"NamedTuple",
"UserDict",
"UserList",
"UserString",
"OrderedDict",
"Counter",
"ChainMap",
"defaultdict",
"deque",
"Mapping",
"MutableMapping",
"Sequence",
"MutableSequence",
"Set",
"MutableSet",
"Iterator",
"Iterable",
"Callable",
"Hashable",
"Reversible",
"Collection",
"Container",
"Coroutine",
"Awaitable",
"AsyncIterable",
"AsyncIterator",
"AsyncGenerator",
"Enum",
"IntEnum",
"Flag",
"IntFlag",
"StrEnum",
"auto",
"Field",
"ContextDecorator",
"AbstractContextManager",
"AbstractAsyncContextManager",
"IOBase",
"RawIOBase",
"BufferedIOBase",
"TextIOBase",
"StringIO",
"BytesIO",
"Thread",
"Timer",
"Lock",
"RLock",
"Condition",
"Semaphore",
"Event",
"Barrier",
"Handler",
"Formatter",
"Filter",
"LogRecord",
"Logger",
"LoggerAdapter",
"TestCase",
"TestSuite",
"TestLoader",
"TestResult",
"Path",
"PurePath",
"PosixPath",
"WindowsPath",
"object",
"type",
"int",
"float",
"str",
"bytes",
"list",
"dict",
"set",
"frozenset",
"tuple",
"bool",
"complex",
];
pub const TYPESCRIPT_STDLIB_CLASSES: &[&str] = &[
"Error",
"TypeError",
"RangeError",
"ReferenceError",
"SyntaxError",
"URIError",
"EvalError",
"AggregateError",
"Object",
"Array",
"Map",
"Set",
"WeakMap",
"WeakSet",
"Promise",
"Date",
"RegExp",
"Function",
"EventTarget",
"Event",
"HTMLElement",
"Element",
"Node",
"Document",
"Iterable",
"Iterator",
"IterableIterator",
"AsyncIterable",
"AsyncIterator",
"ArrayBuffer",
"DataView",
"TypedArray",
"Int8Array",
"Uint8Array",
"Int16Array",
"Uint16Array",
"Int32Array",
"Uint32Array",
"Float32Array",
"Float64Array",
"BigInt64Array",
"BigUint64Array",
];
pub const GO_STDLIB_CLASSES: &[&str] = &[
"error",
"Stringer",
"Reader",
"Writer",
"Closer",
"ReadWriter",
"ReadCloser",
"WriteCloser",
"ReadWriteCloser",
"ReaderAt",
"WriterAt",
"ReaderFrom",
"WriterTo",
"Seeker",
"ByteReader",
"ByteWriter",
"ByteScanner",
"RuneReader",
"RuneScanner",
"StringWriter",
"Marshaler",
"Unmarshaler",
"MarshalJSON",
"UnmarshalJSON",
"MarshalText",
"UnmarshalText",
"Handler",
"HandlerFunc",
"ResponseWriter",
"Flusher",
"Hijacker",
"Driver",
"Conn",
"Scanner",
"Formatter",
"GoStringer",
"State",
"ScanState",
];
pub const RUST_STDLIB_CLASSES: &[&str] = &[
"Clone",
"Copy",
"Debug",
"Display",
"Default",
"Eq",
"PartialEq",
"Ord",
"PartialOrd",
"Hash",
"Send",
"Sync",
"Sized",
"Unpin",
"Drop",
"Fn",
"FnMut",
"FnOnce",
"Iterator",
"IntoIterator",
"ExactSizeIterator",
"DoubleEndedIterator",
"Extend",
"FromIterator",
"AsRef",
"AsMut",
"Borrow",
"BorrowMut",
"From",
"Into",
"TryFrom",
"TryInto",
"Read",
"Write",
"Seek",
"BufRead",
"Error",
"Future",
"Stream",
"Deref",
"DerefMut",
"Index",
"IndexMut",
"Add",
"Sub",
"Mul",
"Div",
"Rem",
"Neg",
"Not",
"BitAnd",
"BitOr",
"BitXor",
"Shl",
"Shr",
"AddAssign",
"SubAssign",
"MulAssign",
"DivAssign",
"Serialize",
"Deserialize",
"ToOwned",
"ToString",
"Any",
];
pub const JAVA_STDLIB_CLASSES: &[&str] = &[
"Object",
"Throwable",
"Exception",
"RuntimeException",
"Error",
"StackOverflowError",
"OutOfMemoryError",
"NullPointerException",
"IllegalArgumentException",
"IllegalStateException",
"UnsupportedOperationException",
"IndexOutOfBoundsException",
"ArrayIndexOutOfBoundsException",
"ClassCastException",
"ClassNotFoundException",
"IOException",
"Thread",
"Runnable",
"Comparable",
"Iterable",
"AutoCloseable",
"Cloneable",
"Enum",
"Number",
"CharSequence",
"AbstractCollection",
"AbstractList",
"AbstractMap",
"AbstractSet",
"AbstractQueue",
"ArrayList",
"HashMap",
"HashSet",
"LinkedList",
"TreeMap",
"TreeSet",
"Collection",
"List",
"Map",
"Set",
"Queue",
"Deque",
"Iterator",
"ListIterator",
"Comparator",
"EventListener",
"EventObject",
"Observable",
"Observer",
"Serializable",
"InputStream",
"OutputStream",
"Reader",
"Writer",
"FilterInputStream",
"FilterOutputStream",
"BufferedReader",
"BufferedWriter",
"Closeable",
"Flushable",
"Function",
"Predicate",
"Consumer",
"Supplier",
"BiFunction",
"BiPredicate",
"BiConsumer",
"UnaryOperator",
"BinaryOperator",
"Callable",
"Future",
"Executor",
"ExecutorService",
"AbstractExecutorService",
"Stream",
"Collector",
];
pub fn is_stdlib_class(name: &str, lang: Language) -> bool {
let classes = match lang {
Language::Python => PYTHON_STDLIB_CLASSES,
Language::TypeScript | Language::JavaScript => TYPESCRIPT_STDLIB_CLASSES,
Language::Go => GO_STDLIB_CLASSES,
Language::Rust => RUST_STDLIB_CLASSES,
Language::Java => JAVA_STDLIB_CLASSES,
_ => return false,
};
classes.contains(&name)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BaseOrigin {
Project,
Stdlib,
External,
}
pub fn resolve_base(base_name: &str, graph: &InheritanceGraph, lang: Language) -> BaseOrigin {
if graph.nodes.contains_key(base_name) {
return BaseOrigin::Project;
}
if is_stdlib_class(base_name, lang) {
return BaseOrigin::Stdlib;
}
BaseOrigin::External
}
pub fn resolve_all_bases(_graph: &mut InheritanceGraph, _project_root: &Path) -> TldrResult<()> {
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::types::InheritanceNode;
use std::path::PathBuf;
#[test]
fn test_python_stdlib_detection() {
assert!(is_stdlib_class("Exception", Language::Python));
assert!(is_stdlib_class("ABC", Language::Python));
assert!(is_stdlib_class("Protocol", Language::Python));
assert!(is_stdlib_class("TestCase", Language::Python));
assert!(!is_stdlib_class("MyCustomClass", Language::Python));
}
#[test]
fn test_typescript_stdlib_detection() {
assert!(is_stdlib_class("Error", Language::TypeScript));
assert!(is_stdlib_class("HTMLElement", Language::TypeScript));
assert!(is_stdlib_class("Promise", Language::TypeScript));
assert!(!is_stdlib_class("MyComponent", Language::TypeScript));
}
#[test]
fn test_go_stdlib_detection() {
assert!(is_stdlib_class("error", Language::Go));
assert!(is_stdlib_class("Reader", Language::Go));
assert!(is_stdlib_class("Writer", Language::Go));
assert!(!is_stdlib_class("MyService", Language::Go));
}
#[test]
fn test_rust_stdlib_detection() {
assert!(is_stdlib_class("Clone", Language::Rust));
assert!(is_stdlib_class("Debug", Language::Rust));
assert!(is_stdlib_class("Iterator", Language::Rust));
assert!(is_stdlib_class("Serialize", Language::Rust));
assert!(!is_stdlib_class("MyTrait", Language::Rust));
}
#[test]
fn test_resolve_base_project() {
let mut graph = InheritanceGraph::new();
graph.add_node(InheritanceNode::new(
"Animal",
PathBuf::from("test.py"),
1,
Language::Python,
));
let origin = resolve_base("Animal", &graph, Language::Python);
assert_eq!(origin, BaseOrigin::Project);
}
#[test]
fn test_resolve_base_stdlib() {
let graph = InheritanceGraph::new();
let origin = resolve_base("Exception", &graph, Language::Python);
assert_eq!(origin, BaseOrigin::Stdlib);
}
#[test]
fn test_resolve_base_external() {
let graph = InheritanceGraph::new();
let origin = resolve_base("FlaskView", &graph, Language::Python);
assert_eq!(origin, BaseOrigin::External);
}
}