|
2 | 2 |
|
3 | 3 | require 'find' |
4 | 4 |
|
| 5 | +require_relative 'include_to_component_resolver' |
5 | 6 | require_relative 'source_component' |
6 | 7 |
|
7 | 8 | # Parses all components of a project |
8 | 9 | class Project |
9 | 10 | def initialize(path) |
10 | 11 | @path = path |
| 12 | + @include_resolver = IncludeToComponentResolver.new(source_components) |
11 | 13 | end |
12 | 14 |
|
13 | 15 | def source_components |
14 | 16 | @source_components ||= build_source_components |
15 | 17 | end |
16 | 18 |
|
17 | 19 | def source_component(name) |
18 | | - source_components.detect { |c| c.name == name } |
| 20 | + return SourceComponent.new('NULL') unless source_components.key?(name) |
| 21 | + source_components[name] |
19 | 22 | end |
20 | 23 |
|
21 | 24 | def dependencies(component) |
22 | | - external_includes(component).map { |include| component_for_include(include) }.reject(&:empty?).uniq |
| 25 | + # TODO: This is repeating the same work twice! component_for_include is called when calling external_includes |
| 26 | + external_includes(component).map { |include| @include_resolver.component_for_include(include) }.reject(&:empty?).uniq |
23 | 27 | end |
24 | 28 |
|
25 | 29 | def external_includes(component) |
26 | | - filter_internal_includes(component) |
| 30 | + @include_resolver.external_includes(component) |
27 | 31 | end |
28 | 32 |
|
29 | 33 | private |
30 | 34 |
|
31 | 35 | def build_source_components |
32 | 36 | # TODO: Dealing with source components with same dir name? |
33 | 37 | dirs = fetch_all_dirs(@path) |
34 | | - source_components = dirs.map { |dir| SourceComponent.new(dir) } |
35 | | - source_components.reject { |c| c.source_files.size.zero? } |
36 | | - end |
37 | | - |
38 | | - def filter_internal_includes(component) |
39 | | - # TODO: This is super inefficient, refactor it |
40 | | - source_file_basenames = component.source_files.map(&:basename) |
41 | | - include_components = component.includes.map { |inc| [inc, component_for_include(inc)] }.to_h |
42 | | - filter = include_components.reject { |_, c| c == component.name } |
43 | | - filter.keys |
44 | | - end |
45 | | - |
46 | | - def component_for_include(include) |
47 | | - header_file = source_files.find { |file| file.basename == include } |
48 | | - parent_component(header_file) |
49 | | - end |
50 | | - |
51 | | - def source_files |
52 | | - @source_files ||= source_components.flat_map(&:source_files) |
53 | | - end |
54 | | - |
55 | | - def parent_component(header_file) |
56 | | - return '' if header_file.nil? |
57 | | - files = source_files.select { |file| file.basename_no_extension == header_file.basename_no_extension } |
58 | | - corresponding_files = files.reject { |file| file.basename == header_file.basename } |
59 | | - return header_file.parent_component if corresponding_files.size == 0 |
60 | | - corresponding_files[0].parent_component |
| 38 | + components = dirs.map do |dir| |
| 39 | + c = SourceComponent.new(dir) |
| 40 | + [c.name, c] |
| 41 | + end.to_h |
| 42 | + components.delete_if { |k, v| v.source_files.size.zero? } |
61 | 43 | end |
62 | 44 |
|
63 | 45 | def fetch_all_dirs(source_dir) |
|
0 commit comments