llvm / llvm/llvm-project

[clang-format] Add additional sorts similar to `SortIncludes`

Open
#187,891 1 comment 4 reactions 0 assignees View on GitHub
clang-format
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

I would like to propose the addition of additional sorting rules, for `import` statements and `using` statements. At the present, only `#include` directives can be sorted. With the growing tool support for modules, I think including this would be relevant.

I would to propose adding: `SortImports` and `SortUsings`. `SortImports` should behave like `SortIncludes`, though it isn't clear to me whether they should be separated by blocks or all clustered into one area. There are multiple potential directions this could go:
```cpp
export module proj.x; // Let the current project module name be "proj.x"

// Option 1

import std;

import proj.a;
import proj.a.x;
import proj.a.y;
import proj.a.z;
import proj.b;
import proj.q;

import extlib.r;
import extlib.s;

import m;

import n;

import o;

// Option 2
import std;
import proj.a;
import proj.a.x;
import proj.a.y;
import proj.a.z;
import proj.b;
import proj.q;
import extlib.r;
import extlib.s;
import m;
import n;
import o;
```
Meanwhile, `SortUsings` is typically something with a known precedence in most languages. I recommend we follow [JetBrains's auto-import for Java](https://www.jetbrains.com/help/idea/creating-and-optimizing-imports.html) or [rustfmt's `use` statement sorting](https://doc.rust-lang.org/style-guide/items.html) for how to sort `using` imports (C++ `using` statements lack the versatility and ergonomics of Rust `use` statements unfortunately, which at least makes it easier to implement like Java's). My guess is it would look something like
```cpp
export module proj.x;

// module imports above, before using imports

using std::expected;
using std::formatter;
using std::string;
using std::unordered_map;
using std::vector;
using std::chrono::duration;
using std::chrono::system_clock;
using std::execution::run_loop;
using std::execution::task;
using std::filesystem::path;
using std::meta::info;
using std::pmr::memory_resource;
using std::pmr::polymorphic_allocator;
using std::views::filter;
using std::views::take;

using proj::a::SomeClassA;
using proj::a::SomeClassB;
using proj::a::x::SomeClassX;
using proj::a::y::SomeClassY;
using proj::a::z::SomeClassZ;
using proj::b::SomeOtherClassA;
using proj::q::YetAnotherClassQ;

using extlib::r::ExternalClassR;
using extlib::s::ExternalClassS;

// I think the picture is clear now, etc.
```

Contributor guide

Open the contributing guide

Research direction

Start by reading clang-format's existing SortIncludes behavior and compare it with the proposed SortImports and SortUsings rules. Resolve whether imports should be separated into blocks or clustered, and define the precedence for using statements. Done means the sorting behavior and configuration options are specified clearly enough to implement.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.