Class: SimpleCov::Formatter::AIFormatter::ASTResolver

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/simplecov-ai/ast_resolver.rb,
lib/simplecov-ai/ast_resolver/node_children.rb,
lib/simplecov-ai/ast_resolver/semantic_node.rb,
lib/simplecov-ai/ast_resolver/bypass_scanner.rb,
lib/simplecov-ai/ast_resolver/parser_backend.rb,
lib/simplecov-ai/ast_resolver/node_classifier.rb,
lib/simplecov-ai/ast_resolver/lenient_literals.rb,
lib/simplecov-ai/ast_resolver/receiver_resolver.rb,
lib/simplecov-ai/ast_resolver/metaclass_resolver.rb,
lib/simplecov-ai/ast_resolver/dynamic_method_resolver.rb

Overview

Employs statically-parsed Abstract Syntax Tree processing (Prism's parser-compatible translation where available, the parser gem otherwise) to correlate raw line-based deficits with high-level semantically meaningful concepts like Classes and Methods. This negates the line-number volatility often experienced by Large Language Models when patching test coverage.

Defined Under Namespace

Modules: BypassScanner, DynamicMethodResolver, LenientLiterals, MetaclassResolver, NodeChildren, NodeClassifier, ParserBackend, ReceiverResolver Classes: SemanticNode

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.read_source(file_path) ⇒ Object



52
53
54
55
# File 'lib/simplecov-ai/ast_resolver.rb', line 52

def self.read_source(file_path)
  source = File.binread(file_path).force_encoding(Encoding::UTF_8)
  source.valid_encoding? ? source : source.force_encoding(Encoding::BINARY)
end

.resolve(file_path) ⇒ Object



35
36
37
38
39
40
41
42
# File 'lib/simplecov-ai/ast_resolver.rb', line 35

def self.resolve(file_path)
  return [] unless File.exist?(file_path)

  source = read_source(file_path)
  buffer = Parser::Source::Buffer.new(file_path, source: source)

  [SemanticNode.root(source.lines.size)] + new.traverse(ParserBackend.parse(buffer))
end

Instance Method Details

#traverse(node, context = '', singleton: false) ⇒ Object



69
70
71
72
73
74
75
76
77
# File 'lib/simplecov-ai/ast_resolver.rb', line 69

def traverse(node, context = '', singleton: false)
  return [] unless node

  current_context, semantic_node, child_singleton = NodeClassifier.classify(node, context, singleton)
  nested = node.children.grep(Parser::AST::Node).flat_map do |child|
    traverse(child, current_context, singleton: child_singleton)
  end
  semantic_node ? [semantic_node] + nested : nested
end