sorbet_view 0.6.0 → 0.8.0

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: c74f0ac2be7deb8aa466c27b4b4558852ebd4de838ada96d434650bb9c5bad0c
4
- data.tar.gz: 4d807c4126e1f272397d4cad1b38c2a5f3341616df90aab21b3efb621874e992
3
+ metadata.gz: 1eb1f1ebb6f7bf77db79673819fc89044d6b998ea2ee1ba069700453d87cc1cd
4
+ data.tar.gz: 40fefcdbe8af51be0b75f3f3dee6a4f31524439424c90468b80c779422b5054f
5
5
  SHA512:
6
- metadata.gz: b8a488ac1a4299128cd8ec4df072c4098a8b801bd080f34cf7e29353f47303ef4eb05e22b89ba56b5dae32e1e9f7edb5325333c11e132610aa13d4c882a287e2
7
- data.tar.gz: 2d40c0ce178370b135c91e8f49cd4e3f2f7fec3dc114849497afc2af3a8326523df09b1cf0362e512e4fa2d87b808db8b11c24325736dc582348ef9b0e556444
6
+ metadata.gz: c468a4efb4b9ed4d2965979d326d885e807b11bb4b6386d26ea08f580db59b2638dd34387f0b82e51d071fbecf9b952dd5015c4be1029e8abb6c457144c86111
7
+ data.tar.gz: f1ec4ae5f31c306ffc1321c7fd56a98c25730858b5fa230bfc4cb63ce221eee4a964f52e01a0e7bf838cd7107dedb6583d7228d4aa7cbb59bc2e3f7863977dcf
@@ -1,6 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
+ require 'listen'
4
5
  require 'logger'
5
6
  require 'set'
6
7
 
@@ -44,6 +45,7 @@ module SorbetView
44
45
  @logger.error("Server error: #{e.message}\n#{e.backtrace&.join("\n")}")
45
46
  ensure
46
47
  @file_watcher&.stop
48
+ @ivar_json_watcher&.stop
47
49
  @sorbet.stop
48
50
  @logger.info('SorbetView LSP server stopped')
49
51
  end
@@ -568,10 +570,46 @@ module SorbetView
568
570
  end
569
571
  @file_watcher.start
570
572
  @logger.info("FileWatcher started for: #{@config.input_dirs.join(', ')}")
573
+
574
+ start_ivar_json_watcher
571
575
  rescue => e
572
576
  @logger.warn("Failed to start FileWatcher: #{e.message}")
573
577
  end
574
578
 
579
+ sig { void }
580
+ def start_ivar_json_watcher
581
+ json_path = File.join(@config.output_dir, '.defined_ivars.json')
582
+ dir = File.dirname(json_path)
583
+ return unless Dir.exist?(dir)
584
+
585
+ @ivar_json_watcher = T.let(nil, T.untyped)
586
+ @ivar_json_watcher = Listen.to(dir, only: /\.defined_ivars\.json$/) do |modified, added, _removed|
587
+ next if (modified + added).empty?
588
+
589
+ @logger.info('.defined_ivars.json changed — recompiling all templates')
590
+ @compiler.invalidate_ivar_cache!
591
+ recompile_all_templates
592
+ end
593
+ @ivar_json_watcher.start
594
+ @logger.info("Watching #{json_path} for ivar mapping changes")
595
+ rescue => e
596
+ @logger.warn("Failed to start ivar JSON watcher: #{e.message}")
597
+ end
598
+
599
+ sig { void }
600
+ def recompile_all_templates
601
+ templates = FileSystem::ProjectScanner.scan(@config)
602
+ templates.each do |path|
603
+ source = File.read(path)
604
+ result = @compiler.compile(path, source)
605
+ @output_manager.write(result)
606
+ @position_translator.register(path, result.source_map)
607
+ notify_sorbet_template_changed(path, result)
608
+ end
609
+ rescue => e
610
+ @logger.error("recompile_all_templates error: #{e.message}")
611
+ end
612
+
575
613
  sig { params(modified: T::Array[String], added: T::Array[String], removed: T::Array[String]).void }
576
614
  def handle_file_changes(modified, added, removed)
577
615
  (modified + added).each do |path|
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module SorbetView
5
- VERSION = '0.6.0'
5
+ VERSION = '0.8.0'
6
6
  end
@@ -40,6 +40,7 @@ module Tapioca
40
40
 
41
41
  generate_ivar_mapping(controllers)
42
42
  process_components
43
+ compile_all_templates
43
44
  end
44
45
 
45
46
  private
@@ -80,17 +81,22 @@ module Tapioca
80
81
  mapping_path = File.join(config.output_dir, '.defined_ivars.json')
81
82
  FileUtils.mkdir_p(File.dirname(mapping_path))
82
83
  File.write(mapping_path, JSON.pretty_generate(mapping))
83
- rescue StandardError
84
- # Non-critical: if mapping fails, all ivars default to NilClass
84
+ rescue StandardError => e
85
+ $stderr.puts "[SorbetView] generate_ivar_mapping failed: #{e.class}: #{e.message}"
86
+ $stderr.puts e.backtrace&.first(5)&.join("\n")
85
87
  end
86
88
 
87
89
  # Resolve view directories from Rails, relative to project root
90
+ # Only include directories within the project (exclude gem paths)
88
91
  sig { returns(T::Array[String]) }
89
92
  def resolve_view_dirs
90
93
  if defined?(::ActionController::Base) && ::ActionController::Base.respond_to?(:view_paths)
94
+ cwd = Dir.pwd
91
95
  ::ActionController::Base.view_paths.paths.filter_map do |p|
92
96
  path_str = p.to_s
93
- relative = path_str.sub(%r{^#{Regexp.escape(Dir.pwd)}/?}, '')
97
+ next unless path_str.start_with?(cwd)
98
+
99
+ relative = path_str.sub(%r{^#{Regexp.escape(cwd)}/?}, '')
94
100
  relative unless relative.empty?
95
101
  end
96
102
  else
@@ -134,11 +140,34 @@ module Tapioca
134
140
  next if name.nil? || name.empty?
135
141
  next if type.nil? || type.empty?
136
142
 
137
- result[name] = type
143
+ result[name] = normalize_type(type)
138
144
  end
139
145
  result
140
146
  end
141
147
 
148
+ # Compile all templates after generating ivar mapping
149
+ sig { void }
150
+ def compile_all_templates
151
+ config = ::SorbetView::Configuration.load
152
+ compiler = ::SorbetView::Compiler::TemplateCompiler.new(config: config)
153
+ output_manager = ::SorbetView::FileSystem::OutputManager.new(config.output_dir)
154
+
155
+ templates = ::SorbetView::FileSystem::ProjectScanner.scan(config)
156
+ templates.each do |path|
157
+ result = compiler.compile_file(path)
158
+ output_manager.write(result)
159
+ end
160
+
161
+ component_compiler = ::SorbetView::Compiler::ComponentCompiler.new(config: config)
162
+ components = ::SorbetView::FileSystem::ProjectScanner.scan_components(config)
163
+ components.each do |path|
164
+ results = component_compiler.compile_file(path)
165
+ results.each { |result| output_manager.write(result) }
166
+ end
167
+ rescue StandardError => e
168
+ $stderr.puts "[SorbetView] compile_all_templates failed: #{e.class}: #{e.message}"
169
+ end
170
+
142
171
  sig { void }
143
172
  def process_components
144
173
  config = ::SorbetView::Configuration.load
@@ -287,6 +316,13 @@ module Tapioca
287
316
  []
288
317
  end
289
318
 
319
+ # Normalize Sorbet literal types to their base types
320
+ # e.g. String("test") → String, Integer(42) → Integer, Symbol(:foo) → Symbol
321
+ sig { params(type: String).returns(String) }
322
+ def normalize_type(type)
323
+ type.gsub(/\b([A-Z]\w*)\(.*?\)/) { $1 }
324
+ end
325
+
290
326
  sig { params(str: String).returns(String) }
291
327
  def camelize(str)
292
328
  str.split('_').map(&:capitalize).join
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorbet_view
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - kazuma