lix/subprojects/lix-clang-tidy
jade b62cc7b361 meson: prepare for include rearrangement
Context: we have include paths that are "types.hh" and similarly common
names. We currently have these compatibly available as
"lix/libutil/types.hh" externally but *not yet internally*. This is
because we don't have any way for the src directory to appear as
`"lix/"` from inside of Lix: the lix/ include directory is created by
the install process.

The goal of this whole thing is to make it clearer which component of
Lix that files are a part of, which should hopefully help at least a
little bit to new developers. One disadvantage of un-mixing these is
that it will cause some API changes if we ever move a file between
libraries, but that is not very common, and we don't care that much
about external API users.

This was planned for a while and is why we have a FixIncludes check to
begin with.

Personally I don't see a great benefit in rearranging our source code,
and in fact, it would probably be counterproductive:
- Moving the includes into a separate `include/` directory would just
  make developers have to deal with more directories, when we can
  already generate the desired layout through the build process.
- This would also decouple the .cc and .hh files which currently
  conventionally have each others' definitions and declarations
  respectively, right next to each other, making it easier for them to
  feel decoupled and diverge.

Content: Add ../include as an include directory so that lix/ in include
paths will resolve to src/ within Lix itself, just as it does externally
today. This prepares for a further series of commits applying the actual
change to each library one-by-one by accepting both include versions at
once.

This could have been done with ../ and a symlink called lix, but we
would like to not accept libexpr/foo.hh internally for it would be
broken externally, so we need an otherwise empty directory for the
include.

Change-Id: Ideac17faadae2bcea2dffbab34eb27c582ede399
2024-11-18 12:22:39 -08:00
..
.clang-format build: implement clang-tidy using our plugin 2024-08-04 20:41:19 -07:00
.editorconfig build: implement clang-tidy using our plugin 2024-08-04 20:41:19 -07:00
CharPtrCast.cc clang-tidy: write a lint for charptr_cast 2024-08-08 14:53:17 -07:00
CharPtrCast.hh clang-tidy: write a lint for charptr_cast 2024-08-08 14:53:17 -07:00
default.nix build: implement clang-tidy using our plugin 2024-08-04 20:41:19 -07:00
FixIncludes.cc meson: prepare for include rearrangement 2024-11-18 12:22:39 -08:00
FixIncludes.hh build: implement clang-tidy using our plugin 2024-08-04 20:41:19 -07:00
HasPrefixSuffix.cc build: implement clang-tidy using our plugin 2024-08-04 20:41:19 -07:00
HasPrefixSuffix.hh build: implement clang-tidy using our plugin 2024-08-04 20:41:19 -07:00
LixClangTidyChecks.cc clang-tidy: write a lint for charptr_cast 2024-08-08 14:53:17 -07:00
meson.build lix-clang-tidy: Require Clang >= 16 2024-08-23 12:17:01 -07:00
meson.options build: implement clang-tidy using our plugin 2024-08-04 20:41:19 -07:00
README.md build: implement clang-tidy using our plugin 2024-08-04 20:41:19 -07:00

Clang tidy lints for Lix

This is a skeleton of a clang-tidy lints library for Lix.

Currently there is one check (which is already obsolete as it has served its goal and is there as an example), HasPrefixSuffixCheck.

Running fixes/checks

One file:

ninja -C build && clang-tidy --checks='-*,lix-*' --load=build/liblix-clang-tidy.so -p ../compile_commands.json -header-filter '\.\./src/.*\.h' --fix ../src/libcmd/installables.cc

Several files, in parallel:

ninja -C build && run-clang-tidy -checks='-*,lix-*' -load=build/liblix-clang-tidy.so -p .. -header-filter '\.\./src/.*\.h' -fix ../src | tee -a clang-tidy-result

Resources

Developing new checks

Put something like so in myquery.txt:

set traversal     IgnoreUnlessSpelledInSource
# ^ Ignore implicit AST nodes. May need to use AsIs depending on how you are
# working.
set bind-root     true
# ^ true unless you use any .bind("foo") commands
set print-matcher true
enable output     dump
match callExpr(callee(functionDecl(hasName("hasPrefix"))), optionally(hasArgument( 0, cxxConstructExpr(hasDeclaration(functionDecl(hasParameter(0, parmVarDecl(hasType(asString("const char *"))).bind("meow2"))))))))

Then run, e.g. clang-query --preload hasprefix.query -p compile_commands.json src/libcmd/installables.cc.

With this you can iterate a query before writing it in C++ and suffering from C++.

Tips and tricks for the C++

There is a function dump() on many things that will dump to stderr. Also llvm::errs() lets you print to stderr.

When I wrote HasPrefixSuffixCheck, I was not really able to figure out how the structured replacement system was supposed to work. In principle you can describe the replacement with a nice DSL. Look up the Stencil system in Clang for details.