kumi 0.0.8 β 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CLAUDE.md +28 -44
- data/README.md +188 -108
- data/docs/AST.md +8 -1
- data/docs/FUNCTIONS.md +52 -8
- data/docs/compiler_design_principles.md +86 -0
- data/docs/features/README.md +22 -2
- data/docs/features/hierarchical-broadcasting.md +349 -0
- data/docs/features/javascript-transpiler.md +148 -0
- data/docs/features/performance.md +1 -3
- data/docs/features/s-expression-printer.md +77 -0
- data/docs/schema_metadata.md +7 -7
- data/examples/game_of_life.rb +2 -4
- data/lib/kumi/analyzer.rb +0 -2
- data/lib/kumi/compiler.rb +6 -275
- data/lib/kumi/core/analyzer/passes/broadcast_detector.rb +600 -42
- data/lib/kumi/core/analyzer/passes/input_collector.rb +4 -2
- data/lib/kumi/core/analyzer/passes/semantic_constraint_validator.rb +27 -0
- data/lib/kumi/core/analyzer/passes/type_checker.rb +6 -2
- data/lib/kumi/core/analyzer/passes/unsat_detector.rb +90 -46
- data/lib/kumi/core/cascade_executor_builder.rb +132 -0
- data/lib/kumi/core/compiler/expression_compiler.rb +146 -0
- data/lib/kumi/core/compiler/function_invoker.rb +55 -0
- data/lib/kumi/core/compiler/path_traversal_compiler.rb +158 -0
- data/lib/kumi/core/compiler/reference_compiler.rb +46 -0
- data/lib/kumi/core/compiler_base.rb +137 -0
- data/lib/kumi/core/explain.rb +2 -2
- data/lib/kumi/core/function_registry/collection_functions.rb +86 -3
- data/lib/kumi/core/function_registry/function_builder.rb +5 -3
- data/lib/kumi/core/function_registry/logical_functions.rb +171 -1
- data/lib/kumi/core/function_registry/stat_functions.rb +156 -0
- data/lib/kumi/core/function_registry.rb +32 -10
- data/lib/kumi/core/nested_structure_utils.rb +78 -0
- data/lib/kumi/core/ruby_parser/dsl_cascade_builder.rb +2 -2
- data/lib/kumi/core/ruby_parser/input_builder.rb +61 -8
- data/lib/kumi/core/schema_instance.rb +4 -0
- data/lib/kumi/core/vectorized_function_builder.rb +88 -0
- data/lib/kumi/errors.rb +2 -0
- data/lib/kumi/js/compiler.rb +878 -0
- data/lib/kumi/js/function_registry.rb +333 -0
- data/lib/kumi/js.rb +23 -0
- data/lib/kumi/registry.rb +61 -1
- data/lib/kumi/schema.rb +1 -1
- data/lib/kumi/support/s_expression_printer.rb +162 -0
- data/lib/kumi/syntax/array_expression.rb +6 -6
- data/lib/kumi/syntax/call_expression.rb +4 -4
- data/lib/kumi/syntax/cascade_expression.rb +4 -4
- data/lib/kumi/syntax/case_expression.rb +4 -4
- data/lib/kumi/syntax/declaration_reference.rb +4 -4
- data/lib/kumi/syntax/hash_expression.rb +4 -4
- data/lib/kumi/syntax/input_declaration.rb +6 -5
- data/lib/kumi/syntax/input_element_reference.rb +5 -5
- data/lib/kumi/syntax/input_reference.rb +5 -5
- data/lib/kumi/syntax/literal.rb +4 -4
- data/lib/kumi/syntax/node.rb +34 -34
- data/lib/kumi/syntax/root.rb +6 -6
- data/lib/kumi/syntax/trait_declaration.rb +4 -4
- data/lib/kumi/syntax/value_declaration.rb +4 -4
- data/lib/kumi/version.rb +1 -1
- data/lib/kumi.rb +1 -1
- data/scripts/analyze_broadcast_methods.rb +68 -0
- data/scripts/analyze_cascade_methods.rb +74 -0
- data/scripts/check_broadcasting_coverage.rb +51 -0
- data/scripts/find_dead_code.rb +114 -0
- metadata +22 -4
- data/docs/features/array-broadcasting.md +0 -170
- data/lib/kumi/cli.rb +0 -449
- data/lib/kumi/core/vectorization_metadata.rb +0 -110
@@ -2,11 +2,12 @@
|
|
2
2
|
|
3
3
|
module Kumi
|
4
4
|
module Syntax
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
# For field metadata declarations inside input blocks
|
6
|
+
InputDeclaration = Struct.new(:name, :domain, :type, :children, :access_mode) do
|
7
|
+
include Node
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
def children = self[:children] || []
|
10
|
+
def access_mode = self[:access_mode]
|
11
|
+
end
|
11
12
|
end
|
12
13
|
end
|
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
module Kumi
|
4
4
|
module Syntax
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
# For field usage/reference in expressions (input.field_name)
|
6
|
+
InputElementReference = Struct.new(:path) do
|
7
|
+
include Node
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
def children = []
|
10
|
+
end
|
11
11
|
end
|
12
12
|
end
|
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
module Kumi
|
4
4
|
module Syntax
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
# For field usage/reference in expressions (input.field_name)
|
6
|
+
InputReference = Struct.new(:name) do
|
7
|
+
include Node
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
def children = []
|
10
|
+
end
|
11
11
|
end
|
12
12
|
end
|
data/lib/kumi/syntax/literal.rb
CHANGED
data/lib/kumi/syntax/node.rb
CHANGED
@@ -2,45 +2,45 @@
|
|
2
2
|
|
3
3
|
module Kumi
|
4
4
|
module Syntax
|
5
|
-
|
6
|
-
|
5
|
+
# A struct to hold standardized source location information.
|
6
|
+
Location = Struct.new(:file, :line, :column, keyword_init: true)
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
# Base module included by all AST nodes to provide a standard
|
9
|
+
# interface for accessing source location information..
|
10
|
+
module Node
|
11
|
+
attr_accessor :loc
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
def initialize(*args, loc: nil, **kwargs)
|
14
|
+
@loc = loc
|
15
|
+
super(*args, **kwargs)
|
16
|
+
freeze
|
17
|
+
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
19
|
+
def ==(other)
|
20
|
+
other.is_a?(self.class) &&
|
21
|
+
# for Struct-based nodes
|
22
|
+
(if respond_to?(:members)
|
23
|
+
members.all? { |m| self[m] == other[m] }
|
24
|
+
else
|
25
|
+
instance_variables.reject { |iv| iv == :@loc }
|
26
|
+
.all? do |iv|
|
27
|
+
instance_variable_get(iv) ==
|
28
|
+
other.instance_variable_get(iv)
|
30
29
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
end
|
31
|
+
)
|
32
|
+
end
|
33
|
+
alias eql? ==
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
35
|
+
def hash
|
36
|
+
values = if respond_to?(:members)
|
37
|
+
members.map { |m| self[m] }
|
38
|
+
else
|
39
|
+
instance_variables.reject { |iv| iv == :@loc }
|
40
|
+
.map { |iv| instance_variable_get(iv) }
|
41
|
+
end
|
42
|
+
[self.class, *values].hash
|
44
43
|
end
|
44
|
+
end
|
45
45
|
end
|
46
46
|
end
|
data/lib/kumi/syntax/root.rb
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
module Kumi
|
4
4
|
module Syntax
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
# Represents the root of the Abstract Syntax Tree.
|
6
|
+
# It holds all the top-level declarations parsed from the source.
|
7
|
+
Root = Struct.new(:inputs, :attributes, :traits) do
|
8
|
+
include Node
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
def children = [inputs, attributes, traits]
|
11
|
+
end
|
12
12
|
end
|
13
13
|
end
|
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
module Kumi
|
4
4
|
module Syntax
|
5
|
-
|
6
|
-
|
5
|
+
TraitDeclaration = Struct.new(:name, :expression) do
|
6
|
+
include Node
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
def children = [expression]
|
9
|
+
end
|
10
10
|
end
|
11
11
|
end
|
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
module Kumi
|
4
4
|
module Syntax
|
5
|
-
|
6
|
-
|
5
|
+
ValueDeclaration = Struct.new(:name, :expression) do
|
6
|
+
include Node
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
def children = [expression]
|
9
|
+
end
|
10
10
|
end
|
11
11
|
end
|
data/lib/kumi/version.rb
CHANGED
data/lib/kumi.rb
CHANGED
@@ -11,7 +11,7 @@ module Kumi
|
|
11
11
|
extend Schema
|
12
12
|
|
13
13
|
def self.inspector_from_schema
|
14
|
-
Inspector.new(@__syntax_tree__, @__analyzer_result__, @__compiled_schema__)
|
14
|
+
Schema::Inspector.new(@__syntax_tree__, @__analyzer_result__, @__compiled_schema__)
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.reset!
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
coverage_file = "coverage/.resultset.json"
|
7
|
+
|
8
|
+
unless File.exist?(coverage_file)
|
9
|
+
puts "β No coverage data found. Run tests first:"
|
10
|
+
puts " COVERAGE=true bundle exec rspec"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
data = JSON.parse(File.read(coverage_file))
|
15
|
+
coverage = data.values.first["coverage"]
|
16
|
+
|
17
|
+
broadcast_file = coverage.find { |file, _| file.include?("broadcast_detector.rb") }
|
18
|
+
|
19
|
+
if broadcast_file
|
20
|
+
file_path, line_data = broadcast_file
|
21
|
+
lines = line_data["lines"]
|
22
|
+
|
23
|
+
puts "π BroadcastDetector Coverage Analysis:"
|
24
|
+
puts "File: #{File.basename(file_path)}"
|
25
|
+
|
26
|
+
total_lines = lines.count { |hits| !hits.nil? }
|
27
|
+
covered_lines = lines.count { |hits| hits && hits > 0 }
|
28
|
+
coverage_percent = (covered_lines.to_f / total_lines * 100).round(1)
|
29
|
+
|
30
|
+
puts "Coverage: #{coverage_percent}% (#{covered_lines}/#{total_lines} lines)"
|
31
|
+
|
32
|
+
# Find uncovered method definitions
|
33
|
+
file_content = File.read(file_path)
|
34
|
+
uncovered_methods = []
|
35
|
+
covered_methods = []
|
36
|
+
|
37
|
+
file_content.lines.each_with_index do |line, i|
|
38
|
+
if line.match?(/^\s*def\s+(\w+)/)
|
39
|
+
method_name = line.match(/^\s*def\s+(\w+)/)[1]
|
40
|
+
line_hits = lines[i]
|
41
|
+
|
42
|
+
if line_hits.nil?
|
43
|
+
# Line not tracked
|
44
|
+
elsif line_hits == 0
|
45
|
+
uncovered_methods << "#{method_name} (line #{i+1})"
|
46
|
+
else
|
47
|
+
covered_methods << "#{method_name} (line #{i+1})"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
puts "\nπ Method Coverage Summary:"
|
53
|
+
puts " Total methods: #{covered_methods.length + uncovered_methods.length}"
|
54
|
+
puts " Covered methods: #{covered_methods.length}"
|
55
|
+
puts " Uncovered methods: #{uncovered_methods.length}"
|
56
|
+
|
57
|
+
if uncovered_methods.any?
|
58
|
+
puts "\nπ¨ Uncovered methods (potential dead code):"
|
59
|
+
uncovered_methods.each { |m| puts " - #{m}" }
|
60
|
+
end
|
61
|
+
|
62
|
+
if covered_methods.any?
|
63
|
+
puts "\nβ
Covered methods:"
|
64
|
+
covered_methods.each { |m| puts " - #{m}" }
|
65
|
+
end
|
66
|
+
else
|
67
|
+
puts "β BroadcastDetector file not found in coverage data"
|
68
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
coverage_file = "coverage/.resultset.json"
|
7
|
+
target_file = "cascade_executor_builder.rb"
|
8
|
+
|
9
|
+
unless File.exist?(coverage_file)
|
10
|
+
puts "β No coverage data found. Run tests first"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
data = JSON.parse(File.read(coverage_file))
|
15
|
+
coverage = data.values.first["coverage"]
|
16
|
+
|
17
|
+
file_entry = coverage.find { |file, _| file.include?(target_file) }
|
18
|
+
|
19
|
+
if file_entry
|
20
|
+
file_path, line_data = file_entry
|
21
|
+
lines = line_data["lines"]
|
22
|
+
|
23
|
+
puts "π CascadeExecutorBuilder Method Coverage:"
|
24
|
+
puts "=" * 50
|
25
|
+
|
26
|
+
file_content = File.read(file_path)
|
27
|
+
methods = []
|
28
|
+
|
29
|
+
file_content.lines.each_with_index do |line, i|
|
30
|
+
if line.match?(/^\s*def\s+/)
|
31
|
+
method_match = line.match(/^\s*def\s+(self\.)?(\w+)/)
|
32
|
+
if method_match
|
33
|
+
method_name = method_match[2]
|
34
|
+
is_class_method = !method_match[1].nil?
|
35
|
+
line_hits = lines[i]
|
36
|
+
|
37
|
+
status = if line_hits.nil?
|
38
|
+
"βͺ NOT TRACKED"
|
39
|
+
elsif line_hits == 0
|
40
|
+
"π¨ UNCOVERED"
|
41
|
+
else
|
42
|
+
"β
COVERED (#{line_hits} hits)"
|
43
|
+
end
|
44
|
+
|
45
|
+
prefix = is_class_method ? "self." : ""
|
46
|
+
methods << {
|
47
|
+
name: "#{prefix}#{method_name}",
|
48
|
+
line: i + 1,
|
49
|
+
hits: line_hits,
|
50
|
+
status: status
|
51
|
+
}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
methods.each do |method|
|
57
|
+
printf " %-25s (line %3d) %s\n", method[:name], method[:line], method[:status]
|
58
|
+
end
|
59
|
+
|
60
|
+
uncovered = methods.select { |m| m[:hits] == 0 }
|
61
|
+
covered = methods.select { |m| m[:hits] && m[:hits] > 0 }
|
62
|
+
|
63
|
+
puts "\nπ Summary:"
|
64
|
+
puts " Total methods: #{methods.length}"
|
65
|
+
puts " Covered: #{covered.length}"
|
66
|
+
puts " Uncovered: #{uncovered.length}"
|
67
|
+
|
68
|
+
if uncovered.any?
|
69
|
+
puts "\nπ¨ Uncovered methods (potential dead code):"
|
70
|
+
uncovered.each { |m| puts " #{m[:name]} (line #{m[:line]})" }
|
71
|
+
end
|
72
|
+
else
|
73
|
+
puts "β #{target_file} not found in coverage data"
|
74
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
coverage_file = "coverage/.resultset.json"
|
7
|
+
|
8
|
+
unless File.exist?(coverage_file)
|
9
|
+
puts "β No coverage data found. Run tests first"
|
10
|
+
exit 1
|
11
|
+
end
|
12
|
+
|
13
|
+
data = JSON.parse(File.read(coverage_file))
|
14
|
+
coverage = data.values.first["coverage"]
|
15
|
+
|
16
|
+
broadcasting_files = [
|
17
|
+
"cascade_executor_builder.rb",
|
18
|
+
"vectorized_function_builder.rb",
|
19
|
+
"nested_structure_utils.rb",
|
20
|
+
"broadcast_detector.rb"
|
21
|
+
]
|
22
|
+
|
23
|
+
puts "π Broadcasting Files Coverage:"
|
24
|
+
puts "=" * 60
|
25
|
+
|
26
|
+
broadcasting_files.each do |filename|
|
27
|
+
file_entry = coverage.find { |file, _| file.include?(filename) }
|
28
|
+
|
29
|
+
if file_entry
|
30
|
+
file_path, line_data = file_entry
|
31
|
+
lines = line_data["lines"]
|
32
|
+
|
33
|
+
total_lines = lines.count { |hits| !hits.nil? }
|
34
|
+
covered_lines = lines.count { |hits| hits && hits > 0 }
|
35
|
+
coverage_percent = total_lines > 0 ? (covered_lines.to_f / total_lines * 100).round(1) : 0
|
36
|
+
|
37
|
+
status = if coverage_percent == 0
|
38
|
+
"π¨ DEAD"
|
39
|
+
elsif coverage_percent < 20
|
40
|
+
"π΄ LOW"
|
41
|
+
elsif coverage_percent < 50
|
42
|
+
"π‘ MEDIUM"
|
43
|
+
else
|
44
|
+
"β
GOOD"
|
45
|
+
end
|
46
|
+
|
47
|
+
printf "%-35s %s %6.1f%% (%d/%d lines)\n", filename, status, coverage_percent, covered_lines, total_lines
|
48
|
+
else
|
49
|
+
printf "%-35s β NOT FOUND\n", filename
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
class SimpleDeadCodeFinder
|
7
|
+
COVERAGE_JSON = "coverage/.resultset.json"
|
8
|
+
|
9
|
+
def run
|
10
|
+
unless File.exist?(COVERAGE_JSON)
|
11
|
+
puts "β No coverage data found. Run tests first:"
|
12
|
+
puts " COVERAGE=true bundle exec rspec"
|
13
|
+
exit 1
|
14
|
+
end
|
15
|
+
|
16
|
+
puts "π Analyzing SimpleCov data for dead code..."
|
17
|
+
|
18
|
+
coverage_data = JSON.parse(File.read(COVERAGE_JSON))
|
19
|
+
coverage = coverage_data.values.first["coverage"]
|
20
|
+
|
21
|
+
find_dead_files(coverage)
|
22
|
+
find_low_coverage_files(coverage)
|
23
|
+
|
24
|
+
puts "\nπ‘ Next steps:"
|
25
|
+
puts " 1. Open coverage/index.html to see detailed line-by-line coverage"
|
26
|
+
puts " 2. Review uncovered files to see if they can be removed"
|
27
|
+
puts " 3. Look at uncovered methods in low-coverage files"
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def find_dead_files(coverage)
|
33
|
+
puts "\nπ¨ COMPLETELY UNCOVERED FILES (potential dead code):"
|
34
|
+
puts "=" * 60
|
35
|
+
|
36
|
+
dead_files = []
|
37
|
+
|
38
|
+
coverage.each do |file, line_data|
|
39
|
+
next unless file.include?("/lib/")
|
40
|
+
|
41
|
+
# Extract lines array from SimpleCov format
|
42
|
+
lines = line_data["lines"]
|
43
|
+
next unless lines
|
44
|
+
|
45
|
+
total_lines = lines.count { |hits| !hits.nil? }
|
46
|
+
covered_lines = lines.count { |hits| hits && hits > 0 }
|
47
|
+
|
48
|
+
if total_lines > 0 && covered_lines == 0
|
49
|
+
relative_path = file.sub("#{Dir.pwd}/", "")
|
50
|
+
dead_files << relative_path
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
if dead_files.empty?
|
55
|
+
puts "β
No completely uncovered files found!"
|
56
|
+
else
|
57
|
+
puts "Found #{dead_files.length} completely uncovered files:"
|
58
|
+
dead_files.sort.each { |f| puts " π #{f}" }
|
59
|
+
|
60
|
+
puts "\nβ οΈ These files are candidates for removal, but verify:"
|
61
|
+
puts " β’ Check if they're loaded via autoloading/zeitwerk"
|
62
|
+
puts " β’ Look for usage in examples/ or external code"
|
63
|
+
puts " β’ Consider if they're part of public API"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def find_low_coverage_files(coverage)
|
68
|
+
puts "\nπ LOW COVERAGE FILES (<20% - check for dead methods):"
|
69
|
+
puts "=" * 20
|
70
|
+
|
71
|
+
low_coverage = []
|
72
|
+
|
73
|
+
coverage.each do |file, line_data|
|
74
|
+
next unless file.include?("/lib/")
|
75
|
+
|
76
|
+
# Extract lines array from SimpleCov format
|
77
|
+
lines = line_data["lines"]
|
78
|
+
next unless lines
|
79
|
+
|
80
|
+
total_lines = lines.count { |hits| !hits.nil? }
|
81
|
+
covered_lines = lines.count { |hits| hits && hits > 0 }
|
82
|
+
|
83
|
+
next if total_lines == 0
|
84
|
+
|
85
|
+
coverage_percent = (covered_lines.to_f / total_lines * 100)
|
86
|
+
|
87
|
+
next unless coverage_percent > 0 && coverage_percent < 20
|
88
|
+
|
89
|
+
relative_path = file.sub("#{Dir.pwd}/", "")
|
90
|
+
low_coverage << {
|
91
|
+
file: relative_path,
|
92
|
+
percent: coverage_percent,
|
93
|
+
covered: covered_lines,
|
94
|
+
total: total_lines
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
if low_coverage.empty?
|
99
|
+
puts "β
No files with very low coverage found!"
|
100
|
+
else
|
101
|
+
low_coverage.sort_by { |f| f[:percent] }.each do |info|
|
102
|
+
printf " π %-50s %5.1f%% (%d/%d lines)\n",
|
103
|
+
info[:file], info[:percent], info[:covered], info[:total]
|
104
|
+
end
|
105
|
+
|
106
|
+
puts "\nπ‘ These files likely contain dead methods:"
|
107
|
+
puts " β’ Open coverage/index.html and click on these files"
|
108
|
+
puts " β’ Red lines are uncovered - potential dead code"
|
109
|
+
puts " β’ Look for entire uncovered methods/classes"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
SimpleDeadCodeFinder.new.run if __FILE__ == $0
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kumi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndrΓ© Muta
|
@@ -39,15 +39,18 @@ files:
|
|
39
39
|
- docs/DSL.md
|
40
40
|
- docs/FUNCTIONS.md
|
41
41
|
- docs/SYNTAX.md
|
42
|
+
- docs/compiler_design_principles.md
|
42
43
|
- docs/development/README.md
|
43
44
|
- docs/development/error-reporting.md
|
44
45
|
- docs/features/README.md
|
45
46
|
- docs/features/analysis-cascade-mutual-exclusion.md
|
46
47
|
- docs/features/analysis-type-inference.md
|
47
48
|
- docs/features/analysis-unsat-detection.md
|
48
|
-
- docs/features/
|
49
|
+
- docs/features/hierarchical-broadcasting.md
|
49
50
|
- docs/features/input-declaration-system.md
|
51
|
+
- docs/features/javascript-transpiler.md
|
50
52
|
- docs/features/performance.md
|
53
|
+
- docs/features/s-expression-printer.md
|
51
54
|
- docs/schema_metadata.md
|
52
55
|
- docs/schema_metadata/broadcasts.md
|
53
56
|
- docs/schema_metadata/cascades.md
|
@@ -65,7 +68,6 @@ files:
|
|
65
68
|
- examples/wide_schema_compilation_and_evaluation_benchmark.rb
|
66
69
|
- lib/kumi.rb
|
67
70
|
- lib/kumi/analyzer.rb
|
68
|
-
- lib/kumi/cli.rb
|
69
71
|
- lib/kumi/compiler.rb
|
70
72
|
- lib/kumi/core/analyzer/analysis_state.rb
|
71
73
|
- lib/kumi/core/analyzer/constant_evaluator.rb
|
@@ -83,7 +85,13 @@ files:
|
|
83
85
|
- lib/kumi/core/analyzer/passes/unsat_detector.rb
|
84
86
|
- lib/kumi/core/analyzer/passes/visitor_pass.rb
|
85
87
|
- lib/kumi/core/atom_unsat_solver.rb
|
88
|
+
- lib/kumi/core/cascade_executor_builder.rb
|
86
89
|
- lib/kumi/core/compiled_schema.rb
|
90
|
+
- lib/kumi/core/compiler/expression_compiler.rb
|
91
|
+
- lib/kumi/core/compiler/function_invoker.rb
|
92
|
+
- lib/kumi/core/compiler/path_traversal_compiler.rb
|
93
|
+
- lib/kumi/core/compiler/reference_compiler.rb
|
94
|
+
- lib/kumi/core/compiler_base.rb
|
87
95
|
- lib/kumi/core/constraint_relationship_solver.rb
|
88
96
|
- lib/kumi/core/domain/enum_analyzer.rb
|
89
97
|
- lib/kumi/core/domain/range_analyzer.rb
|
@@ -108,6 +116,7 @@ files:
|
|
108
116
|
- lib/kumi/core/function_registry/function_builder.rb
|
109
117
|
- lib/kumi/core/function_registry/logical_functions.rb
|
110
118
|
- lib/kumi/core/function_registry/math_functions.rb
|
119
|
+
- lib/kumi/core/function_registry/stat_functions.rb
|
111
120
|
- lib/kumi/core/function_registry/string_functions.rb
|
112
121
|
- lib/kumi/core/function_registry/type_functions.rb
|
113
122
|
- lib/kumi/core/input/type_matcher.rb
|
@@ -116,6 +125,7 @@ files:
|
|
116
125
|
- lib/kumi/core/json_schema.rb
|
117
126
|
- lib/kumi/core/json_schema/generator.rb
|
118
127
|
- lib/kumi/core/json_schema/validator.rb
|
128
|
+
- lib/kumi/core/nested_structure_utils.rb
|
119
129
|
- lib/kumi/core/ruby_parser.rb
|
120
130
|
- lib/kumi/core/ruby_parser/build_context.rb
|
121
131
|
- lib/kumi/core/ruby_parser/declaration_reference_proxy.rb
|
@@ -138,11 +148,15 @@ files:
|
|
138
148
|
- lib/kumi/core/types/inference.rb
|
139
149
|
- lib/kumi/core/types/normalizer.rb
|
140
150
|
- lib/kumi/core/types/validator.rb
|
141
|
-
- lib/kumi/core/
|
151
|
+
- lib/kumi/core/vectorized_function_builder.rb
|
142
152
|
- lib/kumi/errors.rb
|
153
|
+
- lib/kumi/js.rb
|
154
|
+
- lib/kumi/js/compiler.rb
|
155
|
+
- lib/kumi/js/function_registry.rb
|
143
156
|
- lib/kumi/registry.rb
|
144
157
|
- lib/kumi/schema.rb
|
145
158
|
- lib/kumi/schema_metadata.rb
|
159
|
+
- lib/kumi/support/s_expression_printer.rb
|
146
160
|
- lib/kumi/syntax/array_expression.rb
|
147
161
|
- lib/kumi/syntax/call_expression.rb
|
148
162
|
- lib/kumi/syntax/cascade_expression.rb
|
@@ -159,6 +173,10 @@ files:
|
|
159
173
|
- lib/kumi/syntax/value_declaration.rb
|
160
174
|
- lib/kumi/version.rb
|
161
175
|
- migrate_to_core_iterative.rb
|
176
|
+
- scripts/analyze_broadcast_methods.rb
|
177
|
+
- scripts/analyze_cascade_methods.rb
|
178
|
+
- scripts/check_broadcasting_coverage.rb
|
179
|
+
- scripts/find_dead_code.rb
|
162
180
|
- scripts/generate_function_docs.rb
|
163
181
|
homepage: https://github.com/amuta/kumi
|
164
182
|
licenses:
|