llvm-project/clang/lib/Tooling
Konrad Kleine d46fa023ca [clang-format] SortIncludes should support "@import" lines in Objective-C
Fixes [[ https://github.com/llvm/llvm-project/issues/38995 | #38995 ]]

This is an attempt to modify the regular expression to identify
`@import` and `import` alongside the regular `#include`. The challenging
part was not to support `@` in addition to `#` but how to handle
everything that comes after the `include|import` keywords. Previously
everything that wasn't `"` or `<` was consumed. But as you can see in
this example from the issue #38995, there is no `"` or `<` following the
keyword:

```
@import Foundation;
```

I experimented with a lot of fancy and useful expressions in [this
online regex tool](https://regex101.com) only to find out that some
things are simply not supported by the regex implementation in LLVM.

 * For example the beginning `[\t\ ]*` should be replacable by the
   horizontal whitespace character `\h*` but this will break the
   `SortIncludesTest.LeadingWhitespace` test.

That's why I've chosen to come back to the basic building blocks.

The essential change in this patch is the change from this regular
expression:

```
^[\t\ ]*#[\t\ ]*(import|include)[^"<]*(["<][^">]*[">])
        ~                              ~~~~~~~~~~~~~~
        ^                              ^
        |                              |
        only support # prefix not @    |
                                       only support "" and <> as
delimiters
                                       no support for C++ modules and ;
                                       ending. Also this allows for ">
                                       or <" or "" or <> which all seems
                                       either off or wrong.
```

to this:

```
^[\t\ ]*[@#][\t\ ]*(import|include)([^"]*("[^"]+")|[^<]*(<[^>]+>)|[\t\
]*([^;]+;))
        ~~~~                        ~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
~~~~~~~~~~~~~~
        ^                                 ^           ^       ^       ^
        |                                 |           |       |       |
        Now support @ and #.            Clearly support "" and <> as
well as an
                                        include name without enclosing
characters.
                                        Allows for no mixture of "> or
<" or
                                        empty include names.

```

Here is how I've tested this patch:

```
ninja clang-Format
ninja FormatTests
./tools/clang/unittests/Format/FormatTests
--gtest_filter=SortIncludesTest*
```

And if that worked I doubled checked that nothing else broke by running
all format checks:

```
./tools/clang/unittests/Format/FormatTests
```

One side effect of this change is it should partially support
[C++20 Module](https://en.cppreference.com/w/cpp/language/modules)
`import` lines without the optional `export` in front. Adding
this can be a change on its own that shouldn't be too hard. I say
partially because the `@` or `#` are currently *NOT* optional in the
regular expression.

I see an opportunity to optimized the matching to exclude `@include` for
example. But eventually these should be caught by the compiler, so...

With my change, the matching group is not at a fixed position any
longer. I decided to
choose the last match (group) that is not empty.

Reviewed By: HazardyKnusperkeks

Differential Revision: https://reviews.llvm.org/D121370
2022-04-20 07:03:35 +00:00
..
ASTDiff [openmp] Base of tablegen generated OpenMP common declaration 2020-06-23 10:32:32 -04:00
Core [libtooling][clang-tidy] Fix diagnostics not highlighting fed SourceRanges 2021-04-10 16:43:44 +02:00
DependencyScanning [clang][deps] NFC: Inline function with single caller 2022-04-15 16:24:40 +02:00
DumpTool [clang] NFC: Extract DiagnosticOptions parsing 2021-09-02 14:37:14 +02:00
Inclusions [clang-format] SortIncludes should support "@import" lines in Objective-C 2022-04-20 07:03:35 +00:00
Refactoring [clang-rename] Handle designated initializers. 2021-04-12 13:15:14 -07:00
Syntax Reapply [pseudo] Move pseudoparser from clang to clang-tools-extra" 2022-03-16 01:10:55 +01:00
Transformer [libTooling] Support TransformerResult<void> in consumer callbacks 2022-03-28 15:39:46 +00:00
AllTUsExecution.cpp ADT: Allow IntrusiveRefCntPtr construction from std::unique_ptr, NFC 2020-12-08 17:33:19 -08:00
ArgumentsAdjusters.cpp [clang][deps] Move stripping of diagnostic serialization from `clang-scan-deps` to `DependencyScanning` library 2021-06-14 12:23:32 +02:00
CMakeLists.txt [cmake] use project relative paths when generating ASTNodeAPI.json 2021-11-15 12:35:34 +01:00
CommonOptionsParser.cpp [clang] Replace report_fatal_error(std::string) uses with report_fatal_error(Twine) 2021-10-06 11:43:19 +01:00
CompilationDatabase.cpp [CompilationDatabase] Pass Twine by const reference instead of by value. NFCI. 2021-01-07 12:53:28 +00:00
EmptyNodeIntrospection.inc.in [AST] Add DeclarationNameInfo to node introspection 2021-04-25 12:12:03 +01:00
Execution.cpp [NFC] Refactor Registry loops to range for 2020-06-19 00:40:10 +01:00
ExpandResponseFilesCompilationDatabase.cpp [Support] Expand `<CFGDIR>` as the base directory in configuration files. 2021-12-30 13:43:47 -05:00
FileMatchTrie.cpp [clang][Tooling] Try to avoid file system access if there is no record for the file in compile_commads.json 2020-07-17 18:49:14 +02:00
FixIt.cpp
GuessTargetAndModeCompilationDatabase.cpp
InterpolatingCompilationDatabase.cpp [Tooling] When transferring compile commands between files, always use '--' 2022-01-11 01:41:42 +01:00
JSONCompilationDatabase.cpp [clang][Tooling] Use Windows command lines on all Windows, except Cygwin 2021-10-13 22:55:14 +03:00
NodeIntrospection.cpp [AST] Sort introspection results without instantiating other data 2021-04-23 16:21:01 +01:00
Refactoring.cpp
RefactoringCallbacks.cpp
StandaloneExecution.cpp
Tooling.cpp [clang][tooling] Properly initialize DiagnosticsEngine for cc1 command-line construction 2021-09-10 13:54:24 +02:00