Usually we use static code checking tools to ensure code quality in our business projects, through static code checking tools we can find some problems in advance, such as undefined variables, type mismatches, variable scope problems, array subscript overruns, memory leaks, etc. The tools will classify the severity of the problem according to their own rules, giving different signs and hints, static code checking The static code checker helps us to find the problem as early as possible, the common static code checker tools in Go
language are golang-lint
, golint
, these tools have developed some rules, although it can meet most of the scenarios, but sometimes we will encounter the need to do some customization rules for special scenarios, so in this article we learn how to custom linter requirements.
How is static checking implemented in Go language?
It is well known that Go
language is a compiled language, and compiled language cannot be separated from lexical analysis, syntax analysis, semantic analysis, optimization, compilation and linking several stages, those who have learned the compilation principle should be familiar with the following diagram.
The compiler will translate the high-level language into machine language, will first do lexical analysis of the source code, lexical analysis is the process of converting the sequence of characters into a Token
sequence, Token
is generally divided into these categories: keywords, identifiers, literal (including numbers, strings), special symbols (such as the plus sign, etc.), after generating the Token sequence, the need for syntax analysis, after further processing, to generate A syntax tree with expressions as nodes, this syntax tree is what we often call AST
, in the process of generating syntax tree can detect some formal errors, such as the lack of brackets, syntax analysis is completed, it is necessary to carry out semantic analysis, where all the compilation period can check the static semantics, the latter process is the intermediate code generation, target code generation and optimization, linking, here is not Detailed description, here mainly want to introduce the abstract syntax tree (AST), our static code checking tool is through the analysis of the abstract syntax tree (AST) according to the custom rules to do; so what does the abstract syntax tree look like? We can use the go/ast
, go/parser
, go/token
packages provided by the standard library to print out the AST, or we can use the visualization tool: http://goast.yuroyoro.net/ to view the AST, and we can see the following examples of what the AST looks like.
Develop linter rules
Suppose we now want to develop such a code specification in our team, the first argument type of all functions must be Context
, and we have to give a warning if it does not conform to the specification; well, now that the rule has been set, let’s now figure out how to implement it; first, a problematic example.
Corresponds to AST
as follows.
|
|
way one: standard library implementation custom linter
With the AST
structure above we can find out exactly which structure the function parameter type is on, as we can write the parsing code based on this structure as follows.
|
|
Then execute the following command.
We can see from the output that the first argument of the function add()
must be Context; this is a simple implementation, because the structure of AST
is really a bit complicated, so we won’t go into detail about each structure here.
way two: go/analysis
Those who have read the above code must be a bit crazy, there are many entities exist, to develop a linter
, we need to understand many entities, good thing go/analysis
is encapsulated, go/analysis
provides a unified interface for linter
, it simplifies the integration with IDE, metalinters, code Review and other tools. For example, any go/analysis
linter can be efficiently executed by go vet
, and we introduce the advantages of go/analysis
by way of code below.
The code structure of a new project is as follows.
Add the check module code to firstparamcontext.go
by adding the following code.
|
|
Then add the analyzer.
Execute the following command.
If we want to add more rules, just use golang.org/x/tools/go/analysis/multichecker
to append them.
Integration to golang-cli
We can download the code of golang-cli
locally and add firstparamcontext.go
under pkg/golinters
with the following code.
|
|
Then re-make
a golang-cli
executable file, add it to our project and that’s it.
Summary
The pkg/golinters
directory in the golang-cli
repository stores a lot of static checking code, the fastest way to learn a point of knowledge is to copy the code, first learn how to use it, and then slowly make it our own; this article does not do too much introduction to the AST
standard library, because this part of the text description is difficult to understand, the best way or their own The best way is to read the official documentation, plus practice to understand faster.