From a3c11b9c16b1f8678e3b79f1c2a4032161067958 Mon Sep 17 00:00:00 2001 From: ydah Date: Sat, 5 Sep 2026 21:14:42 +0900 Subject: [PATCH] Improve warning diagnostics --- lib/lrama/warnings/implicit_empty.rb | 3 ++- lib/lrama/warnings/mixed_references.rb | 2 +- lib/lrama/warnings/name_conflicts.rb | 2 +- spec/lrama/warnings/implicit_empty_spec.rb | 14 +++++++++----- spec/lrama/warnings/mixed_references_spec.rb | 16 ++++++++-------- spec/lrama/warnings/name_conflicts_spec.rb | 8 ++++---- 6 files changed, 25 insertions(+), 20 deletions(-) diff --git a/lib/lrama/warnings/implicit_empty.rb b/lib/lrama/warnings/implicit_empty.rb index ba81adca0..24f985765 100644 --- a/lib/lrama/warnings/implicit_empty.rb +++ b/lib/lrama/warnings/implicit_empty.rb @@ -20,7 +20,8 @@ def warn(grammar) grammar.rule_builders.each do |builder| if builder.rhs.empty? - @logger.warn("warning: empty rule without %empty") + lhs = builder.lhs #: Lrama::Lexer::Token::Base + @logger.warn(lhs.location.generate_error_message("empty rule for #{lhs.s_value} without %empty").chomp) end end end diff --git a/lib/lrama/warnings/mixed_references.rb b/lib/lrama/warnings/mixed_references.rb index 07c59a36d..b137e0c43 100644 --- a/lib/lrama/warnings/mixed_references.rb +++ b/lib/lrama/warnings/mixed_references.rb @@ -24,7 +24,7 @@ def warn(grammar) build_grouped_usage(grammar).each do |rule, usage| next unless usage[:positional] && usage[:named] - @logger.warn("warning: rule `#{rule.as_comment}` mixes positional and named references; use named references consistently") + @logger.warn("rule `#{rule.as_comment}` mixes positional and named references; use named references consistently") end end diff --git a/lib/lrama/warnings/name_conflicts.rb b/lib/lrama/warnings/name_conflicts.rb index c0754ab55..b150beda8 100644 --- a/lib/lrama/warnings/name_conflicts.rb +++ b/lib/lrama/warnings/name_conflicts.rb @@ -55,7 +55,7 @@ def check_conflicts(parameterized_rules, symbol_names) parameterized_rules.each do |param_rule| next unless symbol_names.include?(param_rule.name) - @logger.warn("warning: parameterized rule name \"#{param_rule.name}\" conflicts with symbol name") + @logger.warn("parameterized rule name \"#{param_rule.name}\" conflicts with symbol name") end end end diff --git a/spec/lrama/warnings/implicit_empty_spec.rb b/spec/lrama/warnings/implicit_empty_spec.rb index 0f4162d45..2054a50fa 100644 --- a/spec/lrama/warnings/implicit_empty_spec.rb +++ b/spec/lrama/warnings/implicit_empty_spec.rb @@ -19,16 +19,20 @@ end context "when warnings true" do - it "has warns for parameterized rule redefined" do + it "warns with the rule location" do grammar = Lrama::Parser.new(y, "states/empty.y").parse grammar.prepare grammar.validate! states = Lrama::States.new(grammar, Lrama::Tracer.new(Lrama::Logger.new)) states.compute - logger = Lrama::Logger.new - allow(logger).to receive(:warn) + out = StringIO.new + logger = Lrama::Logger.new(out) Lrama::Warnings.new(logger, true).warn(grammar, states) - expect(logger).to have_received(:warn).with("warning: empty rule without %empty") + expect(out.string).to eq(<<~WARNING) + warning: states/empty.y:9:0: empty rule for program without %empty + 9 | program: /* empty */ + | ^~~~~~~ + WARNING end end @@ -42,7 +46,7 @@ logger = Lrama::Logger.new allow(logger).to receive(:warn) Lrama::Warnings.new(logger, false).warn(grammar, states) - expect(logger).not_to have_received(:warn).with("warning: empty rule without %empty") + expect(logger).not_to have_received(:warn) end end end diff --git a/spec/lrama/warnings/mixed_references_spec.rb b/spec/lrama/warnings/mixed_references_spec.rb index ef4e1d605..48a878d4e 100644 --- a/spec/lrama/warnings/mixed_references_spec.rb +++ b/spec/lrama/warnings/mixed_references_spec.rb @@ -32,7 +32,7 @@ Lrama::Warnings.new(logger, true).warn(grammar, states) - expect(logger).to have_received(:warn).with("warning: rule `expr: NUM NUM` mixes positional and named references; use named references consistently") + expect(logger).to have_received(:warn).with("rule `expr: NUM NUM` mixes positional and named references; use named references consistently") end it "does not warn when named references are used consistently" do @@ -100,7 +100,7 @@ Lrama::Warnings.new(logger, true).warn(grammar, states) - expect(logger).to have_received(:warn).with(/warning: rule `expr: .*` mixes positional and named references; use named references consistently/).once + expect(logger).to have_received(:warn).with(/rule `expr: .*` mixes positional and named references; use named references consistently/).once end it "does not warn when positional references are used consistently" do @@ -165,7 +165,7 @@ Lrama::Warnings.new(logger, true).warn(grammar, states) - expect(logger).to have_received(:warn).with("warning: rule `expr: NUM` mixes positional and named references; use named references consistently") + expect(logger).to have_received(:warn).with("rule `expr: NUM` mixes positional and named references; use named references consistently") end it "warns when mixing address-of location references and named value references" do @@ -198,7 +198,7 @@ Lrama::Warnings.new(logger, true).warn(grammar, states) - expect(logger).to have_received(:warn).with("warning: rule `expr: NUM NUM` mixes positional and named references; use named references consistently") + expect(logger).to have_received(:warn).with("rule `expr: NUM NUM` mixes positional and named references; use named references consistently") end it "warns when mixing index and named value references" do @@ -231,7 +231,7 @@ Lrama::Warnings.new(logger, true).warn(grammar, states) - expect(logger).to have_received(:warn).with("warning: rule `expr: NUM` mixes positional and named references; use named references consistently") + expect(logger).to have_received(:warn).with("rule `expr: NUM` mixes positional and named references; use named references consistently") end it "does not warn when using only special and positional index references" do @@ -296,7 +296,7 @@ Lrama::Warnings.new(logger, true).warn(grammar, states) - expect(logger).to have_received(:warn).with("warning: rule `expr: NUM` mixes positional and named references; use named references consistently") + expect(logger).to have_received(:warn).with("rule `expr: NUM` mixes positional and named references; use named references consistently") end it "does not warn when mixing special LHS and positional references" do @@ -458,7 +458,7 @@ Lrama::Warnings.new(logger, true).warn(grammar, states) - expect(logger).to have_received(:warn).with("warning: rule `expr: LEFT tPLUS RIGHT` mixes positional and named references; use named references consistently") + expect(logger).to have_received(:warn).with("rule `expr: LEFT tPLUS RIGHT` mixes positional and named references; use named references consistently") end it "warns when mixing tagged LHS alias and positional references" do @@ -490,7 +490,7 @@ Lrama::Warnings.new(logger, true).warn(grammar, states) - expect(logger).to have_received(:warn).with("warning: rule `expr: NUM` mixes positional and named references; use named references consistently") + expect(logger).to have_received(:warn).with("rule `expr: NUM` mixes positional and named references; use named references consistently") end end diff --git a/spec/lrama/warnings/name_conflicts_spec.rb b/spec/lrama/warnings/name_conflicts_spec.rb index 3f48deb13..287788d29 100644 --- a/spec/lrama/warnings/name_conflicts_spec.rb +++ b/spec/lrama/warnings/name_conflicts_spec.rb @@ -31,7 +31,7 @@ logger = Lrama::Logger.new allow(logger).to receive(:warn) Lrama::Warnings.new(logger, true).warn(grammar, states) - expect(logger).to have_received(:warn).with('warning: parameterized rule name "option" conflicts with symbol name') + expect(logger).to have_received(:warn).with('parameterized rule name "option" conflicts with symbol name') end end @@ -78,7 +78,7 @@ logger = Lrama::Logger.new allow(logger).to receive(:warn) Lrama::Warnings.new(logger, true).warn(grammar, states) - expect(logger).to have_received(:warn).with('warning: parameterized rule name "program" conflicts with symbol name') + expect(logger).to have_received(:warn).with('parameterized rule name "program" conflicts with symbol name') end end @@ -193,8 +193,8 @@ logger = Lrama::Logger.new allow(logger).to receive(:warn) Lrama::Warnings.new(logger, true).warn(grammar, states) - expect(logger).to have_received(:warn).with('warning: parameterized rule name "option" conflicts with symbol name') - expect(logger).to have_received(:warn).with('warning: parameterized rule name "separated" conflicts with symbol name') + expect(logger).to have_received(:warn).with('parameterized rule name "option" conflicts with symbol name') + expect(logger).to have_received(:warn).with('parameterized rule name "separated" conflicts with symbol name') end end end