Class: Bash::Merge::FileAnalysis
- Inherits:
-
Object
- Object
- Bash::Merge::FileAnalysis
- Includes:
- Ast::Merge::FileAnalyzable
- Defined in:
- lib/bash/merge/file_analysis.rb
Overview
Analyzes Bash script structure, extracting nodes, comments, and freeze blocks. This is the main analysis class that prepares Bash content for merging.
Constant Summary collapse
- DEFAULT_FREEZE_TOKEN =
Default freeze token for identifying freeze blocks
'bash-merge'
Instance Attribute Summary collapse
-
#ast ⇒ TreeHaver::Tree?
readonly
Parsed AST.
-
#comment_tracker ⇒ CommentTracker
readonly
Comment tracker for this file.
-
#errors ⇒ Array
readonly
Parse errors if any.
Class Method Summary collapse
-
.find_parser_path ⇒ String?
Find the parser library path using TreeHaver::GrammarFinder.
Instance Method Summary collapse
-
#comment_attachment_for(owner, **options) ⇒ Ast::Merge::Comment::Attachment
Build a passive shared comment attachment for an owner.
- #comment_attachment_strategy ⇒ Symbol
-
#comment_augmenter(owners: nil, **options) ⇒ Ast::Merge::Comment::Augmenter
Build a passive shared comment augmenter for this analysis.
-
#comment_capability ⇒ Ast::Merge::Comment::Capability
Get shared comment capability information for this analysis.
-
#comment_node_at(line_num) ⇒ Ast::Merge::Comment::Line?
Get a shared Ast::Merge comment node at a specific line.
-
#comment_nodes ⇒ Array<Ast::Merge::Comment::Line>
Get all tracked comments converted to shared Ast::Merge comment nodes.
-
#comment_region_for_range(range, kind:, full_line_only: false) ⇒ Ast::Merge::Comment::Region
Get comments in a line range converted to a shared comment region.
-
#comment_support_style ⇒ Ast::Merge::Comment::SupportStyle
Describe how Bash merges currently own and emit comments.
-
#fallthrough_node?(value) ⇒ Boolean
Override to detect tree-sitter nodes for signature generator fallthrough.
-
#freeze_block_at(line_num) ⇒ FreezeNode?
Get the freeze block containing the given line.
-
#in_freeze_block?(line_num) ⇒ Boolean
Check if a line is within a freeze block.
-
#initialize(source, freeze_token: DEFAULT_FREEZE_TOKEN, signature_generator: nil, parser_path: nil, **_options) ⇒ FileAnalysis
constructor
Initialize file analysis.
-
#root_node ⇒ NodeWrapper?
Get the root node of the parse tree.
- #ruleset_owner_selector ⇒ Object
- #ruleset_render_family ⇒ Object
-
#statements ⇒ Array<NodeWrapper, FreezeNodeBase>
(also: #nodes)
The base module uses 'statements' - provide both names for compatibility.
-
#top_level_statements ⇒ Array<NodeWrapper>
Get top-level statements from the script.
-
#valid? ⇒ Boolean
Check if parse was successful.
Constructor Details
#initialize(source, freeze_token: DEFAULT_FREEZE_TOKEN, signature_generator: nil, parser_path: nil, **_options) ⇒ FileAnalysis
Initialize file analysis
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/bash/merge/file_analysis.rb', line 45 def initialize(source, freeze_token: DEFAULT_FREEZE_TOKEN, signature_generator: nil, parser_path: nil, **) @source = source @lines = source.lines.map(&:chomp) @freeze_token = freeze_token @signature_generator = signature_generator @parser_path = parser_path @errors = [] # **options captures any additional parameters (e.g., node_typing) for forward compatibility # Initialize comment tracking @comment_tracker = CommentTracker.new(source) # Parse the Bash script DebugLogger.time('FileAnalysis#parse_bash') { parse_bash } # Extract freeze blocks and integrate with nodes @freeze_blocks = extract_freeze_blocks @nodes = integrate_nodes_and_freeze_blocks DebugLogger.debug('FileAnalysis initialized', { signature_generator: signature_generator ? 'custom' : 'default', nodes_count: @nodes.size, freeze_blocks: @freeze_blocks.size, valid: valid? }) end |
Instance Attribute Details
#ast ⇒ TreeHaver::Tree? (readonly)
Returns Parsed AST.
23 24 25 |
# File 'lib/bash/merge/file_analysis.rb', line 23 def ast @ast end |
#comment_tracker ⇒ CommentTracker (readonly)
Returns Comment tracker for this file.
20 21 22 |
# File 'lib/bash/merge/file_analysis.rb', line 20 def comment_tracker @comment_tracker end |
#errors ⇒ Array (readonly)
Returns Parse errors if any.
26 27 28 |
# File 'lib/bash/merge/file_analysis.rb', line 26 def errors @errors end |
Class Method Details
.find_parser_path ⇒ String?
Find the parser library path using TreeHaver::GrammarFinder
33 34 35 |
# File 'lib/bash/merge/file_analysis.rb', line 33 def find_parser_path TreeHaver::GrammarFinder.new(:bash).find_library_path end |
Instance Method Details
#comment_attachment_for(owner, **options) ⇒ Ast::Merge::Comment::Attachment
Build a passive shared comment attachment for an owner.
133 134 135 136 137 138 139 |
# File 'lib/bash/merge/file_analysis.rb', line 133 def (owner, **) ( owner, tracker_attachment: comment_tracker.(owner, **), ** ) end |
#comment_attachment_strategy ⇒ Symbol
142 143 144 |
# File 'lib/bash/merge/file_analysis.rb', line 142 def :augmenter_preferred_tracker_layout end |
#comment_augmenter(owners: nil, **options) ⇒ Ast::Merge::Comment::Augmenter
Build a passive shared comment augmenter for this analysis.
159 160 161 162 163 164 |
# File 'lib/bash/merge/file_analysis.rb', line 159 def comment_augmenter(owners: nil, **) comment_tracker.augment( owners: owners || comment_augmenter_default_owners, ** ) end |
#comment_capability ⇒ Ast::Merge::Comment::Capability
Get shared comment capability information for this analysis.
81 82 83 |
# File 'lib/bash/merge/file_analysis.rb', line 81 def comment_capability @comment_capability ||= comment_tracker.augment(owners: []).capability end |
#comment_node_at(line_num) ⇒ Ast::Merge::Comment::Line?
Get a shared Ast::Merge comment node at a specific line.
110 111 112 |
# File 'lib/bash/merge/file_analysis.rb', line 110 def comment_node_at(line_num) comment_tracker.comment_node_at(line_num) end |
#comment_nodes ⇒ Array<Ast::Merge::Comment::Line>
Get all tracked comments converted to shared Ast::Merge comment nodes.
102 103 104 |
# File 'lib/bash/merge/file_analysis.rb', line 102 def comment_nodes comment_tracker.comment_nodes end |
#comment_region_for_range(range, kind:, full_line_only: false) ⇒ Ast::Merge::Comment::Region
Get comments in a line range converted to a shared comment region.
120 121 122 123 124 125 126 |
# File 'lib/bash/merge/file_analysis.rb', line 120 def comment_region_for_range(range, kind:, full_line_only: false) comment_tracker.comment_region_for_range( range, kind: kind, full_line_only: full_line_only ) end |
#comment_support_style ⇒ Ast::Merge::Comment::SupportStyle
Describe how Bash merges currently own and emit comments.
Bash comment handling is fully source-augmented and emitted through the synthetic merge layer.
91 92 93 94 95 96 97 |
# File 'lib/bash/merge/file_analysis.rb', line 91 def comment_support_style @comment_support_style ||= shared_comment_support_style( source: :bash_source, style: :hash_comment, read_strategy: :source_augmented_portable_write ) end |
#fallthrough_node?(value) ⇒ Boolean
Override to detect tree-sitter nodes for signature generator fallthrough
194 195 196 |
# File 'lib/bash/merge/file_analysis.rb', line 194 def fallthrough_node?(value) value.is_a?(NodeWrapper) || value.is_a?(FreezeNode) || super end |
#freeze_block_at(line_num) ⇒ FreezeNode?
Get the freeze block containing the given line.
187 188 189 |
# File 'lib/bash/merge/file_analysis.rb', line 187 def freeze_block_at(line_num) @freeze_blocks.find { |fb| fb.location.cover?(line_num) } end |
#in_freeze_block?(line_num) ⇒ Boolean
Check if a line is within a freeze block.
179 180 181 |
# File 'lib/bash/merge/file_analysis.rb', line 179 def in_freeze_block?(line_num) @freeze_blocks.any? { |fb| fb.location.cover?(line_num) } end |
#root_node ⇒ NodeWrapper?
Get the root node of the parse tree
200 201 202 203 204 |
# File 'lib/bash/merge/file_analysis.rb', line 200 def root_node return unless valid? NodeWrapper.new(@ast.root_node, lines: @lines, source: @source) end |
#ruleset_owner_selector ⇒ Object
146 147 148 |
# File 'lib/bash/merge/file_analysis.rb', line 146 def ruleset_owner_selector :line_bound_statements end |
#ruleset_render_family ⇒ Object
150 151 152 |
# File 'lib/bash/merge/file_analysis.rb', line 150 def ruleset_render_family :bash_script_statements end |
#statements ⇒ Array<NodeWrapper, FreezeNodeBase> Also known as: nodes
The base module uses 'statements' - provide both names for compatibility
168 169 170 |
# File 'lib/bash/merge/file_analysis.rb', line 168 def statements @nodes || [] end |
#top_level_statements ⇒ Array<NodeWrapper>
Get top-level statements from the script
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/bash/merge/file_analysis.rb', line 208 def top_level_statements return [] unless valid? @top_level_statements ||= begin root = @ast.root_node if root statements = [] root.each do |child| next if child.type.to_s == 'comment' # Comments handled separately statements << NodeWrapper.new(child, lines: @lines, source: @source) end statements else [] end end end |
#valid? ⇒ Boolean
Check if parse was successful
74 75 76 |
# File 'lib/bash/merge/file_analysis.rb', line 74 def valid? @errors.empty? && !@ast.nil? end |