ryac 0.2.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.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +145 -0
  4. data/Rakefile +45 -0
  5. data/Steepfile +9 -0
  6. data/bin/console +11 -0
  7. data/bin/ryac +134 -0
  8. data/bin/setup +8 -0
  9. data/lib/ryac/analysis/constant/collection.rb +332 -0
  10. data/lib/ryac/analysis/constant/rename_mapping.rb +346 -0
  11. data/lib/ryac/analysis/cvar/collection.rb +37 -0
  12. data/lib/ryac/analysis/gvar/collection.rb +36 -0
  13. data/lib/ryac/analysis/gvar/rename_mapping.rb +82 -0
  14. data/lib/ryac/analysis/ivar/collection.rb +281 -0
  15. data/lib/ryac/analysis/keyword/collection.rb +213 -0
  16. data/lib/ryac/analysis/keyword/rename_mapping.rb +167 -0
  17. data/lib/ryac/analysis/local_scopes.rb +582 -0
  18. data/lib/ryac/analysis/method/collection.rb +298 -0
  19. data/lib/ryac/analysis/method/rename_mapping.rb +337 -0
  20. data/lib/ryac/analysis/method_aliases.rb +83 -0
  21. data/lib/ryac/analysis/method_aliasing.rb +65 -0
  22. data/lib/ryac/analysis/nesting.rb +123 -0
  23. data/lib/ryac/analysis/scope_management.rb +25 -0
  24. data/lib/ryac/analysis/site_bucket_mapping.rb +127 -0
  25. data/lib/ryac/analysis/type_oracle.rb +386 -0
  26. data/lib/ryac/ast_utils.rb +321 -0
  27. data/lib/ryac/errors.rb +32 -0
  28. data/lib/ryac/gem_resolver.rb +55 -0
  29. data/lib/ryac/minifier.rb +169 -0
  30. data/lib/ryac/name_generator.rb +68 -0
  31. data/lib/ryac/pipeline/analyzer.rb +264 -0
  32. data/lib/ryac/pipeline/attr_decl_shorten.rb +61 -0
  33. data/lib/ryac/pipeline/boolean_shorten.rb +26 -0
  34. data/lib/ryac/pipeline/char_shorten.rb +20 -0
  35. data/lib/ryac/pipeline/compactor.rb +1202 -0
  36. data/lib/ryac/pipeline/concatenator.rb +248 -0
  37. data/lib/ryac/pipeline/constant_aliaser.rb +240 -0
  38. data/lib/ryac/pipeline/constant_fold.rb +93 -0
  39. data/lib/ryac/pipeline/control_flow_simplify.rb +352 -0
  40. data/lib/ryac/pipeline/data_types.rb +179 -0
  41. data/lib/ryac/pipeline/endless_method.rb +60 -0
  42. data/lib/ryac/pipeline/errors.rb +94 -0
  43. data/lib/ryac/pipeline/file_collector.rb +360 -0
  44. data/lib/ryac/pipeline/method_renamer.rb +151 -0
  45. data/lib/ryac/pipeline/paren_optimizer.rb +161 -0
  46. data/lib/ryac/pipeline/rename_patcher.rb +274 -0
  47. data/lib/ryac/pipeline/source_patcher.rb +54 -0
  48. data/lib/ryac/pipeline/spelling_shorten.rb +60 -0
  49. data/lib/ryac/pipeline/stage.rb +72 -0
  50. data/lib/ryac/pipeline/stage_runner.rb +84 -0
  51. data/lib/ryac/pipeline/variable_renamer.rb +125 -0
  52. data/lib/ryac/union_find.rb +42 -0
  53. data/lib/ryac/version.rb +5 -0
  54. data/lib/ryac.rb +29 -0
  55. data/rbs_collection.lock.yaml +224 -0
  56. data/rbs_collection.yaml +25 -0
  57. data/sig/ryac/analysis/constant/collection.rbs +30 -0
  58. data/sig/ryac/analysis/constant/rename_mapping.rbs +60 -0
  59. data/sig/ryac/analysis/cvar/collection.rbs +11 -0
  60. data/sig/ryac/analysis/gvar/collection.rbs +9 -0
  61. data/sig/ryac/analysis/gvar/rename_mapping.rbs +23 -0
  62. data/sig/ryac/analysis/ivar/collection.rbs +26 -0
  63. data/sig/ryac/analysis/keyword/collection.rbs +27 -0
  64. data/sig/ryac/analysis/keyword/rename_mapping.rbs +31 -0
  65. data/sig/ryac/analysis/local_scopes.rbs +77 -0
  66. data/sig/ryac/analysis/method/collection.rbs +25 -0
  67. data/sig/ryac/analysis/method/rename_mapping.rbs +82 -0
  68. data/sig/ryac/analysis/method_aliases.rbs +10 -0
  69. data/sig/ryac/analysis/method_aliasing.rbs +9 -0
  70. data/sig/ryac/analysis/nesting.rbs +9 -0
  71. data/sig/ryac/analysis/scope_management.rbs +5 -0
  72. data/sig/ryac/analysis/site_bucket_mapping.rbs +26 -0
  73. data/sig/ryac/analysis/type_oracle.rbs +61 -0
  74. data/sig/ryac/ast_utils.rbs +34 -0
  75. data/sig/ryac/errors.rbs +21 -0
  76. data/sig/ryac/gem_resolver.rbs +28 -0
  77. data/sig/ryac/minifier.rbs +33 -0
  78. data/sig/ryac/name_generator.rbs +14 -0
  79. data/sig/ryac/pipeline/analyzer.rbs +34 -0
  80. data/sig/ryac/pipeline/attr_decl_shorten.rbs +17 -0
  81. data/sig/ryac/pipeline/boolean_shorten.rbs +11 -0
  82. data/sig/ryac/pipeline/char_shorten.rbs +11 -0
  83. data/sig/ryac/pipeline/compactor.rbs +125 -0
  84. data/sig/ryac/pipeline/concatenator.rbs +28 -0
  85. data/sig/ryac/pipeline/constant_aliaser.rbs +35 -0
  86. data/sig/ryac/pipeline/constant_fold.rbs +20 -0
  87. data/sig/ryac/pipeline/control_flow_simplify.rbs +34 -0
  88. data/sig/ryac/pipeline/data_types.rbs +151 -0
  89. data/sig/ryac/pipeline/endless_method.rbs +14 -0
  90. data/sig/ryac/pipeline/errors.rbs +46 -0
  91. data/sig/ryac/pipeline/file_collector.rbs +34 -0
  92. data/sig/ryac/pipeline/method_renamer.rbs +25 -0
  93. data/sig/ryac/pipeline/paren_optimizer.rbs +16 -0
  94. data/sig/ryac/pipeline/rename_patcher.rbs +38 -0
  95. data/sig/ryac/pipeline/source_patcher.rbs +12 -0
  96. data/sig/ryac/pipeline/spelling_shorten.rbs +14 -0
  97. data/sig/ryac/pipeline/stage.rbs +28 -0
  98. data/sig/ryac/pipeline/stage_runner.rbs +18 -0
  99. data/sig/ryac/pipeline/variable_renamer.rbs +21 -0
  100. data/sig/ryac/union_find.rbs +17 -0
  101. data/sig/ryac.rbs +13 -0
  102. data/sig/shims/env.rbs +19 -0
  103. data/sig/shims/typeprof/core/ast.rbs +299 -0
  104. data/sig/shims/typeprof/core/type.rbs +22 -0
  105. data/sig/shims/typeprof/core.rbs +73 -0
  106. data/tools/regen_pins.rb +45 -0
  107. metadata +201 -0
@@ -0,0 +1,34 @@
1
+ module Ryac
2
+ module Pipeline
3
+ class ControlFlowSimplify < Stage
4
+
5
+ COLLECTION_CONTEXT_BYTES: Array[Integer]
6
+ OPERATOR_START_BYTES: Array[Integer]
7
+
8
+ def fixpoint?: () -> bool
9
+ def collect: (StageContext ctx, Array[patch_entry] patches) -> void
10
+
11
+ private
12
+
13
+ def walk: (Prism::Node node, String source, Array[patch_entry] patches, ?bool statement_position) -> void
14
+ def try_if: (Prism::IfNode node, String source, bool statement_position) -> String?
15
+ def try_sole_nested_if: (Prism::IfNode node, Prism::Node inner, String source) -> String?
16
+ def logic_operand_text: (Prism::Node pred, String text) -> String
17
+ def else_text_for_ternary: (Prism::Node? subsequent, String source) -> String?
18
+ def build_ternary: (Prism::Node cond_node, String cond, Prism::Node? then_node, String? then_expr, String? else_expr) -> String
19
+ def try_tail_return: (Prism::DefNode node, Array[patch_entry] patches) -> void
20
+ def collect_tail_returns: (Prism::Node? node, Array[patch_entry] patches) -> void
21
+ def contains_tail_return_patch?: (Prism::Node node) -> bool
22
+ def try_unless: (Prism::UnlessNode node, String source, bool statement_position) -> String?
23
+ def try_loop: (Prism::WhileNode | Prism::UntilNode node, String source, bool statement_position, String keyword) -> String?
24
+ def too_complex_for_ternary?: (String? text) -> bool?
25
+ def in_collection_context?: (Prism::Node node, String source) -> bool
26
+ LOCAL_BINDING_NODES: Array[Class]
27
+ def condition_assigns_var_used_in_body?: (Prism::Node predicate, Prism::Node? body) -> bool
28
+ def collect_assigned_vars: (Prism::Node node) -> Set[Symbol]
29
+ def collect_read_vars: (Prism::Node? node) -> Set[Symbol]
30
+ def traverse: (Prism::Node? node) { (Prism::Node) -> void } -> void
31
+ def if_end_followed_by_operator?: (Prism::IfNode node, String source) -> bool
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,151 @@
1
+ module Ryac
2
+ module Pipeline
3
+ class FileEntry
4
+ attr_reader path: String
5
+ attr_reader content: String
6
+ attr_reader dependencies: Array[String]
7
+ attr_reader require_nodes: Array[require_node_info]
8
+ attr_reader in_class_dependencies: Array[String]
9
+
10
+ def self.new: (path: String, content: String, dependencies: Array[String], require_nodes: Array[require_node_info], ?in_class_dependencies: Array[String]) -> FileEntry
11
+ def initialize: (path: String, content: String, dependencies: Array[String], require_nodes: Array[require_node_info], ?in_class_dependencies: Array[String]) -> void
12
+ end
13
+
14
+ class DependencyGraph
15
+ attr_reader files: Hash[String, FileEntry]
16
+ attr_reader adjacency: Hash[String, Array[String]]
17
+ attr_reader in_degrees: Hash[String, Integer]
18
+ attr_reader rbs_files: Hash[String, String]
19
+
20
+ def initialize: () -> void
21
+ def add_file: (FileEntry entry) -> void
22
+ def paths: () -> Array[String]
23
+ def []: (String path) -> FileEntry?
24
+ def size: () -> Integer
25
+ def empty?: () -> bool
26
+ end
27
+
28
+ class FileBoundary
29
+ attr_reader path: String
30
+ attr_reader start_line: Integer
31
+ attr_reader end_line: Integer
32
+
33
+ def self.new: (path: String, start_line: Integer, end_line: Integer) -> FileBoundary
34
+ end
35
+
36
+ class ConcatenatedSource
37
+ attr_reader content: String
38
+ attr_reader file_boundaries: Array[FileBoundary]
39
+ attr_reader original_size: Integer
40
+ attr_reader stdlib_requires: Array[String]
41
+ attr_reader rbs_files: Hash[String, String]
42
+
43
+ def self.new: (content: String, ?file_boundaries: Array[FileBoundary], ?original_size: Integer?, ?stdlib_requires: Array[String], ?rbs_files: Hash[String, String]) -> ConcatenatedSource
44
+ def initialize: (content: String, ?file_boundaries: Array[FileBoundary], ?original_size: Integer?, ?stdlib_requires: Array[String], ?rbs_files: Hash[String, String]) -> void
45
+ def with: (?content: String, ?file_boundaries: Array[FileBoundary], ?original_size: Integer, ?stdlib_requires: Array[String], ?rbs_files: Hash[String, String]) -> ConcatenatedSource
46
+ end
47
+
48
+ class AnalysisResult
49
+ attr_reader prism_ast: Prism::ProgramNode
50
+ attr_reader scope_mappings: scope_mapping_table
51
+ attr_reader constant_mapping: ConstantRenameMapping?
52
+ attr_reader rename_map: Hash[location_key, String]
53
+ attr_reader method_alias_map: Hash[location_key, Symbol]
54
+ attr_reader method_transform_map: Hash[location_key, String]
55
+ attr_reader source: ConcatenatedSource
56
+ attr_reader attr_rename_map: Hash[location_key, Hash[Symbol, String]]
57
+ attr_reader block_param_names_map: Hash[location_key, Hash[Symbol, String]]
58
+ attr_reader syntax_data: Hash[[Integer, Integer], Hash[Symbol, syntax_value]]
59
+ attr_reader const_resolution_map: Hash[location_key, Array[Symbol]]
60
+ attr_reader const_full_path_map: Hash[location_key, Array[Symbol]]
61
+ attr_reader const_write_cpath_map: Hash[location_key, Array[Symbol]]
62
+ attr_reader class_cpath_map: Hash[location_key, Array[Symbol]]
63
+ attr_reader superclass_resolution_map: Hash[location_key, Array[Symbol]]
64
+ attr_reader meta_node_map: Hash[location_key, meta_node_entry]
65
+ attr_reader local_rename_entries: Hash[location_key, String]
66
+ attr_reader keyword_rename_entries: Hash[location_key, String]
67
+ attr_reader ivar_rename_entries: Hash[location_key, String]
68
+ attr_reader attr_ivar_entries: Hash[location_key, String]
69
+ attr_reader cvar_rename_entries: Hash[location_key, String]
70
+ attr_reader gvar_rename_entries: Hash[location_key, String]
71
+
72
+ def self.new: (
73
+ prism_ast: Prism::ProgramNode,
74
+ scope_mappings: scope_mapping_table,
75
+ constant_mapping: ConstantRenameMapping?,
76
+ rename_map: Hash[location_key, String],
77
+ method_alias_map: Hash[location_key, Symbol],
78
+ method_transform_map: Hash[location_key, String],
79
+ source: ConcatenatedSource,
80
+ attr_rename_map: Hash[location_key, Hash[Symbol, String]],
81
+ block_param_names_map: Hash[location_key, Hash[Symbol, String]],
82
+ syntax_data: Hash[[Integer, Integer], Hash[Symbol, syntax_value]],
83
+ const_resolution_map: Hash[location_key, Array[Symbol]],
84
+ const_full_path_map: Hash[location_key, Array[Symbol]],
85
+ const_write_cpath_map: Hash[location_key, Array[Symbol]],
86
+ class_cpath_map: Hash[location_key, Array[Symbol]],
87
+ superclass_resolution_map: Hash[location_key, Array[Symbol]],
88
+ meta_node_map: Hash[location_key, meta_node_entry],
89
+ ?local_rename_entries: Hash[location_key, String],
90
+ ?keyword_rename_entries: Hash[location_key, String],
91
+ ?ivar_rename_entries: Hash[location_key, String],
92
+ ?attr_ivar_entries: Hash[location_key, String],
93
+ ?cvar_rename_entries: Hash[location_key, String],
94
+ ?gvar_rename_entries: Hash[location_key, String]
95
+ ) -> AnalysisResult
96
+ def initialize: (
97
+ prism_ast: Prism::ProgramNode,
98
+ scope_mappings: scope_mapping_table,
99
+ constant_mapping: ConstantRenameMapping?,
100
+ rename_map: Hash[location_key, String],
101
+ method_alias_map: Hash[location_key, Symbol],
102
+ method_transform_map: Hash[location_key, String],
103
+ source: ConcatenatedSource,
104
+ attr_rename_map: Hash[location_key, Hash[Symbol, String]],
105
+ block_param_names_map: Hash[location_key, Hash[Symbol, String]],
106
+ syntax_data: Hash[[Integer, Integer], Hash[Symbol, syntax_value]],
107
+ const_resolution_map: Hash[location_key, Array[Symbol]],
108
+ const_full_path_map: Hash[location_key, Array[Symbol]],
109
+ const_write_cpath_map: Hash[location_key, Array[Symbol]],
110
+ class_cpath_map: Hash[location_key, Array[Symbol]],
111
+ superclass_resolution_map: Hash[location_key, Array[Symbol]],
112
+ meta_node_map: Hash[location_key, meta_node_entry],
113
+ ?local_rename_entries: Hash[location_key, String],
114
+ ?keyword_rename_entries: Hash[location_key, String],
115
+ ?ivar_rename_entries: Hash[location_key, String],
116
+ ?attr_ivar_entries: Hash[location_key, String],
117
+ ?cvar_rename_entries: Hash[location_key, String],
118
+ ?gvar_rename_entries: Hash[location_key, String]
119
+ ) -> void
120
+ end
121
+
122
+ class CompressionStats
123
+ attr_reader original_size: Integer
124
+ attr_reader minified_size: Integer
125
+ attr_reader compression_ratio: Float
126
+ attr_reader file_count: Integer
127
+
128
+ def self.new: (original_size: Integer, minified_size: Integer, compression_ratio: Float, file_count: Integer) -> CompressionStats
129
+ end
130
+
131
+ class RenameResult
132
+ attr_reader code: String
133
+ attr_reader aliases: String
134
+ attr_reader preamble: String
135
+
136
+ def self.new: (code: String, ?aliases: String, ?preamble: String) -> RenameResult
137
+ def initialize: (code: String, ?aliases: String, ?preamble: String) -> void
138
+ end
139
+
140
+ class MinifiedResult
141
+ attr_reader content: String
142
+ attr_reader aliases: String
143
+ attr_reader preamble: String
144
+ attr_reader stats: CompressionStats
145
+
146
+ def self.new: (content: String, ?aliases: String, ?preamble: String, stats: CompressionStats) -> MinifiedResult
147
+ def initialize: (content: String, ?aliases: String, ?preamble: String, stats: CompressionStats) -> void
148
+ def full_content: () -> String
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,14 @@
1
+ module Ryac
2
+ module Pipeline
3
+ class EndlessMethod < Stage
4
+ def fixpoint?: () -> bool
5
+ def collect: (StageContext ctx, Array[patch_entry] patches) -> void
6
+
7
+ private
8
+
9
+ def walk: (Prism::Node node, String source, Array[patch_entry] patches) -> void
10
+ def try_def: (Prism::DefNode node, String source) -> String?
11
+ def keyword_logical?: (Prism::Node node, String source) -> bool
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,46 @@
1
+ module Ryac
2
+ module Pipeline
3
+ class StageError < Ryac::InputError
4
+ end
5
+
6
+ class FileNotFoundError < StageError
7
+ attr_reader path: String
8
+ attr_reader required_from: String?
9
+ attr_reader line: Integer?
10
+
11
+ def initialize: (String path, ?required_from: String?, ?line: Integer?) -> void
12
+ end
13
+
14
+ class DynamicRequireError < StageError
15
+ attr_reader path: String
16
+ attr_reader line: Integer
17
+ attr_reader expression: String
18
+
19
+ def initialize: (String path, line: Integer, expression: String) -> void
20
+ end
21
+
22
+ class CircularDependencyError < StageError
23
+ attr_reader cycle: Array[String]
24
+
25
+ def initialize: (Array[String] cycle) -> void
26
+ end
27
+
28
+ class NoFilesError < StageError
29
+ def initialize: () -> void
30
+ end
31
+
32
+ class GemNotFoundError < StageError
33
+ attr_reader gem_name: String
34
+
35
+ def initialize: (String gem_name) -> void
36
+ end
37
+
38
+ class InvalidOutputError < Ryac::InternalError
39
+ def initialize: (String label, Array[Prism::ParseError] errors) -> void
40
+ end
41
+
42
+ class RenameCollisionError < Ryac::InternalError
43
+ def initialize: (String scope, Array[[String, Array[Symbol]]] collisions) -> void
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,34 @@
1
+ module Ryac
2
+ module Pipeline
3
+ # resolved_path is absent for :require_stdlib nodes; every node records
4
+ # whether it sits inside a class/module body and/or a method body.
5
+ type require_node_info = { type: Symbol, path: String, line: Integer, start_offset: Integer, length: Integer, in_class: bool, in_method: bool, ?resolved_path: String }
6
+
7
+ class FileCollector
8
+ @graph: DependencyGraph
9
+ @visited: Set[String]
10
+ @gem_names: Array[String]
11
+ @project_roots: Array[String]
12
+
13
+ def call: (String | Array[String] entry_path, ?project_root: String | Array[String] | nil, ?gem_names: Array[String], ?gem_require_paths: Array[String]) -> DependencyGraph
14
+
15
+ private
16
+
17
+ def collect_file: (String file_path, ?required_from: String?, ?line: Integer?) -> void
18
+ def extract_require_nodes: (String file_path, String content) -> Array[require_node_info]
19
+ def traverse_for_requires: (Prism::Node? node, Array[require_node_info] nodes, String file_path, ?in_method: bool, ?in_class: bool) -> void
20
+ def handle_call_node: (Prism::CallNode node, Array[require_node_info] nodes, String file_path, ?in_method: bool, ?in_class: bool) -> void
21
+ def handle_require_relative: (Prism::CallNode node, Array[require_node_info] nodes, String file_path, ?in_method: bool, ?in_class: bool) -> void
22
+ def handle_require: (Prism::CallNode node, Array[require_node_info] nodes, String file_path, ?in_method: bool, ?in_class: bool) -> void
23
+ def handle_autoload: (Prism::CallNode node, Array[require_node_info] nodes, String file_path, ?in_method: bool, ?in_class: bool) -> void
24
+ def dir_interpolated_path: (Prism::Node path_arg) -> String?
25
+ def ensure_load_paths: (Array[String] require_paths) -> void
26
+ def collect_rbs_files: (Array[String] entry_paths) -> void
27
+ def collect_rbs_stdlib_files: () -> void
28
+ def load_rbs_from: (String dir) -> void
29
+ def find_project_root: (Array[String] entry_paths) -> String?
30
+ def resolve_relative_path: (String path, String from_file) -> String
31
+ def resolve_bare_require: (String path) -> String?
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,25 @@
1
+ module Ryac
2
+ module Pipeline
3
+ class MethodRenamer < Stage
4
+ include RenamePatcher
5
+
6
+ @negated_transforms: Hash[location_key, bool]
7
+ @source_bytes: String
8
+
9
+ def needs_analysis?: () -> bool
10
+ def collect: (StageContext ctx, Array[patch_entry] patches) -> void
11
+
12
+ private
13
+
14
+ def collect_patches: (Prism::Node node, Array[patch_entry] patches, AnalysisResult analysis, Hash[location_key, String] rename_map, Hash[location_key, Symbol] method_alias_map) -> void
15
+ def handle_node: (Prism::Node subnode, Array[patch_entry] patches, AnalysisResult analysis, Hash[location_key, String] rename_map, Hash[location_key, Symbol] method_alias_map) -> void
16
+ def patch_def_name: (Prism::DefNode node, Array[patch_entry] patches, Hash[location_key, String] rename_map) -> void
17
+ def patch_call_node: (Prism::CallNode node, Array[patch_entry] patches, Hash[location_key, String] rename_map, Hash[location_key, Symbol] method_alias_map, AnalysisResult analysis) -> void
18
+
19
+ SEND_METHODS: Array[Symbol]
20
+
21
+ def patch_send_symbol: (Prism::CallNode node, Array[patch_entry] patches, String short_name) -> void
22
+ def patch_call_operator_write: (Prism::CallOperatorWriteNode | Prism::CallOrWriteNode | Prism::CallAndWriteNode node, Array[patch_entry] patches, Hash[location_key, String] rename_map, Hash[location_key, Symbol] method_alias_map) -> void
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,16 @@
1
+ module Ryac
2
+ module Pipeline
3
+ class ParenOptimizer < Stage
4
+ def collect: (StageContext ctx, Array[patch_entry] patches) -> void
5
+
6
+ private
7
+
8
+ def walk: (Prism::Node node, String source, Array[patch_entry] patches, statement_level: bool) -> void
9
+ def walk_if: (Prism::IfNode node, String source, Array[patch_entry] patches) -> void
10
+ def walk_call_children: (Prism::CallNode node, String source, Array[patch_entry] patches) -> void
11
+ def try_remove_call_parens: (Prism::CallNode node, String source, Array[patch_entry] patches) -> void
12
+ def try_remove_yield_parens: (Prism::YieldNode node, Array[patch_entry] patches) -> void
13
+ def add_paren_removal_patches: (Prism::Location open_loc, Prism::Location close_loc, Array[patch_entry] patches) -> void
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,38 @@
1
+ module Ryac
2
+ module Pipeline
3
+ type patch_entry = { start: Integer, end: Integer, replacement: String }
4
+
5
+ module RenamePatcher
6
+ # Prism nodes whose name_loc is always present (variable write /
7
+ # operator-write nodes and similar). Prism types name_loc as nullable
8
+ # only on bare rest/block parameters, which never reach these helpers.
9
+ interface _NodeWithNameLoc
10
+ def name_loc: () -> Prism::Location
11
+ end
12
+
13
+ private
14
+
15
+ def walk_prism: (Prism::Node? node) { (Prism::Node) -> untyped } -> void
16
+ def prism_location_key: (Prism::Node node) -> location_key
17
+ def patch_variable: (Prism::Node node, Array[patch_entry] patches, Hash[location_key, String] rename_map) -> void
18
+ def patch_variable_name_only: (Prism::Node & _NodeWithNameLoc node, Array[patch_entry] patches, Hash[location_key, String] rename_map) -> void
19
+ def patch_def_params: (Prism::DefNode node, Array[patch_entry] patches, AnalysisResult analysis, Symbol param_names_key) -> void
20
+ def patch_required_params: (Array[Prism::Node]? requireds, Hash[Symbol, String] param_names, Array[patch_entry] patches) -> void
21
+ def patch_multi_target_params: (Prism::MultiTargetNode node, Hash[Symbol, String] param_names, Array[patch_entry] patches) -> void
22
+ def patch_optional_params: (Array[Prism::OptionalParameterNode]? optionals, Hash[Symbol, String] param_names, Array[patch_entry] patches) -> void
23
+ def patch_named_param: (Symbol name, Prism::Location? name_loc, Hash[Symbol, String] param_names, Array[patch_entry] patches) -> void
24
+ def patch_rest_param: (Prism::Node? rest, Hash[Symbol, String] param_names, Array[patch_entry] patches) -> void
25
+ def patch_post_params: (Array[Prism::Node]? posts, Hash[Symbol, String] param_names, Array[patch_entry] patches) -> void
26
+ def patch_keyword_params: (Array[Prism::RequiredKeywordParameterNode | Prism::OptionalKeywordParameterNode]? keywords, Hash[Symbol, String] param_names, Array[patch_entry] patches) -> void
27
+ def patch_keyword_rest: (Prism::Node? keyword_rest, Hash[Symbol, String] param_names, Array[patch_entry] patches) -> void
28
+ def patch_block_param_node: (Prism::Node? block, Hash[Symbol, String] param_names, Array[patch_entry] patches) -> void
29
+ def patch_block_params: (Prism::CallNode node, Array[patch_entry] patches, Hash[location_key, Hash[Symbol, String]] block_param_names_map) -> void
30
+ def patch_for_node: (Prism::ForNode node, Array[patch_entry] patches, AnalysisResult analysis, Symbol mangled_key) -> void
31
+ # The return value is only ever compared against :skip_children; a
32
+ # record-alias union here sends typeprof's solver into unbounded
33
+ # re-propagation during self-hosting, so it stays untyped.
34
+ def patch_assoc: (Prism::AssocNode node, Array[patch_entry] patches, Hash[location_key, String] rename_map, ?keyword_arg: bool) -> untyped
35
+ def patch_keyword_hash: (Prism::KeywordHashNode node, Array[patch_entry] patches, Hash[location_key, String] rename_map) { (Prism::Node) -> untyped } -> void
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,12 @@
1
+ module Ryac
2
+ module Pipeline
3
+ module SourcePatcher
4
+ private
5
+
6
+ def mk: (Prism::Node node, String replacement) -> { start: Integer, end: Integer, replacement: String }
7
+ def apply_patches: (String source, Array[{ start: Integer, end: Integer, replacement: String }] patches) -> String
8
+ def src: (String source, Prism::Node node) -> String
9
+ def verify_parses: (String text, String label) -> void
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ module Ryac
2
+ module Pipeline
3
+ class SpellingShorten < Stage
4
+ SAFE_WORD: Regexp
5
+
6
+ def collect: (StageContext ctx, Array[patch_entry] patches) -> void
7
+
8
+ private
9
+
10
+ def try_percent_array: (Prism::ArrayNode node, Array[patch_entry] patches) -> void
11
+ def plain?: (Prism::Node node, Class klass) -> bool
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,28 @@
1
+ module Ryac
2
+ module Pipeline
3
+ class StageContext < Struct[untyped]
4
+ attr_accessor source: String
5
+ attr_accessor ast: Prism::ProgramNode
6
+ attr_accessor analysis: AnalysisResult?
7
+ attr_accessor aliases: String
8
+ attr_accessor preamble: String
9
+
10
+ def self.new: (String source, Prism::ProgramNode ast, AnalysisResult? analysis, String aliases, String preamble) -> StageContext
11
+ end
12
+
13
+ class Stage
14
+ include SourcePatcher
15
+
16
+ def self.new: (**untyped) -> Stage
17
+ def needs_analysis?: () -> bool
18
+ def fixpoint?: () -> bool
19
+ def collect: (StageContext ctx, Array[patch_entry] patches) -> void
20
+ def finish: (StageContext ctx) -> void
21
+ def call: (String input) -> String
22
+
23
+ private
24
+
25
+ def analysis: (StageContext ctx) -> AnalysisResult
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ module Ryac
2
+ module Pipeline
3
+ class StageRunner
4
+ include SourcePatcher
5
+
6
+ @stdlib_requires: Array[String]
7
+ @rbs_files: Hash[String, String]
8
+
9
+ def initialize: (?stdlib_requires: Array[String], ?rbs_files: Hash[String, String]) -> void
10
+ def call: (String code, Array[Minifier::stage_entry] stage_defs) -> RenameResult
11
+
12
+ private
13
+
14
+ def instantiate: (Minifier::stage_entry entry) -> Stage
15
+ def run_analysis_batch: (String code, Array[Stage] batch) -> [String, String, String]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ module Ryac
2
+ module Pipeline
3
+ class VariableRenamer < Stage
4
+ include RenamePatcher
5
+
6
+ FEATURES: Hash[Symbol, bool]
7
+
8
+ @features: Hash[Symbol, bool]
9
+
10
+ def needs_analysis?: () -> bool
11
+ def initialize: (?features: Hash[Symbol, bool]) -> void
12
+ def collect: (StageContext ctx, Array[patch_entry] patches) -> void
13
+
14
+ private
15
+
16
+ def build_rename_map: (AnalysisResult analysis) -> Hash[location_key, String]
17
+ def collect_patches: (Prism::Node node, Array[patch_entry] patches, AnalysisResult analysis, Hash[location_key, String] rename_map, Hash[location_key, Hash[Symbol, String]] block_param_names_map) -> void
18
+ def handle_node: (Prism::Node subnode, Array[patch_entry] patches, AnalysisResult analysis, Hash[location_key, String] rename_map, Hash[location_key, Hash[Symbol, String]] block_param_names_map) -> void
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ module Ryac
2
+ # Union-Find over arbitrary hashable keys; each includer picks its key type
3
+ # (both current includers use method_key).
4
+ module UnionFind[K < Object]
5
+ @parent: Hash[K, K]
6
+ @rank: Hash[K, Integer]
7
+
8
+ def uf_init: () -> void
9
+ def uf_root: (K key) -> K
10
+ def merge_groups: (K key1, K key2) -> void
11
+
12
+ private
13
+
14
+ def uf_add: (K key) -> Integer
15
+ def uf_remove: (K key) -> void
16
+ end
17
+ end
data/sig/ryac.rbs ADDED
@@ -0,0 +1,13 @@
1
+ module Ryac
2
+ VERSION: String
3
+
4
+ type location_key = [Integer, Integer]
5
+ # Line/column coordinates — a separate space from byte-offset location_key;
6
+ # build with AstUtils.line_col_key, never by hand.
7
+ type line_col_key = [Integer, Integer]
8
+ type scope_id = location_key
9
+ type scope_mapping_table = Hash[scope_id, Hash[Symbol, String]]
10
+ type syntax_value = String | Integer | Symbol | bool | Hash[Symbol, String] | nil
11
+ type syntax_data_map = Hash[line_col_key, Hash[Symbol, syntax_value]]
12
+ type meta_node_entry = { type: Symbol, ?args: Array[Symbol] }
13
+ end
data/sig/shims/env.rbs ADDED
@@ -0,0 +1,19 @@
1
+ # Environment patches: methods missing from rbs core and from the
2
+ # Bundler shim shipped inside the rbs gem — needed by the
3
+ # BootConstants probe.
4
+
5
+ module Bundler
6
+ def self.with_unbundled_env: [X] () { () -> X } -> X
7
+ end
8
+
9
+ module Process
10
+ def self.last_status: () -> ::Process::Status?
11
+ end
12
+
13
+ class IO
14
+ # `IO.popen([env_hash, cmd, *args])` — the env-hash-inside-the-array form
15
+ # the boot probe uses; rbs core only types env as a separate leading
16
+ # argument.
17
+ def self.popen: [X] (Array[Hash[String, String?] | String] env_and_cmd, ?String mode) { (instance) -> X } -> X
18
+ | ...
19
+ end