gaq
gaq copied to clipboard
GAQ(Go Ast Query) is the library to query ast.Node children like JavaScript querySelector or querySelectorAll for Go.
GAQ(Go AST Query)
GAQ is the library to query ast.Node
children like JavaScript querySelector
or querySelectorAll
.
Table of Contents
-
GAQ(Go AST Query)
- Table of Contents
-
Install
-
Library
- Usage
-
CLI
-
Usage
- Filter Mode
- Replace Mode
-
Usage
-
Library
-
Query Specfication
- Supported Combinators
- Supported Attribute Syntax
- Supported Pseudo Class
Install
Library
go get github.com/tamayika/gaq/pkg/gaq
Usage
Please refer pkg/gaq/example_test.go
CLI
go get github.com/tamayika/gaq
or there are binaries for various os at Releases.
Usage
You can see help with --help
flag.
$ gaq --help
gaq is the cli tool to query ast node.
Typical usage is
cat <go file path> | gaq <Query>
cat <go file path> | gaq -m replace <Query> <Replace command>
Please see details at https://github.com/tamayika/gaq
Usage:
gaq <Query> [flags]
Flags:
-f, --format string Output format, 'text' or 'pos'. Default is 'text' (default "text")
-h, --help help for gaq
-m, --mode string Execution mode, 'filter' or 'replace'. Default is 'filter' (default "filter")
--version version for gaq
Filter Mode
Default mode is filter
.
For example, File > Ident
query filters package name in main.go
$ cat main.go | gaq "File > Ident"
main
Replace Mode
You can replace matched node text by replace
mode.
For example, below command exports functions except main
function.
$ cat main.go | gaq -m replace "FuncDecl > Ident:not([Name='main'])" -- sed -e "s/^\(.\)/\U\1/"
In replace
mode, below sequence is executed for each matched node
- command is spawned
- gaq passes node text as stdin
- wait command exit
- replace node text by command output
You can use any tool which gets input from stdin and puts result to stdout, sed
, awk
, tr
etc.
Query Specfication
Heavily inspired by CSS Selector.
Query:
Selector [',' Selector]
Selector:
SimpleSelector [Combinator SimpleSelector]
SimpleSelector:
[[NodeName] [Attribute] [Pseudo]]!
Attribute:
'[' Field [ AttributeOperator Value ] ']'
Pseudo:
':' Name [ '(' Expression ')' ]
Full used example
File > Ident[Name*='test']:first-child, File > Ident[Name*='test']:last-child
Here, NodeName is one of node type of ast.
For example, if you want to find *ast.StructType
, NodeName is StructType
.
You can also specify *
as any node type.
If you don't know NodeName, VSCode extension vscode-go-ast-explorer will help you to find it out.
Supported Combinators
Combinator | Name | Meaning |
---|---|---|
+ | Adjacent sibling combinator | The second node directly follows the first, and both share the same parent. |
~ | General sibling combinator | The second node follows the first (though not necessarily immediately), and both share the same parent. |
> | Child combinator | Selects nodes that are direct children of the first node. |
(whitespace) | Descendant combinator | Selects nodes that are descendants of the first node. |
Supported Attribute Syntax
Syntax | Meaning |
---|---|
[f] |
Represents Node with an field name of f. |
[f=value] |
Represents Node with an field name of f whose value is exactly value. |
[f~=value] |
Represents Node with an field name of f whose value is a whitespace-separated list of words, one of which is exactly value. |
[f|=value] |
Represents Node with an field name of f whose value can be exactly value or can begin with value immediately followed by a hyphen, - . |
[f^=value] |
Represents Node with an field name of f whose value is prefixed (preceded) by value. |
[f$=value] |
Represents Node with an field name of f whose value is suffixed (followed) by value. |
[f*=value] |
Represents Node with an field name of f whose value contains at least one occurrence of value within the string. |
Supported Pseudo Class
Syntax | Meaning |
---|---|
:empty |
Represents nodes that has no children. ast.CommentGroup and ast.Comment are ignored. |
:first-child |
Represents the first node among a group of sibling nodes. |
:first-of-type |
Represents the first node of its type among a group of sibling nodes. |
:has(Query) |
Represents a node if any of the selectors passed as parameters, match at least one node. |
:is(Query) |
Represents nodes that can be selected by one of the selectors in that list |
:last-child |
Represents the last node among a group of sibling nodes. |
:last-of-type |
Represents the last node of its type among a group of sibling nodes. |
:not(Query) |
Represents nodes that do not match a list of selectors. |
:root |
Represents the root node. When gaq.Parse(source string) is used, the root node is *ast.File . When gaq.ParseNode(n ast.Node) is used, the root node is n . |