mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Merge pull request #414 from crystal-ameba/add-ascii-identifiers-rule
Add `Naming/AsciiIdentifiers` rule
This commit is contained in:
commit
0abb73f0b6
2 changed files with 174 additions and 0 deletions
94
spec/ameba/rule/naming/ascii_identifiers_spec.cr
Normal file
94
spec/ameba/rule/naming/ascii_identifiers_spec.cr
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
require "../../../spec_helper"
|
||||||
|
|
||||||
|
module Ameba::Rule::Naming
|
||||||
|
subject = AsciiIdentifiers.new
|
||||||
|
|
||||||
|
describe AsciiIdentifiers do
|
||||||
|
it "reports classes with names containing non-ascii characters" do
|
||||||
|
expect_issue subject, <<-CRYSTAL
|
||||||
|
class BigAwesome🐺
|
||||||
|
# ^^^^^^^^^^^ error: Identifier contains non-ascii characters
|
||||||
|
@🐺_name : String
|
||||||
|
# ^^^^^^^ error: Identifier contains non-ascii characters
|
||||||
|
end
|
||||||
|
CRYSTAL
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reports modules with names containing non-ascii characters" do
|
||||||
|
expect_issue subject, <<-CRYSTAL
|
||||||
|
module Bąk
|
||||||
|
# ^^^ error: Identifier contains non-ascii characters
|
||||||
|
@@bąk_name : String
|
||||||
|
# ^^^^^^^^^^ error: Identifier contains non-ascii characters
|
||||||
|
end
|
||||||
|
CRYSTAL
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reports enums with names containing non-ascii characters" do
|
||||||
|
expect_issue subject, <<-CRYSTAL
|
||||||
|
enum TypeOf🔥
|
||||||
|
# ^^^^^^^ error: Identifier contains non-ascii characters
|
||||||
|
end
|
||||||
|
CRYSTAL
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reports defs with names containing non-ascii characters" do
|
||||||
|
expect_issue subject, <<-CRYSTAL
|
||||||
|
def łódź
|
||||||
|
# ^^^^ error: Identifier contains non-ascii characters
|
||||||
|
end
|
||||||
|
CRYSTAL
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reports defs with parameter names containing non-ascii characters" do
|
||||||
|
expect_issue subject, <<-CRYSTAL
|
||||||
|
def forest_adventure(include_🐺 = true, include_🐿 = true)
|
||||||
|
# ^ error: Identifier contains non-ascii characters
|
||||||
|
# ^ 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 aliases with names containing non-ascii characters" do
|
||||||
|
expect_issue subject, <<-CRYSTAL
|
||||||
|
alias JSON🧀 = JSON::Any
|
||||||
|
# ^^^^^ error: Identifier contains non-ascii characters
|
||||||
|
CRYSTAL
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reports constants with names containing non-ascii characters" do
|
||||||
|
expect_issue subject, <<-CRYSTAL
|
||||||
|
I_LOVE_🍣 = true
|
||||||
|
# ^^^^^^ error: Identifier contains non-ascii characters
|
||||||
|
CRYSTAL
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reports assignments with variable names containing non-ascii characters" do
|
||||||
|
expect_issue subject, <<-CRYSTAL
|
||||||
|
space_👾 = true
|
||||||
|
# ^^^^^ error: Identifier contains non-ascii characters
|
||||||
|
CRYSTAL
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reports multiple assignments with variable names containing non-ascii characters" do
|
||||||
|
expect_issue subject, <<-CRYSTAL
|
||||||
|
foo, space_👾 = true, 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
|
||||||
|
end
|
||||||
|
end
|
80
src/ameba/rule/naming/ascii_identifiers.cr
Normal file
80
src/ameba/rule/naming/ascii_identifiers.cr
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
module Ameba::Rule::Naming
|
||||||
|
# A rule that reports non-ascii characters in identifiers.
|
||||||
|
#
|
||||||
|
# Favour this:
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# class BigAwesomeWolf
|
||||||
|
# end
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# Over this:
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# class BigAwesome🐺
|
||||||
|
# end
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# YAML configuration example:
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# Naming/AsciiIdentifiers:
|
||||||
|
# Enabled: true
|
||||||
|
# ```
|
||||||
|
class AsciiIdentifiers < Base
|
||||||
|
include AST::Util
|
||||||
|
|
||||||
|
properties do
|
||||||
|
description "Disallows non-ascii characters in identifiers"
|
||||||
|
end
|
||||||
|
|
||||||
|
MSG = "Identifier contains non-ascii characters"
|
||||||
|
|
||||||
|
def test(source, node : Crystal::Assign)
|
||||||
|
if (target = node.target).is_a?(Crystal::Path)
|
||||||
|
check_issue(source, target, target)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test(source, node : Crystal::MultiAssign)
|
||||||
|
node.targets.each do |target|
|
||||||
|
check_issue(source, target, target)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test(source, node : Crystal::Def)
|
||||||
|
check_issue_with_location(source, node)
|
||||||
|
|
||||||
|
node.args.each do |arg|
|
||||||
|
check_issue_with_location(source, arg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test(source, node : Crystal::ClassVar | Crystal::InstanceVar | Crystal::Var | Crystal::Alias)
|
||||||
|
check_issue_with_location(source, node)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test(source, node : Crystal::ClassDef | Crystal::ModuleDef | Crystal::EnumDef | Crystal::LibDef)
|
||||||
|
check_issue(source, node.name, node.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
private def check_issue_with_location(source, node)
|
||||||
|
location = name_location(node)
|
||||||
|
end_location = name_end_location(node)
|
||||||
|
|
||||||
|
if location && end_location
|
||||||
|
check_issue(source, location, end_location, node.name)
|
||||||
|
else
|
||||||
|
check_issue(source, node, node.name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private def check_issue(source, location, end_location, name)
|
||||||
|
issue_for location, end_location, MSG unless name.to_s.ascii_only?
|
||||||
|
end
|
||||||
|
|
||||||
|
private def check_issue(source, node, name)
|
||||||
|
issue_for node, MSG unless name.to_s.ascii_only?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue