Skip to content

Report symbol literals in Naming/AsciiIdentifiers rule #424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions spec/ameba/rule/naming/ascii_identifiers_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,35 @@ module Ameba::Rule::Naming
CRYSTAL
end

it "reports defs with parameter default values containing non-ascii characters" do
expect_issue subject, <<-CRYSTAL
def forest_adventure(animal_type = :🐺)
# ^^ error: Identifier contains non-ascii characters
end
CRYSTAL
end

it "reports argument names containing non-ascii characters" do
expect_issue subject, <<-CRYSTAL
%w[wensleydale cheddar brie].each { |🧀| nil }
# ^ error: Identifier contains non-ascii characters
CRYSTAL
end

it "reports calls with arguments containing non-ascii characters" do
expect_issue subject, <<-CRYSTAL
%i[🐺 🐿].index!(:🐺)
# ^^ error: Identifier contains non-ascii characters
CRYSTAL
end

it "reports calls with named arguments containing non-ascii characters" do
expect_issue subject, <<-CRYSTAL
%i[🐺 🐿].index!(obj: :🐺)
# ^^ error: Identifier contains non-ascii characters
CRYSTAL
end

it "reports aliases with names containing non-ascii characters" do
expect_issue subject, <<-CRYSTAL
alias JSON🧀 = JSON::Any
Expand Down Expand Up @@ -84,11 +106,46 @@ module Ameba::Rule::Naming
CRYSTAL
end

it "reports assignments with symbol literals containing non-ascii characters" do
expect_issue subject, <<-CRYSTAL
foo = :신장
# ^^^ error: Identifier contains non-ascii characters
CRYSTAL
end

it "reports multiple assignments with symbol literals containing non-ascii characters" do
expect_issue subject, <<-CRYSTAL
foo, bar = :신장, true
# ^^^ error: Identifier contains non-ascii characters
CRYSTAL
end

it "passes for strings with non-ascii characters" do
expect_no_issues subject, <<-CRYSTAL
space = "👾"
space = :invader # 👾
CRYSTAL
end

context "properties" do
context "#ignore_symbols" do
it "returns `false` by default" do
rule = AsciiIdentifiers.new
rule.ignore_symbols?.should be_false
end

it "stops reporting symbol literals if set to `true`" do
rule = AsciiIdentifiers.new
rule.ignore_symbols = true

expect_no_issues rule, <<-CRYSTAL
def forest_adventure(animal_type = :🐺); end
%i[🐺 🐿].index!(:🐺)
foo, bar = :신장, true
foo = :신장
CRYSTAL
end
end
end
end
end
1 change: 1 addition & 0 deletions src/ameba/ast/visitors/node_visitor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module Ameba::AST
IsA,
LibDef,
ModuleDef,
MultiAssign,
NilLiteral,
StringInterpolation,
Unless,
Expand Down
24 changes: 22 additions & 2 deletions src/ameba/rule/naming/ascii_identifiers.cr
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ module Ameba::Rule::Naming
# ```
# Naming/AsciiIdentifiers:
# Enabled: true
# IgnoreSymbols: false
# ```
class AsciiIdentifiers < Base
properties do
description "Disallows non-ascii characters in identifiers"
ignore_symbols false
end

MSG = "Identifier contains non-ascii characters"
Expand All @@ -32,11 +34,21 @@ module Ameba::Rule::Naming
if (target = node.target).is_a?(Crystal::Path)
check_issue(source, target, target)
end
check_symbol_literal(source, node.value)
end

def test(source, node : Crystal::MultiAssign)
node.targets.each do |target|
check_issue(source, target, target)
node.values.each do |value|
check_symbol_literal(source, value)
end
end

def test(source, node : Crystal::Call)
node.args.each do |arg|
check_symbol_literal(source, arg)
end
node.named_args.try &.each do |arg|
check_symbol_literal(source, arg.value)
end
end

Expand All @@ -45,6 +57,7 @@ module Ameba::Rule::Naming

node.args.each do |arg|
check_issue(source, arg, prefer_name_location: true)
check_symbol_literal(source, arg.default_value)
end
end

Expand All @@ -56,6 +69,13 @@ module Ameba::Rule::Naming
check_issue(source, node.name, node.name)
end

private def check_symbol_literal(source, node)
return if ignore_symbols?
return unless node.is_a?(Crystal::SymbolLiteral)

check_issue(source, node, node.value)
end

private def check_issue(source, location, end_location, name)
issue_for location, end_location, MSG unless name.to_s.ascii_only?
end
Expand Down