aboutsummaryrefslogtreecommitdiffstats
path: root/HOWTO
blob: 09d2c8e994faa80e242aae41c4680d1035a4dd12 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
Help on how to create a new check or a fixit

--------------------------------------------------------------------------------
Files to create or modify

checks/levelX/my-check.cpp
checks/levelX/my-check.h
checks/README-my-check.md
tests/my-check/config.json
tests/my-check/main.cpp
ClazySources.cmake
--------------------------------------------------------------------------------
Tips

- Write the unit-test before the check

- Dump the abstract syntax tree (AST) of your unit-test:

  ./run_tests.py my-test --dump-ast

  This creates a main.cpp.ast file, if you include Qt headers, the AST will be
  very big, your stuff will be at the end of the file. Use the AST to check which
  nodes you have to visit.

- You can also dump the AST of a statement in C++:
  stmt->dump()

  This dumps the sub-AST to stdout, having stmt as it's root

- llvm::errs() is useful to print to stderr
  llvm::errs() << record->getNameAsString() << "\n";
  llvm::errs() << stmt->getLocStart().printToString(m_ci.getSourceManager()) << "\n";

- Look in Utils.h, StringUtils.h, QtUtils.h, FixitUtils.h, etc for helper functions you might need.

--------------------------------------------------------------------------------
Using ASTMatchers

- See the qcolor-from-literal check for how to use ASTMatchers with clazy
--------------------------------------------------------------------------------
Tips for fixits

- Don't forget to register your fixit with:
  REGISTER_FIXIT(MyFixEnumerator, "fix-my-check", "my-check")
  Where the 1st argument is some enum value, which your create, mostly useful if you have more than one fixit type.

- When testing main.cpp, the unit-test framework will automatically have fixits enabled, and a main.cpp_fixed.cpp is created.
  You should add this to config.json, so that main.cpp_fixed.cpp is also compiled:
        {
            "filename" : "main.cpp_fixed.cpp",
            "isFixedFile" : true
        }

  The expected result is the main.cpp_fixed.cpp itself, so, if the file looks correctly fixed:
      cp main.cpp_fixed.cpp main.cpp_fixed.cpp.expected

- Usually you'll have to poke around and debug print getLocStart and getLocEnd of statements until
  you find the locations you want, otherwise you'll have to manipulate the locations with Lexer,
  see FixItUtils.cpp.

- Learn from existing fixits:
    qgetenv.cpp
    functionargsbyref.cpp
    autounexpectedqstringbuilder.cpp
    qstringref.cpp
    qt4-qstring-from-array.cpp

--------------------------------------------------------------------------------
Running tests
    ./run_tests.py # This runs all tests
    ./run_tests.py my-check # This runs one tests
    ./run_tests.py my-check --verbose # Prints the compiler invocation command
    ./run_tests.py my-check --dump-ast # dumps the AST into a file with .ast extension
--------------------------------------------------------------------------------