Skip to content
This repository has been archived by the owner on May 4, 2024. It is now read-only.

Commit

Permalink
Rename registry to tree
Browse files Browse the repository at this point in the history
  • Loading branch information
floriandejonckheere committed Mar 31, 2024
1 parent e4f887a commit 959a353
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 38 deletions.
12 changes: 6 additions & 6 deletions lib/mosaik/extractors/structural.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@ class Structural < Extractor
def call
return unless options[:structural].positive?

# Instantiate a constant registry
registry = Syntax::Registry.new
# Instantiate a constant tree
tree = Syntax::Tree.new

# Parse file with an appropriate parser
MOSAIK.configuration.files.each do |file|
PARSERS
.fetch(File.extname(file))
.new
.parse(file, registry)
.parse(file, tree)
rescue KeyError
raise UnknownFileType, "No parser for file type: #{File.extname(file)}"
end

# Print the registry
registry.each do |constant|
# Print the constant tree
tree.each do |constant|
debug constant

constant.methods.each_value do |method|
Expand All @@ -42,7 +42,7 @@ def call
debug (" " * constant.name.scan("::").count) + constant.name
end

registry.each { |constant| construct(constant) } # rubocop:disable Style/CombinableLoops
tree.each { |constant| construct(constant) } # rubocop:disable Style/CombinableLoops
end

private
Expand Down
4 changes: 2 additions & 2 deletions lib/mosaik/parsers/ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Parsers
# Parser for Ruby code
#
class Ruby
def parse(file, registry)
def parse(file, tree)
debug "Parsing file: #{file}"

# Parse Abstract Syntax Tree
Expand All @@ -15,7 +15,7 @@ def parse(file, registry)

# Process AST to extract constants, methods and references
Processors::Ruby
.new(registry)
.new(tree)
.process(ast)
end
end
Expand Down
16 changes: 8 additions & 8 deletions lib/mosaik/processors/ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ module Processors
# Abstract Syntax Tree parser for Ruby code
#
class Ruby < AST::Processor
attr_reader :registry
attr_reader :tree
attr_accessor :current_class, :current_method

def initialize(registry)
def initialize(tree)
super()

@registry = registry
@tree = tree
end

def on_class(node)
Expand All @@ -22,7 +22,7 @@ def on_class(node)
self.current_class = current_class ? "#{current_class}::#{class_name}" : class_name

# Register class
registry[current_class]
tree[current_class]

debug "Class #{current_class} in #{node.loc.expression.source_buffer.name}:#{node.loc.line}"

Expand All @@ -40,7 +40,7 @@ def on_module(node)
self.current_class = current_class ? "#{current_class}::#{module_name}" : module_name

# Register module
registry[current_class]
tree[current_class]

debug "Module #{current_class} in #{node.loc.expression.source_buffer.name}:#{node.loc.line}"

Expand All @@ -61,7 +61,7 @@ def on_def(node)

debug "Class instance method #{current_class}##{method_name} in #{file}:#{line_num}"

registry[current_class].add_method(method_name, file, line_num)
tree[current_class].add_method(method_name, file, line_num)

# Traverse the AST (first two children are method name and arguments)
node.children[2..].each { |c| process(c) }
Expand All @@ -77,7 +77,7 @@ def on_defs(node)

debug "Class method #{current_class}.#{node.children[1]} in #{file}:#{line_num}"

registry[current_class].add_method(method_name, file, line_num)
tree[current_class].add_method(method_name, file, line_num)

# Traverse the AST (first two children are method name and arguments)
node.children[2..].each { |c| process(c) }
Expand All @@ -99,7 +99,7 @@ def on_send(node)

debug "Reference to #{constant_name}##{callee} from #{current_class}##{current_method} in #{node.loc.expression.source_buffer.name}:#{node.loc.line}"

registry[current_class].methods[current_method].references << Syntax::Reference.new(registry[constant_name], callee)
tree[current_class].methods[current_method].references << Syntax::Reference.new(tree[constant_name], callee)
end

private
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Syntax
##
# Tree of constants in the codebase
#
class Registry
class Tree
include Enumerable

attr_reader :top
Expand Down
10 changes: 5 additions & 5 deletions spec/mosaik/parsers/ruby_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
subject(:parser) { described_class.new }

let(:file) { "spec/fixtures/lib/app/user.rb" }
let(:registry) { MOSAIK::Syntax::Registry.new }
let(:tree) { MOSAIK::Syntax::Tree.new }

it "parses a Ruby file" do
parser.parse(file, registry)
parser.parse(file, tree)

# Test constants
app = build(:constant, name: "App")
user = build(:constant, name: "App::User")
validators = build(:constant, name: "Validators")
user_validator = build(:constant, name: "Validators::User") # FIXME: fully qualify the constant

expect(registry).to contain_exactly app, user, validators, user_validator
expect(tree).to contain_exactly app, user, validators, user_validator

# Test methods
initialize = build(:method, constant: user, name: "initialize")
Expand All @@ -26,11 +26,11 @@
valid_ = build(:method, constant: user, name: "valid?")
to_s = build(:method, constant: user, name: "to_s")

expect(registry["App::User"].methods.values).to eq [initialize, name, email, admin, valid_, to_s]
expect(tree["App::User"].methods.values).to eq [initialize, name, email, admin, valid_, to_s]

# Test references
reference = build(:reference, constant: user_validator, method: "valid?")

expect(registry["App::User"].methods["valid?"].references).to eq [reference]
expect(tree["App::User"].methods["valid?"].references).to eq [reference]
end
end
Original file line number Diff line number Diff line change
@@ -1,60 +1,60 @@
# frozen_string_literal: true

RSpec.describe MOSAIK::Syntax::Registry do
subject(:registry) { described_class.new }
RSpec.describe MOSAIK::Syntax::Tree do
subject(:tree) { build(:tree) }

describe "#[]" do
it "returns a constant" do
constant = registry["Foo"]
constant = tree["Foo"]

expect(constant).to be_a MOSAIK::Syntax::Constant
expect(constant.name).to eq "Foo"
end

it "returns the same constant for the same name" do
constant1 = registry["Foo"]
constant2 = registry["Foo"]
constant1 = tree["Foo"]
constant2 = tree["Foo"]

expect(constant1).to eq constant2
end

it "returns nested constants" do
constant = registry["Foo::Bar"]
constant = tree["Foo::Bar"]

expect(constant.name).to eq "Foo::Bar"
end

it "stores the constants hierarchically" do
registry["Foo::Bar"]
registry["Foo::Baz::Bat"]
tree["Foo::Bar"]
tree["Foo::Baz::Bat"]

foo = registry["Foo"]
foo = tree["Foo"]

expect(foo.descendants.map(&:name)).to eq ["Foo::Bar", "Foo::Baz"]
expect(foo.parent.name).to be_nil

foo_bar = registry["Foo::Bar"]
foo_bar = tree["Foo::Bar"]
expect(foo_bar.descendants.map(&:name)).to eq []
expect(foo_bar.parent.name).to eq "Foo"

foo_baz = registry["Foo::Baz"]
foo_baz = tree["Foo::Baz"]
expect(foo_baz.descendants.map(&:name)).to eq ["Foo::Baz::Bat"]
expect(foo_baz.parent.name).to eq "Foo"

foo_baz_bat = registry["Foo::Baz::Bat"]
foo_baz_bat = tree["Foo::Baz::Bat"]
expect(foo_baz_bat.descendants.map(&:name)).to eq []
expect(foo_baz_bat.parent.name).to eq "Foo::Baz"
end
end

describe "#each" do
it "yields each constant in depth-first order" do
registry["Foo"]
registry["Foo::Bar"]
registry["Foo::Baz::Bat"]
tree["Foo"]
tree["Foo::Bar"]
tree["Foo::Baz::Bat"]

constants = []
registry.each { |constant| constants << constant.name }
tree.each { |constant| constants << constant.name }

expect(constants).to eq ["Foo", "Foo::Bar", "Foo::Baz", "Foo::Baz::Bat"]
end
Expand Down
2 changes: 2 additions & 0 deletions spec/support/factories/syntax.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@
constant
add_attribute :method
end

factory :tree, class: MOSAIK::Syntax::Tree
end

0 comments on commit 959a353

Please sign in to comment.