kumi 0.0.29 → 0.0.30

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.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -1
  3. data/CHANGELOG.md +12 -0
  4. data/README.md +5 -6
  5. data/docs/DEVELOPMENT.md +23 -1
  6. data/docs/GOLDEN_QUICK_START.md +141 -0
  7. data/docs/GOLDEN_TESTS.md +240 -0
  8. data/golden/array_element/expected/schema_ruby.rb +1 -1
  9. data/golden/array_index/expected/schema_ruby.rb +1 -1
  10. data/golden/array_operations/expected/schema_ruby.rb +1 -1
  11. data/golden/cascade_logic/expected/schema_ruby.rb +1 -1
  12. data/golden/chained_fusion/expected/schema_ruby.rb +1 -1
  13. data/golden/decimal_explicit/expected/schema_ruby.rb +1 -1
  14. data/golden/element_arrays/expected/schema_ruby.rb +1 -1
  15. data/golden/empty_and_null_inputs/expected/schema_ruby.rb +1 -1
  16. data/golden/function_overload/expected/schema_ruby.rb +1 -1
  17. data/golden/game_of_life/expected/schema_ruby.rb +1 -1
  18. data/golden/hash_keys/expected/schema_ruby.rb +1 -1
  19. data/golden/hash_value/expected/schema_ruby.rb +1 -1
  20. data/golden/hierarchical_complex/expected/schema_ruby.rb +1 -1
  21. data/golden/inline_rename_scope_leak/expected/schema_ruby.rb +1 -1
  22. data/golden/input_reference/expected/schema_ruby.rb +1 -1
  23. data/golden/interleaved_fusion/expected/schema_ruby.rb +1 -1
  24. data/golden/let_inline/expected/schema_ruby.rb +1 -1
  25. data/golden/loop_fusion/expected/schema_ruby.rb +1 -1
  26. data/golden/min_reduce_scope/expected/schema_ruby.rb +1 -1
  27. data/golden/mixed_dimensions/expected/schema_ruby.rb +1 -1
  28. data/golden/multirank_hoisting/expected/schema_ruby.rb +1 -1
  29. data/golden/nested_hash/expected/schema_ruby.rb +1 -1
  30. data/golden/reduction_broadcast/expected/schema_ruby.rb +1 -1
  31. data/golden/roll/expected/schema_ruby.rb +1 -1
  32. data/golden/shift/expected/schema_ruby.rb +1 -1
  33. data/golden/shift_2d/expected/schema_ruby.rb +1 -1
  34. data/golden/simple_math/expected/schema_ruby.rb +1 -1
  35. data/golden/streaming_basics/expected/schema_ruby.rb +1 -1
  36. data/golden/tuples/expected/schema_ruby.rb +1 -1
  37. data/golden/tuples_and_arrays/expected/schema_ruby.rb +1 -1
  38. data/golden/us_tax_2024/expected/schema_ruby.rb +1 -1
  39. data/golden/with_constants/expected/schema_ruby.rb +1 -1
  40. data/lib/kumi/analyzer.rb +39 -79
  41. data/lib/kumi/core/analyzer/analysis_state.rb +2 -0
  42. data/lib/kumi/core/analyzer/constant_evaluator.rb +0 -2
  43. data/lib/kumi/core/analyzer/execution_phase.rb +24 -0
  44. data/lib/kumi/core/analyzer/execution_result.rb +38 -0
  45. data/lib/kumi/core/analyzer/pass_failure.rb +26 -0
  46. data/lib/kumi/core/analyzer/pass_manager.rb +136 -0
  47. data/lib/kumi/core/analyzer/passes/codegen/js/declaration_emitter.rb +1 -1
  48. data/lib/kumi/core/analyzer/passes/codegen/js_pass.rb +1 -1
  49. data/lib/kumi/core/analyzer/passes/codegen/ruby/declaration_emitter.rb +1 -1
  50. data/lib/kumi/core/analyzer/passes/codegen/ruby_pass.rb +1 -1
  51. data/lib/kumi/core/analyzer/passes/constant_folding_pass.rb +1 -1
  52. data/lib/kumi/core/analyzer/passes/formal_constraint_propagator.rb +13 -31
  53. data/lib/kumi/core/analyzer/passes/input_access_planner_pass.rb +1 -1
  54. data/lib/kumi/core/analyzer/passes/input_collector.rb +1 -1
  55. data/lib/kumi/core/analyzer/passes/input_form_schema_pass.rb +1 -1
  56. data/lib/kumi/core/analyzer/passes/lir/loop_invariant_code_motion_pass.rb +1 -1
  57. data/lib/kumi/core/analyzer/passes/lir/stencil_emitter.rb +0 -2
  58. data/lib/kumi/core/analyzer/passes/normalize_to_nast_pass.rb +5 -1
  59. data/lib/kumi/core/analyzer/passes/output_schema_pass.rb +2 -1
  60. data/lib/kumi/core/analyzer/passes/snast_pass.rb +1 -1
  61. data/lib/kumi/core/analyzer/passes/unsat_detector.rb +8 -10
  62. data/lib/kumi/core/compiler/access_planner_v2.rb +1 -2
  63. data/lib/kumi/core/functions/overload_resolver.rb +15 -19
  64. data/lib/kumi/core/functions/type_categories.rb +3 -3
  65. data/lib/kumi/core/functions/type_error_reporter.rb +1 -3
  66. data/lib/kumi/core/input/type_matcher.rb +1 -1
  67. data/lib/kumi/core/types/normalizer.rb +8 -10
  68. data/lib/kumi/core/types/validator.rb +1 -1
  69. data/lib/kumi/core/types/value_objects.rb +5 -2
  70. data/lib/kumi/core/types.rb +2 -4
  71. data/lib/kumi/dev/codegen.rb +1 -1
  72. data/lib/kumi/dev/golden/generator.rb +14 -10
  73. data/lib/kumi/dev/golden/reporter.rb +5 -5
  74. data/lib/kumi/dev/golden/representation.rb +1 -3
  75. data/lib/kumi/dev/golden/result.rb +1 -1
  76. data/lib/kumi/dev/golden/runtime_test.rb +0 -2
  77. data/lib/kumi/dev/golden/suite.rb +20 -4
  78. data/lib/kumi/dev/golden/value_normalizer.rb +1 -3
  79. data/lib/kumi/doc_generator/formatters/json.rb +11 -11
  80. data/lib/kumi/doc_generator/formatters/markdown.rb +35 -37
  81. data/lib/kumi/doc_generator/loader.rb +8 -6
  82. data/lib/kumi/doc_generator/merger.rb +12 -12
  83. data/lib/kumi/frontends/text.rb +4 -6
  84. data/lib/kumi/registry_v2/loader.rb +32 -33
  85. data/lib/kumi/schema.rb +2 -2
  86. data/lib/kumi/version.rb +1 -1
  87. metadata +13 -14
  88. data/debug_ordering.rb +0 -52
  89. data/examples/deep_schema_compilation_and_evaluation_benchmark.rb +0 -106
  90. data/examples/federal_tax_calculator_2024.rb +0 -115
  91. data/examples/game_of_life.rb +0 -95
  92. data/examples/simple_rpg_game.rb +0 -1000
  93. data/examples/static_analysis_errors.rb +0 -178
  94. data/examples/wide_schema_compilation_and_evaluation_benchmark.rb +0 -80
@@ -5,7 +5,7 @@ module Kumi
5
5
  module Analyzer
6
6
  module Passes
7
7
  class InputFormSchemaPass < PassBase
8
- def run(errors)
8
+ def run(_errors)
9
9
  input_metadata = get_state(:input_metadata)
10
10
  return state unless input_metadata
11
11
 
@@ -97,7 +97,7 @@ module Kumi
97
97
  new_ops
98
98
  end
99
99
 
100
- def is_invariant(ins, defs_in_loop, prefix, depth)
100
+ def is_invariant(ins, defs_in_loop, prefix, _depth)
101
101
  prefix_inner = "#{prefix} "
102
102
  debug "#{prefix_inner}- Checking: #{ins.result_register || '(no result)'} = #{ins.opcode}(#{ins.inputs.join(', ')})"
103
103
 
@@ -231,8 +231,6 @@ module Kumi
231
231
  when NAST::Ref
232
232
  decl = @snast.decls.fetch(node.name) { return nil }
233
233
  resolve_call(decl.body)
234
- else
235
- nil
236
234
  end
237
235
  end
238
236
  end
@@ -80,7 +80,11 @@ module Kumi
80
80
  # Try to get the function to check if it's expandable
81
81
  # For expandable functions, we need to resolve now
82
82
  # For regular functions, we defer resolution to NASTDimensionalAnalyzerPass
83
- func = @registry.function(fn_alias) rescue nil
83
+ func = begin
84
+ @registry.function(fn_alias)
85
+ rescue StandardError
86
+ nil
87
+ end
84
88
  rescue StandardError
85
89
  # puts "MISSING_FUNCTION: #{node.fn_name.inspect}"
86
90
  raise
@@ -5,7 +5,7 @@ module Kumi
5
5
  module Analyzer
6
6
  module Passes
7
7
  class OutputSchemaPass < PassBase
8
- def run(errors)
8
+ def run(_errors)
9
9
  snast_module = get_state(:snast_module)
10
10
  return state unless snast_module
11
11
 
@@ -19,6 +19,7 @@ module Kumi
19
19
  def build_output_schema(snast_module, hints)
20
20
  snast_module.decls.each_with_object({}) do |(name, decl), acc|
21
21
  next if hints[name][:inline]
22
+
22
23
  acc[name] = build_output_field(decl)
23
24
  end
24
25
  end
@@ -176,7 +176,7 @@ module Kumi
176
176
  m = meta_for(n)
177
177
  # Use the function ID from metadata (already resolved with type awareness in NASTDimensionalAnalyzerPass)
178
178
  fn_id = m[:function] || @registry.resolve_function(n.fn)
179
- out = n.class.new(id: n.id, fn: fn_id.to_sym, args:, opts: n.opts, loc: n.loc)
179
+ out = n.class.new(id: n.id, fn: fn_id.to_sym, args:, opts: n.opts, loc: n.loc)
180
180
  stamp!(out, m[:result_scope], m[:result_type])
181
181
  end
182
182
 
@@ -32,14 +32,14 @@ module Kumi
32
32
  next if atoms.empty?
33
33
 
34
34
  # Check for formal, obvious contradictions
35
- if contradicting_equalities?(atoms) || domain_violations?(atoms, input_meta) ||
36
- propagated_violations?(atoms, definitions, input_meta, registry)
37
- report_error(
38
- errors,
39
- "conjunction `#{decl.name}` is impossible",
40
- location: decl.loc
41
- )
42
- end
35
+ next unless contradicting_equalities?(atoms) || domain_violations?(atoms, input_meta) ||
36
+ propagated_violations?(atoms, definitions, input_meta, registry)
37
+
38
+ report_error(
39
+ errors,
40
+ "conjunction `#{decl.name}` is impossible",
41
+ location: decl.loc
42
+ )
43
43
  end
44
44
 
45
45
  state
@@ -90,8 +90,6 @@ module Kumi
90
90
  val == :unknown ? node.name : val
91
91
  when InputReference
92
92
  node.name
93
- else
94
- nil
95
93
  end
96
94
  end
97
95
 
@@ -29,8 +29,7 @@ module Kumi
29
29
  axes << root_name.to_sym
30
30
  end
31
31
 
32
- # Emit normal plan for the root node
33
- node_axes = [] # The root axes are always [], e.g. array :x (the container :x opens [:x], but is not inside that dim)
32
+ # Emit normal plan for the root node # The root axes are always [], e.g. array :x (the container :x opens [:x], but is not inside that dim)
34
33
  walk([root_name.to_s], node, steps, axes, steps, [])
35
34
 
36
35
  # If the root array defines an index, emit a *synthetic* index plan now
@@ -31,13 +31,12 @@ module Kumi
31
31
  validate_arity!(s, arg_types)
32
32
  fn = @functions[s]
33
33
  score = match_score(fn.params, arg_types)
34
- if score > 0
35
- return s
36
- else
37
- # Type constraints failed
38
- raise ResolutionError,
39
- "#{alias_or_id}(#{format_types(arg_types)}) - type mismatch"
40
- end
34
+ return s if score > 0
35
+
36
+ # Type constraints failed
37
+ raise ResolutionError,
38
+ "#{alias_or_id}(#{format_types(arg_types)}) - type mismatch"
39
+
41
40
  end
42
41
 
43
42
  # Get all candidate overloads for this alias
@@ -50,13 +49,12 @@ module Kumi
50
49
  validate_arity!(fn_id, arg_types)
51
50
  fn = @functions[fn_id]
52
51
  score = match_score(fn.params, arg_types)
53
- if score > 0
54
- return fn_id
55
- else
56
- # Type constraints failed for the only overload
57
- raise ResolutionError,
58
- "#{alias_or_id}(#{format_types(arg_types)}) - type mismatch"
59
- end
52
+ return fn_id if score > 0
53
+
54
+ # Type constraints failed for the only overload
55
+ raise ResolutionError,
56
+ "#{alias_or_id}(#{format_types(arg_types)}) - type mismatch"
57
+
60
58
  end
61
59
 
62
60
  # Multiple overloads - find best match by type constraints (prefer exact matches)
@@ -68,9 +66,7 @@ module Kumi
68
66
 
69
67
  best_match, score = candidates_with_scores.max_by { |_, s| s }
70
68
 
71
- if score > 0
72
- return best_match
73
- end
69
+ return best_match if score > 0
74
70
 
75
71
  # No match found - provide helpful error
76
72
  raise ResolutionError,
@@ -134,6 +130,7 @@ module Kumi
134
130
  # Check if it's a type category
135
131
  if TypeCategories.category?(constraint)
136
132
  return false unless type_obj.is_a?(Kumi::Core::Types::ScalarType)
133
+
137
134
  return TypeCategories.includes?(constraint, type_obj.kind)
138
135
  end
139
136
 
@@ -160,6 +157,7 @@ module Kumi
160
157
  # Check if it's a type category
161
158
  if TypeCategories.category?(param_dtype_str)
162
159
  return false unless arg_type.is_a?(Kumi::Core::Types::ScalarType)
160
+
163
161
  return TypeCategories.includes?(param_dtype_str, arg_type.kind)
164
162
  end
165
163
 
@@ -189,8 +187,6 @@ module Kumi
189
187
  "function #{fn_id} expects #{fn.params.size} arguments, got #{arg_types.size}"
190
188
  end
191
189
 
192
- private
193
-
194
190
  def format_types(arg_types)
195
191
  arg_types.map(&:to_s).join(", ")
196
192
  end
@@ -9,11 +9,11 @@ module Kumi
9
9
  class TypeCategories
10
10
  # Define type categories as unions of scalar kinds
11
11
  CATEGORIES = {
12
- numeric: [:integer, :float, :decimal],
13
- comparable: [:integer, :float, :decimal, :string],
12
+ numeric: %i[integer float decimal],
13
+ comparable: %i[integer float decimal string],
14
14
  boolean: [:boolean],
15
15
  stringable: [:string],
16
- orderable: [:integer, :float, :decimal, :string]
16
+ orderable: %i[integer float decimal string]
17
17
  }.freeze
18
18
 
19
19
  def self.expand(dtype_constraint)
@@ -103,14 +103,12 @@ module Kumi
103
103
  error
104
104
  end
105
105
 
106
- private
107
-
108
106
  def self.format_overload_error(alias_or_id, arg_types, available_overloads)
109
107
  arg_types_str = arg_types.map(&:inspect).join(", ")
110
108
  available_str = available_overloads.map { |id| "'#{id}'" }.join(", ")
111
109
 
112
110
  "no overload of '#{alias_or_id}' matches argument types (#{arg_types_str}). " \
113
- "Available overloads: #{available_str}"
111
+ "Available overloads: #{available_str}"
114
112
  end
115
113
  end
116
114
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bigdecimal'
3
+ require "bigdecimal"
4
4
 
5
5
  module Kumi
6
6
  module Core
@@ -14,18 +14,16 @@ module Kumi
14
14
  # Already a Type object, return as-is
15
15
  type_input
16
16
  when Symbol
17
- if Validator.valid_kind?(type_input)
18
- Kumi::Core::Types.scalar(type_input)
19
- else
20
- raise ArgumentError, "Invalid type symbol: #{type_input}"
21
- end
17
+ raise ArgumentError, "Invalid type symbol: #{type_input}" unless Validator.valid_kind?(type_input)
18
+
19
+ Kumi::Core::Types.scalar(type_input)
20
+
22
21
  when String
23
22
  symbol_type = type_input.to_sym
24
- if Validator.valid_kind?(symbol_type)
25
- Kumi::Core::Types.scalar(symbol_type)
26
- else
27
- raise ArgumentError, "Invalid type string: #{type_input}"
28
- end
23
+ raise ArgumentError, "Invalid type string: #{type_input}" unless Validator.valid_kind?(symbol_type)
24
+
25
+ Kumi::Core::Types.scalar(symbol_type)
26
+
29
27
  when Hash
30
28
  raise ArgumentError, "Hash-based types no longer supported, use Type objects instead"
31
29
  when Class
@@ -20,7 +20,7 @@ module Kumi
20
20
  when ScalarType
21
21
  valid_kind?(type.kind)
22
22
  when ArrayType, TupleType
23
- true # If constructed, it's valid
23
+ true # If constructed, it's valid
24
24
  when Symbol
25
25
  valid_kind?(type)
26
26
  else
@@ -36,6 +36,7 @@ module Kumi
36
36
 
37
37
  def ==(other)
38
38
  return false unless other.is_a?(ScalarType)
39
+
39
40
  @kind == other.kind
40
41
  end
41
42
 
@@ -61,11 +62,12 @@ module Kumi
61
62
  end
62
63
 
63
64
  def inspect
64
- "#<ArrayType:#{to_s}>"
65
+ "#<ArrayType:#{self}>"
65
66
  end
66
67
 
67
68
  def ==(other)
68
69
  return false unless other.is_a?(ArrayType)
70
+
69
71
  @element_type == other.element_type
70
72
  end
71
73
 
@@ -91,11 +93,12 @@ module Kumi
91
93
  end
92
94
 
93
95
  def inspect
94
- "#<TupleType:#{to_s}>"
96
+ "#<TupleType:#{self}>"
95
97
  end
96
98
 
97
99
  def ==(other)
98
100
  return false unless other.is_a?(TupleType)
101
+
99
102
  @element_types == other.element_types
100
103
  end
101
104
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'types/value_objects'
3
+ require_relative "types/value_objects"
4
4
 
5
5
  module Kumi
6
6
  module Core
@@ -44,9 +44,7 @@ module Kumi
44
44
  end
45
45
 
46
46
  def self.tuple(element_types)
47
- unless element_types.is_a?(Array)
48
- raise ArgumentError, "tuple expects array of Type objects, got #{element_types.class}"
49
- end
47
+ raise ArgumentError, "tuple expects array of Type objects, got #{element_types.class}" unless element_types.is_a?(Array)
50
48
 
51
49
  # Convert any non-Type elements to Type objects
52
50
  converted = element_types.map do |t|
@@ -110,7 +110,7 @@ module Kumi
110
110
  schema, = Kumi::Frontends.load(path: schema_path)
111
111
  result = Kumi::Analyzer.analyze!(schema)
112
112
 
113
- code = result.state[:ruby_codegen_files]["codegen.rb"]
113
+ result.state[:ruby_codegen_files]["codegen.rb"]
114
114
 
115
115
  File.write("#{output_dir}/schema_ruby.rb", ruby_code)
116
116
  puts " ✓ Ruby code generated"
@@ -34,11 +34,13 @@ module Kumi
34
34
 
35
35
  def update_representation(repr)
36
36
  output = generate_output(repr)
37
- return GenerationResult.new(
38
- schema_name: schema_name,
39
- representation: repr.name,
40
- status: :skipped
41
- ) unless output
37
+ unless output
38
+ return GenerationResult.new(
39
+ schema_name: schema_name,
40
+ representation: repr.name,
41
+ status: :skipped
42
+ )
43
+ end
42
44
 
43
45
  expected_file = File.join(expected_dir, repr.filename)
44
46
 
@@ -73,11 +75,13 @@ module Kumi
73
75
 
74
76
  def generate_representation(repr, output_dir)
75
77
  output = generate_output(repr)
76
- return GenerationResult.new(
77
- schema_name: schema_name,
78
- representation: repr.name,
79
- status: :skipped
80
- ) unless output
78
+ unless output
79
+ return GenerationResult.new(
80
+ schema_name: schema_name,
81
+ representation: repr.name,
82
+ status: :skipped
83
+ )
84
+ end
81
85
 
82
86
  output_file = File.join(output_dir, repr.filename)
83
87
  File.write(output_file, output)
@@ -79,11 +79,11 @@ module Kumi
79
79
  def report_diff(results_by_schema)
80
80
  results_by_schema.each do |schema_name, results|
81
81
  results.each do |result|
82
- if result.failed? && result.diff
83
- puts "=== #{schema_name}/#{result.representation}.* ==="
84
- puts result.diff
85
- puts
86
- end
82
+ next unless result.failed? && result.diff
83
+
84
+ puts "=== #{schema_name}/#{result.representation}.* ==="
85
+ puts result.diff
86
+ puts
87
87
  end
88
88
  end
89
89
  end
@@ -17,9 +17,7 @@ module Kumi
17
17
  end
18
18
 
19
19
  def generate(schema_path)
20
- unless PrettyPrinter.respond_to?(generator_method)
21
- raise "Unknown generator method: #{generator_method}"
22
- end
20
+ raise "Unknown generator method: #{generator_method}" unless PrettyPrinter.respond_to?(generator_method)
23
21
 
24
22
  PrettyPrinter.send(generator_method, schema_path)
25
23
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'value_normalizer'
3
+ require_relative "value_normalizer"
4
4
 
5
5
  module Kumi
6
6
  module Dev
@@ -77,8 +77,6 @@ module Kumi
77
77
  decl_names.to_h { |name| [name, instance[name.to_sym]] }
78
78
  end
79
79
 
80
- private
81
-
82
80
  def convert_decimal_strings(value)
83
81
  case value
84
82
  when Hash
@@ -16,25 +16,41 @@ module Kumi
16
16
  end
17
17
 
18
18
  def update(name = nil)
19
- names = name ? (name.is_a?(Array) ? name : [name]) : schema_names
19
+ names = if name
20
+ name.is_a?(Array) ? name : [name]
21
+ else
22
+ schema_names
23
+ end
20
24
  results = update_schemas(names)
21
25
  Reporter.new.report_update(results)
22
26
  end
23
27
 
24
28
  def verify(name = nil)
25
- names = name ? (name.is_a?(Array) ? name : [name]) : schema_names
29
+ names = if name
30
+ name.is_a?(Array) ? name : [name]
31
+ else
32
+ schema_names
33
+ end
26
34
  results = verify_schemas(names)
27
35
  Reporter.new.report_verify(results)
28
36
  end
29
37
 
30
38
  def diff(name = nil)
31
- names = name ? (name.is_a?(Array) ? name : [name]) : schema_names
39
+ names = if name
40
+ name.is_a?(Array) ? name : [name]
41
+ else
42
+ schema_names
43
+ end
32
44
  results = diff_schemas(names)
33
45
  Reporter.new.report_diff(results)
34
46
  end
35
47
 
36
48
  def test(name = nil)
37
- names = name ? (name.is_a?(Array) ? name : [name]) : schema_names
49
+ names = if name
50
+ name.is_a?(Array) ? name : [name]
51
+ else
52
+ schema_names
53
+ end
38
54
 
39
55
  update_schemas(names)
40
56
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bigdecimal'
3
+ require "bigdecimal"
4
4
 
5
5
  module Kumi
6
6
  module Dev
@@ -32,8 +32,6 @@ module Kumi
32
32
  compare_values(norm_actual, norm_expected, language: language)
33
33
  end
34
34
 
35
- private
36
-
37
35
  def self.decimal_string?(str)
38
36
  # Match decimal number strings like "10.50", "123", "-45.67"
39
37
  str.match?(/\A-?\d+(\.\d+)?\z/)
@@ -1,4 +1,4 @@
1
- require 'json'
1
+ require "json"
2
2
 
3
3
  module Kumi
4
4
  module DocGenerator
@@ -10,16 +10,16 @@ module Kumi
10
10
 
11
11
  def format
12
12
  enriched = @docs.each_with_object({}) do |(alias_name, entry), acc|
13
- kernel_ids = extract_kernel_ids(entry['kernels'])
13
+ kernel_ids = extract_kernel_ids(entry["kernels"])
14
14
  acc[alias_name] = {
15
- 'id' => entry['id'],
16
- 'kind' => entry['kind'],
17
- 'arity' => entry['arity'],
18
- 'params' => entry['params'],
19
- 'kernels' => kernel_ids,
20
- 'dtype' => entry['dtype'],
21
- 'aliases' => entry['aliases'],
22
- 'reduction_strategy' => entry['reduction_strategy']
15
+ "id" => entry["id"],
16
+ "kind" => entry["kind"],
17
+ "arity" => entry["arity"],
18
+ "params" => entry["params"],
19
+ "kernels" => kernel_ids,
20
+ "dtype" => entry["dtype"],
21
+ "aliases" => entry["aliases"],
22
+ "reduction_strategy" => entry["reduction_strategy"]
23
23
  }
24
24
  end
25
25
 
@@ -30,7 +30,7 @@ module Kumi
30
30
 
31
31
  def extract_kernel_ids(kernels)
32
32
  kernels.each_with_object({}) do |(target, kernel), acc|
33
- acc[target] = kernel.is_a?(Hash) ? kernel['id'] : kernel
33
+ acc[target] = kernel.is_a?(Hash) ? kernel["id"] : kernel
34
34
  end
35
35
  end
36
36
  end