-
Notifications
You must be signed in to change notification settings - Fork 58
Rich generators #80
Rich generators #80
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Copyright (c) Andrew Arnott. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. | ||
|
||
namespace CodeGeneration.Roslyn | ||
{ | ||
using System; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.CodeAnalysis; | ||
|
||
/// <summary> | ||
/// Describes a code generator that responds to attributes on members to generate code, | ||
/// and returns compilation unit members | ||
/// </summary> | ||
public interface IRichCodeGenerator : ICodeGenerator | ||
{ | ||
Task<RichGenerationResult> GenerateRichAsync(TransformationContext context, IProgress<Diagnostic> progress, CancellationToken cancellationToken); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright (c) Andrew Arnott. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. | ||
|
||
namespace CodeGeneration.Roslyn | ||
{ | ||
using System.Diagnostics; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
|
||
/// <summary> | ||
/// Contains <see cref="CompilationUnitSyntax"/> additions generated by the <see cref="IRichCodeGenerator"/>. | ||
/// </summary> | ||
public struct RichGenerationResult | ||
{ | ||
/// <summary> | ||
/// Creates <see cref="RichGenerationResult"/> with provided arguments as property values. | ||
/// </summary> | ||
/// <param name="members">Assigned to <see cref="Members"/>.</param> | ||
/// <param name="usings">Assigned to <see cref="Usings"/>.</param> | ||
/// <param name="attributeLists">Assigned to <see cref="AttributeLists"/>.</param> | ||
/// <param name="externs">Assigned to <see cref="Externs"/>.</param> | ||
[DebuggerStepThrough] | ||
public RichGenerationResult( | ||
SyntaxList<MemberDeclarationSyntax> members, | ||
SyntaxList<UsingDirectiveSyntax> usings = default, | ||
SyntaxList<AttributeListSyntax> attributeLists = default, | ||
SyntaxList<ExternAliasDirectiveSyntax> externs = default) | ||
{ | ||
|
||
Members = members; | ||
Usings = usings; | ||
AttributeLists = attributeLists; | ||
Externs = externs; | ||
} | ||
|
||
/// <summary> | ||
/// Gets <see cref="MemberDeclarationSyntax"/> to add to generated <see cref="CompilationUnitSyntax"/>. | ||
/// </summary> | ||
public SyntaxList<MemberDeclarationSyntax> Members { get; } | ||
|
||
/// <summary> | ||
/// Gets <see cref="UsingDirectiveSyntax"/> to add to generated <see cref="CompilationUnitSyntax"/>. | ||
/// </summary> | ||
public SyntaxList<UsingDirectiveSyntax> Usings { get; } | ||
|
||
/// <summary> | ||
/// Gets <see cref="ExternAliasDirectiveSyntax"/> to add to generated <see cref="CompilationUnitSyntax"/>. | ||
/// </summary> | ||
public SyntaxList<ExternAliasDirectiveSyntax> Externs { get; } | ||
|
||
/// <summary> | ||
/// Gets <see cref="AttributeListSyntax"/> to add to generated <see cref="CompilationUnitSyntax"/>. | ||
/// </summary> | ||
public SyntaxList<AttributeListSyntax> AttributeLists { get; } | ||
|
||
[DebuggerHidden, DebuggerStepThrough] | ||
public void Deconstruct(out SyntaxList<MemberDeclarationSyntax> members, | ||
out SyntaxList<UsingDirectiveSyntax> usings, | ||
out SyntaxList<AttributeListSyntax> attributeLists, | ||
out SyntaxList<ExternAliasDirectiveSyntax> externs) | ||
{ | ||
members = Members; | ||
usings = Usings; | ||
attributeLists = AttributeLists; | ||
externs = Externs; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not a fan of deconstruction unless it's very obvious what the members will be to the caller and what order they should come in (i.e. first and last name). As the members grow, their order in this list are basically arbitrary -- they look arbitrary right now. That leads to bugs in code when you add/refactor in this class but fail to update every caller (which is hard, since they don't actually call Deconstruct explicitly) and it happens to compile because the types between two reordered members remains the same. |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,10 @@ | ||
using Microsoft.CodeAnalysis; | ||
// Copyright (c) Andrew Arnott. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. | ||
|
||
using System.Collections.Generic; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
|
||
namespace CodeGeneration.Roslyn | ||
{ | ||
|
@@ -12,13 +17,19 @@ public class TransformationContext | |
/// <param name="semanticModel">The semantic model.</param> | ||
/// <param name="compilation">The overall compilation being generated for.</param> | ||
/// <param name="projectDirectory">The absolute path of the directory where the project file is located</param> | ||
/// <param name="compilationUnitUsings">The using directives already queued to be generated.</param> | ||
/// <param name="compilationUnitExterns">The extern aliases already queued to be generated.</param> | ||
public TransformationContext(CSharpSyntaxNode processingNode, SemanticModel semanticModel, CSharpCompilation compilation, | ||
string projectDirectory) | ||
string projectDirectory, | ||
IEnumerable<UsingDirectiveSyntax> compilationUnitUsings, | ||
IEnumerable<ExternAliasDirectiveSyntax> compilationUnitExterns) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While this is a technically breaking change, it should only break unit tests that may have been written for generators, which isn't as severe. |
||
ProcessingNode = processingNode; | ||
SemanticModel = semanticModel; | ||
Compilation = compilation; | ||
ProjectDirectory = projectDirectory; | ||
CompilationUnitUsings = compilationUnitUsings; | ||
CompilationUnitExterns = compilationUnitExterns; | ||
} | ||
|
||
/// <summary>Gets the syntax node the generator attribute is found on.</summary> | ||
|
@@ -30,9 +41,13 @@ public TransformationContext(CSharpSyntaxNode processingNode, SemanticModel sema | |
/// <summary>Gets the overall compilation being generated for.</summary> | ||
public CSharpCompilation Compilation { get; } | ||
|
||
/// <summary> | ||
/// Gets the absolute path of the directory where the project file is located | ||
/// </summary> | ||
/// <summary>Gets the absolute path of the directory where the project file is located.</summary> | ||
public string ProjectDirectory { get; } | ||
|
||
/// <summary>Gets a collection of using directives already queued to be generated.</summary> | ||
public IEnumerable<UsingDirectiveSyntax> CompilationUnitUsings { get; } | ||
|
||
/// <summary>Gets a collection of extern aliases already queued to be generated.</summary> | ||
public IEnumerable<ExternAliasDirectiveSyntax> CompilationUnitExterns { get; } | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's go ahead and shoot for 7.3. 😄 #Closed