-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathinclude_to_component_resolver.rb
More file actions
63 lines (50 loc) · 2.08 KB
/
Copy pathinclude_to_component_resolver.rb
File metadata and controls
63 lines (50 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# frozen_string_literal: true
require_relative 'source_component'
# Resolves a given include to a source component
class IncludeToComponentResolver
def initialize(components)
@components = components
@component_external_include_cache = {}
@component_include_map_cache = {}
end
def external_includes(component)
unless @component_external_include_cache.key?(component)
@component_external_include_cache[component] = external_includes_private(component)
end
@component_external_include_cache[component]
end
def component_for_include(include)
return '' unless source_files.key?(include.basename)
component = component_for_include_private(include.basename) unless @component_include_map_cache.key?(include.basename)
return '' if !include.component.empty? and include.component != component
@component_include_map_cache[include] = component
@component_include_map_cache[include]
end
private
def external_includes_private(component)
include_components = component.includes.map { |inc| [inc, component_for_include(inc)] }.to_h
external_include_components = include_components.delete_if { |_, c| c == component.name }
external_include_components.keys
end
def component_for_include_private(include)
header_file = source_files[include]
implementation_files = implementation_files(header_file)
return header_file.parent_component if implementation_files.empty?
implementation_files[0].parent_component
end
def implementation_files(header_file)
implementation_files = []
source_files.each_value do |file|
implementation_files.push(file) if file.basename_no_extension == header_file.basename_no_extension
end
implementation_files.reject! { |file| file.basename == header_file.basename }
end
def source_files
@source_files ||= build_source_file_map
end
def build_source_file_map
# TODO: SourceComponent should return a hash for source files which can be merged here
source_files = @components.values.flat_map(&:source_files)
source_files.map { |s| [s.basename, s] }.to_h
end
end