Class: FiberAudit::Static::SemanticIndex
- Inherits:
-
Object
- Object
- FiberAudit::Static::SemanticIndex
- Defined in:
- lib/fiber_audit/static/semantic_index.rb
Overview
Semantic index backed by Rubydex 0.2.9.
Line/column conventions (FiberAudit standard)
- Lines are one-based (1, 2, 3, ...).
- Columns are zero-based (0, 1, 2, ...).
Rubydex 0.2.9 reports start_line as zero-based and start_column as
zero-based. The normalize_location helper adds 1 to start_line so that
all returned locations use FiberAudit's one-based line convention.
Defined Under Namespace
Classes: Constant, Declaration, Reference, RubydexGap
Instance Attribute Summary collapse
-
#gaps ⇒ Object
readonly
Returns the value of attribute gaps.
-
#root ⇒ Object
readonly
Returns the value of attribute root.
Instance Method Summary collapse
-
#ancestors_of(name) ⇒ Object
Returns Array of ancestor class/module names.
-
#build ⇒ Object
Build (or rebuild) the index.
-
#declarations ⇒ Object
Returns Array for classes/modules/methods in the workspace.
-
#descendants_of(name) ⇒ Object
Returns Array of descendant class/module names.
-
#initialize(root:) ⇒ SemanticIndex
constructor
A new instance of SemanticIndex.
-
#references_to(name) ⇒ Object
Returns Array for references to a given constant.
-
#resolve_constant(name, nesting:) ⇒ Object
Resolves a constant name to a Constant object.
Constructor Details
#initialize(root:) ⇒ SemanticIndex
Returns a new instance of SemanticIndex.
26 27 28 29 30 |
# File 'lib/fiber_audit/static/semantic_index.rb', line 26 def initialize(root:) @root = Pathname.new(root)..cleanpath @graph = nil @gaps = [] end |
Instance Attribute Details
#gaps ⇒ Object (readonly)
Returns the value of attribute gaps.
24 25 26 |
# File 'lib/fiber_audit/static/semantic_index.rb', line 24 def gaps @gaps end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
24 25 26 |
# File 'lib/fiber_audit/static/semantic_index.rb', line 24 def root @root end |
Instance Method Details
#ancestors_of(name) ⇒ Object
Returns Array of ancestor class/module names.
Uses Rubydex's ancestors method which considers ALL class/module
declarations (including external/framework ancestors) while the target
declaration itself remains workspace-owned (via find_declaration).
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/fiber_audit/static/semantic_index.rb', line 86 def ancestors_of(name) return [] unless @graph decl = find_declaration(name) return [] unless decl return [] unless decl.respond_to?(:ancestors) ancestors = decl.ancestors return [] unless ancestors ancestors.select { |ancestor| class_or_module?(ancestor) && ancestor.name != name } .map(&:name) rescue StandardError [] end |
#build ⇒ Object
Build (or rebuild) the index. Clears and deduplicates gaps on every call.
33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/fiber_audit/static/semantic_index.rb', line 33 def build @gaps = [] @graph = ::Rubydex::Graph.new @graph.workspace_path = @root.to_s @graph.index_workspace @graph.resolve record_gaps self rescue StandardError => e @gaps << RubydexGap.new(method: 'build', reason: e.) self end |
#declarations ⇒ Object
Returns Array for classes/modules/methods in the workspace. Returns one Declaration per workspace definition site so that reopened classes expose both (or more) definition sites.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/fiber_audit/static/semantic_index.rb', line 49 def declarations return [] unless @graph @graph.declarations.select { |d| workspace_declaration?(d) }.filter_map do |decl| kind = declaration_kind(decl) workspace_definition_locations(decl).filter_map do |loc| path, line = normalize_location(loc) next unless path Declaration.new(name: decl.name, kind: kind, path: path, line: line) end end.flatten rescue StandardError [] end |
#descendants_of(name) ⇒ Object
Returns Array of descendant class/module names. Gracefully returns [] if Rubydex cannot compute descendants.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/fiber_audit/static/semantic_index.rb', line 104 def descendants_of(name) return [] unless @graph decl = find_declaration(name) return [] unless decl return [] unless decl.respond_to?(:descendants) descendants = decl.descendants return [] unless descendants descendants.map(&:name).uniq - [name] rescue StandardError [] end |
#references_to(name) ⇒ Object
Returns Array for references to a given constant. Filters to workspace and rescues non-file URIs per reference.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/fiber_audit/static/semantic_index.rb', line 121 def references_to(name) return [] unless @graph @graph.constant_references.filter_map do |ref| next unless ref.respond_to?(:declaration) && ref.declaration&.name == name loc = ref.location next unless workspace_location?(loc) path, line, column = normalize_location_full(loc) Reference.new(name: name, path: path, line: line, column: column, context: nil) rescue StandardError nil end rescue StandardError [] end |
#resolve_constant(name, nesting:) ⇒ Object
Resolves a constant name to a Constant object. Returns nil if the constant cannot be resolved or is outside the workspace.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/fiber_audit/static/semantic_index.rb', line 67 def resolve_constant(name, nesting:) return nil unless @graph result = @graph.resolve_constant(name.to_s, nesting || []) return nil unless result loc = first_workspace_location(result) return nil unless loc path, line = normalize_location(loc) Constant.new(name: result.name, path: path, line: line) rescue StandardError nil end |