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

Generate GenerateAutomaticInterfaceAttribute #47

Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 59 additions & 67 deletions AutomaticInterface/AutomaticInterface.sln
Original file line number Diff line number Diff line change
@@ -1,67 +1,59 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31702.278
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutomaticInterfaceExample", "AutomaticInterfaceExample\AutomaticInterfaceExample.csproj", "{AFDAB373-7268-4A1B-ABAF-EA076C3B2B4C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutomaticInterface", "AutomaticInterface\AutomaticInterface.csproj", "{AA3F5AAE-44B7-4F33-8152-A5251B51AD79}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutomaticInterfaceAttribute", "AutomaticInterfaceAttribute\AutomaticInterfaceAttribute.csproj", "{ADEA885F-9F6F-443E-945A-512223AEFC11}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{E267C5B3-44DD-4D26-A2F7-5FDF92FF28D5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{96FEC8F8-B0D8-41C9-B9C4-6D1B221D6128}"
ProjectSection(SolutionItems) = preProject
Directory.Build.targets = Directory.Build.targets
..\.github\workflows\action.yml = ..\.github\workflows\action.yml
..\README.md = ..\README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestNuget", "TestNuget\TestNuget.csproj", "{E7CF6623-54D8-4A40-A1B1-CE078551EFE1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
DebugGenerator|Any CPU = DebugGenerator|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AFDAB373-7268-4A1B-ABAF-EA076C3B2B4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AFDAB373-7268-4A1B-ABAF-EA076C3B2B4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AFDAB373-7268-4A1B-ABAF-EA076C3B2B4C}.DebugGenerator|Any CPU.ActiveCfg = DebugGenerator|Any CPU
{AFDAB373-7268-4A1B-ABAF-EA076C3B2B4C}.DebugGenerator|Any CPU.Build.0 = DebugGenerator|Any CPU
{AFDAB373-7268-4A1B-ABAF-EA076C3B2B4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AFDAB373-7268-4A1B-ABAF-EA076C3B2B4C}.Release|Any CPU.Build.0 = Release|Any CPU
{AA3F5AAE-44B7-4F33-8152-A5251B51AD79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA3F5AAE-44B7-4F33-8152-A5251B51AD79}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA3F5AAE-44B7-4F33-8152-A5251B51AD79}.DebugGenerator|Any CPU.ActiveCfg = DebugGenerator|Any CPU
{AA3F5AAE-44B7-4F33-8152-A5251B51AD79}.DebugGenerator|Any CPU.Build.0 = DebugGenerator|Any CPU
{AA3F5AAE-44B7-4F33-8152-A5251B51AD79}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA3F5AAE-44B7-4F33-8152-A5251B51AD79}.Release|Any CPU.Build.0 = Release|Any CPU
{ADEA885F-9F6F-443E-945A-512223AEFC11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ADEA885F-9F6F-443E-945A-512223AEFC11}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ADEA885F-9F6F-443E-945A-512223AEFC11}.DebugGenerator|Any CPU.ActiveCfg = DebugGenerator|Any CPU
{ADEA885F-9F6F-443E-945A-512223AEFC11}.DebugGenerator|Any CPU.Build.0 = DebugGenerator|Any CPU
{ADEA885F-9F6F-443E-945A-512223AEFC11}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ADEA885F-9F6F-443E-945A-512223AEFC11}.Release|Any CPU.Build.0 = Release|Any CPU
{E267C5B3-44DD-4D26-A2F7-5FDF92FF28D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E267C5B3-44DD-4D26-A2F7-5FDF92FF28D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E267C5B3-44DD-4D26-A2F7-5FDF92FF28D5}.DebugGenerator|Any CPU.ActiveCfg = DebugGenerator|Any CPU
{E267C5B3-44DD-4D26-A2F7-5FDF92FF28D5}.DebugGenerator|Any CPU.Build.0 = DebugGenerator|Any CPU
{E267C5B3-44DD-4D26-A2F7-5FDF92FF28D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E267C5B3-44DD-4D26-A2F7-5FDF92FF28D5}.Release|Any CPU.Build.0 = Release|Any CPU
{E7CF6623-54D8-4A40-A1B1-CE078551EFE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E7CF6623-54D8-4A40-A1B1-CE078551EFE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7CF6623-54D8-4A40-A1B1-CE078551EFE1}.DebugGenerator|Any CPU.ActiveCfg = Debug|Any CPU
{E7CF6623-54D8-4A40-A1B1-CE078551EFE1}.DebugGenerator|Any CPU.Build.0 = Debug|Any CPU
{E7CF6623-54D8-4A40-A1B1-CE078551EFE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7CF6623-54D8-4A40-A1B1-CE078551EFE1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B144CF18-21D8-4CB6-9847-DDE7451543D4}
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34728.123
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutomaticInterfaceExample", "AutomaticInterfaceExample\AutomaticInterfaceExample.csproj", "{AFDAB373-7268-4A1B-ABAF-EA076C3B2B4C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutomaticInterface", "AutomaticInterface\AutomaticInterface.csproj", "{AA3F5AAE-44B7-4F33-8152-A5251B51AD79}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{E267C5B3-44DD-4D26-A2F7-5FDF92FF28D5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{96FEC8F8-B0D8-41C9-B9C4-6D1B221D6128}"
ProjectSection(SolutionItems) = preProject
..\.github\workflows\action.yml = ..\.github\workflows\action.yml
Directory.Build.targets = Directory.Build.targets
..\README.md = ..\README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestNuget", "TestNuget\TestNuget.csproj", "{E7CF6623-54D8-4A40-A1B1-CE078551EFE1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
DebugGenerator|Any CPU = DebugGenerator|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AFDAB373-7268-4A1B-ABAF-EA076C3B2B4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AFDAB373-7268-4A1B-ABAF-EA076C3B2B4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AFDAB373-7268-4A1B-ABAF-EA076C3B2B4C}.DebugGenerator|Any CPU.ActiveCfg = DebugGenerator|Any CPU
{AFDAB373-7268-4A1B-ABAF-EA076C3B2B4C}.DebugGenerator|Any CPU.Build.0 = DebugGenerator|Any CPU
{AFDAB373-7268-4A1B-ABAF-EA076C3B2B4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AFDAB373-7268-4A1B-ABAF-EA076C3B2B4C}.Release|Any CPU.Build.0 = Release|Any CPU
{AA3F5AAE-44B7-4F33-8152-A5251B51AD79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA3F5AAE-44B7-4F33-8152-A5251B51AD79}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA3F5AAE-44B7-4F33-8152-A5251B51AD79}.DebugGenerator|Any CPU.ActiveCfg = DebugGenerator|Any CPU
{AA3F5AAE-44B7-4F33-8152-A5251B51AD79}.DebugGenerator|Any CPU.Build.0 = DebugGenerator|Any CPU
{AA3F5AAE-44B7-4F33-8152-A5251B51AD79}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA3F5AAE-44B7-4F33-8152-A5251B51AD79}.Release|Any CPU.Build.0 = Release|Any CPU
{E267C5B3-44DD-4D26-A2F7-5FDF92FF28D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E267C5B3-44DD-4D26-A2F7-5FDF92FF28D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E267C5B3-44DD-4D26-A2F7-5FDF92FF28D5}.DebugGenerator|Any CPU.ActiveCfg = DebugGenerator|Any CPU
{E267C5B3-44DD-4D26-A2F7-5FDF92FF28D5}.DebugGenerator|Any CPU.Build.0 = DebugGenerator|Any CPU
{E267C5B3-44DD-4D26-A2F7-5FDF92FF28D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E267C5B3-44DD-4D26-A2F7-5FDF92FF28D5}.Release|Any CPU.Build.0 = Release|Any CPU
{E7CF6623-54D8-4A40-A1B1-CE078551EFE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E7CF6623-54D8-4A40-A1B1-CE078551EFE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7CF6623-54D8-4A40-A1B1-CE078551EFE1}.DebugGenerator|Any CPU.ActiveCfg = Debug|Any CPU
{E7CF6623-54D8-4A40-A1B1-CE078551EFE1}.DebugGenerator|Any CPU.Build.0 = Debug|Any CPU
{E7CF6623-54D8-4A40-A1B1-CE078551EFE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7CF6623-54D8-4A40-A1B1-CE078551EFE1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B144CF18-21D8-4CB6-9847-DDE7451543D4}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System;
using System.Collections.Immutable;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;

namespace AutomaticInterface;

Expand All @@ -13,6 +15,32 @@ public class AutomaticInterfaceGenerator : IIncrementalGenerator

public void Initialize(IncrementalGeneratorInitializationContext context)
{
context.RegisterPostInitializationOutput(static postInitializationContext =>
{
postInitializationContext.AddSource(
$"{DefaultAttributeName}.Attribute.g.cs",
SourceText.From(
$$$"""
// <auto-generated />
using System;

namespace AutomaticInterface
{
/// <summary>
/// Use source generator to automatically create a Interface from this class
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
internal sealed class {{{DefaultAttributeName}}}Attribute : Attribute
{
internal {{{DefaultAttributeName}}}Attribute(string namespaceName = "") { }
}
}
""",
Encoding.UTF8
)
);
});

var classes = context
.SyntaxProvider.CreateSyntaxProvider(CouldBeClassWithInterfaceAttribute, Transform)
.Where(type => type is not null)
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\AutomaticInterfaceAttribute\AutomaticInterfaceAttribute.csproj" />
<ProjectReference Include="..\AutomaticInterface\AutomaticInterface.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>

Expand Down
2 changes: 1 addition & 1 deletion AutomaticInterface/AutomaticInterfaceExample/DemoClass.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.Threading.Tasks;
using AutomaticInterfaceAttribute;
using AutomaticInterface;

namespace AutomaticInterfaceExample
{
Expand All @@ -18,9 +18,9 @@
/// <summary>
/// Property Documentation will be copied
/// </summary>
public string Hello { get; set; } // included, get and set are copied to the interface when public

Check warning on line 21 in AutomaticInterface/AutomaticInterfaceExample/DemoClass.cs

View workflow job for this annotation

GitHub Actions / test

Non-nullable property 'Hello' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

public string OnlyGet { get; } // included, get and set are copied to the interface when public

Check warning on line 23 in AutomaticInterface/AutomaticInterfaceExample/DemoClass.cs

View workflow job for this annotation

GitHub Actions / test

Non-nullable property 'OnlyGet' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

public string? NullableProperty { get; set; }

Expand Down Expand Up @@ -48,7 +48,7 @@

public Task<string?> ASync(string x, string y)
{
return Task.FromResult("");

Check warning on line 51 in AutomaticInterface/AutomaticInterfaceExample/DemoClass.cs

View workflow job for this annotation

GitHub Actions / test

Nullability of reference types in value of type 'Task<string>' doesn't match target type 'Task<string?>'.
}

public static string StaticProperty => "abc"; // static property, ignored
Expand All @@ -62,18 +62,18 @@
/// event Documentation will be copied
/// </summary>
#pragma warning disable S3264 // Events should be invoked
public event EventHandler ShapeChanged; // included

Check warning on line 65 in AutomaticInterface/AutomaticInterfaceExample/DemoClass.cs

View workflow job for this annotation

GitHub Actions / test

Non-nullable event 'ShapeChanged' must contain a non-null value when exiting constructor. Consider declaring the event as nullable.

Check warning on line 65 in AutomaticInterface/AutomaticInterfaceExample/DemoClass.cs

View workflow job for this annotation

GitHub Actions / test

The event 'DemoClass.ShapeChanged' is never used
#pragma warning restore S3264 // Events should be invoked

#pragma warning disable S3264 // Events should be invoked
#pragma warning disable IDE0051 // Remove unused private members
private event EventHandler ShapeChanged2; // ignored because not public

Check warning on line 70 in AutomaticInterface/AutomaticInterfaceExample/DemoClass.cs

View workflow job for this annotation

GitHub Actions / test

Non-nullable event 'ShapeChanged2' must contain a non-null value when exiting constructor. Consider declaring the event as nullable.
#pragma warning restore IDE0051 // Remove unused private members
#pragma warning restore S3264 // Events should be invoked

public event EventHandler? ShapeChangedNullable; // included

Check warning on line 74 in AutomaticInterface/AutomaticInterfaceExample/DemoClass.cs

View workflow job for this annotation

GitHub Actions / test

The event 'DemoClass.ShapeChangedNullable' is never used

public event EventHandler<string?> ShapeChangedNullable2; // included

Check warning on line 76 in AutomaticInterface/AutomaticInterfaceExample/DemoClass.cs

View workflow job for this annotation

GitHub Actions / test

Non-nullable event 'ShapeChangedNullable2' must contain a non-null value when exiting constructor. Consider declaring the event as nullable.

Check warning on line 76 in AutomaticInterface/AutomaticInterfaceExample/DemoClass.cs

View workflow job for this annotation

GitHub Actions / test

The event 'DemoClass.ShapeChangedNullable2' is never used

private readonly int[] arr = new int[100];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using AutomaticInterfaceAttribute;
using AutomaticInterface;
using CustomNamespace;

namespace AutomaticInterfaceExample
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#nullable enable
using System;
using System.CodeDom.Compiler;
using AutomaticInterfaceAttribute;
using AutomaticInterface;

namespace AutomaticInterfaceExample
{
Expand Down
14 changes: 14 additions & 0 deletions AutomaticInterface/TestNuget/RemoveThisOnNextVersionAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;

namespace AutomaticInterface
crwsolutions marked this conversation as resolved.
Show resolved Hide resolved
{
/// <summary>
/// Use source generator to automatically create a Interface from this class
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
[Obsolete("This attribute is obsolete. Use generated attribute instead.", false)]
internal sealed class GenerateAutomaticInterfaceAttribute : Attribute
{
internal GenerateAutomaticInterfaceAttribute(string namespaceName = "") { }
}
}
2 changes: 1 addition & 1 deletion AutomaticInterface/TestNuget/Test.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using AutomaticInterfaceAttribute;
using AutomaticInterface;

namespace TestNuget
{
[GenerateAutomaticInterface]

Check warning on line 5 in AutomaticInterface/TestNuget/Test.cs

View workflow job for this annotation

GitHub Actions / test

'GenerateAutomaticInterfaceAttribute' is obsolete: 'This attribute is obsolete. Use generated attribute instead.'
public class Test : ITest
{
public string GetString()
Expand Down
4 changes: 0 additions & 4 deletions AutomaticInterface/TestNuget/TestNuget.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,4 @@
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\AutomaticInterfaceAttribute\AutomaticInterfaceAttribute.csproj" />
</ItemGroup>

</Project>
10 changes: 2 additions & 8 deletions AutomaticInterface/Tests/GeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1901,17 +1901,11 @@ public void CustomNameSpace()
{
const string code = """

using AutomaticInterfaceAttribute;
using AutomaticInterface;
using System;

namespace AutomaticInterfaceExample
{
[AttributeUsage(AttributeTargets.Class)]
public class GenerateAutomaticInterfaceAttribute : Attribute
{
public GenerateAutomaticInterfaceAttribute(string namespaceName = "") { }
}

/// <summary>
/// Bla bla
/// </summary>
Expand Down Expand Up @@ -1946,7 +1940,7 @@ class DemoClass

#nullable enable
using System.CodeDom.Compiler;
using AutomaticInterfaceAttribute;
using AutomaticInterface;
using System;

namespace CustomNameSpace
Expand Down
1 change: 0 additions & 1 deletion AutomaticInterface/Tests/Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\AutomaticInterfaceAttribute\AutomaticInterfaceAttribute.csproj" />
<ProjectReference Include="..\AutomaticInterface\AutomaticInterface.csproj" />
</ItemGroup>
</Project>
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This interface will be generated on each subsequent build, eliminating the the f
## Example

```c#
using AutomaticInterfaceAttribute;
using AutomaticInterface;
using System;

namespace AutomaticInterfaceExample
Expand Down Expand Up @@ -85,7 +85,7 @@ This will create this interface:
```C#
#nullable enable
using System.CodeDom.Compiler;
using AutomaticInterfaceAttribute;
using AutomaticInterface;
using System;

/// <summary>
Expand Down Expand Up @@ -126,9 +126,8 @@ namespace AutomaticInterfaceExample
## How to use it?
crwsolutions marked this conversation as resolved.
Show resolved Hide resolved

1. Install the nuget: `dotnet add package AutomaticInterface`
2. Create an Attribute with the Name `[GenerateAutomaticInterface]`. You can just copy the minimal code from this Repo (see the `AutomaticInterfaceAttribute` project). It's the easiest way to get that attribute because you cannot reference any code from the analyzer package.
crwsolutions marked this conversation as resolved.
Show resolved Hide resolved
3. Let your class implement the interface, e.g. `SomeClass: ISomeClass`
4. Build Solution, the Interface should now be available.
2. Let your class implement the interface, e.g. `SomeClass: ISomeClass`
3. Build Solution, the Interface should now be available.

Any errors? Ping me at: [email protected]

Expand Down
Loading