diff --git a/.claude/commands/pr.md b/.claude/commands/pr.md new file mode 100644 index 0000000..aecc2b5 --- /dev/null +++ b/.claude/commands/pr.md @@ -0,0 +1,3 @@ +# Open PR for current branch +- Use this [template](https://github.com/LayeredCraft/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md) for the PR. +- $ARGUMENTS \ No newline at end of file diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000..46c33a8 --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "csharpier": { + "version": "1.2.3", + "commands": [ + "csharpier" + ], + "rollForward": false + }, + "jetbrains.resharper.globaltools": { + "version": "2025.3.0.4", + "commands": [ + "jb" + ], + "rollForward": false + } + } +} \ No newline at end of file diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f94d1a7 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +max_line_length = 100 + +[*.cs] +indent_size = 4 +end_of_line = LF +insert_final_newline = true +trim_trailing_whitespace = true + diff --git a/.gitignore b/.gitignore index 61a2cff..b3eebc8 100644 --- a/.gitignore +++ b/.gitignore @@ -55,4 +55,6 @@ nunit-*.xml .idea -**/*DotSettings.user \ No newline at end of file +**/*DotSettings.user + +**/*.env \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props index 30af134..1fc3423 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -5,7 +5,7 @@ MIT Jonas Ha - csharp;library;utility;source generator + csharp;library;utility;SourceGenerator https://github.com/LayeredCraft/source-generator-tools Copyright © 2025 Jonas Ha https://github.com/LayeredCraft/source-generator-tools @@ -25,5 +25,6 @@ README.md + icon.png diff --git a/Directory.Packages.props b/Directory.Packages.props index 45b9ef4..f552466 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,6 +6,7 @@ + @@ -13,5 +14,7 @@ + + diff --git a/LayeredCraft.SourceGeneratorTools.sln.DotSettings b/LayeredCraft.SourceGeneratorTools.sln.DotSettings new file mode 100644 index 0000000..ea1af3d --- /dev/null +++ b/LayeredCraft.SourceGeneratorTools.sln.DotSettings @@ -0,0 +1,138 @@ + + <?xml version="1.0" encoding="utf-16"?><Profile name="Full Custom Cleanup"><CppReformatCode>True</CppReformatCode><FSharpReformatCode>True</FSharpReformatCode><ShaderLabReformatCode>True</ShaderLabReformatCode><XMLReformatCode>True</XMLReformatCode><VBReformatCode>True</VBReformatCode><CSReformatCode>True</CSReformatCode><CSharpReformatComments>True</CSharpReformatComments><CSCodeStyleAttributes ArrangeVarStyle="True" ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" ArrangeArgumentsStyle="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeCodeBodyStyle="True" ArrangeTrailingCommas="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" ArrangeNullCheckingPattern="True" /><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CppCodeStyleCleanupDescriptor ArrangeBraces="True" ArrangeAuto="True" ArrangeFunctionDeclarations="True" ArrangeNestedNamespaces="True" ArrangeTypeAliases="True" ArrangeCVQualifiers="True" ArrangeSlashesInIncludeDirectives="True" ArrangeOverridingFunctions="True" SortDefinitions="True" SortIncludeDirectives="True" SortMemberInitializers="True" /><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><VBOptimizeImports>True</VBOptimizeImports><VBShortenReferences>True</VBShortenReferences><Xaml.RemoveRedundantNamespaceAlias>True</Xaml.RemoveRedundantNamespaceAlias><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><CSReorderTypeMembers>True</CSReorderTypeMembers><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CppAddTypenameTemplateKeywords>True</CppAddTypenameTemplateKeywords><CppCStyleToStaticCastDescriptor>True</CppCStyleToStaticCastDescriptor><CppRedundantDereferences>True</CppRedundantDereferences><CppDeleteRedundantAccessSpecifier>True</CppDeleteRedundantAccessSpecifier><CppRemoveCastDescriptor>True</CppRemoveCastDescriptor><CppRemoveElseKeyword>True</CppRemoveElseKeyword><CppShortenQualifiedName>True</CppShortenQualifiedName><CppDeleteRedundantSpecifier>True</CppDeleteRedundantSpecifier><CppRemoveStatement>True</CppRemoveStatement><CppDeleteRedundantTypenameTemplateKeywords>True</CppDeleteRedundantTypenameTemplateKeywords><CppReplaceExpressionWithBooleanConst>True</CppReplaceExpressionWithBooleanConst><CppMakeIfConstexpr>True</CppMakeIfConstexpr><CppMakePostfixOperatorPrefix>True</CppMakePostfixOperatorPrefix><CppMakeVariableConstexpr>True</CppMakeVariableConstexpr><CppChangeSmartPointerToMakeFunction>True</CppChangeSmartPointerToMakeFunction><CppReplaceThrowWithRethrowFix>True</CppReplaceThrowWithRethrowFix><CppTypeTraitAliasDescriptor>True</CppTypeTraitAliasDescriptor><CppRemoveRedundantConditionalExpressionDescriptor>True</CppRemoveRedundantConditionalExpressionDescriptor><CppSimplifyConditionalExpressionDescriptor>True</CppSimplifyConditionalExpressionDescriptor><CppReplaceExpressionWithNullptr>True</CppReplaceExpressionWithNullptr><CppReplaceTieWithStructuredBindingDescriptor>True</CppReplaceTieWithStructuredBindingDescriptor><CppUseAssociativeContainsDescriptor>True</CppUseAssociativeContainsDescriptor><CppUseEraseAlgorithmDescriptor>True</CppUseEraseAlgorithmDescriptor><CppJoinDeclarationAndAssignmentDescriptor>True</CppJoinDeclarationAndAssignmentDescriptor><CppMakeClassFinal>True</CppMakeClassFinal><CppMakeLocalVarConstDescriptor>True</CppMakeLocalVarConstDescriptor><CppMakeMethodConst>True</CppMakeMethodConst><CppMakeMethodStatic>True</CppMakeMethodStatic><CppMakePtrOrRefParameterConst>True</CppMakePtrOrRefParameterConst><CppMakeParameterConst>True</CppMakeParameterConst><CppPassValueParameterByConstReference>True</CppPassValueParameterByConstReference><CppRemoveElaboratedTypeSpecifierDescriptor>True</CppRemoveElaboratedTypeSpecifierDescriptor><CppRemoveRedundantLambdaParameterListDescriptor>True</CppRemoveRedundantLambdaParameterListDescriptor><CppRemoveRedundantMemberInitializerDescriptor>True</CppRemoveRedundantMemberInitializerDescriptor><CppRemoveRedundantParentheses>True</CppRemoveRedundantParentheses><CppRemoveTemplateArgumentsDescriptor>True</CppRemoveTemplateArgumentsDescriptor><CppRemoveUnreachableCode>True</CppRemoveUnreachableCode><CppRemoveUnusedIncludes>True</CppRemoveUnusedIncludes><CppRemoveUnusedLambdaCaptures>True</CppRemoveUnusedLambdaCaptures><CppReplaceIfWithIfConsteval>True</CppReplaceIfWithIfConsteval><RemoveCodeRedundanciesVB>True</RemoveCodeRedundanciesVB><VBMakeFieldReadonly>True</VBMakeFieldReadonly><Xaml.RedundantFreezeAttribute>True</Xaml.RedundantFreezeAttribute><Xaml.RemoveRedundantModifiersAttribute>True</Xaml.RemoveRedundantModifiersAttribute><Xaml.RemoveRedundantNameAttribute>True</Xaml.RemoveRedundantNameAttribute><Xaml.RemoveRedundantResource>True</Xaml.RemoveRedundantResource><Xaml.RemoveRedundantCollectionProperty>True</Xaml.RemoveRedundantCollectionProperty><Xaml.RemoveRedundantAttachedPropertySetter>True</Xaml.RemoveRedundantAttachedPropertySetter><Xaml.RemoveRedundantStyledValue>True</Xaml.RemoveRedundantStyledValue><Xaml.RemoveForbiddenResourceName>True</Xaml.RemoveForbiddenResourceName><Xaml.RemoveRedundantGridDefinitionsAttribute>True</Xaml.RemoveRedundantGridDefinitionsAttribute><Xaml.RemoveRedundantUpdateSourceTriggerAttribute>True</Xaml.RemoveRedundantUpdateSourceTriggerAttribute><Xaml.RemoveRedundantBindingModeAttribute>True</Xaml.RemoveRedundantBindingModeAttribute><Xaml.RemoveRedundantGridSpanAttribut>True</Xaml.RemoveRedundantGridSpanAttribut><IDEA_SETTINGS>&lt;profile version="1.0"&gt; + &lt;option name="myName" value="Full Custom Cleanup" /&gt; + &lt;inspection_tool class="ConditionalExpressionWithIdenticalBranchesJS" enabled="true" level="WARNING" enabled_by_default="true" /&gt; + &lt;inspection_tool class="ES6ShorthandObjectProperty" enabled="true" level="WARNING" enabled_by_default="true" /&gt; + &lt;inspection_tool class="JSArrowFunctionBracesCanBeRemoved" enabled="true" level="WARNING" enabled_by_default="true" /&gt; + &lt;inspection_tool class="JSRemoveUnnecessaryParentheses" enabled="true" level="WARNING" enabled_by_default="true" /&gt; + &lt;inspection_tool class="UnterminatedStatementJS" enabled="true" level="WARNING" enabled_by_default="true" /&gt; +&lt;/profile&gt;</IDEA_SETTINGS><RIDER_SETTINGS>&lt;profile&gt; + &lt;Language id="CSS"&gt; + &lt;Rearrange&gt;true&lt;/Rearrange&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="EditorConfig"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="HCL"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="HTML"&gt; + &lt;OptimizeImports&gt;true&lt;/OptimizeImports&gt; + &lt;Rearrange&gt;true&lt;/Rearrange&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="HTTP Request"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="Handlebars"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="Ini"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="JSON"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="Jade"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="JavaScript"&gt; + &lt;OptimizeImports&gt;true&lt;/OptimizeImports&gt; + &lt;Rearrange&gt;true&lt;/Rearrange&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="Markdown"&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="Mermaid"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="PowerShell"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="Properties"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="RELAX-NG"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="Razor"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="SQL"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="TOML"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="VueExpr"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="XML"&gt; + &lt;OptimizeImports&gt;true&lt;/OptimizeImports&gt; + &lt;Rearrange&gt;true&lt;/Rearrange&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="yaml"&gt; + &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;/Language&gt; +&lt;/profile&gt;</RIDER_SETTINGS><CSharpFormatDocComments>True</CSharpFormatDocComments><RemoveCodeRedundancies>True</RemoveCodeRedundancies></Profile> + Built-in: Full Cleanup + NotRequired + NotRequired + NotRequired + NotRequired + ExpressionBody + ExpressionBody + ExpressionBody + True + False + False + False + False + False + False + False + True + 1 + ALWAYS + ALWAYS + ALWAYS + False + NEVER + False + False + ALWAYS_IF_MULTILINE + True + True + CHOP_IF_LONG + False + True + True + True + True + True + CHOP_IF_LONG + True + CHOP_IF_LONG + CHOP_IF_LONG + 2 + False + False + 2 + ByFirstAttr + True + False + False + True + False + False + True + False + False + True + True + True + True + True \ No newline at end of file diff --git a/LayeredCraft.SourceGeneratorTools.slnx b/LayeredCraft.SourceGeneratorTools.slnx index 8cd28e9..61b75cb 100644 --- a/LayeredCraft.SourceGeneratorTools.slnx +++ b/LayeredCraft.SourceGeneratorTools.slnx @@ -1,4 +1,7 @@ + + + @@ -6,6 +9,7 @@ + diff --git a/examples/LayeredCraft.SourceGeneratorTools.BasicExample/LayeredCraft.SourceGeneratorTools.BasicExample.csproj b/examples/LayeredCraft.SourceGeneratorTools.BasicExample/LayeredCraft.SourceGeneratorTools.BasicExample.csproj new file mode 100644 index 0000000..69590d4 --- /dev/null +++ b/examples/LayeredCraft.SourceGeneratorTools.BasicExample/LayeredCraft.SourceGeneratorTools.BasicExample.csproj @@ -0,0 +1,17 @@ + + + Exe + net10.0 + preview + enable + enable + false + + + + + diff --git a/examples/LayeredCraft.SourceGeneratorTools.BasicExample/Program.cs b/examples/LayeredCraft.SourceGeneratorTools.BasicExample/Program.cs new file mode 100644 index 0000000..2924520 --- /dev/null +++ b/examples/LayeredCraft.SourceGeneratorTools.BasicExample/Program.cs @@ -0,0 +1,6 @@ +// See https://aka.ms/new-console-template for more information + +using LayeredCraft.SourceGeneratorTools.Types; + +Console.WriteLine("Hello, World!"); +new EquatableArray(); diff --git a/global.json b/global.json new file mode 100644 index 0000000..38f47fa --- /dev/null +++ b/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "rollForward": "latestMinor", + "version": "10.0.101" + } +} \ No newline at end of file diff --git a/src/LayeredCraft.SourceGeneratorTools.Generator/GeneratableFeature.cs b/src/LayeredCraft.SourceGeneratorTools.Generator/GeneratableFeature.cs new file mode 100644 index 0000000..5fb8897 --- /dev/null +++ b/src/LayeredCraft.SourceGeneratorTools.Generator/GeneratableFeature.cs @@ -0,0 +1,3 @@ +namespace LayeredCraft.SourceGeneratorTools.Generator; + +internal readonly record struct GeneratableFeature(string Name, string[] FolderPaths); diff --git a/src/LayeredCraft.SourceGeneratorTools.Generator/GeneratorConstants.cs b/src/LayeredCraft.SourceGeneratorTools.Generator/GeneratorConstants.cs new file mode 100644 index 0000000..e2d09b1 --- /dev/null +++ b/src/LayeredCraft.SourceGeneratorTools.Generator/GeneratorConstants.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; + +namespace LayeredCraft.SourceGeneratorTools.Generator; + +internal static class GeneratorConstants +{ + internal const string GeneratedCodeHeader = """ + //------------------------------------------------------------------------------ + // + // This code was generated by a tool. + // + // Changes to this file may cause incorrect behavior and will be lost if + // the code is regenerated. + // + //------------------------------------------------------------------------------ + + #nullable enable + + + """; + + internal static readonly Dictionary Features = new() + { + ["EquatableArray"] = new GeneratableFeature( + "EquatableArray", + [ + "Tools/Types/EquatableArray/EquatableArray.cs", + "Tools/Types/EquatableArray/EquatableArrayExtensions.cs", + "Tools/Utilities/HashCode.cs", + ] + ), + }; +} diff --git a/src/LayeredCraft.SourceGeneratorTools.Generator/LayeredCraft.SourceGeneratorTools.Generator.csproj b/src/LayeredCraft.SourceGeneratorTools.Generator/LayeredCraft.SourceGeneratorTools.Generator.csproj new file mode 100644 index 0000000..e37c386 --- /dev/null +++ b/src/LayeredCraft.SourceGeneratorTools.Generator/LayeredCraft.SourceGeneratorTools.Generator.csproj @@ -0,0 +1,48 @@ + + + netstandard2.0 + preview + enable + Library + true + true + true + false + LayeredCraft.SourceGeneratorTools.Generator + A generator to create a collection of helpers and tools for working with source generators + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + Tools\%(RecursiveDir)%(Filename)%(Extension) + + + + + System.Runtime.CompilerServices.ModuleInitializerAttribute + + + + + diff --git a/src/LayeredCraft.SourceGeneratorTools.Generator/SourceGeneratorToolsGenerator.cs b/src/LayeredCraft.SourceGeneratorTools.Generator/SourceGeneratorToolsGenerator.cs new file mode 100644 index 0000000..eaa1bb4 --- /dev/null +++ b/src/LayeredCraft.SourceGeneratorTools.Generator/SourceGeneratorToolsGenerator.cs @@ -0,0 +1,76 @@ +using System; +using System.IO; +using System.Text; +using Microsoft.CodeAnalysis; + +namespace LayeredCraft.SourceGeneratorTools.Generator; + +[Generator] +public class SourceGeneratorToolsGenerator : IIncrementalGenerator +{ + private const string PublicModifier = "public"; + private const string InternalModifier = "internal"; + private const string NoReplaceComment = "// no-replace"; + private const int PublicModifierLength = 6; + + public void Initialize(IncrementalGeneratorInitializationContext context) => + context.RegisterPostInitializationOutput(ctx => + { + // For now, hardcode to EquatableArray - in the future this could be configurable + var featureKeys = new[] { "EquatableArray" }; + + var assembly = typeof(SourceGeneratorToolsGenerator).Assembly; + + foreach (var featureKey in featureKeys) + { + if (!GeneratorConstants.Features.TryGetValue(featureKey, out var feature)) + continue; + + // Get the assembly namespace for resource lookup + var assemblyNamespace = assembly.GetName().Name; + + // Load each file path specified in the feature + foreach (var filePath in feature.FolderPaths) + { + // Convert file path to embedded resource name (add assembly namespace and + // replace / with .) + var resourceName = $"{assemblyNamespace}.{filePath.Replace('/', '.')}"; + + using var stream = assembly.GetManifestResourceStream(resourceName); + if (stream == null) + continue; + + var content = ConvertPublicToInternal(stream); + + // Extract filename from the path + var fileName = Path.GetFileName(filePath); + var generatedFileName = Path.GetFileNameWithoutExtension(fileName) + ".g.cs"; + + var source = GeneratorConstants.GeneratedCodeHeader + content; + + ctx.AddSource(generatedFileName, source); + } + } + }); + + /// + /// Sets any line that starts with "public" to be "internal". This only impacts top-level + /// statements. This behavior can be skipped by adding a "// no-replace" at the end of the line. + /// + private static string ConvertPublicToInternal(Stream stream) + { + var sb = new StringBuilder((int)stream.Length); + using var reader = new StreamReader(stream); + + while (reader.ReadLine() is { } line) + if ( + line.StartsWith(PublicModifier) + && !line.Contains(NoReplaceComment, StringComparison.Ordinal) + ) + sb.Append(InternalModifier).AppendLine(line[PublicModifierLength..]); + else + sb.AppendLine(line); + + return sb.ToString(); + } +} diff --git a/src/LayeredCraft.SourceGeneratorTools/LayeredCraft.SourceGeneratorTools.csproj b/src/LayeredCraft.SourceGeneratorTools/LayeredCraft.SourceGeneratorTools.csproj index 0fb88a3..b36d1ee 100644 --- a/src/LayeredCraft.SourceGeneratorTools/LayeredCraft.SourceGeneratorTools.csproj +++ b/src/LayeredCraft.SourceGeneratorTools/LayeredCraft.SourceGeneratorTools.csproj @@ -4,6 +4,8 @@ preview enable Library + LayeredCraft.SourceGeneratorTools + A collection of helpers and tools for working with source generators diff --git a/src/LayeredCraft.SourceGeneratorTools/Types/EquatableArray.cs b/src/LayeredCraft.SourceGeneratorTools/Types/EquatableArray/EquatableArray.cs similarity index 96% rename from src/LayeredCraft.SourceGeneratorTools/Types/EquatableArray.cs rename to src/LayeredCraft.SourceGeneratorTools/Types/EquatableArray/EquatableArray.cs index 0ab266a..08ee32e 100644 --- a/src/LayeredCraft.SourceGeneratorTools/Types/EquatableArray.cs +++ b/src/LayeredCraft.SourceGeneratorTools/Types/EquatableArray/EquatableArray.cs @@ -6,6 +6,8 @@ using System.Collections.Generic; using System.Collections.Immutable; +// ReSharper disable RedundantNameQualifier + namespace LayeredCraft.SourceGeneratorTools.Types; /// @@ -37,7 +39,7 @@ public override int GetHashCode() if (_array is not T[] array) return 0; - HashCode hashCode = default; + LayeredCraft.SourceGeneratorTools.Utilities.HashCode hashCode = default; foreach (var item in array) hashCode.Add(item); diff --git a/src/LayeredCraft.SourceGeneratorTools/Types/EquatableArrayExtensions.cs b/src/LayeredCraft.SourceGeneratorTools/Types/EquatableArray/EquatableArrayExtensions.cs similarity index 100% rename from src/LayeredCraft.SourceGeneratorTools/Types/EquatableArrayExtensions.cs rename to src/LayeredCraft.SourceGeneratorTools/Types/EquatableArray/EquatableArrayExtensions.cs diff --git a/src/LayeredCraft.SourceGeneratorTools/Types/HashCode.cs b/src/LayeredCraft.SourceGeneratorTools/Utilities/HashCode.cs similarity index 99% rename from src/LayeredCraft.SourceGeneratorTools/Types/HashCode.cs rename to src/LayeredCraft.SourceGeneratorTools/Utilities/HashCode.cs index 4ec9b86..d6b50ac 100644 --- a/src/LayeredCraft.SourceGeneratorTools/Types/HashCode.cs +++ b/src/LayeredCraft.SourceGeneratorTools/Utilities/HashCode.cs @@ -3,10 +3,10 @@ using System.ComponentModel; using System.Runtime.CompilerServices; -namespace LayeredCraft.SourceGeneratorTools.Types; +namespace LayeredCraft.SourceGeneratorTools.Utilities; /// Polyfill for .NET 6 HashCode -internal struct HashCode +public struct HashCode { private static readonly uint s_seed = GenerateGlobalSeed(); diff --git a/taskfile.yaml b/taskfile.yaml new file mode 100644 index 0000000..e69de29 diff --git a/test/LayeredCraft.SourceGeneratorTools.UnitTests/Types/HashCodeTests.cs b/test/LayeredCraft.SourceGeneratorTools.UnitTests/Types/HashCodeTests.cs index 4eebe00..c5f291c 100644 --- a/test/LayeredCraft.SourceGeneratorTools.UnitTests/Types/HashCodeTests.cs +++ b/test/LayeredCraft.SourceGeneratorTools.UnitTests/Types/HashCodeTests.cs @@ -1,6 +1,6 @@ using AwesomeAssertions; using JetBrains.Annotations; -using HashCode = LayeredCraft.SourceGeneratorTools.Types.HashCode; +using HashCode = LayeredCraft.SourceGeneratorTools.Utilities.HashCode; namespace LayeredCraft.SourceGeneratorTools.UnitTests.Types;