...
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
module code
|
||||
|
||||
pub struct Const {
|
||||
pub mut:
|
||||
name string
|
||||
value string
|
||||
}
|
||||
|
||||
@@ -2,17 +2,6 @@ module codeparser
|
||||
|
||||
import incubaid.herolib.core.code
|
||||
import incubaid.herolib.core.pathlib
|
||||
// import incubaid.herolib.ui.console
|
||||
// import os
|
||||
|
||||
@[params]
|
||||
pub struct ParserOptions {
|
||||
pub:
|
||||
path string @[required]
|
||||
recursive bool = true
|
||||
exclude_patterns []string
|
||||
include_patterns []string = ['*.v']
|
||||
}
|
||||
|
||||
// ParseError represents an error that occurred while parsing a file
|
||||
pub struct ParseError {
|
||||
@@ -54,57 +43,80 @@ pub mut:
|
||||
parse_errors []ParseError
|
||||
}
|
||||
|
||||
// new creates a CodeParser and scans the given root directory
|
||||
@[params]
|
||||
pub fn new(args ParserOptions) !CodeParser {
|
||||
mut parser := CodeParser{
|
||||
root_dir: args.path
|
||||
options: args
|
||||
parsed_files: map[string]ParsedFile{}
|
||||
modules: map[string][]string{}
|
||||
// scan_directory recursively walks the directory and identifies all V files
|
||||
// Files are stored but not parsed until parse() is called
|
||||
fn (mut parser CodeParser) scan_directory() ! {
|
||||
mut root := pathlib.get_dir(path: parser.root_dir, create: false)!
|
||||
|
||||
if !root.exists() {
|
||||
return error('root directory does not exist: ${parser.root_dir}')
|
||||
}
|
||||
parser.scan_directory()!
|
||||
return parser
|
||||
}
|
||||
|
||||
// Accessor properties for backward compatibility
|
||||
pub fn (parser CodeParser) files() map[string]code.VFile {
|
||||
mut result := map[string]code.VFile{}
|
||||
for _, parsed_file in parser.parsed_files {
|
||||
result[parsed_file.path] = parsed_file.vfile
|
||||
// Use pathlib's recursive listing capability
|
||||
mut items := root.list(recursive: parser.options.recursive)!
|
||||
|
||||
for item in items.paths {
|
||||
// Skip non-V files
|
||||
if !item.path.ends_with('.v') {
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip generated files (ending with _.v)
|
||||
if item.path.ends_with('_.v') {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check exclude patterns
|
||||
should_skip := parser.options.exclude_patterns.any(item.path.contains(it))
|
||||
if should_skip {
|
||||
continue
|
||||
}
|
||||
|
||||
// Store file path for lazy parsing
|
||||
parsed_file := ParsedFile{
|
||||
path: item.path
|
||||
module_name: ''
|
||||
vfile: code.VFile{}
|
||||
}
|
||||
parser.parsed_files[item.path] = parsed_file
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
pub fn (parser CodeParser) errors() []ParseError {
|
||||
return parser.parse_errors
|
||||
// parse processes all V files that were scanned and parses them
|
||||
pub fn (mut parser CodeParser) parse() ! {
|
||||
for file_path, _ in parser.parsed_files {
|
||||
if parser.parsed_files[file_path].vfile.mod == '' {
|
||||
// Only parse if not already parsed
|
||||
parser.parse_file(file_path)!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parse_file parses a single V file and adds it to the index (public wrapper)
|
||||
pub fn (mut parser CodeParser) parse_file(file_path string) {
|
||||
// parse_file parses a single V file and adds it to the index
|
||||
pub fn (mut parser CodeParser) parse_file(file_path string) ! {
|
||||
mut file := pathlib.get_file(path: file_path) or {
|
||||
parser.parse_errors << ParseError{
|
||||
file_path: file_path
|
||||
error: err.msg()
|
||||
error: 'Failed to access file: ${err.msg()}'
|
||||
}
|
||||
return
|
||||
return error('Failed to access file: ${err.msg()}')
|
||||
}
|
||||
|
||||
content := file.read() or {
|
||||
parser.parse_errors << ParseError{
|
||||
file_path: file_path
|
||||
error: err.msg()
|
||||
error: 'Failed to read file: ${err.msg()}'
|
||||
}
|
||||
return
|
||||
return error('Failed to read file: ${err.msg()}')
|
||||
}
|
||||
|
||||
// Parse the V file
|
||||
vfile := code.parse_vfile(content) or {
|
||||
parser.parse_errors << ParseError{
|
||||
file_path: file_path
|
||||
error: err.msg()
|
||||
error: 'Parse error: ${err.msg()}'
|
||||
}
|
||||
return
|
||||
return error('Parse error: ${err.msg()}')
|
||||
}
|
||||
|
||||
parsed_file := ParsedFile{
|
||||
@@ -119,27 +131,8 @@ pub fn (mut parser CodeParser) parse_file(file_path string) {
|
||||
if vfile.mod !in parser.modules {
|
||||
parser.modules[vfile.mod] = []string{}
|
||||
}
|
||||
parser.modules[vfile.mod] << file_path
|
||||
}
|
||||
|
||||
// parse processes all V files that were scanned
|
||||
pub fn (mut parser CodeParser) parse() ! {
|
||||
for file_path, _ in parser.parsed_files {
|
||||
parser.parse_file(file_path)
|
||||
}
|
||||
}
|
||||
|
||||
// get_module_stats calculates statistics for a module
|
||||
pub fn (parser CodeParser) get_module_stats(module string) ModuleStats {
|
||||
// TODO: Fix this function
|
||||
return ModuleStats{}
|
||||
}
|
||||
|
||||
// error adds a new parsing error to the list
|
||||
fn (mut parser CodeParser) error(file_path string, msg string) {
|
||||
parser.parse_errors << ParseError{
|
||||
file_path: file_path
|
||||
error: msg
|
||||
if file_path !in parser.modules[vfile.mod] {
|
||||
parser.modules[vfile.mod] << file_path
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,40 +3,24 @@ module codeparser
|
||||
import incubaid.herolib.core.pathlib
|
||||
import incubaid.herolib.core.code
|
||||
|
||||
// scan_directory recursively walks the directory and parses all V files using pathlib
|
||||
fn (mut parser CodeParser) scan_directory() ! {
|
||||
mut root := pathlib.get_dir(path: parser.root_dir, create: false)!
|
||||
|
||||
if !root.exists() {
|
||||
return error('root directory does not exist: ${parser.root_dir}')
|
||||
}
|
||||
|
||||
// Use pathlib's recursive listing capability
|
||||
mut items := root.list(recursive: parser.options.recursive)!
|
||||
|
||||
for item in items.paths {
|
||||
// Skip non-V files
|
||||
if !item.path.ends_with('.v') {
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip generated files
|
||||
if item.path.ends_with('_.v') {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check exclude patterns
|
||||
should_skip := parser.options.exclude_patterns.any(item.path.contains(it))
|
||||
if should_skip {
|
||||
continue
|
||||
}
|
||||
|
||||
// Store file path for later parsing
|
||||
parsed_file := ParsedFile{
|
||||
path: item.path
|
||||
module_name: ''
|
||||
vfile: code.VFile{}
|
||||
}
|
||||
parser.parsed_files[item.path] = parsed_file
|
||||
}
|
||||
@[params]
|
||||
pub struct ParserOptions {
|
||||
pub:
|
||||
path string @[required]
|
||||
recursive bool = true
|
||||
exclude_patterns []string
|
||||
include_patterns []string = ['*.v']
|
||||
}
|
||||
|
||||
// new creates a CodeParser and scans the given root directory
|
||||
pub fn new(args ParserOptions) !CodeParser {
|
||||
mut parser := CodeParser{
|
||||
root_dir: args.path
|
||||
options: args
|
||||
parsed_files: map[string]ParsedFile{}
|
||||
modules: map[string][]string{}
|
||||
parse_errors: []ParseError{}
|
||||
}
|
||||
parser.scan_directory()!
|
||||
return parser
|
||||
}
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
module codeparser
|
||||
|
||||
import incubaid.herolib.core.code
|
||||
import regex
|
||||
|
||||
@[params]
|
||||
pub struct FilterOptions {
|
||||
pub:
|
||||
module_ string
|
||||
name_regex string
|
||||
module_name string
|
||||
name_filter string // just partial match
|
||||
is_public bool
|
||||
has_receiver bool
|
||||
}
|
||||
|
||||
// structs returns a filtered list of all structs found in the parsed files
|
||||
pub fn (p CodeParser) structs(options FilterOptions) []code.Struct {
|
||||
pub fn (parser CodeParser) structs(options FilterOptions) []code.Struct {
|
||||
mut result := []code.Struct{}
|
||||
for _, file in p.parsed_files {
|
||||
if options.module_ != '' && file.module_name != options.module_ {
|
||||
for _, file in parser.parsed_files {
|
||||
if options.module_name != '' && file.module_name != options.module_name {
|
||||
continue
|
||||
}
|
||||
for struct_ in file.vfile.structs() {
|
||||
if options.name_regex != '' && !struct_.name.match_regex(options.name_regex) {
|
||||
continue
|
||||
if options.name_filter.len > 0 {
|
||||
if !struct_.name.contains(options.name_filter) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if options.is_public && !struct_.is_pub {
|
||||
continue
|
||||
@@ -32,20 +35,22 @@ pub fn (p CodeParser) structs(options FilterOptions) []code.Struct {
|
||||
}
|
||||
|
||||
// functions returns a filtered list of all functions found in the parsed files
|
||||
pub fn (p CodeParser) functions(options FilterOptions) []code.Function {
|
||||
pub fn (parser CodeParser) functions(options FilterOptions) []code.Function {
|
||||
mut result := []code.Function{}
|
||||
for _, file in p.parsed_files {
|
||||
if options.module_ != '' && file.module_name != options.module_ {
|
||||
for _, file in parser.parsed_files {
|
||||
if options.module_name != '' && file.module_name != options.module_name {
|
||||
continue
|
||||
}
|
||||
for func in file.vfile.functions() {
|
||||
if options.name_regex != '' && !func.name.match_regex(options.name_regex) {
|
||||
continue
|
||||
if options.name_filter.len > 0 {
|
||||
if !func.name.contains(options.name_filter) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if options.is_public && !func.is_pub {
|
||||
continue
|
||||
}
|
||||
if options.has_receiver && func.receiver.typ.name == '' {
|
||||
if options.has_receiver && func.receiver.typ.symbol() == '' {
|
||||
continue
|
||||
}
|
||||
result << func
|
||||
@@ -53,3 +58,27 @@ pub fn (p CodeParser) functions(options FilterOptions) []code.Function {
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// filter_public_structs returns all public structs
|
||||
pub fn (parser CodeParser) filter_public_structs(module_name string) []code.Struct {
|
||||
return parser.structs(
|
||||
module_name: module_name
|
||||
is_public: true
|
||||
)
|
||||
}
|
||||
|
||||
// filter_public_functions returns all public functions
|
||||
pub fn (parser CodeParser) filter_public_functions(module_name string) []code.Function {
|
||||
return parser.functions(
|
||||
module_name: module_name
|
||||
is_public: true
|
||||
)
|
||||
}
|
||||
|
||||
// filter_methods returns all functions with receivers (methods)
|
||||
pub fn (parser CodeParser) filter_methods(module_name string) []code.Function {
|
||||
return parser.functions(
|
||||
module_name: module_name
|
||||
has_receiver: true
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,89 +2,92 @@ module codeparser
|
||||
|
||||
import incubaid.herolib.core.code
|
||||
|
||||
@[params]
|
||||
pub struct FinderOptions {
|
||||
pub:
|
||||
name string @[required]
|
||||
struct_name string // only useful for methods on structs
|
||||
module_name string
|
||||
}
|
||||
|
||||
// find_struct searches for a struct by name
|
||||
pub fn (parser CodeParser) find_struct(name: string, module: string = '') !code.Struct {
|
||||
pub fn (parser CodeParser) find_struct(args FinderOptions) !code.Struct {
|
||||
for _, parsed_file in parser.parsed_files {
|
||||
if module != '' && parsed_file.module_name != module {
|
||||
if args.module_name != '' && parsed_file.module_name != args.module_name {
|
||||
continue
|
||||
}
|
||||
|
||||
structs := parsed_file.vfile.structs()
|
||||
for struct_ in structs {
|
||||
if struct_.name == name {
|
||||
if struct_.name == args.name {
|
||||
return struct_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error('struct \'${name}\' not found${if module != '' { ' in module \'${module}\'' } else { '' }}')
|
||||
module_suffix := if args.module_name != '' { ' in module \'${args.module_name}\'' } else { '' }
|
||||
return error('struct \'${args.name}\' not found${module_suffix}')
|
||||
}
|
||||
|
||||
// find_function searches for a function by name
|
||||
pub fn (parser CodeParser) find_function(name: string, module: string = '') !code.Function {
|
||||
pub fn (parser CodeParser) find_function(args FinderOptions) !code.Function {
|
||||
for _, parsed_file in parser.parsed_files {
|
||||
if module != '' && parsed_file.module_name != module {
|
||||
if args.module_name != '' && parsed_file.module_name != args.module_name {
|
||||
continue
|
||||
}
|
||||
|
||||
if func := parsed_file.vfile.get_function(name) {
|
||||
if func := parsed_file.vfile.get_function(args.name) {
|
||||
return func
|
||||
}
|
||||
}
|
||||
|
||||
return error('function \'${name}\' not found${if module != '' { ' in module \'${module}\'' } else { '' }}')
|
||||
module_suffix := if args.module_name != '' { ' in module \'${args.module_name}\'' } else { '' }
|
||||
return error('function \'${args.name}\' not found${module_suffix}')
|
||||
}
|
||||
|
||||
// find_interface searches for an interface by name
|
||||
pub fn (parser CodeParser) find_interface(name: string, module: string = '') !code.Interface {
|
||||
pub fn (parser CodeParser) find_interface(args FinderOptions) !code.Interface {
|
||||
for _, parsed_file in parser.parsed_files {
|
||||
if module != '' && parsed_file.module_name != module {
|
||||
if args.module_name != '' && parsed_file.module_name != args.module_name {
|
||||
continue
|
||||
}
|
||||
|
||||
for item in parsed_file.vfile.items {
|
||||
if item is code.Interface {
|
||||
iface := item as code.Interface
|
||||
if iface.name == name {
|
||||
if iface.name == args.name {
|
||||
return iface
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error('interface \'${name}\' not found${if module != '' { ' in module \'${module}\'' } else { '' }}')
|
||||
module_suffix := if args.module_name != '' { ' in module \'${args.module_name}\'' } else { '' }
|
||||
return error('interface \'${args.name}\' not found${module_suffix}')
|
||||
}
|
||||
|
||||
// find_method searches for a method on a struct
|
||||
pub fn (parser CodeParser) find_method(struct_name: string, method_name: string, module: string = '') !code.Function {
|
||||
methods := parser.list_methods_on_struct(struct_name, module)
|
||||
pub fn (parser CodeParser) find_method(args FinderOptions) !code.Function {
|
||||
methods := parser.list_methods_on_struct(args.struct_name, args.module_name)
|
||||
|
||||
for method in methods {
|
||||
if method.name == method_name {
|
||||
if method.name == args.name {
|
||||
return method
|
||||
}
|
||||
}
|
||||
|
||||
return error('method \'${method_name}\' on struct \'${struct_name}\' not found${if module != '' { ' in module \'${module}\'' } else { '' }}')
|
||||
module_suffix := if args.module_name != '' { ' in module \'${args.module_name}\'' } else { '' }
|
||||
return error('method \'${args.name}\' on struct \'${args.struct_name}\' not found${module_suffix}')
|
||||
}
|
||||
|
||||
// find_module searches for a module by name
|
||||
pub fn (parser CodeParser) find_module(module_name: string) !ParsedModule {
|
||||
pub fn (parser CodeParser) find_module(module_name string) !ParsedModule {
|
||||
if module_name !in parser.modules {
|
||||
return error('module \'${module_name}\' not found')
|
||||
}
|
||||
|
||||
file_paths := parser.modules[module_name]
|
||||
|
||||
mut stats := ModuleStats{}
|
||||
for file_path in file_paths {
|
||||
if parsed_file := parser.parsed_files[file_path] {
|
||||
stats.file_count++
|
||||
stats.struct_count += parsed_file.vfile.structs().len
|
||||
stats.function_count += parsed_file.vfile.functions().len
|
||||
stats.const_count += parsed_file.vfile.consts.len
|
||||
}
|
||||
}
|
||||
stats := parser.get_module_stats(module_name)
|
||||
|
||||
return ParsedModule{
|
||||
name: module_name
|
||||
@@ -94,7 +97,7 @@ pub fn (parser CodeParser) find_module(module_name: string) !ParsedModule {
|
||||
}
|
||||
|
||||
// find_file retrieves parsed file information
|
||||
pub fn (parser CodeParser) find_file(path: string) !ParsedFile {
|
||||
pub fn (parser CodeParser) find_file(path string) !ParsedFile {
|
||||
if path !in parser.parsed_files {
|
||||
return error('file \'${path}\' not found in parsed files')
|
||||
}
|
||||
@@ -103,12 +106,12 @@ pub fn (parser CodeParser) find_file(path: string) !ParsedFile {
|
||||
}
|
||||
|
||||
// find_structs_with_method finds all structs that have a specific method
|
||||
pub fn (parser CodeParser) find_structs_with_method(method_name: string, module: string = '') []string {
|
||||
pub fn (parser CodeParser) find_structs_with_method(args FinderOptions) []string {
|
||||
mut struct_names := []string{}
|
||||
|
||||
functions := parser.list_functions(module)
|
||||
functions := parser.list_functions(args.module_name)
|
||||
for func in functions {
|
||||
if func.name == method_name && func.receiver.name != '' {
|
||||
if func.name == args.name && func.receiver.name != '' {
|
||||
struct_type := func.receiver.typ.symbol()
|
||||
if struct_type !in struct_names {
|
||||
struct_names << struct_type
|
||||
@@ -120,15 +123,15 @@ pub fn (parser CodeParser) find_structs_with_method(method_name: string, module:
|
||||
}
|
||||
|
||||
// find_callers finds all functions that call a specific function (basic text matching)
|
||||
pub fn (parser CodeParser) find_callers(function_name: string, module: string = '') []code.Function {
|
||||
pub fn (parser CodeParser) find_callers(args FinderOptions) []code.Function {
|
||||
mut callers := []code.Function{}
|
||||
|
||||
functions := parser.list_functions(module)
|
||||
functions := parser.list_functions(args.module_name)
|
||||
for func in functions {
|
||||
if func.body.contains(function_name) {
|
||||
if func.body.contains(args.name) {
|
||||
callers << func
|
||||
}
|
||||
}
|
||||
|
||||
return callers
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,26 +2,28 @@ module codeparser
|
||||
|
||||
import incubaid.herolib.core.code
|
||||
|
||||
// list_modules returns a list of all parsed module names
|
||||
pub fn (parser CodeParser) list_modules() []string {
|
||||
return parser.modules.keys()
|
||||
}
|
||||
|
||||
// get_module_stats returns statistics for a given module
|
||||
// get_module_stats calculates statistics for a module
|
||||
pub fn (parser CodeParser) get_module_stats(module_name string) ModuleStats {
|
||||
mut stats := ModuleStats{}
|
||||
if file_paths := parser.modules[module_name] {
|
||||
stats.file_count = file_paths.len
|
||||
for file_path in file_paths {
|
||||
if parsed_file := parser.parsed_files[file_path] {
|
||||
vfile := parsed_file.vfile
|
||||
stats.struct_count += vfile.structs().len
|
||||
stats.function_count += vfile.functions().len
|
||||
stats.const_count += vfile.consts.len
|
||||
stats.interface_count += vfile.interfaces().len
|
||||
|
||||
file_paths := parser.modules[module_name] or { []string{} }
|
||||
|
||||
for file_path in file_paths {
|
||||
if parsed_file := parser.parsed_files[file_path] {
|
||||
stats.file_count++
|
||||
stats.struct_count += parsed_file.vfile.structs().len
|
||||
stats.function_count += parsed_file.vfile.functions().len
|
||||
|
||||
for item in parsed_file.vfile.items {
|
||||
if item is code.Interface {
|
||||
stats.interface_count++
|
||||
}
|
||||
}
|
||||
|
||||
stats.const_count += parsed_file.vfile.consts.len
|
||||
}
|
||||
}
|
||||
|
||||
return stats
|
||||
}
|
||||
|
||||
@@ -77,11 +79,11 @@ pub fn (p CodeParser) all_enums() []code.Enum {
|
||||
return all
|
||||
}
|
||||
|
||||
// all_interfaces returns all interfaces from all parsed files
|
||||
pub fn (p CodeParser) all_interfaces() []code.Interface {
|
||||
mut all := []code.Interface{}
|
||||
for _, file in p.parsed_files {
|
||||
all << file.vfile.interfaces()
|
||||
}
|
||||
return all
|
||||
}
|
||||
// // all_interfaces returns all interfaces from all parsed files
|
||||
// pub fn (p CodeParser) all_interfaces() []code.Interface {
|
||||
// mut all := []code.Interface{}
|
||||
// for _, file in p.parsed_files {
|
||||
// all << file.vfile.interfaces()
|
||||
// }
|
||||
// return all
|
||||
// }
|
||||
|
||||
@@ -5,18 +5,18 @@ import incubaid.herolib.core.code
|
||||
|
||||
// JSON export structures
|
||||
pub struct CodeParserJSON {
|
||||
pub:
|
||||
pub mut:
|
||||
root_dir string
|
||||
modules map[string]ModuleJSON
|
||||
summary SummaryJSON
|
||||
}
|
||||
|
||||
pub struct ModuleJSON {
|
||||
pub:
|
||||
name string
|
||||
files map[string]FileJSON
|
||||
stats ModuleStats
|
||||
imports []string
|
||||
pub mut:
|
||||
name string
|
||||
files map[string]FileJSON
|
||||
stats ModuleStats
|
||||
imports []string
|
||||
}
|
||||
|
||||
pub struct FileJSON {
|
||||
@@ -61,7 +61,7 @@ pub:
|
||||
}
|
||||
|
||||
pub struct SummaryJSON {
|
||||
pub:
|
||||
pub mut:
|
||||
total_files int
|
||||
total_modules int
|
||||
total_structs int
|
||||
@@ -70,23 +70,23 @@ pub:
|
||||
}
|
||||
|
||||
// to_json exports the complete code structure to JSON
|
||||
//
|
||||
//
|
||||
// Args:
|
||||
// module - optional module filter (if empty, exports all modules)
|
||||
// module_name - optional module filter (if empty, exports all modules)
|
||||
// Returns:
|
||||
// JSON string representation
|
||||
pub fn (parser CodeParser) to_json(module: string = '') !string {
|
||||
pub fn (parser CodeParser) to_json(module_name string) !string {
|
||||
mut result := CodeParserJSON{
|
||||
root_dir: parser.root_dir
|
||||
modules: map[string]ModuleJSON{}
|
||||
summary: SummaryJSON{}
|
||||
}
|
||||
|
||||
modules_to_process := if module != '' {
|
||||
if module in parser.modules {
|
||||
[module]
|
||||
modules_to_process := if module_name != '' {
|
||||
if module_name in parser.modules {
|
||||
[module_name]
|
||||
} else {
|
||||
return error('module \'${module}\' not found')
|
||||
return error('module \'${module_name}\' not found')
|
||||
}
|
||||
} else {
|
||||
parser.list_modules()
|
||||
@@ -180,13 +180,11 @@ pub fn (parser CodeParser) to_json(module: string = '') !string {
|
||||
result.summary.total_modules++
|
||||
}
|
||||
|
||||
result.summary.total_files = result.modules.values().map(it.stats.file_count).sum()
|
||||
// mut total_files := 0
|
||||
// for module in result.modules.values() {
|
||||
// total_files += module.stats.file_count
|
||||
// }
|
||||
// result.summary.total_files = total_files
|
||||
|
||||
return json.encode(result)
|
||||
return json.encode_pretty(result)
|
||||
}
|
||||
|
||||
// to_json_pretty exports to pretty-printed JSON
|
||||
pub fn (parser CodeParser) to_json_pretty(module: string = '') !string {
|
||||
json_str := parser.to_json(module)!
|
||||
return json.encode_pretty(json.decode(map[string]interface{}, json_str)!)
|
||||
}
|
||||
@@ -2,28 +2,27 @@ module codeparser
|
||||
|
||||
import incubaid.herolib.core.code
|
||||
|
||||
// list_modules returns all module names found in the codebase
|
||||
// list_modules returns a list of all parsed module names
|
||||
pub fn (parser CodeParser) list_modules() []string {
|
||||
return parser.modules.keys()
|
||||
}
|
||||
|
||||
// list_files returns all parsed file paths
|
||||
pub fn (parser CodeParser) list_files() []string {
|
||||
return parser.parsed_files.keys()
|
||||
}
|
||||
|
||||
// list_files_in_module returns all file paths in a specific module
|
||||
pub fn (parser CodeParser) list_files_in_module(module: string) []string {
|
||||
return parser.modules[module] or { []string{} }
|
||||
pub fn (parser CodeParser) list_files_in_module(module_name string) []string {
|
||||
return parser.modules[module_name] or { []string{} }
|
||||
}
|
||||
|
||||
// list_structs returns all structs in the codebase (optionally filtered by module)
|
||||
pub fn (parser CodeParser) list_structs(module: string = '') []code.Struct {
|
||||
pub fn (parser CodeParser) list_structs(module_name string) []code.Struct {
|
||||
mut structs := []code.Struct{}
|
||||
|
||||
for _, parsed_file in parser.parsed_files {
|
||||
// Skip if module filter is provided and doesn't match
|
||||
if module != '' && parsed_file.module_name != module {
|
||||
if module_name != '' && parsed_file.module_name != module_name {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -35,11 +34,11 @@ pub fn (parser CodeParser) list_structs(module: string = '') []code.Struct {
|
||||
}
|
||||
|
||||
// list_functions returns all functions in the codebase (optionally filtered by module)
|
||||
pub fn (parser CodeParser) list_functions(module: string = '') []code.Function {
|
||||
pub fn (parser CodeParser) list_functions(module_name string) []code.Function {
|
||||
mut functions := []code.Function{}
|
||||
|
||||
for _, parsed_file in parser.parsed_files {
|
||||
if module != '' && parsed_file.module_name != module {
|
||||
if module_name != '' && parsed_file.module_name != module_name {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -51,11 +50,11 @@ pub fn (parser CodeParser) list_functions(module: string = '') []code.Function {
|
||||
}
|
||||
|
||||
// list_interfaces returns all interfaces in the codebase (optionally filtered by module)
|
||||
pub fn (parser CodeParser) list_interfaces(module: string = '') []code.Interface {
|
||||
pub fn (parser CodeParser) list_interfaces(module_name string) []code.Interface {
|
||||
mut interfaces := []code.Interface{}
|
||||
|
||||
for _, parsed_file in parser.parsed_files {
|
||||
if module != '' && parsed_file.module_name != module {
|
||||
if module_name != '' && parsed_file.module_name != module_name {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -71,13 +70,14 @@ pub fn (parser CodeParser) list_interfaces(module: string = '') []code.Interface
|
||||
}
|
||||
|
||||
// list_methods_on_struct returns all methods (receiver functions) for a struct
|
||||
pub fn (parser CodeParser) list_methods_on_struct(struct_name: string, module: string = '') []code.Function {
|
||||
pub fn (parser CodeParser) list_methods_on_struct(struct_name string, module_name string) []code.Function {
|
||||
mut methods := []code.Function{}
|
||||
|
||||
functions := parser.list_functions(module)
|
||||
functions := parser.list_functions(module_name)
|
||||
for func in functions {
|
||||
// Check if function has a receiver of the matching type
|
||||
if func.receiver.typ.symbol().contains(struct_name) {
|
||||
receiver_type := func.receiver.typ.symbol()
|
||||
if receiver_type.contains(struct_name) {
|
||||
methods << func
|
||||
}
|
||||
}
|
||||
@@ -86,11 +86,11 @@ pub fn (parser CodeParser) list_methods_on_struct(struct_name: string, module: s
|
||||
}
|
||||
|
||||
// list_imports returns all unique imports used in the codebase (optionally filtered by module)
|
||||
pub fn (parser CodeParser) list_imports(module: string = '') []code.Import {
|
||||
pub fn (parser CodeParser) list_imports(module_name string) []code.Import {
|
||||
mut imports := map[string]code.Import{}
|
||||
|
||||
for _, parsed_file in parser.parsed_files {
|
||||
if module != '' && parsed_file.module_name != module {
|
||||
if module_name != '' && parsed_file.module_name != module_name {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -103,11 +103,11 @@ pub fn (parser CodeParser) list_imports(module: string = '') []code.Import {
|
||||
}
|
||||
|
||||
// list_constants returns all constants in the codebase (optionally filtered by module)
|
||||
pub fn (parser CodeParser) list_constants(module: string = '') []code.Const {
|
||||
pub fn (parser CodeParser) list_constants(module_name string) []code.Const {
|
||||
mut consts := []code.Const{}
|
||||
|
||||
for _, parsed_file in parser.parsed_files {
|
||||
if module != '' && parsed_file.module_name != module {
|
||||
if module_name != '' && parsed_file.module_name != module_name {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -115,4 +115,4 @@ pub fn (parser CodeParser) list_constants(module: string = '') []code.Const {
|
||||
}
|
||||
|
||||
return consts
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user