Skip to content

Commit

Permalink
Merge pull request #109 from arthurward/feature/filterRecords
Browse files Browse the repository at this point in the history
Suppress the compiler-generated members of record types in source generator.
  • Loading branch information
pierre3 authored Nov 25, 2024
2 parents 87cdd74 + 4a6a830 commit 7b3d1ed
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public static string GetName(this IMethodSymbol symbol)
}
public static string GetReturnTypeString(this IMethodSymbol symbol)
{
if(symbol.MethodKind is MethodKind.Constructor
or MethodKind.SharedConstructor
if (symbol.MethodKind is MethodKind.Constructor
or MethodKind.SharedConstructor
or MethodKind.StaticConstructor)
{ return ""; }
return symbol.ReturnsVoid ? " : void" : $" : {symbol.ReturnType.GetTypeName()}";
Expand All @@ -29,7 +29,7 @@ public static string GetModifiersString(this IMethodSymbol symbol)
var modifiers = string.Join(" ",
new[]
{
symbol.ContainingType.TypeKind is not TypeKind.Interface
symbol.ContainingType.TypeKind is not TypeKind.Interface
&& symbol.IsAbstract ? "{abstract}" : "",
symbol.IsStatic ? "{static}" : "",
symbol.IsSealed ? "<<sealed>>" : "",
Expand All @@ -49,4 +49,21 @@ public static string GetParametersString(this IMethodSymbol symbol)
return string.Join(", ", symbol.Parameters
.Select(param => $"{param.Name} : {param.Type.GetTypeName()}"));
}

/// <summary>
/// Determine if the given method is the sole explicit constructor for a
/// record type.
/// </summary>
/// <param name="method">The method to inspect.</param>
/// <returns>True if there are no other explicit constructors in the method's type.</returns>
public static bool IsSoleRecordConstructor(this IMethodSymbol method)
{
var containingType = method.ContainingType;
var explicitConstructors = containingType.GetMembers()
.OfType<IMethodSymbol>()
.Where(m => !m.IsImplicitlyDeclared && m.MethodKind is MethodKind.Constructor or MethodKind.SharedConstructor or MethodKind.StaticConstructor);

return containingType.IsRecord
&& explicitConstructors.Count() == 1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,16 @@ private void ProcessMembersSymbol(IImmutableSet<INamedTypeSymbol> symbols)
}
break;
case IPropertySymbol propertySymbol:
SetPropertyDeclaration(propertySymbol);
SetPropertyAssociation(propertySymbol, symbols);
// Skip compiler-generated properties.
if (!propertySymbol.IsImplicitlyDeclared)
{
SetPropertyDeclaration(propertySymbol);
SetPropertyAssociation(propertySymbol, symbols);
}
break;
case IMethodSymbol methodSymbol:
if (methodSymbol.MethodKind is not MethodKind.PropertyGet
if (!methodSymbol.IsSoleRecordConstructor() // Only include constructor when there is more than one.
&& methodSymbol.MethodKind is not MethodKind.PropertyGet
and not MethodKind.PropertySet
and not MethodKind.EventAdd
and not MethodKind.EventRemove
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
@startuml Item
class Item <<record>> {
+ Item(Name : string, Value : double)
# <<readonly>> <<virtual>> EqualityContract : Type <<get>>
+ Name : string <<get>> <<set>>
+ Value : double <<get>> <<set>>
+ <<override>> ToString() : string
# <<virtual>> PrintMembers(builder : StringBuilder) : bool
+ {static} operator !=(left : Item?, right : Item?) : bool
+ {static} operator ==(left : Item?, right : Item?) : bool
+ <<override>> GetHashCode() : int
+ <<override>> Equals(obj : object?) : bool
+ <<virtual>> Equals(other : Item?) : bool
# Item(original : Item)
+ Deconstruct(Name : string, Value : double) : void
}
@enduml
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
@startuml Parameters
class Parameters <<record>> {
# <<readonly>> <<virtual>> EqualityContract : Type <<get>>
+ <<readonly>> X : int <<get>>
+ <<readonly>> Y : int <<get>>
+ Parameters(x : int, y : int)
+ Area() : int
+ <<override>> ToString() : string
# <<virtual>> PrintMembers(builder : StringBuilder) : bool
+ {static} operator !=(left : Parameters?, right : Parameters?) : bool
+ {static} operator ==(left : Parameters?, right : Parameters?) : bool
+ <<override>> GetHashCode() : int
+ <<override>> Equals(obj : object?) : bool
+ <<virtual>> Equals(other : Parameters?) : bool
# Parameters(original : Parameters)
}
"IEquatable`1" "<Parameters>" <|.. Parameters
@enduml
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
@startuml RecordA
class RecordA <<record>> {
+ RecordA(Name : string, Value : int)
# <<readonly>> <<virtual>> EqualityContract : Type <<get>>
+ Name : string <<get>> <<set>>
+ Value : int <<get>> <<set>>
+ <<override>> ToString() : string
# <<virtual>> PrintMembers(builder : StringBuilder) : bool
+ {static} operator !=(left : RecordA?, right : RecordA?) : bool
+ {static} operator ==(left : RecordA?, right : RecordA?) : bool
+ <<override>> GetHashCode() : int
+ <<override>> Equals(obj : object?) : bool
+ <<virtual>> Equals(other : RecordA?) : bool
# RecordA(original : RecordA)
+ Deconstruct(Name : string, Value : int) : void
}
@enduml
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
@startuml RecordStruct
struct RecordStruct <<sealed>> <<record>> {
+ RecordStruct(X : float, Y : float, Z : float)
+ X : float <<get>> <<set>>
+ Y : float <<get>> <<set>>
+ Z : float <<get>> <<set>>
+ <<readonly>> <<override>> ToString() : string
- <<readonly>> PrintMembers(builder : StringBuilder) : bool
+ {static} operator !=(left : RecordStruct, right : RecordStruct) : bool
+ {static} operator ==(left : RecordStruct, right : RecordStruct) : bool
+ <<readonly>> <<override>> GetHashCode() : int
+ <<readonly>> <<override>> Equals(obj : object) : bool
+ <<readonly>> Equals(other : RecordStruct) : bool
+ <<readonly>> Deconstruct(X : float, Y : float, Z : float) : void
+ RecordStruct()
}
@enduml

0 comments on commit 7b3d1ed

Please sign in to comment.