Skip to content

Commit 4a55a62

Browse files
authored
AstVisitor rework (#149)
1 parent ebb76f3 commit 4a55a62

File tree

63 files changed

+3362
-951
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+3362
-951
lines changed

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ dotnet_naming_style.end_in_async_style.required_prefix =
253253
dotnet_naming_style.end_in_async_style.required_suffix = Async
254254

255255
# dotnet_naming_rule.<namingRuleTitle>.severity = <value>
256-
dotnet_naming_rule.async_methods_end_in_async.severity = warning
256+
dotnet_naming_rule.async_methods_end_in_async.severity = suggestion
257257

258258
# Remove unnecessary import https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0005
259259
dotnet_diagnostic.IDE0005.severity = warning

README.md

Lines changed: 55 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ The parser from this library is used in [GraphQL for .NET](https://github.com/gr
2424

2525
Preview versions of this package are available on [GitHub Packages](https://github.com/orgs/graphql-dotnet/packages?repo_name=parser).
2626

27-
## Lexer
27+
## 1. Lexer
2828

2929
Generates token based on input text. Lexer takes advantage of `ReadOnlyMemory<char>` and in most cases
3030
does not allocate memory on the managed heap at all.
@@ -38,7 +38,7 @@ var token = Lexer.Lex("\"str\"");
3838
Lex method always returns the first token it finds. In this case case the result would look like following.
3939
![lexer example](assets/lexer-example.png)
4040

41-
## Parser
41+
## 2. Parser
4242

4343
Parses provided GraphQL expression into AST (abstract syntax tree). Parser also takes advantage of
4444
`ReadOnlyMemory<char>` but still allocates memory for AST.
@@ -61,51 +61,60 @@ By default `ParserOptions.Ignore` is `IgnoreOptions.IgnoreComments` to improve p
6161
If you don't need information about tokens locations in the source document, then use `IgnoreOptions.IgnoreCommentsAndLocations`.
6262
This will maximize the saving of memory allocated in the managed heap for AST.
6363

64-
### Example of json representation of the resulting AST
64+
## 3. INodeVisitor
6565

66-
```json
66+
`INodeVisitor` provides API to traverse AST of the parsed GraphQL document.
67+
Default implementation of this interface is `DefaultNodeVisitor` that
68+
traverses all AST nodes of the provided one. You can inherit from it and
69+
implement your own AST processing algorithm.
70+
71+
For printing SDL from AST, you can use `SDLWriter<TContext>` visitor.
72+
This is a highly optimized visitor for asynchronous non-blocking SDL output
73+
into provided `TextWriter`. In the majority of cases it does not allocate
74+
memory in the managed heap at all.
75+
76+
You can also find a `StructureWriter<TContext>` visitor that prints AST
77+
into the provided `TextWriter` as a hierarchy of node types. It can be useful
78+
when debugging for better understanding the AST structure.
79+
Consider GraphQL document
80+
81+
```graphql
82+
query a { name age }
83+
```
84+
85+
After `StructureWriter` processing the output text will be
86+
87+
```
88+
Document
89+
OperationDefinition
90+
Name [a]
91+
SelectionSet
92+
Field
93+
Name [name]
94+
Field
95+
Name [age]
96+
```
97+
98+
### Usage
99+
100+
```c#
101+
public class Context : IWriteContext
67102
{
68-
"Definitions": [{
69-
"Directives": [],
70-
"Kind": 2,
71-
"Name": null,
72-
"Operation": 0,
73-
"SelectionSet": {
74-
"Kind": 5,
75-
"Selections": [{
76-
"Alias": null,
77-
"Arguments": [],
78-
"Directives": [],
79-
"Kind": 6,
80-
"Name": {
81-
"Kind": 0,
82-
"Value": "field",
83-
"Location": {
84-
"End": 50,
85-
"Start": 31
86-
}
87-
},
88-
"SelectionSet": null,
89-
"Location": {
90-
"End": 50,
91-
"Start": 31
92-
}
93-
}],
94-
"Location": {
95-
"End": 50,
96-
"Start": 13
97-
}
98-
},
99-
"VariableDefinitions": null,
100-
"Location": {
101-
"End": 50,
102-
"Start": 13
103-
}
104-
}],
105-
"Kind": 1,
106-
"Location": {
107-
"End": 50,
108-
"Start": 13
109-
}
103+
public TextWriter Writer { get; set; } = new StringWriter();
104+
105+
public Stack<AST.ASTNode> Parents { get; set; } = new Stack<AST.ASTNode>();
106+
107+
public CancellationToken CancellationToken { get; set; }
108+
}
109+
110+
public static void Parse(string text)
111+
{
112+
var document = Parser.Parse(text);
113+
114+
var context = new Context();
115+
var visitor = new SDLWriter<Context>()
116+
await visitor.Visit(document, context);
117+
var rendered = context.Writer.ToString();
118+
Console.WriteLine(rendered);
110119
}
111120
```

src/GraphQLParser.ApiTests/GraphQLParser.approved.txt

Lines changed: 200 additions & 45 deletions
Large diffs are not rendered by default.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
query q
2+
{
3+
#alias comment
4+
a
5+
#colon comment
6+
:
7+
#field comment
8+
name
9+
}

0 commit comments

Comments
 (0)