Class: Ast::Merge::Comment::CStyleTrackerBase
- Inherits:
-
Object
- Object
- Ast::Merge::Comment::CStyleTrackerBase
- Defined in:
- lib/ast/merge/comment/c_style_tracker_base.rb
Overview
Shared base class for C-style comment trackers across the merge family.
This base owns reusable // + /* */ scanning, span-aware lookup for
multi-line block comments, shared line-comment region/attachment building,
and augmenter integration. It intentionally keeps the current shared
tracked-hash adapter boundary: block comments are tracked and queryable,
but shared nodes/regions/attachments still expose only line-style comments
until a broader block-comment normalization layer exists.
Subclasses may override:
- #owner_line_num for format-specific owner resolution
- #inline_comment_candidate? for syntax-specific inline-comment heuristics
The tracked-comment hash shape extends the tracked-hash adapter input with
C-style facts such as :block and optional :end_line for multi-line
block spans.
Constant Summary collapse
- SINGLE_LINE_COMMENT_REGEX =
Matches a full-line single-line C-style comment.
%r{\A(?<indent>\s*)//\s?(?<text>.*)\z}- BLOCK_COMMENT_SINGLE_REGEX =
Matches a full-line block comment contained on one line.
%r{\A(?<indent>\s*)/\*\s?(?<text>.*?)\s?\*/\s*\z}
Instance Attribute Summary collapse
-
#comments ⇒ Object
readonly
Returns the value of attribute comments.
-
#lines ⇒ Object
readonly
Returns the value of attribute lines.
Instance Method Summary collapse
-
#augment(owners: [], **options) ⇒ Object
---------------------------------------------------------------- Augmenter integration ----------------------------------------------------------------.
- #blank_line?(line_num) ⇒ Boolean
-
#comment_at(line_num) ⇒ Object
---------------------------------------------------------------- Single-comment lookup ----------------------------------------------------------------.
-
#comment_attachment_for(owner, line_num: nil, leading_comments: nil, inline_comment: nil, trailing_comments: nil, **metadata) ⇒ Object
---------------------------------------------------------------- Attachment building ----------------------------------------------------------------.
-
#comment_node_at(line_num) ⇒ Comment::Line?
Return the normalized shared comment node at a line.
-
#comment_nodes ⇒ Array<Comment::Line>
Return all normalized shared comment nodes eligible for region building.
-
#comment_region_for_range(range, kind:, full_line_only: false) ⇒ Region
Build a normalized region from comments intersecting a line range.
-
#comments_in_range(range) ⇒ Object
---------------------------------------------------------------- Range queries ----------------------------------------------------------------.
-
#full_line_comment?(line_num) ⇒ Boolean
---------------------------------------------------------------- Line utilities ----------------------------------------------------------------.
-
#initialize(lines) ⇒ CStyleTrackerBase
constructor
A new instance of CStyleTrackerBase.
-
#inline_comment_at(line_num) ⇒ Hash?
Return the inline comment tracked on a line.
-
#inline_comment_region_at(line_num, comment: nil) ⇒ Region?
Return the normalized inline region for a single line.
-
#leading_comment_region_before(line_num, comments: nil) ⇒ Region?
Return the normalized leading comment region before a line.
-
#leading_comments_before(line_num) ⇒ Object
---------------------------------------------------------------- Leading / inline comment helpers ----------------------------------------------------------------.
-
#line_at(line_num) ⇒ String?
Return the raw source line at a 1-based line number.
-
#trailing_comment_region_after(line_num, upper_bound: nil, comments: nil, owner: nil) ⇒ Region?
Return the normalized trailing region after an owner span.
-
#trailing_comments_after(line_num, upper_bound: nil, owner: nil) ⇒ Array<Hash>
Return adjacent full-line trailing line comments after an owner span.
Constructor Details
#initialize(lines) ⇒ CStyleTrackerBase
Returns a new instance of CStyleTrackerBase.
35 36 37 38 39 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 35 def initialize(lines) @lines = Array(lines) @comments = extract_comments @comments_by_line = build_comments_by_line(@comments) end |
Instance Attribute Details
#comments ⇒ Object (readonly)
Returns the value of attribute comments.
32 33 34 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 32 def comments @comments end |
#lines ⇒ Object (readonly)
Returns the value of attribute lines.
32 33 34 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 32 def lines @lines end |
Instance Method Details
#augment(owners: [], **options) ⇒ Object
Augmenter integration
277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 277 def augment(owners: [], **) Augmenter.new( lines: @lines, comments: shared_region_comments, owners: owners, style: :c_style_line, total_comment_count: @comments.size, block_comment_count: @comments.count { |comment| comment[:block] }, ** ) end |
#blank_line?(line_num) ⇒ Boolean
257 258 259 260 261 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 257 def blank_line?(line_num) return false if line_num < 1 || line_num > @lines.length @lines[line_num - 1].to_s.strip.empty? end |
#comment_at(line_num) ⇒ Object
Single-comment lookup
45 46 47 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 45 def comment_at(line_num) @comments_by_line[line_num]&.first end |
#comment_attachment_for(owner, line_num: nil, leading_comments: nil, inline_comment: nil, trailing_comments: nil, **metadata) ⇒ Object
Attachment building
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 222 def (owner, line_num: nil, leading_comments: nil, inline_comment: nil, trailing_comments: nil, **) resolved_line_num = line_num || owner_line_num(owner) resolved_end_line = owner_end_line(owner) || resolved_line_num leading_region = if resolved_line_num leading_comment_region_before(resolved_line_num, comments: leading_comments) end inline_region = (inline_comment_region_at(resolved_line_num, comment: inline_comment) if resolved_line_num) trailing_region = if resolved_end_line trailing_comment_region_after(resolved_end_line, comments: trailing_comments, owner: owner) end Attachment.new( owner: owner, leading_region: leading_region, inline_region: inline_region, trailing_region: trailing_region, metadata: .merge( line_num: resolved_line_num, end_line: resolved_end_line, source: :comment_tracker ) ) end |
#comment_node_at(line_num) ⇒ Comment::Line?
Return the normalized shared comment node at a line.
60 61 62 63 64 65 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 60 def comment_node_at(line_num) comment = comment_at(line_num) return unless comment && shared_region_comment?(comment) build_comment_node(comment) end |
#comment_nodes ⇒ Array<Comment::Line>
Return all normalized shared comment nodes eligible for region building.
52 53 54 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 52 def comment_nodes @comment_nodes ||= shared_region_comments.map { |comment| build_comment_node(comment) } end |
#comment_region_for_range(range, kind:, full_line_only: false) ⇒ Region
Build a normalized region from comments intersecting a line range.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 83 def comment_region_for_range(range, kind:, full_line_only: false) selected = comments_in_range(range).select { |comment| shared_region_comment?(comment) } selected = selected.select { |comment| comment[:full_line] } if full_line_only build_region( kind: kind, comments: selected, metadata: { range: range, full_line_only: full_line_only, source: :comment_tracker } ) end |
#comments_in_range(range) ⇒ Object
Range queries
71 72 73 74 75 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 71 def comments_in_range(range) @comments.select do |comment| range.begin <= comment_end_line(comment) && range.end >= comment_start_line(comment) end end |
#full_line_comment?(line_num) ⇒ Boolean
Line utilities
252 253 254 255 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 252 def full_line_comment?(line_num) comment = comment_at(line_num) comment&.dig(:full_line) || false end |
#inline_comment_at(line_num) ⇒ Hash?
Return the inline comment tracked on a line.
143 144 145 146 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 143 def inline_comment_at(line_num) comment = comment_at(line_num) comment if comment && !comment[:full_line] end |
#inline_comment_region_at(line_num, comment: nil) ⇒ Region?
Return the normalized inline region for a single line.
153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 153 def inline_comment_region_at(line_num, comment: nil) selected = [comment || inline_comment_at(line_num)].compact.select { |item| shared_region_comment?(item) } return if selected.empty? build_region( kind: :inline, comments: selected, metadata: { line_num: line_num, source: :comment_tracker } ) end |
#leading_comment_region_before(line_num, comments: nil) ⇒ Region?
Return the normalized leading comment region before a line.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 124 def leading_comment_region_before(line_num, comments: nil) selected = comments || leading_comments_before(line_num) selected = selected.select { |comment| comment[:full_line] && shared_region_comment?(comment) } return if selected.empty? build_region( kind: :leading, comments: selected, metadata: { line_num: line_num, source: :comment_tracker } ) end |
#leading_comments_before(line_num) ⇒ Object
Leading / inline comment helpers
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 102 def leading_comments_before(line_num) leading = [] current = line_num - 1 current -= 1 while current >= 1 && blank_line?(current) while current >= 1 comment = comment_at(current) break unless comment && comment[:full_line] leading.unshift(comment) current = comment_start_line(comment) - 1 current -= 1 while current >= 1 && blank_line?(current) end leading end |
#line_at(line_num) ⇒ String?
Return the raw source line at a 1-based line number.
267 268 269 270 271 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 267 def line_at(line_num) return if line_num < 1 || line_num > @lines.length @lines[line_num - 1] end |
#trailing_comment_region_after(line_num, upper_bound: nil, comments: nil, owner: nil) ⇒ Region?
Return the normalized trailing region after an owner span.
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 202 def trailing_comment_region_after(line_num, upper_bound: nil, comments: nil, owner: nil) selected = comments || trailing_comments_after(line_num, upper_bound: upper_bound, owner: owner) selected = selected.select { |comment| comment[:full_line] && shared_region_comment?(comment) } return if selected.empty? build_region( kind: :trailing, comments: selected, metadata: { line_num: line_num, upper_bound: upper_bound, source: :comment_tracker } ) end |
#trailing_comments_after(line_num, upper_bound: nil, owner: nil) ⇒ Array<Hash>
Return adjacent full-line trailing line comments after an owner span.
The first trailing comment must begin immediately after the owner. Blank lines are only preserved between later trailing comments, not between the owner and the first trailing comment.
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/ast/merge/comment/c_style_tracker_base.rb', line 176 def trailing_comments_after(line_num, upper_bound: nil, owner: nil) trailing = [] current = line_num + 1 max_line = upper_bound ? upper_bound - 1 : @lines.length return trailing if current > max_line || blank_line?(current) while current <= max_line comment = comment_at(current) break unless comment && comment[:full_line] && shared_region_comment?(comment) && trailing_comment_owned_by?( comment, owner ) trailing << comment current = comment_end_line(comment) + 1 current += 1 while current <= max_line && blank_line?(current) end trailing end |