Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reworked the syntax rewriter and introduced a syntax navigator. #5078

Merged
merged 28 commits into from
May 27, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8512379
Add initial implementation for navigation rewriter with rewriters ref…
matt-psaltis May 18, 2022
03a85f6
Remove coordinates used basic naming in tests
matt-psaltis May 18, 2022
538d861
Merge branch 'main' into mp/language-rewriters-primitives
michaelstaib May 18, 2022
0be3934
Feedback fixes
matt-psaltis May 19, 2022
ce327d7
Update src/HotChocolate/Language/src/Language.Rewriters/Contracts/INa…
michaelstaib May 19, 2022
261d418
Update src/HotChocolate/Language/src/Language.Rewriters/Contracts/ISy…
michaelstaib May 19, 2022
d48cf1a
Update src/HotChocolate/Language/src/Language.Rewriters/DefaultSyntax…
michaelstaib May 19, 2022
885d65e
Update src/HotChocolate/Language/src/Language.Rewriters/DefaultSyntax…
michaelstaib May 19, 2022
ce1f47f
Adds TryPop
matt-psaltis May 19, 2022
001c9dc
Fixes GetParent
matt-psaltis May 19, 2022
6c17565
Changes parent to property
matt-psaltis May 19, 2022
00b1c41
Update src/HotChocolate/Language/src/Language.Rewriters/Contracts/ISy…
michaelstaib May 19, 2022
0861b5e
Fixes Pop signature
matt-psaltis May 19, 2022
8534272
Merge branch 'main' into mp/language-rewriters-primitives
michaelstaib May 22, 2022
cbdad60
stated cleanup
michaelstaib May 22, 2022
7add32a
edits
michaelstaib May 24, 2022
236b3be
edits
michaelstaib May 24, 2022
a19bd89
edits
michaelstaib May 27, 2022
11d5663
edits
michaelstaib May 27, 2022
285df51
edits
michaelstaib May 27, 2022
cbc3ae5
edits
michaelstaib May 27, 2022
b8aadea
edits
michaelstaib May 27, 2022
c257728
edits
michaelstaib May 27, 2022
767eb32
edits
michaelstaib May 27, 2022
78a2139
edits
michaelstaib May 27, 2022
0f915f8
edits
michaelstaib May 27, 2022
58a902a
Fixed snapshot
michaelstaib May 27, 2022
7a1c77d
Merge branch 'main' into mp/language-rewriters-primitives
michaelstaib May 27, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace HotChocolate.Language.Rewriters;

public interface INavigatorContext
michaelstaib marked this conversation as resolved.
Show resolved Hide resolved
{
/// <summary>
/// Gets the associated <see cref="ISyntaxNavigator" /> from the current context.
/// </summary>
ISyntaxNavigator Navigator { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.Collections.Generic;

namespace HotChocolate.Language.Rewriters;

public interface ISyntaxNavigator
matt-psaltis marked this conversation as resolved.
Show resolved Hide resolved
michaelstaib marked this conversation as resolved.
Show resolved Hide resolved
{
/// <summary>
/// Adds a syntax node to the Syntax Navigator to record the parent of the Syntax Node being visited.
/// </summary>
/// <param name="node">The parent syntax node to be added to the Syntax Navigator</param>
void Push(ISyntaxNode node);

/// <summary>
/// Removes the current parent node from the Syntax Navigator.
/// </summary>
/// <param name="node">The removed parent node.</param>
void Pop(out ISyntaxNode node);
matt-psaltis marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Returns the first ancestor of the provided <see cref="TNode" /> type.
/// </summary>
/// <typeparam name="TNode">The type of syntax node to be returned.</typeparam>
/// <returns>The matching first ancestor or null if no match is found.</returns>
TNode? GetAncestor<TNode>()
where TNode : ISyntaxNode;

/// <summary>
/// Returns all ancestors of the provided <see cref="TNode" /> type.
/// </summary>
/// <typeparam name="TNode">The type of syntax nodes to be returned.</typeparam>
/// <returns>A collection of Syntax Nodes of type <see cref="TNode" /></returns>
IEnumerable<TNode> GetAncestors<TNode>()
where TNode : ISyntaxNode;

/// <summary>
/// Returns the immediate parent of the current Syntax Node
/// </summary>
/// <returns>The parent Syntax Node or null if the current node does not have a parent.</returns>
ISyntaxNode? GetParent();
matt-psaltis marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using static HotChocolate.Language.Rewriters.LangRewritersResources;

namespace HotChocolate.Language.Rewriters;

public class DefaultSyntaxNavigator : ISyntaxNavigator
matt-psaltis marked this conversation as resolved.
Show resolved Hide resolved
michaelstaib marked this conversation as resolved.
Show resolved Hide resolved
{
private readonly List<ISyntaxNode> _ancestors = new();

/// <inheritdoc cref="ISyntaxNavigator.Push"/>
public void Push(ISyntaxNode node) => _ancestors.Add(node);

/// <inheritdoc cref="ISyntaxNavigator.Pop"/>
public void Pop(out ISyntaxNode node)
{
michaelstaib marked this conversation as resolved.
Show resolved Hide resolved
if (_ancestors.Count == 0)
{
throw new InvalidOperationException(DefaultSyntaxNavigator_NoAncestors);
matt-psaltis marked this conversation as resolved.
Show resolved Hide resolved
}

node = _ancestors[_ancestors.Count - 1];
_ancestors.RemoveAt(_ancestors.Count - 1);
}

/// <inheritdoc cref="ISyntaxNavigator.GetAncestor{TNode}"/>
public TNode? GetAncestor<TNode>()
where TNode : ISyntaxNode
{
for (var i = _ancestors.Count - 1; i >= 0; i--)
{
if (_ancestors[i] is TNode typedNode)
{
return typedNode;
}
}

return default;
}

/// <inheritdoc cref="ISyntaxNavigator.GetAncestors{TNode}"/>
public IEnumerable<TNode> GetAncestors<TNode>()
where TNode : ISyntaxNode
{
for (var i = _ancestors.Count - 1; i >= 0; i--)
{
if (_ancestors[i] is TNode typedNode)
{
yield return typedNode;
}
}
}

/// <inheritdoc cref="ISyntaxNavigator.GetParent"/>
public ISyntaxNode? GetParent() => GetAncestor<ISyntaxNode>();
michaelstaib marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Collections.Generic;

namespace HotChocolate.Language;
namespace HotChocolate.Language.Rewriters;

public class DirectiveQuerySyntaxRewriter
: QuerySyntaxRewriter<DirectiveNode>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace HotChocolate.Language;
namespace HotChocolate.Language.Rewriters;

public static class DocumentRewriterExtensions
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<PackageId>HotChocolate.Language.Rewriters</PackageId>
<AssemblyName>HotChocolate.Language.Rewriters</AssemblyName>
<RootNamespace>HotChocolate.Language.Rewriters</RootNamespace>
<Description>This package contains Syntax Rewrite primitives of Hot Chocolate.</Description>
</PropertyGroup>

<ItemGroup>
<None Remove="HotChocolate.Language.Rewriters.csproj.DotSettings" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Language.SyntaxTree\HotChocolate.Language.SyntaxTree.csproj" />
</ItemGroup>

<ItemGroup>
<Compile Update="Properties\LangRewritersResources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>LangRewritersResources.resx</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Properties\LangRewritersResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>LangRewritersResources.Designer.cs</LastGenOutput>
<CustomToolNamespace>HotChocolate.Language.Rewriters</CustomToolNamespace>
</EmbeddedResource>
</ItemGroup>

</Project>

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema

Version 2.0

The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.

Example:

... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>

There are any number of "resheader" rows that contain simple
name/value pairs.

Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.

The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:

Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.

mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="DefaultSyntaxNavigator_NoAncestors" xml:space="preserve">
<value>The navigator does not contain any ancestors</value>
</data>
<data name="QuerySyntaxRewriter_NotSupported" xml:space="preserve">
<value>The given syntax node is not supported by this rewriter.</value>
</data>
</root>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#nullable enable
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using static HotChocolate.Language.Properties.LangUtf8Resources;
using static HotChocolate.Language.Rewriters.LangRewritersResources;

namespace HotChocolate.Language;
namespace HotChocolate.Language.Rewriters;

public class QuerySyntaxRewriter<TContext>
: SyntaxRewriter<TContext>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;

namespace HotChocolate.Language;
namespace HotChocolate.Language.Rewriters;

public class SchemaSyntaxRewriter<TContext>
: SyntaxRewriter<TContext>
Expand Down