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
-
#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.
-
#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 || self.class.find_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
#fallthrough_node?(value) ⇒ Boolean
Override to detect tree-sitter nodes for signature generator fallthrough
106 107 108 |
# File 'lib/bash/merge/file_analysis.rb', line 106 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.
99 100 101 |
# File 'lib/bash/merge/file_analysis.rb', line 99 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.
91 92 93 |
# File 'lib/bash/merge/file_analysis.rb', line 91 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
112 113 114 115 116 |
# File 'lib/bash/merge/file_analysis.rb', line 112 def root_node return unless valid? NodeWrapper.new(@ast.root_node, lines: @lines, source: @source) end |
#statements ⇒ Array<NodeWrapper, FreezeNodeBase> Also known as: nodes
The base module uses ‘statements’ - provide both names for compatibility
80 81 82 |
# File 'lib/bash/merge/file_analysis.rb', line 80 def statements @nodes ||= [] end |
#top_level_statements ⇒ Array<NodeWrapper>
Get top-level statements from the script
120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/bash/merge/file_analysis.rb', line 120 def top_level_statements return [] unless valid? root = @ast.root_node return [] unless 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 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 |