t-ruby 0.0.39 → 0.0.40

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64bc7ea0ab44e83d6580d07227fee508ae3b5e53bc0e6b19b8164857eaf31376
4
- data.tar.gz: 01da8585df97030974563634d8212058a3d3325ca9bc05188ae12ccf1cdc6770
3
+ metadata.gz: 54f0b9008d5a42a8cbf851eac8a0eb540670c3c87018dd87182baf6ab30c7d55
4
+ data.tar.gz: 42929dd91ae55ea84e75fd6978298deea2fec1d3517a801bde06af6f70865557
5
5
  SHA512:
6
- metadata.gz: b0bf9cd9518368e5ef256dd1851285fbbb78404b16c837346ecb286bfde37d2b8f8f5738782629efb5507fb7419eaea197726ae85f1ccb9481c09abc26d80a7f
7
- data.tar.gz: 67de07897cec9ef86c5df0798c4f2d44e1d54da0d8bfe799386eb544c28a4c0d5595f17dcc0c0bbc4236a44c17e76f1283fc75a9cd4452cee40f34daa86ef609
6
+ metadata.gz: 20916cbdb9a4d62bd9208c8496df8e8f425885c600d5caa9ef0d5a545c4d52a62fa66d05157bfc89a0c57328658f6ecb08889336352e76b4cfb757518365f50b
7
+ data.tar.gz: b6125521d066808e825747418d794ca6adb94503e7d89b61fe5a9bb009e2c2fcc49952b0ea3fd12f5c0bb51de9d20de0ff3a7b4f0ab37358d0616010e1f9ca55
@@ -7,16 +7,17 @@ module TRuby
7
7
  # \p{L} matches any Unicode letter, \p{N} matches any Unicode number
8
8
  IDENTIFIER_CHAR = '[\p{L}\p{N}_]'
9
9
  METHOD_NAME_PATTERN = "#{IDENTIFIER_CHAR}+[?!]?".freeze
10
+ # Visibility modifiers for method definitions
11
+ VISIBILITY_PATTERN = '(?:(?:private|protected|public)\s+)?'
10
12
 
11
13
  class Compiler
12
- attr_reader :declaration_loader, :use_ir, :optimizer
14
+ attr_reader :declaration_loader, :optimizer
13
15
 
14
- def initialize(config = nil, use_ir: true, optimize: true)
16
+ def initialize(config = nil, optimize: true)
15
17
  @config = config || Config.new
16
- @use_ir = use_ir
17
18
  @optimize = optimize
18
19
  @declaration_loader = DeclarationLoader.new
19
- @optimizer = IR::Optimizer.new if use_ir && optimize
20
+ @optimizer = IR::Optimizer.new if optimize
20
21
  @type_inferrer = ASTTypeInferrer.new if type_check?
21
22
  setup_declaration_paths if @config
22
23
  end
@@ -42,16 +43,16 @@ module TRuby
42
43
  source = File.read(input_path)
43
44
 
44
45
  # Parse with IR support
45
- parser = Parser.new(source, use_combinator: @use_ir)
46
- parse_result = parser.parse
46
+ parser = Parser.new(source)
47
+ parser.parse
47
48
 
48
49
  # Run type checking if enabled
49
- if type_check? && @use_ir && parser.ir_program
50
+ if type_check? && parser.ir_program
50
51
  check_types(parser.ir_program, input_path)
51
52
  end
52
53
 
53
54
  # Transform source to Ruby code
54
- output = @use_ir ? transform_with_ir(source, parser) : transform_legacy(source, parse_result)
55
+ output = transform_with_ir(source, parser)
55
56
 
56
57
  # Compute output path (respects preserve_structure setting)
57
58
  output_path = compute_output_path(input_path, @config.ruby_dir, ".rb")
@@ -63,11 +64,7 @@ module TRuby
63
64
  if @config.compiler["generate_rbs"]
64
65
  rbs_path = compute_output_path(input_path, @config.rbs_dir, ".rbs")
65
66
  FileUtils.mkdir_p(File.dirname(rbs_path))
66
- if @use_ir && parser.ir_program
67
- generate_rbs_from_ir_to_path(rbs_path, parser.ir_program)
68
- else
69
- generate_rbs_file_to_path(rbs_path, parse_result)
70
- end
67
+ generate_rbs_from_ir_to_path(rbs_path, parser.ir_program)
71
68
  end
72
69
 
73
70
  # Generate .d.trb file if enabled in config (legacy support)
@@ -87,25 +84,17 @@ module TRuby
87
84
  def compile_string(source, options = {})
88
85
  generate_rbs = options.fetch(:rbs, true)
89
86
 
90
- parser = Parser.new(source, use_combinator: @use_ir)
91
- parse_result = parser.parse
87
+ parser = Parser.new(source)
88
+ parser.parse
92
89
 
93
90
  # Transform source to Ruby code
94
- ruby_output = @use_ir ? transform_with_ir(source, parser) : transform_legacy(source, parse_result)
91
+ ruby_output = transform_with_ir(source, parser)
95
92
 
96
93
  # Generate RBS if requested
97
94
  rbs_output = ""
98
- if generate_rbs
99
- if @use_ir && parser.ir_program
100
- generator = IR::RBSGenerator.new
101
- rbs_output = generator.generate(parser.ir_program)
102
- else
103
- generator = RBSGenerator.new
104
- rbs_output = generator.generate(
105
- parse_result[:functions] || [],
106
- parse_result[:type_aliases] || []
107
- )
108
- end
95
+ if generate_rbs && parser.ir_program
96
+ generator = IR::RBSGenerator.new
97
+ rbs_output = generator.generate(parser.ir_program)
109
98
  end
110
99
 
111
100
  {
@@ -134,7 +123,7 @@ module TRuby
134
123
  end
135
124
 
136
125
  source = File.read(input_path)
137
- parser = Parser.new(source, use_combinator: true)
126
+ parser = Parser.new(source)
138
127
  parser.parse
139
128
  parser.ir_program
140
129
  end
@@ -380,10 +369,10 @@ module TRuby
380
369
  @declaration_loader.add_search_path("./lib/types")
381
370
  end
382
371
 
383
- # Transform using IR system (new approach)
372
+ # Transform using IR system
384
373
  def transform_with_ir(source, parser)
385
374
  ir_program = parser.ir_program
386
- return transform_legacy(source, parser.parse) unless ir_program
375
+ return source unless ir_program
387
376
 
388
377
  # Run optimization passes if enabled
389
378
  if @optimize && @optimizer
@@ -396,33 +385,15 @@ module TRuby
396
385
  generator.generate_with_source(ir_program, source)
397
386
  end
398
387
 
399
- # Legacy transformation using TypeErasure (backward compatible)
400
- def transform_legacy(source, parse_result)
401
- if parse_result[:type] == :success
402
- eraser = TypeErasure.new(source)
403
- eraser.erase
404
- else
405
- source
406
- end
407
- end
408
-
409
388
  # Generate RBS from IR to a specific path
410
389
  def generate_rbs_from_ir_to_path(rbs_path, ir_program)
390
+ return unless ir_program
391
+
411
392
  generator = IR::RBSGenerator.new
412
393
  rbs_content = generator.generate(ir_program)
413
394
  File.write(rbs_path, rbs_content) unless rbs_content.strip.empty?
414
395
  end
415
396
 
416
- # Legacy RBS generation to a specific path
417
- def generate_rbs_file_to_path(rbs_path, parse_result)
418
- generator = RBSGenerator.new
419
- rbs_content = generator.generate(
420
- parse_result[:functions] || [],
421
- parse_result[:type_aliases] || []
422
- )
423
- File.write(rbs_path, rbs_content) unless rbs_content.empty?
424
- end
425
-
426
397
  def generate_dtrb_file(input_path, out_dir)
427
398
  dtrb_path = compute_output_path(input_path, out_dir, DeclarationGenerator::DECLARATION_EXTENSION)
428
399
  FileUtils.mkdir_p(File.dirname(dtrb_path))
@@ -511,7 +482,8 @@ module TRuby
511
482
  result = source.dup
512
483
 
513
484
  # Match function definitions and remove type annotations from parameters
514
- result.gsub!(/^(\s*def\s+#{TRuby::METHOD_NAME_PATTERN}\s*\()([^)]+)(\)\s*)(?::\s*[^\n]+)?(\s*$)/) do |_match|
485
+ # Also supports visibility modifiers: private def, protected def, public def
486
+ result.gsub!(/^(\s*#{TRuby::VISIBILITY_PATTERN}def\s+#{TRuby::METHOD_NAME_PATTERN}\s*\()([^)]+)(\)\s*)(?::\s*[^\n]+)?(\s*$)/) do |_match|
515
487
  indent = ::Regexp.last_match(1)
516
488
  params = ::Regexp.last_match(2)
517
489
  close_paren = ::Regexp.last_match(3)
@@ -558,10 +530,13 @@ module TRuby
558
530
  params.join(", ")
559
531
  end
560
532
 
561
- # Clean a single parameter (remove type annotation)
533
+ # Clean a single parameter (remove type annotation, preserve default value)
562
534
  def clean_param(param)
563
- # Match: name: Type or name (supports Unicode identifiers)
564
- if (match = param.match(/^(#{TRuby::IDENTIFIER_CHAR}+)\s*:/))
535
+ # Match: name: Type = value (with default value)
536
+ if (match = param.match(/^(#{TRuby::IDENTIFIER_CHAR}+)\s*:\s*.+?\s*(=\s*.+)$/))
537
+ "#{match[1]} #{match[2]}"
538
+ # Match: name: Type (without default value)
539
+ elsif (match = param.match(/^(#{TRuby::IDENTIFIER_CHAR}+)\s*:/))
565
540
  match[1]
566
541
  else
567
542
  param
@@ -580,11 +555,4 @@ module TRuby
580
555
  result
581
556
  end
582
557
  end
583
-
584
- # Legacy Compiler for backward compatibility (no IR)
585
- class LegacyCompiler < Compiler
586
- def initialize(config)
587
- super(config, use_ir: false, optimize: false)
588
- end
589
- end
590
558
  end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TRuby
4
+ # Detects regions that should be skipped during parsing:
5
+ # - Heredoc content
6
+ # - Block comments (=begin/=end)
7
+ class HeredocDetector
8
+ # Heredoc start patterns:
9
+ # <<IDENTIFIER, <<-IDENTIFIER, <<~IDENTIFIER
10
+ # <<'IDENTIFIER', <<"IDENTIFIER"
11
+ HEREDOC_START_PATTERN = /<<([~-])?(['"]?)(\w+)\2/
12
+
13
+ # Detect all skippable ranges in lines (heredocs and block comments)
14
+ # @param lines [Array<String>] source lines
15
+ # @return [Array<Range>] content ranges to skip (0-indexed)
16
+ def self.detect(lines)
17
+ ranges = []
18
+ i = 0
19
+
20
+ while i < lines.length
21
+ line = lines[i]
22
+
23
+ # Check for =begin block comment
24
+ if line.strip == "=begin"
25
+ start_line = i
26
+ i += 1
27
+
28
+ # Find =end
29
+ while i < lines.length
30
+ break if lines[i].strip == "=end"
31
+
32
+ i += 1
33
+ end
34
+
35
+ # Range covers from =begin to =end (inclusive)
36
+ ranges << (start_line..i) if i < lines.length
37
+ # Check for heredoc
38
+ elsif (match = line.match(HEREDOC_START_PATTERN))
39
+ delimiter = match[3]
40
+ squiggly = match[1] == "~"
41
+ start_line = i
42
+ i += 1
43
+
44
+ # Find closing delimiter
45
+ while i < lines.length
46
+ # For squiggly heredoc or dash heredoc, delimiter can be indented
47
+ # For regular heredoc, delimiter must be at line start
48
+ if squiggly || match[1] == "-"
49
+ break if lines[i].strip == delimiter
50
+ elsif lines[i].chomp == delimiter
51
+ break
52
+ end
53
+ i += 1
54
+ end
55
+
56
+ # Range covers content lines (after start, up to and including end delimiter)
57
+ ranges << ((start_line + 1)..i) if i < lines.length
58
+ end
59
+
60
+ i += 1
61
+ end
62
+
63
+ ranges
64
+ end
65
+
66
+ # Check if a line index is inside any skippable region
67
+ # @param line_index [Integer] line index to check
68
+ # @param heredoc_ranges [Array<Range>] ranges from detect()
69
+ # @return [Boolean]
70
+ def self.inside_heredoc?(line_index, heredoc_ranges)
71
+ heredoc_ranges.any? { |range| range.include?(line_index) }
72
+ end
73
+ end
74
+ end
data/lib/t_ruby/ir.rb CHANGED
@@ -778,7 +778,8 @@ module TRuby
778
778
  name: info[:name],
779
779
  params: params,
780
780
  return_type: info[:return_type] ? parse_type(info[:return_type]) : nil,
781
- body: body
781
+ body: body,
782
+ visibility: info[:visibility] || :public
782
783
  )
783
784
  end
784
785
 
@@ -1051,7 +1052,8 @@ module TRuby
1051
1052
  end
1052
1053
 
1053
1054
  return_type ||= "untyped"
1054
- emit("def #{node.name}: (#{params}) -> #{return_type}")
1055
+ visibility_prefix = format_visibility(node.visibility)
1056
+ emit("#{visibility_prefix}def #{node.name}: (#{params}) -> #{return_type}")
1055
1057
  end
1056
1058
 
1057
1059
  def visit_class_decl(node)
@@ -1092,6 +1094,17 @@ module TRuby
1092
1094
  def emit(text)
1093
1095
  @output << ((" " * @indent) + text)
1094
1096
  end
1097
+
1098
+ def format_visibility(visibility)
1099
+ # RBS only supports private visibility, not protected
1100
+ # See: https://github.com/ruby/rbs/issues/579
1101
+ case visibility
1102
+ when :private
1103
+ "private "
1104
+ else
1105
+ ""
1106
+ end
1107
+ end
1095
1108
  end
1096
1109
 
1097
1110
  #==========================================================================
@@ -787,7 +787,7 @@ module TRuby
787
787
  lines = text.split("\n")
788
788
 
789
789
  # Parse the document to get IR
790
- parser = Parser.new(text, use_combinator: true)
790
+ parser = Parser.new(text)
791
791
  parse_result = parser.parse
792
792
  parser.ir_program
793
793
 
data/lib/t_ruby/parser.rb CHANGED
@@ -12,15 +12,16 @@ module TRuby
12
12
  IDENTIFIER_CHAR = '[\p{L}\p{N}_]'
13
13
  # Method names can end with ? or !
14
14
  METHOD_NAME_PATTERN = "#{IDENTIFIER_CHAR}+[?!]?".freeze
15
+ # Visibility modifiers for method definitions
16
+ VISIBILITY_PATTERN = '(?:(?:private|protected|public)\s+)?'
15
17
 
16
- attr_reader :source, :ir_program, :use_combinator
18
+ attr_reader :source, :ir_program
17
19
 
18
- def initialize(source, use_combinator: true, parse_body: true)
20
+ def initialize(source, parse_body: true)
19
21
  @source = source
20
22
  @lines = source.split("\n")
21
- @use_combinator = use_combinator
22
23
  @parse_body = parse_body
23
- @type_parser = ParserCombinator::TypeParser.new if use_combinator
24
+ @type_parser = ParserCombinator::TypeParser.new
24
25
  @body_parser = BodyParser.new if parse_body
25
26
  @ir_program = nil
26
27
  end
@@ -32,7 +33,16 @@ module TRuby
32
33
  classes = []
33
34
  i = 0
34
35
 
36
+ # Pre-detect heredoc regions to skip
37
+ heredoc_ranges = HeredocDetector.detect(@lines)
38
+
35
39
  while i < @lines.length
40
+ # Skip lines inside heredoc content
41
+ if HeredocDetector.inside_heredoc?(i, heredoc_ranges)
42
+ i += 1
43
+ next
44
+ end
45
+
36
46
  line = @lines[i]
37
47
 
38
48
  # Match type alias definitions
@@ -62,7 +72,7 @@ module TRuby
62
72
  end
63
73
 
64
74
  # Match function definitions (top-level only, not inside class)
65
- if line.match?(/^\s*def\s+#{IDENTIFIER_CHAR}+/)
75
+ if line.match?(/^\s*#{VISIBILITY_PATTERN}def\s+#{IDENTIFIER_CHAR}+/)
66
76
  func_info, next_i = parse_function_with_body(i)
67
77
  if func_info
68
78
  functions << func_info
@@ -82,11 +92,9 @@ module TRuby
82
92
  classes: classes,
83
93
  }
84
94
 
85
- # Build IR if combinator is enabled
86
- if @use_combinator
87
- builder = IR::Builder.new
88
- @ir_program = builder.build(result, source: @source)
89
- end
95
+ # Build IR
96
+ builder = IR::Builder.new
97
+ @ir_program = builder.build(result, source: @source)
90
98
 
91
99
  result
92
100
  end
@@ -97,10 +105,8 @@ module TRuby
97
105
  @ir_program
98
106
  end
99
107
 
100
- # Parse a type expression using combinator (new API)
108
+ # Parse a type expression using combinator
101
109
  def parse_type(type_string)
102
- return nil unless @use_combinator
103
-
104
110
  result = @type_parser.parse(type_string)
105
111
  result[:success] ? result[:type] : nil
106
112
  end
@@ -149,16 +155,14 @@ module TRuby
149
155
  alias_name = match[1]
150
156
  definition = match[2].strip
151
157
 
152
- # Use combinator for complex type parsing if available
153
- if @use_combinator
154
- type_result = @type_parser.parse(definition)
155
- if type_result[:success]
156
- return {
157
- name: alias_name,
158
- definition: definition,
159
- ir_type: type_result[:type],
160
- }
161
- end
158
+ # Use combinator for complex type parsing
159
+ type_result = @type_parser.parse(definition)
160
+ if type_result[:success]
161
+ return {
162
+ name: alias_name,
163
+ definition: definition,
164
+ ir_type: type_result[:type],
165
+ }
162
166
  end
163
167
 
164
168
  {
@@ -173,12 +177,14 @@ module TRuby
173
177
  # def foo(): Type - no params but with return type
174
178
  # def foo(params) - with params, no return type
175
179
  # def foo - no params, no return type
176
- match = line.match(/^\s*def\s+(#{METHOD_NAME_PATTERN})\s*(?:\((.*?)\))?\s*(?::\s*(.+?))?\s*$/)
180
+ # Also supports visibility modifiers: private def, protected def, public def
181
+ match = line.match(/^\s*(?:(private|protected|public)\s+)?def\s+(#{METHOD_NAME_PATTERN})\s*(?:\((.*?)\))?\s*(?::\s*(.+?))?\s*$/)
177
182
  return nil unless match
178
183
 
179
- function_name = match[1]
180
- params_str = match[2] || ""
181
- return_type_str = match[3]&.strip
184
+ visibility = match[1] ? match[1].to_sym : :public
185
+ function_name = match[2]
186
+ params_str = match[3] || ""
187
+ return_type_str = match[4]&.strip
182
188
 
183
189
  # Validate return type if present
184
190
  if return_type_str
@@ -191,10 +197,11 @@ module TRuby
191
197
  name: function_name,
192
198
  params: params,
193
199
  return_type: return_type_str,
200
+ visibility: visibility,
194
201
  }
195
202
 
196
- # Parse return type with combinator if available
197
- if @use_combinator && return_type_str
203
+ # Parse return type with combinator
204
+ if return_type_str
198
205
  type_result = @type_parser.parse(return_type_str)
199
206
  result[:ir_return_type] = type_result[:type] if type_result[:success]
200
207
  end
@@ -286,8 +293,8 @@ module TRuby
286
293
  type: type_str,
287
294
  }
288
295
 
289
- # Parse type with combinator if available
290
- if @use_combinator && type_str
296
+ # Parse type with combinator
297
+ if type_str
291
298
  type_result = @type_parser.parse(type_str)
292
299
  result[:ir_type] = type_result[:type] if type_result[:success]
293
300
  end
@@ -326,7 +333,7 @@ module TRuby
326
333
  current_line = @lines[i]
327
334
 
328
335
  # Match method definitions inside class
329
- if current_line.match?(/^\s*def\s+#{IDENTIFIER_CHAR}+/)
336
+ if current_line.match?(/^\s*#{VISIBILITY_PATTERN}def\s+#{IDENTIFIER_CHAR}+/)
330
337
  method_info, next_i = parse_method_in_class(i, class_end)
331
338
  if method_info
332
339
  methods << method_info
@@ -438,10 +445,8 @@ module TRuby
438
445
  }
439
446
 
440
447
  # Parse member type with combinator
441
- if @use_combinator
442
- type_result = @type_parser.parse(member[:type])
443
- member[:ir_type] = type_result[:type] if type_result[:success]
444
- end
448
+ type_result = @type_parser.parse(member[:type])
449
+ member[:ir_type] = type_result[:type] if type_result[:success]
445
450
 
446
451
  members << member
447
452
  end
@@ -453,11 +458,4 @@ module TRuby
453
458
  [{ name: interface_name, members: members }, i]
454
459
  end
455
460
  end
456
-
457
- # Legacy Parser for backward compatibility (regex-only)
458
- class LegacyParser < Parser
459
- def initialize(source)
460
- super(source, use_combinator: false)
461
- end
462
- end
463
461
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TRuby
4
- VERSION = "0.0.39"
4
+ VERSION = "0.0.40"
5
5
  end
data/lib/t_ruby.rb CHANGED
@@ -11,6 +11,7 @@ require_relative "t_ruby/smt_solver"
11
11
 
12
12
  # Basic components
13
13
  require_relative "t_ruby/type_alias_registry"
14
+ require_relative "t_ruby/heredoc_detector"
14
15
  require_relative "t_ruby/body_parser"
15
16
  require_relative "t_ruby/parser"
16
17
  require_relative "t_ruby/union_type_parser"
@@ -18,7 +19,6 @@ require_relative "t_ruby/generic_type_parser"
18
19
  require_relative "t_ruby/intersection_type_parser"
19
20
  require_relative "t_ruby/type_erasure"
20
21
  require_relative "t_ruby/error_handler"
21
- require_relative "t_ruby/rbs_generator"
22
22
  require_relative "t_ruby/declaration_generator"
23
23
  require_relative "t_ruby/compiler"
24
24
  require_relative "t_ruby/lsp_server"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: t-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.39
4
+ version: 0.0.40
5
5
  platform: ruby
6
6
  authors:
7
7
  - Y. Fred Kim
@@ -52,13 +52,13 @@ files:
52
52
  - lib/t_ruby/docs_example_verifier.rb
53
53
  - lib/t_ruby/error_handler.rb
54
54
  - lib/t_ruby/generic_type_parser.rb
55
+ - lib/t_ruby/heredoc_detector.rb
55
56
  - lib/t_ruby/intersection_type_parser.rb
56
57
  - lib/t_ruby/ir.rb
57
58
  - lib/t_ruby/lsp_server.rb
58
59
  - lib/t_ruby/package_manager.rb
59
60
  - lib/t_ruby/parser.rb
60
61
  - lib/t_ruby/parser_combinator.rb
61
- - lib/t_ruby/rbs_generator.rb
62
62
  - lib/t_ruby/runtime_validator.rb
63
63
  - lib/t_ruby/smt_solver.rb
64
64
  - lib/t_ruby/type_alias_registry.rb
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module TRuby
4
- class RBSGenerator
5
- def initialize
6
- # RBS generation configuration
7
- end
8
-
9
- def generate(functions, type_aliases)
10
- # Add type aliases
11
- lines = type_aliases.map do |type_alias|
12
- generate_type_alias(type_alias)
13
- end
14
-
15
- lines << "" if type_aliases.any? && functions.any?
16
-
17
- # Add function signatures
18
- functions.each do |func|
19
- lines << generate_function_signature(func)
20
- end
21
-
22
- lines.compact.join("\n")
23
- end
24
-
25
- def generate_type_aliases(aliases)
26
- aliases.map { |alias_def| generate_type_alias(alias_def) }.join("\n")
27
- end
28
-
29
- def generate_type_alias(type_alias)
30
- name = type_alias[:name]
31
- definition = type_alias[:definition]
32
-
33
- "type #{name} = #{definition}"
34
- end
35
-
36
- def generate_function_signature(func)
37
- name = func[:name]
38
- params = func[:params] || []
39
- return_type = func[:return_type]
40
-
41
- param_str = format_parameters(params)
42
- return_str = format_return_type(return_type)
43
-
44
- "def #{name}: (#{param_str}) -> #{return_str}"
45
- end
46
-
47
- private
48
-
49
- def format_parameters(params)
50
- return if params.empty?
51
-
52
- param_strs = params.map do |param|
53
- param_name = param[:name]
54
- param_type = param[:type] || "Object"
55
-
56
- "#{param_name}: #{param_type}"
57
- end
58
-
59
- param_strs.join(", ")
60
- end
61
-
62
- def format_return_type(return_type)
63
- return "void" if return_type == "void"
64
- return "nil" if return_type.nil?
65
-
66
- return_type
67
- end
68
- end
69
- end