aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts/linters/no_use_as_alias.rb
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-28 17:45:06 +0900
committernsfisis <nsfisis@gmail.com>2026-06-28 17:45:26 +0900
commit53f1fb395f33e0fb8db9aebd09ea9082f650f9f1 (patch)
treef9e8bf0e9d4b1e98cce383574fb6a13b684fff08 /scripts/linters/no_use_as_alias.rb
parent212f5cd75b1403ee75ffa44d7ebdb181174340c0 (diff)
downloadphp-shirabe-53f1fb395f33e0fb8db9aebd09ea9082f650f9f1.tar.gz
php-shirabe-53f1fb395f33e0fb8db9aebd09ea9082f650f9f1.tar.zst
php-shirabe-53f1fb395f33e0fb8db9aebd09ea9082f650f9f1.zip
refactor: add linter
Diffstat (limited to 'scripts/linters/no_use_as_alias.rb')
-rw-r--r--scripts/linters/no_use_as_alias.rb57
1 files changed, 57 insertions, 0 deletions
diff --git a/scripts/linters/no_use_as_alias.rb b/scripts/linters/no_use_as_alias.rb
new file mode 100644
index 0000000..8e0c86b
--- /dev/null
+++ b/scripts/linters/no_use_as_alias.rb
@@ -0,0 +1,57 @@
+def no_use_as_alias(root_dir, excludes = [])
+ pattern = root_dir.join('crates', '**', '*.rs').to_s
+ errors = Dir.glob(pattern).sort.flat_map do |path|
+ relative = Pathname.new(path).relative_path_from(root_dir).to_s
+ next [] if excludes.include?(relative)
+
+ find_use_aliases(path, relative)
+ end
+
+ return true if errors.empty?
+
+ puts 'Found `use ... as name` aliases.'
+ puts 'Aliasing imports merely to shorten a namespace is forbidden.'
+ puts 'Only `as _` (e.g. `use std::io::Write as _;`) and PascalCase renames'
+ puts '(for collision avoidance, e.g. `use foo::Error as FooError;`) are allowed:'
+ errors.each do |err|
+ puts " #{err}"
+ end
+ false
+end
+
+USE_ALIAS_START_RE = /\A(?:pub(?:\([^)]*\))?\s+)?use\b/
+PASCAL_CASE_RE = /\A[A-Z][A-Za-z0-9]*\z/
+
+def find_use_aliases(path, relative)
+ errors = []
+ in_use = false
+ brace_depth = 0
+
+ File.readlines(path).each_with_index do |raw, idx|
+ code = raw.split('//', 2).first || raw
+ stripped = code.strip
+
+ unless in_use
+ next unless stripped =~ USE_ALIAS_START_RE
+
+ in_use = true
+ brace_depth = 0
+ end
+
+ code.scan(/\bas\s+([A-Za-z_][A-Za-z0-9_]*)/) do |m|
+ name = m[0]
+ next if name == '_'
+ next if name =~ PASCAL_CASE_RE
+
+ errors << "#{relative}:#{idx + 1}: `as #{name}` aliasing in `use` statement"
+ end
+
+ brace_depth += code.count('{') - code.count('}')
+ if brace_depth <= 0 && code.rstrip.end_with?(';')
+ in_use = false
+ brace_depth = 0
+ end
+ end
+
+ errors
+end