feat: improve queries (#316)

* feat: improve queries

* chore: format files
pull/324/head
Amaan Qureshi 1 year ago committed by GitHub
parent 1be8ef7cdf
commit f45b072606
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3,6 +3,7 @@
A modern go neovim plugin based on treesitter, nvim-lsp and dap debugger. It is written in Lua and async as much as possible. A modern go neovim plugin based on treesitter, nvim-lsp and dap debugger. It is written in Lua and async as much as possible.
PR & Suggestions welcome. PR & Suggestions welcome.
The plugin covers most features required for a gopher. The plugin covers most features required for a gopher.
- Perproject setup. Allows you setup plugin behavior per project based on project files(launch.json, .gonvim) - Perproject setup. Allows you setup plugin behavior per project based on project files(launch.json, .gonvim)
- Async jobs with libuv - Async jobs with libuv
- Syntax highlight & Texobject: Native treesitter support is faster and more accurate. All you need is a theme support treesitter, try - Syntax highlight & Texobject: Native treesitter support is faster and more accurate. All you need is a theme support treesitter, try
@ -58,8 +59,8 @@ use 'neovim/nvim-lspconfig'
use 'nvim-treesitter/nvim-treesitter' use 'nvim-treesitter/nvim-treesitter'
``` ```
### [lazy.nvim](https://github.com/folke/lazy.nvim) ### [lazy.nvim](https://github.com/folke/lazy.nvim)
```lua ```lua
{ {
"ray-x/go.nvim", "ray-x/go.nvim",
@ -77,12 +78,10 @@ use 'nvim-treesitter/nvim-treesitter'
} }
``` ```
The go.nvim load speed is fast and you can enable it by default The go.nvim load speed is fast and you can enable it by default
<img width="479" alt="image" src="https://user-images.githubusercontent.com/1681295/218074895-5182c791-8649-46ad-b18e-8eb1af8c0ffa.png"> <img width="479" alt="image" src="https://user-images.githubusercontent.com/1681295/218074895-5182c791-8649-46ad-b18e-8eb1af8c0ffa.png">
Make sure the `$GOPATH/bin` path is added to your `$PATH` environment variable. To check this you can run Make sure the `$GOPATH/bin` path is added to your `$PATH` environment variable. To check this you can run
```bash ```bash
@ -117,7 +116,6 @@ To startup/setup the plugin
require('go').setup() require('go').setup()
``` ```
## Screenshots ## Screenshots
### Add comments ### Add comments
@ -133,16 +131,17 @@ require('go').setup()
![gotest](https://user-images.githubusercontent.com/1681295/143160335-b8046ffa-82cd-4d84-af3e-3b0dbb4c609e.png) ![gotest](https://user-images.githubusercontent.com/1681295/143160335-b8046ffa-82cd-4d84-af3e-3b0dbb4c609e.png)
Use: Use:
```vim ```vim
:GoTermClose :GoTermClose
``` ```
To close the floating term. To close the floating term.
### SQL/JSON Highlight injection ### SQL/JSON Highlight injection
<img width="718" alt="image" src="https://user-images.githubusercontent.com/1681295/227125827-538c5f3f-298d-4ae1-8762-42dfb92e79f3.png"> <img width="718" alt="image" src="https://user-images.githubusercontent.com/1681295/227125827-538c5f3f-298d-4ae1-8762-42dfb92e79f3.png">
## refactor gorename ## refactor gorename
gorename as an alternative to gopls rename as it supports rename across packages gorename as an alternative to gopls rename as it supports rename across packages
@ -217,7 +216,6 @@ Note: auto fill struct also supported by gopls lsp-action
[GoFixPlurals Youtube video](https://www.youtube.com/watch?v=IP67Gkb5-qA) [GoFixPlurals Youtube video](https://www.youtube.com/watch?v=IP67Gkb5-qA)
```go ```go
package foo package foo
@ -261,49 +259,50 @@ The following go binaries are used in `go.nvim` (depends on your setup):
If you run `GoFmt` and the configured binary (e.g. golines) was not installed, the plugin will install it for you. But the If you run `GoFmt` and the configured binary (e.g. golines) was not installed, the plugin will install it for you. But the
first run of `GoFmt` may fail. Recommended to run `GoInstallBinaries` to install all binaries before using the plugin. first run of `GoFmt` may fail. Recommended to run `GoInstallBinaries` to install all binaries before using the plugin.
| command | Description | | command | Description |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------- | | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
| GoInstallBinary go_binary_name | use `go install go_binary_url@latest` to install tool, if installed will skip | | GoInstallBinary go_binary_name | use `go install go_binary_url@latest` to install tool, if installed will skip |
| GoUpdateBinary go_binary_name | use `go install go_binary_url@latest` Will force re-install/update if already installed, otherwise same as GoInstallBinary | | GoUpdateBinary go_binary_name | use `go install go_binary_url@latest` Will force re-install/update if already installed, otherwise same as GoInstallBinary |
| GoInstallBinaries | use `go install` to install all tools, skip the ones installed | | GoInstallBinaries | use `go install` to install all tools, skip the ones installed |
| GoUpdateBinaries | use `go install` to update all tools to the latest version | | GoUpdateBinaries | use `go install` to update all tools to the latest version |
## Build and test ## Build and test
| command | Description | | command | Description |
| --------------------------------------------- | ------------------------------------------------------------------------ | | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| GoMake | async make, use with other commands | | GoMake | async make, use with other commands |
| GoBuild args | go build args (-g: enable debug, %: expand to current file, %:h expand to current package) | | GoBuild args | go build args (-g: enable debug, %: expand to current file, %:h expand to current package) |
| GoGenerate | | | GoGenerate | |
| GoRun {args} | e.g. GoRun equal to `go run .`; or `GoRun ./cmd` equal to `go run ./cmd, Additional args: -F run in floaterm` | | GoRun {args} | e.g. GoRun equal to `go run .`; or `GoRun ./cmd` equal to `go run ./cmd, Additional args: -F run in floaterm` |
| GoStop {job_id} | `stop the job started with GoRun` | | GoStop {job_id} | `stop the job started with GoRun` |
| GoTest | go test ./... | | GoTest | go test ./... |
| GoTestSum {pkgname} {gotestsum arguments} | run gotestsum and show result in side panel | | GoTestSum {pkgname} {gotestsum arguments} | run gotestsum and show result in side panel |
| GoTestSum -w | run gotestsum in watch mode | | GoTestSum -w | run gotestsum in watch mode |
| GoTest -v | go test -v current_file_path | | GoTest -v | go test -v current_file_path |
| GoTest -c | go test -c current_file_path | | GoTest -c | go test -c current_file_path |
| GoTest -n | test nearest, see GoTestFunc | | GoTest -n | test nearest, see GoTestFunc |
| GoTest -f | test current file, see GoTestFile | | GoTest -f | test current file, see GoTestFile |
| GoTest -n 1 | -count=1 flag | | GoTest -n 1 | -count=1 flag |
| GoTest -p | test current package, see GoTestPkg | | GoTest -p | test current package, see GoTestPkg |
| GoTest -t yourtags | go test ./... -tags=yourtags, see notes | | GoTest -t yourtags | go test ./... -tags=yourtags, see notes |
| GoTest -a your_args | go test ./... -args=yourargs, see notes | | GoTest -a your_args | go test ./... -args=yourargs, see notes |
| GoTest package_path -t yourtags | go test packagepath -tags=yourtags | | GoTest package_path -t yourtags | go test packagepath -tags=yourtags |
| GoTest package_path -t yourtags other_args | go test packagepath -tags=yourtags other_args | | GoTest package_path -t yourtags other_args | go test packagepath -tags=yourtags other_args |
| GoLint | golangci-lint | | GoLint | golangci-lint |
| GoGet {package_url} | go get package_url and restart gopls. Note1 | | GoGet {package_url} | go get package_url and restart gopls. Note1 |
| GoVet | go vet | | GoVet | go vet |
| GoCoverage | go test -coverprofile | | GoCoverage | go test -coverprofile |
| GoCoverage -p | go test -coverprofile (only tests package for current buffer) | | GoCoverage -p | go test -coverprofile (only tests package for current buffer) |
| GoCoverage -f coverage_file_name | load coverage file | | GoCoverage -f coverage_file_name | load coverage file |
| GoCoverage {flags} | -t : toggle, -r: remove signs, -R remove sings from all files, -m show metrics| | GoCoverage {flags} | -t : toggle, -r: remove signs, -R remove sings from all files, -m show metrics |
| GoCoverage {flags} {go test flags} | e.g: GoCoverage -p -coverpkg 'yourpackagename' | | GoCoverage {flags} {go test flags} | e.g: GoCoverage -p -coverpkg 'yourpackagename' |
| GoTermClose | `closes the floating term` | | GoTermClose | `closes the floating term` |
Note: Note:
1. if package_url not provided, will check current line is a valid package url or not, if it is valid, will 1. if package_url not provided, will check current line is a valid package url or not, if it is valid, will
fetch current url fetch current url
2. tags: if ``//+build tags`` exist it will be added automatically 2. tags: if `//+build tags` exist it will be added automatically
3. args: if multiple args is provided, you need toconcatenate it with '\ ', e.g. GoTest -args yourtags\ other_args 3. args: if multiple args is provided, you need toconcatenate it with '\ ', e.g. GoTest -args yourtags\ other_args
4. % will expand to current file path, e.g. GoBuild % 4. % will expand to current file path, e.g. GoBuild %
@ -324,9 +323,9 @@ Support table based unit test auto generate, parse current function/method name
| GoTestFunc | run test for current func | | GoTestFunc | run test for current func |
| GoTestFunc -s | select the test function you want to run | | GoTestFunc -s | select the test function you want to run |
| GoTestFunc -tags=yourtag | run test for current func with `-tags yourtag` option | | GoTestFunc -tags=yourtag | run test for current func with `-tags yourtag` option |
| GoTestFile | run test for current file | | GoTestFile | run test for current file |
| GoTestFile -tags=yourtag | run test for current folder with `-tags yourtag` option | | GoTestFile -tags=yourtag | run test for current folder with `-tags yourtag` option |
| GoTestPkg | run test for current package/folder | | GoTestPkg | run test for current package/folder |
| GoTestPkg -tags=yourtag | run test for current folder with `-tags yourtag` option | | GoTestPkg -tags=yourtag | run test for current folder with `-tags yourtag` option |
| GoAddTest [-parallel] | Add test for current func | | GoAddTest [-parallel] | Add test for current func |
| GoAddExpTest [-parallel] | Add tests for exported funcs | | GoAddExpTest [-parallel] | Add tests for exported funcs |
@ -334,20 +333,20 @@ Support table based unit test auto generate, parse current function/method name
GoTestXXX Arguments GoTestXXX Arguments
| arguments | Description | | arguments | Description |
| ------------ | --------------------------------- | | --------- | ------------- |
| -v | verbose mode | | -v | verbose mode |
| -c | compile | | -c | compile |
| -C | coverprofile | | -C | coverprofile |
| -n | count | | -n | count |
| -t | tags | | -t | tags |
| -f | fuzz | | -f | fuzz |
| -b | bench | | -b | bench |
| -m | metric | | -m | metric |
| -s | select | | -s | select |
| -p | package | | -p | package |
| -F | floaterm mode | | -F | floaterm mode |
| -a | args | | -a | args |
Note: For GoTestXXX Note: For GoTestXXX
@ -383,7 +382,6 @@ If guihua not installed fallback to loclist
<img width="902" alt="image" src="https://user-images.githubusercontent.com/1681295/175231905-82df4e4b-a508-4bb8-b878-9f0029643005.png"> <img width="902" alt="image" src="https://user-images.githubusercontent.com/1681295/175231905-82df4e4b-a508-4bb8-b878-9f0029643005.png">
## Modifytags ## Modifytags
Modify struct tags by [`gomodifytags`](https://github.com/fatih/gomodifytags) and treesitter Modify struct tags by [`gomodifytags`](https://github.com/fatih/gomodifytags) and treesitter
@ -403,13 +401,13 @@ Options:
nvim-lsp support goimport by default. The plugin provided a new formatter, goline + gofumpt (stricter version of nvim-lsp support goimport by default. The plugin provided a new formatter, goline + gofumpt (stricter version of
gofmt) gofmt)
| command | Description | | command | Description |
| --------------------- | --------------------------- | | --------------------- | ------------------------ |
| GoFmt {opts} | default: gofumpt | | GoFmt {opts} | default: gofumpt |
| GoImport | default: goimport | | GoImport | default: goimport |
| GoImport package_path | gopls add_import package | | GoImport package_path | gopls add_import package |
{opts} : ``-a`` format all buffers {opts} : `-a` format all buffers
## GoImpl ## GoImpl
@ -431,45 +429,48 @@ e.g:
``` ```
:GoImpl f *File io.Reader :GoImpl f *File io.Reader
``` ```
or simply put your cursor in a struct and do or simply put your cursor in a struct and do
``` ```
:GoImpl io.Reader :GoImpl io.Reader
``` ```
or simply your cursor on a interface and specify a receiver type or simply your cursor on a interface and specify a receiver type
``` ```
:GoImpl MyType :GoImpl MyType
``` ```
## Debug ## Debug
| command | Description | | command | Description |
| ---------------- | ------------------------------------------------ | | ------------------ | ------------------------------------------------ |
| GoDebug | start debug session, Note 1 | | GoDebug | start debug session, Note 1 |
| GoDebug -h | show helps info | | GoDebug -h | show helps info |
| GoDebug -c | compile only | | GoDebug -c | compile only |
| GoDebug -t | start debug session for go test file, Note 2 | | GoDebug -t | start debug session for go test file, Note 2 |
| GoDebug -R | restart debug session | | GoDebug -R | restart debug session |
| GoDebug -n | start debug session for nearest go test function | | GoDebug -n | start debug session for nearest go test function |
| GoDebug -p | launch package test and start debug | | GoDebug -p | launch package test and start debug |
| GoDebug -e program | dap exec program | | GoDebug -e program | dap exec program |
| GoDebug -a | attach to remote process | | GoDebug -a | attach to remote process |
| GoDebug -s | stop debug session and unmap debug keymap | | GoDebug -s | stop debug session and unmap debug keymap |
| GoDebug -A args | debug session with args | | GoDebug -A args | debug session with args |
| GoDbgKeys | show debug keymaps in a floating window (guihua) | | GoDbgKeys | show debug keymaps in a floating window (guihua) |
| GoBreakToggle | GoDebug -b | | GoBreakToggle | GoDebug -b |
| GoDbgStop | Same as GoDebug -s | | GoDbgStop | Same as GoDebug -s |
| GoDbgContinue | Continue debug session | | GoDbgContinue | Continue debug session |
| BreakCondition | conditional break | | BreakCondition | conditional break |
Notes: Notes:
1. Without any argument, will check if launch.json existed or not, if existed, using launch.json and popup input.
If launch.json not existed, will start debug session for current file, if current file is package main will run 1. Without any argument, will check if launch.json existed or not, if existed, using launch.json and popup input.
main(), else will start debug package test If launch.json not existed, will start debug session for current file, if current file is package main will run
2. with -t option, if current file is not test file, will switch to test file and run test for current function main(), else will start debug package test
3. If cursor inside scope of a test function, will debug current test function, if cursor inside a test file, will debug 2. with -t option, if current file is not test file, will switch to test file and run test for current function
current test file 3. If cursor inside scope of a test function, will debug current test function, if cursor inside a test file, will debug
current test file
## Switch between go and test file ## Switch between go and test file
@ -482,15 +483,14 @@ Notes:
## Go Mock ## Go Mock
go mock with mockgen is supported go mock with mockgen is supported
| command | Description | | command | Description |
| ---------------- | ------------------------------------------------------- | | ---------------- | ------------------------------------------------------- |
| GoMockGen | default: generate mocks for current file | | GoMockGen | default: generate mocks for current file |
options: options:
-s source mode(default) -s source mode(default)
-i interface mode, provide interface name or put cursor on interface -i interface mode, provide interface name or put cursor on interface
-p package name default: mocks -p package name default: mocks
-d destination directory, default: ./mocks -d destination directory, default: ./mocks
## Comments and Doc ## Comments and Doc
@ -512,17 +512,18 @@ The code will be:
// GoLintComplaining struct no more complaint ;P // GoLintComplaining struct no more complaint ;P
type GoLintComplaining struct{} type GoLintComplaining struct{}
``` ```
| command | Description |
| ---------------- | ------------------------------------------------------- | | command | Description |
| GoCmt | Add comment | | ------- | ----------- |
| GoCmt | Add comment |
## GoModTidy ## GoModTidy
| command | Description | | command | Description |
| ---------------- | ------------------------------------------------------- | | ----------- | ------------------------------------- |
| GoModInit | run `go mod init` and restart gopls | | GoModInit | run `go mod init` and restart gopls |
| GoModTidy | run `go mod tidy` and restart gopls | | GoModTidy | run `go mod tidy` and restart gopls |
| GoModVendor | run `go mod vendor` and restart gopls | | GoModVendor | run `go mod vendor` and restart gopls |
run `go mod tidy` and restart gopls run `go mod tidy` and restart gopls
@ -602,7 +603,7 @@ If launch.json is valid, run `GoDebug` will launch from the launch.json configur
### Command ### Command
* GoToggleInlay - GoToggleInlay
#### Note: #### Note:
@ -614,32 +615,38 @@ Please use jsonls/null-ls check your launch.json is valid json file. Following s
Here is a sample [launch.json](https://github.com/ray-x/go.nvim/blob/master/playground/sampleApp/.vscode/launch.json) Here is a sample [launch.json](https://github.com/ray-x/go.nvim/blob/master/playground/sampleApp/.vscode/launch.json)
### Json to Go struct ### Json to Go struct
* ["x]GoJson2Struct!
Visual select the json and run `GoJson2Struct youStructName` - ["x]GoJson2Struct!
-bang will put result to register `a` Visual select the json and run `GoJson2Struct youStructName`
if ["x] specified, will put get json from clipboard -bang will put result to register `a`
if ["x] specified, will put get json from clipboard
### Load Env file ### Load Env file
* GoEnv {filename}
By default load .env file in current directory, if you want to load other file, use {filename} option - GoEnv {filename}
By default load .env file in current directory, if you want to load other file, use {filename} option
### Generate return value ### Generate return value
* GoGenReturn - GoGenReturn
create return value for current function create return value for current function
e.g. if we have e.g. if we have
```go ```go
func Foo() (int, error) { func Foo() (int, error) {
return 1, nil return 1, nil
} }
``` ```
and in your code you cursor on Foo and in your code you cursor on Foo
```go ```go
Foo() Foo()
``` ```
will generate will generate
```go ```go
i, err := Foo() i, err := Foo()
if err != nil { if err != nil {
@ -647,42 +654,42 @@ if err != nil {
} }
``` ```
### Rename modules ### Rename modules
* Gomvp
Rename module name in under cursor
e.g.
Gomvp
Gomvp old_mod_name
Gomvp old_mod_name new_mod_name
- Gomvp
Rename module name in under cursor
e.g.
Gomvp
Gomvp old_mod_name
Gomvp old_mod_name new_mod_name
### govulncheck ### govulncheck
* GoVulnCheck {arguments}
Run govulncheck on current project
- GoVulnCheck {arguments}
Run govulncheck on current project
### goenum ### goenum
* Goenum {arguments}
Run goenum on current project
- Goenum {arguments}
Run goenum on current project
### gonew ### gonew
* GoNew {filename}
Create new go file. It will use template file. e.g. `GoNew ./pkg/string.go` will create string.go with template file - GoNew {filename}
Create new go file. It will use template file. e.g. `GoNew ./pkg/string.go` will create string.go with template file
### ginkgo ### ginkgo
* Ginkgo {args}
| Arg | Description | - Ginkgo {args}
| --- | ----------- |
| run | |
| watch | |
| build | |
| bootstrap | |
| labels | |
| outline | |
| Arg | Description |
| --------- | ----------- |
| run | |
| watch | |
| build | |
| bootstrap | |
| labels | |
| outline | |
### Debug Commands ### Debug Commands
@ -690,8 +697,8 @@ Create new go file. It will use template file. e.g. `GoNew ./pkg/string.go` will
| -------------- | ----------------------------------------------------------------------------------------------- | | -------------- | ----------------------------------------------------------------------------------------------- |
| GoDebug | Start debugger, to debug test, run `GoDebug test`, to add addition args run `GoDebug arg1 arg2` | | GoDebug | Start debugger, to debug test, run `GoDebug test`, to add addition args run `GoDebug arg1 arg2` |
| GoDebugConfig | Open launch.json file | | GoDebugConfig | Open launch.json file |
| GoBreakSave | save all breakpoints to project file | | GoBreakSave | save all breakpoints to project file |
| GoBreakLoad | load all breakpoints from project file | | GoBreakLoad | load all breakpoints from project file |
| GoBreakToggle | toggle break point | | GoBreakToggle | toggle break point |
| BreakCondition | conditional break point | | BreakCondition | conditional break point |
| ReplRun | dap repl run_last | | ReplRun | dap repl run_last |
@ -864,8 +871,8 @@ return {
null_ls_document_formatting_disable = true null_ls_document_formatting_disable = true
} }
``` ```
This will override your global `go.nvim` setup
This will override your global `go.nvim` setup
## Text object ## Text object
@ -969,6 +976,7 @@ My treesitter config:
``` ```
## LuaSnip supports ## LuaSnip supports
go.nvim provides a better snippet support for go. go.nvim provides a better snippet support for go.
Please check [snippets for all languages](https://github.com/ray-x/go.nvim/blob/master/lua/snips/all.lua) Please check [snippets for all languages](https://github.com/ray-x/go.nvim/blob/master/lua/snips/all.lua)
and [snippets for go](https://github.com/ray-x/go.nvim/blob/master/lua/snips/go.lua) and [snippets for go](https://github.com/ray-x/go.nvim/blob/master/lua/snips/go.lua)
@ -988,7 +996,6 @@ For diagnostic issue, you can use the default setup. There are also quite a few
## Integrate with mason-lspconfig ## Integrate with mason-lspconfig
```lua ```lua
require("mason").setup() require("mason").setup()
require("mason-lspconfig").setup() require("mason-lspconfig").setup()
@ -1017,11 +1024,14 @@ local cfg = require'go.lsp'.config() -- config() return the go.nvim gopls setup
require('lspconfig').gopls.setup(cfg) require('lspconfig').gopls.setup(cfg)
``` ```
## Integrate null-ls ## Integrate null-ls
### The plugin provides: ### The plugin provides:
* `gotest` LSP diagnostic source for null-ls
* `golangci_lint` A async version of golangci-lint null-ls lint - `gotest` LSP diagnostic source for null-ls
* `gotest_action` LSP test code action for null-ls - `golangci_lint` A async version of golangci-lint null-ls lint
- `gotest_action` LSP test code action for null-ls
Gotest allow you run `go test <package>` when you save your go file and add diagnostics to nvim Gotest allow you run `go test <package>` when you save your go file and add diagnostics to nvim
@ -1048,13 +1058,11 @@ null_ls.setup({ sources = sources, debounce = 1000, default_timeout = 5000 })
null_ls.register(gotest) null_ls.register(gotest)
``` ```
You will see the failed tests flagged You will see the failed tests flagged
![null-ls ![null-ls
go.nvim](https://user-images.githubusercontent.com/1681295/212526174-4fa98a63-c90a-4a54-9340-27de98ecf17c.jpg) go.nvim](https://user-images.githubusercontent.com/1681295/212526174-4fa98a63-c90a-4a54-9340-27de98ecf17c.jpg)
## Sample vimrc ## Sample vimrc
The following vimrc will enable all features provided by go.nvim The following vimrc will enable all features provided by go.nvim
@ -1095,11 +1103,10 @@ EOF
This will setup gopls with non default configure provided by go.nvim (Includes lspconfig default keymaps) This will setup gopls with non default configure provided by go.nvim (Includes lspconfig default keymaps)
## Other plugins that you may like ## Other plugins that you may like
* [goplay](https://github.com/jeniasaigak/goplay.nvim)
* [a different way to highlight coverage results](https://github.com/rafaelsq/nvim-goc.lua)
- [goplay](https://github.com/jeniasaigak/goplay.nvim)
- [a different way to highlight coverage results](https://github.com/rafaelsq/nvim-goc.lua)
## Q & A: ## Q & A:

@ -1,137 +1,64 @@
;; extends ; extends
; inject sql into any const string with word query in the name
; e.g. const query = `SELECT * FROM users WHERE name = 'John'`;
(
(const_spec
name: (identifier) @_id
value: (expression_list (raw_string_literal) @injection.content))
(#match? @_id ".*[Q|q]uery.*")
(#set! injection.language "sql")
)
(short_var_declaration
left: (expression_list
(identifier) @_id (#match? @_id ".*[Q|q]uery.*"))
right: (expression_list
(raw_string_literal) @sql (#offset! @sql 0 1 0 -1))
)
; inject sql in single line strings ; inject sql in single line strings
; e.g. db.GetContext(ctx, "SELECT * FROM users WHERE name = 'John'") ; e.g. db.GetContext(ctx, "SELECT * FROM users WHERE name = 'John'")
(call_expression
((call_expression
(selector_expression (selector_expression
field: (field_identifier) @_field (#any-of? @_field "Exec" "GetContext" "ExecContext" "SelectContext" "In" "RebindNamed" "Rebind" "QueryRowxContext" "NamedExec")) field: (field_identifier) @_field)
(argument_list (argument_list
(interpreted_string_literal) @sql) (interpreted_string_literal) @sql))
(#offset! @sql 0 1 0 -1)) (#any-of? @_field "Exec" "GetContext" "ExecContext" "SelectContext" "In"
"RebindNamed" "Rebind" "QueryRowxContext" "NamedExec")
; ---------------------------------------------------------------- (#offset! @sql 0 1 0 -1))
; Go code example with interpreted string literal
; query := fmt.Sprintf("UPDATE task SET %s = ? WHERE id = ?", field)
(short_var_declaration
left: (expression_list) @_left (#eq? @_left "query")
right: (expression_list
(call_expression
function: (selector_expression
operand: (identifier) @_operand (#eq? @_operand "fmt")
field: (field_identifier) @_field (#eq? @_field "Sprintf")
)
arguments: (argument_list
(interpreted_string_literal) @sql
)
)
)
)
; ----------------------------------------------------------------
; Go code example with interpreted string literal and type identifier
; var query string = fmt.Sprintf("SELECT * from kkk WHERE id = ?", bb)
(var_declaration
(var_spec
name: (identifier) @_name (#match? @_name "[Q|q]uery")
value: (expression_list
(call_expression
function: (selector_expression
operand: (identifier) @_operand (#eq? @_operand "fmt")
field: (field_identifier) @_field (#eq? @_field "Sprintf")
)
arguments: (argument_list
(interpreted_string_literal) @sql
)
)
)
)
)
; ----------------------------------------------------------------
; Go code example with interpreted string literal and type identifier:
; var query string = "SELECT * FROM books"
(var_declaration
(var_spec
name: (identifier) @_name (#match? @_name "[Q|q]uery")
value: (expression_list
(interpreted_string_literal) @sql
)
)
)
; ---------------------------------------------------------------- ; ----------------------------------------------------------------
; a general query injection ; a general query injection
(((
[(interpreted_string_literal) ([
(raw_string_literal)] @sql (interpreted_string_literal)
(#match? @sql "(SELECT|select|INSERT|insert|UPDATE|update|DELETE|delete).+(FROM|from|INTO|into|VALUES|values|SET|set).*(WHERE|where|GROUP BY|group by)?" (raw_string_literal)
)))) ] @sql
(#match? @sql "(SELECT|select|INSERT|insert|UPDATE|update|DELETE|delete).+(FROM|from|INTO|into|VALUES|values|SET|set).*(WHERE|where|GROUP BY|group by)?")
(#offset! @sql 0 1 0 -1))
; ---------------------------------------------------------------- ; ----------------------------------------------------------------
; fallback keyword and comment based injection ; fallback keyword and comment based injection
(
(raw_string_literal) @sql ([
(#contains? @sql "-- sql" "--sql" "ADD CONSTRAINT" "ALTER TABLE" "ALTER COLUMN" "DATABASE" "FOREIGN KEY" "GROUP BY" "HAVING" "CREEATE INDEX" "INSERT INTO" "NOT NULL" "PRIMARY KEY" "UPDATE SET" "TRUNCATE TABLE" "LEFT JOIN") (interpreted_string_literal)
(#offset! @sql 0 1 0 -1) (raw_string_literal)
) ] @sql
( (#contains? @sql "-- sql" "--sql" "ADD CONSTRAINT" "ALTER TABLE" "ALTER COLUMN"
(interpreted_string_literal) @sql "DATABASE" "FOREIGN KEY" "GROUP BY" "HAVING" "CREATE INDEX" "INSERT INTO"
(#contains? @sql "-- sql" "--sql" "ADD CONSTRAINT" "ALTER TABLE" "ALTER COLUMN" "DATABASE" "FOREIGN KEY" "GROUP BY" "HAVING" "CREEATE INDEX" "INSERT INTO" "NOT NULL" "PRIMARY KEY" "UPDATE SET" "TRUNCATE TABLE" "LEFT JOIN") "NOT NULL" "PRIMARY KEY" "UPDATE SET" "TRUNCATE TABLE" "LEFT JOIN")
(#offset! @sql 0 1 0 -1) (#offset! @sql 0 1 0 -1))
)
; should I use a more exhaustive list of keywords? ; should I use a more exhaustive list of keywords?
; "ADD" "ADD CONSTRAINT" "ALL" "ALTER" "AND" "ASC" "COLUMN" "CONSTRAINT" "CREATE" "DATABASE" "DELETE" "DESC" "DISTINCT" "DROP" "EXISTS" "FOREIGN KEY" "FROM" "JOIN" "GROUP BY" "HAVING" "IN" "INDEX" "INSERT INTO" "LIKE" "LIMIT" "NOT" "NOT NULL" "OR" "ORDER BY" "PRIMARY KEY" "SELECT" "SET" "TABLE" "TRUNCATE TABLE" "UNION" "UNIQUE" "UPDATE" "VALUES" "WHERE" ; "ADD" "ADD CONSTRAINT" "ALL" "ALTER" "AND" "ASC" "COLUMN" "CONSTRAINT" "CREATE" "DATABASE" "DELETE" "DESC" "DISTINCT" "DROP" "EXISTS" "FOREIGN KEY" "FROM" "JOIN" "GROUP BY" "HAVING" "IN" "INDEX" "INSERT INTO" "LIKE" "LIMIT" "NOT" "NOT NULL" "OR" "ORDER BY" "PRIMARY KEY" "SELECT" "SET" "TABLE" "TRUNCATE TABLE" "UNION" "UNIQUE" "UPDATE" "VALUES" "WHERE"
; json ; json
(
(const_spec
name: (identifier) @_id
value: (expression_list (raw_string_literal) @json))
(#match? @_id ".*[J|j]son.*") ((const_spec
) name: (identifier) @_const
value: (expression_list (raw_string_literal) @json))
(#lua-match? @_const ".*[J|j]son.*"))
; jsonStr := `{"foo": "bar"}` ; jsonStr := `{"foo": "bar"}`
(short_var_declaration
((short_var_declaration
left: (expression_list left: (expression_list
(identifier) @_id (#match? @_id ".*[J|j]son.*")) (identifier) @_var)
right: (expression_list right: (expression_list
(raw_string_literal) @json (#offset! @json 0 1 0 -1)) (raw_string_literal) @json))
) (#lua-match? @_var ".*[J|j]son.*")
(#offset! @json 0 1 0 -1))
((composite_literal ((composite_literal
type: (type_identifier) @_type type: (type_identifier) @_type
body: (literal_value body: (literal_value
(keyed_element (keyed_element
(literal_element) @_key (literal_element) @_key
(literal_element) @lua))) (literal_element) @lua)))
(#eq? @_key "overrideScript") (#eq? @_type "generatorTestCase")
(#eq? @_type "generatorTestCase")) (#eq? @_key "overrideScript"))

@ -1,15 +1,15 @@
;; extends ; extends
(var_spec) @scope
(field_declaration (field_declaration
name: (field_identifier) @definition.field) name: (field_identifier) @definition.field)
(method_spec (method_spec
name: (field_identifier) @method.name name: (field_identifier) @method.name
parameters:(parameter_list) @method.parameter_list parameters: (parameter_list) @method.parameter_list) @interface.method.declaration
)@interface.method.declaration
(type_declaration (type_declaration
(type_spec (type_spec
name: (type_identifier) @name name: (type_identifier) @name
type: [(struct_type) (interface_type)] @type)) @start type: [(struct_type) (interface_type)] @type)) @start
(var_spec) @scope

@ -1,4 +1,4 @@
std="vim" std = "vim"
[rules] [rules]
global_usage = "allow" global_usage = "allow"

Loading…
Cancel
Save