rfmt 0.2.3 → 0.2.4
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/CHANGELOG.md +5 -0
- data/Cargo.lock +1 -1
- data/ext/rfmt/Cargo.toml +1 -1
- data/ext/rfmt/src/ast/mod.rs +2 -0
- data/ext/rfmt/src/config/mod.rs +2 -2
- data/ext/rfmt/src/emitter/mod.rs +118 -0
- data/ext/rfmt/src/lib.rs +3 -0
- data/ext/rfmt/src/logging/logger.rs +5 -1
- data/lib/rfmt/prism_bridge.rb +2 -0
- data/lib/rfmt/rfmt.so +0 -0
- data/lib/rfmt/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d42c0061474a8e7ef36fc5cbce1d7bfdad2bc5a9dbbff9b1a2c2b700b373c6ca
|
|
4
|
+
data.tar.gz: f12d17ab726936fbdf69e4e5aaf3bca55fadf49230aa641adf0cba61c363f5ca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 51948c8616f667de54435f87f7e154209c27777e82a84ada9f73d97c8928f68a063da72c1d7268035ca7d8d6e3eec658e4f6d874770658501edaad68a512ecdf
|
|
7
|
+
data.tar.gz: e9a794b23d30ba314aa2b0f5fcacb6bbaff7408430bab6623169ef7d76fad53f32f58789e2a0a828a3b9e38dc074ca22bb0c4ff93f023e7c1a8c000081ba66e5
|
data/CHANGELOG.md
CHANGED
data/Cargo.lock
CHANGED
data/ext/rfmt/Cargo.toml
CHANGED
data/ext/rfmt/src/ast/mod.rs
CHANGED
|
@@ -40,6 +40,7 @@ pub enum NodeType {
|
|
|
40
40
|
// Expressions
|
|
41
41
|
CallNode,
|
|
42
42
|
IfNode,
|
|
43
|
+
ElseNode,
|
|
43
44
|
UnlessNode,
|
|
44
45
|
|
|
45
46
|
// Literals
|
|
@@ -83,6 +84,7 @@ impl NodeType {
|
|
|
83
84
|
"def_node" => Self::DefNode,
|
|
84
85
|
"call_node" => Self::CallNode,
|
|
85
86
|
"if_node" => Self::IfNode,
|
|
87
|
+
"else_node" => Self::ElseNode,
|
|
86
88
|
"unless_node" => Self::UnlessNode,
|
|
87
89
|
"string_node" => Self::StringNode,
|
|
88
90
|
"integer_node" => Self::IntegerNode,
|
data/ext/rfmt/src/config/mod.rs
CHANGED
|
@@ -110,7 +110,7 @@ impl Config {
|
|
|
110
110
|
for filename in &config_files {
|
|
111
111
|
let config_path = current_dir.join(filename);
|
|
112
112
|
if config_path.exists() {
|
|
113
|
-
log::
|
|
113
|
+
log::info!("Found config file: {:?}", config_path);
|
|
114
114
|
return Self::load_file(&config_path);
|
|
115
115
|
}
|
|
116
116
|
}
|
|
@@ -133,7 +133,7 @@ impl Config {
|
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
log::
|
|
136
|
+
log::info!("No config file found, using defaults");
|
|
137
137
|
Ok(Config::default())
|
|
138
138
|
}
|
|
139
139
|
|
data/ext/rfmt/src/emitter/mod.rs
CHANGED
|
@@ -113,6 +113,8 @@ impl Emitter {
|
|
|
113
113
|
NodeType::ClassNode => self.emit_class(node, indent_level)?,
|
|
114
114
|
NodeType::ModuleNode => self.emit_module(node, indent_level)?,
|
|
115
115
|
NodeType::DefNode => self.emit_method(node, indent_level)?,
|
|
116
|
+
NodeType::IfNode => self.emit_if_unless(node, indent_level, false, "if")?,
|
|
117
|
+
NodeType::UnlessNode => self.emit_if_unless(node, indent_level, false, "unless")?,
|
|
116
118
|
_ => self.emit_generic(node, indent_level)?,
|
|
117
119
|
}
|
|
118
120
|
Ok(())
|
|
@@ -304,6 +306,122 @@ impl Emitter {
|
|
|
304
306
|
Ok(())
|
|
305
307
|
}
|
|
306
308
|
|
|
309
|
+
/// Emit if/unless/elsif/else node
|
|
310
|
+
/// is_elsif: true if this is an elsif clause (don't emit 'end')
|
|
311
|
+
/// keyword: "if" or "unless"
|
|
312
|
+
fn emit_if_unless(&mut self, node: &Node, indent_level: usize, is_elsif: bool, keyword: &str) -> Result<()> {
|
|
313
|
+
// Check if this is a postfix if (modifier form)
|
|
314
|
+
// In postfix if, the statements come before the if keyword in source
|
|
315
|
+
let is_postfix = if let (Some(predicate), Some(statements)) =
|
|
316
|
+
(node.children.first(), node.children.get(1)) {
|
|
317
|
+
statements.location.start_offset < predicate.location.start_offset
|
|
318
|
+
} else {
|
|
319
|
+
false
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// Postfix if/unless: "statement if/unless condition"
|
|
323
|
+
if is_postfix && !is_elsif {
|
|
324
|
+
self.emit_comments_before(node.location.start_line, indent_level)?;
|
|
325
|
+
self.emit_indent(indent_level)?;
|
|
326
|
+
|
|
327
|
+
// Emit statement
|
|
328
|
+
if let Some(statements) = node.children.get(1) {
|
|
329
|
+
if matches!(statements.node_type, NodeType::StatementsNode) {
|
|
330
|
+
// Extract the statement text (without extra indentation)
|
|
331
|
+
if !self.source.is_empty() {
|
|
332
|
+
let start = statements.location.start_offset;
|
|
333
|
+
let end = statements.location.end_offset;
|
|
334
|
+
if let Some(text) = self.source.get(start..end) {
|
|
335
|
+
write!(self.buffer, "{}", text.trim())?;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
write!(self.buffer, " {} ", keyword)?;
|
|
342
|
+
|
|
343
|
+
// Emit condition
|
|
344
|
+
if let Some(predicate) = node.children.first() {
|
|
345
|
+
if !self.source.is_empty() {
|
|
346
|
+
let start = predicate.location.start_offset;
|
|
347
|
+
let end = predicate.location.end_offset;
|
|
348
|
+
if let Some(text) = self.source.get(start..end) {
|
|
349
|
+
write!(self.buffer, "{}", text)?;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return Ok(());
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Normal if/unless/elsif
|
|
358
|
+
if !is_elsif {
|
|
359
|
+
self.emit_comments_before(node.location.start_line, indent_level)?;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Emit 'if'/'unless' or 'elsif' keyword
|
|
363
|
+
self.emit_indent(indent_level)?;
|
|
364
|
+
if is_elsif {
|
|
365
|
+
write!(self.buffer, "elsif ")?;
|
|
366
|
+
} else {
|
|
367
|
+
write!(self.buffer, "{} ", keyword)?;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Emit predicate (condition) - first child
|
|
371
|
+
if let Some(predicate) = node.children.first() {
|
|
372
|
+
// Extract predicate from source
|
|
373
|
+
if !self.source.is_empty() {
|
|
374
|
+
let start = predicate.location.start_offset;
|
|
375
|
+
let end = predicate.location.end_offset;
|
|
376
|
+
if let Some(text) = self.source.get(start..end) {
|
|
377
|
+
write!(self.buffer, "{}", text)?;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
self.buffer.push('\n');
|
|
383
|
+
|
|
384
|
+
// Emit then clause (second child is StatementsNode)
|
|
385
|
+
if let Some(statements) = node.children.get(1) {
|
|
386
|
+
if matches!(statements.node_type, NodeType::StatementsNode) {
|
|
387
|
+
self.emit_statements(statements, indent_level + 1)?;
|
|
388
|
+
self.buffer.push('\n');
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Check for elsif/else (third child)
|
|
393
|
+
if let Some(consequent) = node.children.get(2) {
|
|
394
|
+
match &consequent.node_type {
|
|
395
|
+
NodeType::IfNode => {
|
|
396
|
+
// This is an elsif clause (only valid for if, not unless)
|
|
397
|
+
self.emit_if_unless(consequent, indent_level, true, "if")?;
|
|
398
|
+
}
|
|
399
|
+
NodeType::ElseNode => {
|
|
400
|
+
// This is an else clause
|
|
401
|
+
self.emit_indent(indent_level)?;
|
|
402
|
+
write!(self.buffer, "else\n")?;
|
|
403
|
+
|
|
404
|
+
// Emit else body (first child of ElseNode)
|
|
405
|
+
if let Some(else_statements) = consequent.children.first() {
|
|
406
|
+
if matches!(else_statements.node_type, NodeType::StatementsNode) {
|
|
407
|
+
self.emit_statements(else_statements, indent_level + 1)?;
|
|
408
|
+
self.buffer.push('\n');
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
_ => {}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Only emit 'end' for the outermost if (not for elsif)
|
|
417
|
+
if !is_elsif {
|
|
418
|
+
self.emit_indent(indent_level)?;
|
|
419
|
+
write!(self.buffer, "end")?;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
Ok(())
|
|
423
|
+
}
|
|
424
|
+
|
|
307
425
|
/// Emit generic node by extracting from source
|
|
308
426
|
fn emit_generic(&mut self, node: &Node, indent_level: usize) -> Result<()> {
|
|
309
427
|
// Emit any comments before this node
|
data/ext/rfmt/src/lib.rs
CHANGED
|
@@ -14,6 +14,7 @@ use magnus::{define_module, function, prelude::*, Error, Ruby};
|
|
|
14
14
|
use parser::{PrismAdapter, RubyParser};
|
|
15
15
|
|
|
16
16
|
fn format_ruby_code(ruby: &Ruby, source: String, json: String) -> Result<String, Error> {
|
|
17
|
+
log::info!("format_ruby_code called");
|
|
17
18
|
let policy = SecurityPolicy::default();
|
|
18
19
|
|
|
19
20
|
policy
|
|
@@ -26,7 +27,9 @@ fn format_ruby_code(ruby: &Ruby, source: String, json: String) -> Result<String,
|
|
|
26
27
|
let ast = parser.parse(&json).map_err(|e| e.to_magnus_error(ruby))?;
|
|
27
28
|
|
|
28
29
|
// Load configuration from file or use defaults
|
|
30
|
+
log::info!("Attempting to discover config file...");
|
|
29
31
|
let config = Config::discover().map_err(|e| e.to_magnus_error(ruby))?;
|
|
32
|
+
log::info!("Config loaded successfully, line_length: {}", config.formatting.line_length);
|
|
30
33
|
let mut emitter = Emitter::with_source(config, source);
|
|
31
34
|
|
|
32
35
|
let formatted = emitter.emit(&ast).map_err(|e| e.to_magnus_error(ruby))?;
|
|
@@ -22,7 +22,11 @@ impl RfmtLogger {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
pub fn init() {
|
|
25
|
-
let
|
|
25
|
+
let level = std::env::var("RFMT_LOG")
|
|
26
|
+
.ok()
|
|
27
|
+
.and_then(|s| s.parse().ok())
|
|
28
|
+
.unwrap_or(LevelFilter::Info);
|
|
29
|
+
let logger = Self::new(level);
|
|
26
30
|
log::set_boxed_logger(Box::new(logger)).expect("Failed to initialize logger");
|
|
27
31
|
log::set_max_level(LevelFilter::Trace);
|
|
28
32
|
}
|
data/lib/rfmt/prism_bridge.rb
CHANGED
data/lib/rfmt/rfmt.so
CHANGED
|
Binary file
|
data/lib/rfmt/version.rb
CHANGED