-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from HamletTanyavong/dev
Remove type parameter requirement for numeric types
- Loading branch information
Showing
31 changed files
with
1,473 additions
and
1,130 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// <copyright file="Extensions.cs" company="Mathematics.NET"> | ||
// Mathematics.NET | ||
// https://github.com/HamletTanyavong/Mathematics.NET | ||
// | ||
// MIT License | ||
// | ||
// Copyright (c) 2023 Hamlet Tanyavong | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in all | ||
// copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
// SOFTWARE. | ||
// </copyright> | ||
|
||
namespace Mathematics.NET.SourceGenerators; | ||
|
||
public static class Extensions | ||
{ | ||
public static string? GetValue(this NameSyntax name) | ||
{ | ||
return name switch | ||
{ | ||
SimpleNameSyntax simpleNameSyntax => simpleNameSyntax.Identifier.Text, | ||
QualifiedNameSyntax qualifiedNameSyntax => qualifiedNameSyntax.Right.Identifier.Text, | ||
_ => null | ||
}; | ||
} | ||
|
||
// TODO: Determine if every equation should/will have an attribute to remove. | ||
public static MethodDeclarationSyntax RemoveEquationAttribute(this MethodDeclarationSyntax methodDeclarationSyntax) | ||
{ | ||
var equationAttributeNode = methodDeclarationSyntax | ||
.DescendantNodes() | ||
.OfType<AttributeSyntax>() | ||
.First(syntax => syntax.Name.GetValue() is "Equation" or "EquationAttribute"); | ||
|
||
if (equationAttributeNode.Parent!.ChildNodes().Count() > 1) | ||
{ | ||
return methodDeclarationSyntax.RemoveNode(equationAttributeNode, SyntaxRemoveOptions.KeepNoTrivia)!; | ||
} | ||
else | ||
{ | ||
return methodDeclarationSyntax.RemoveNode(equationAttributeNode.Parent, SyntaxRemoveOptions.KeepNoTrivia)!; | ||
} | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
src/Mathematics.NET.SourceGenerators/IncrementalGenerators/DerivativeGenerator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// <copyright file="DerivativeGenerator.cs" company="Mathematics.NET"> | ||
// Mathematics.NET | ||
// https://github.com/HamletTanyavong/Mathematics.NET | ||
// | ||
// MIT License | ||
// | ||
// Copyright (c) 2023 Hamlet Tanyavong | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in all | ||
// copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
// SOFTWARE. | ||
// </copyright> | ||
|
||
using System.Collections.Immutable; | ||
using System.Text; | ||
using Mathematics.NET.SourceGenerators.Models; | ||
using Mathematics.NET.SourceGenerators.SourceBuilders; | ||
|
||
namespace Mathematics.NET.SourceGenerators.IncrementalGenerators; | ||
|
||
/// <summary>A generator for calculating derivatives</summary> | ||
[Generator] | ||
public sealed class DerivativeGenerator : IIncrementalGenerator | ||
{ | ||
public void Initialize(IncrementalGeneratorInitializationContext context) | ||
{ | ||
var provider = context.SyntaxProvider | ||
.CreateSyntaxProvider(CouldBeEquationAttribute, GetEquationOrNull) | ||
.Where(info => info is not null); | ||
var compilation = context.CompilationProvider.Combine(provider.Collect()); | ||
context.RegisterSourceOutput(compilation, (context, source) => GenerateCode(context, source.Left, source.Right!)); | ||
} | ||
|
||
private static bool CouldBeEquationAttribute(SyntaxNode syntaxNode, CancellationToken cancellationToken) | ||
=> syntaxNode is AttributeSyntax attributeSyntax && attributeSyntax.Name.GetValue() is "Equation" or "EquationAttribute"; | ||
|
||
private static MethodInformation? GetEquationOrNull(GeneratorSyntaxContext context, CancellationToken cancellationToken) | ||
{ | ||
// The method syntax will not be null if attribute syntax is not null since the attribute can only be applied to methods. | ||
var attribute = (AttributeSyntax)context.Node; | ||
return new(attribute, (MethodDeclarationSyntax)attribute.Parent!.Parent!); | ||
} | ||
|
||
private void GenerateCode(SourceProductionContext context, Compilation compilation, ImmutableArray<MethodInformation> methodInformation) | ||
{ | ||
var derivatives = new DerivativesBuilder(compilation, methodInformation); | ||
context.AddSource("Equations.g.cs", derivatives.GenerateSource().GetText(Encoding.UTF8).ToString()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
src/Mathematics.NET.SourceGenerators/Models/MethodInformation.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// <copyright file="MethodInformation.cs" company="Mathematics.NET"> | ||
// Mathematics.NET | ||
// https://github.com/HamletTanyavong/Mathematics.NET | ||
// | ||
// MIT License | ||
// | ||
// Copyright (c) 2023 Hamlet Tanyavong | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in all | ||
// copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
// SOFTWARE. | ||
// </copyright> | ||
|
||
namespace Mathematics.NET.SourceGenerators.Models; | ||
|
||
/// <summary>A class containing information about a specific method</summary> | ||
public sealed class MethodInformation | ||
{ | ||
public MethodInformation(AttributeSyntax attributeSyntax, MethodDeclarationSyntax methodDeclaration) | ||
{ | ||
AttributeSyntax = attributeSyntax; | ||
MethodDeclaration = methodDeclaration; | ||
} | ||
|
||
public AttributeSyntax AttributeSyntax { get; } | ||
|
||
public MethodDeclarationSyntax MethodDeclaration { get; } | ||
} |
101 changes: 101 additions & 0 deletions
101
src/Mathematics.NET.SourceGenerators/SourceBuilders/DerivativesBuilder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// <copyright file="DerivativesBuilder.cs" company="Mathematics.NET"> | ||
// Mathematics.NET | ||
// https://github.com/HamletTanyavong/Mathematics.NET | ||
// | ||
// MIT License | ||
// | ||
// Copyright (c) 2023 Hamlet Tanyavong | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in all | ||
// copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
// SOFTWARE. | ||
// </copyright> | ||
|
||
using System.Collections.Immutable; | ||
using Mathematics.NET.SourceGenerators.Models; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; | ||
|
||
namespace Mathematics.NET.SourceGenerators.SourceBuilders; | ||
|
||
/// <summary>Derivatives builder</summary> | ||
public sealed class DerivativesBuilder | ||
{ | ||
private readonly string _assemblyName; | ||
private readonly ImmutableArray<MethodInformation> _methodInformation; | ||
|
||
public DerivativesBuilder(Compilation compilationUnitSyntax, ImmutableArray<MethodInformation> methodInformation) | ||
{ | ||
_assemblyName = compilationUnitSyntax.AssemblyName!; | ||
_methodInformation = methodInformation; | ||
} | ||
|
||
public CompilationUnitSyntax GenerateSource() | ||
{ | ||
var members = GenerateMembers(); | ||
return CreateCompilationUnit(members); | ||
} | ||
|
||
private CompilationUnitSyntax CreateCompilationUnit(MemberDeclarationSyntax[] memberDeclarations) | ||
{ | ||
return CompilationUnit() | ||
.WithUsings( | ||
SingletonList( | ||
UsingDirective( | ||
QualifiedName( | ||
QualifiedName( | ||
IdentifierName("Mathematics"), | ||
IdentifierName("NET")), | ||
IdentifierName("Core"))) | ||
.WithUsingKeyword( | ||
Token( | ||
TriviaList( | ||
Comment("// Auto-generated code")), | ||
SyntaxKind.UsingKeyword, | ||
TriviaList())))) | ||
.WithMembers( | ||
SingletonList<MemberDeclarationSyntax>( | ||
FileScopedNamespaceDeclaration( | ||
QualifiedName( | ||
QualifiedName( | ||
IdentifierName(_assemblyName), | ||
IdentifierName("Generated")), | ||
IdentifierName("Mathematics"))) | ||
.WithMembers( | ||
SingletonList<MemberDeclarationSyntax>( | ||
ClassDeclaration("Equations") | ||
.WithModifiers( | ||
TokenList(new[] { | ||
Token(SyntaxKind.PublicKeyword), | ||
Token(SyntaxKind.StaticKeyword) })) | ||
.WithMembers( | ||
List(memberDeclarations)))))) | ||
.NormalizeWhitespace(); | ||
} | ||
|
||
private MemberDeclarationSyntax[] GenerateMembers() | ||
{ | ||
var result = new MemberDeclarationSyntax[_methodInformation.Length]; | ||
for (int i = 0; i < _methodInformation.Length; i++) | ||
{ | ||
var equation = _methodInformation[i].MethodDeclaration.RemoveEquationAttribute(); | ||
var transformedEquation = SymbolicsHelper.TransformEquation(equation); | ||
result[i] = transformedEquation; | ||
} | ||
return result; | ||
} | ||
} |
Oops, something went wrong.