|
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