-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enums can be extended, i.e. derived from - which comes with some limi…
…tations
- Loading branch information
Showing
66 changed files
with
1,962 additions
and
312 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
76 changes: 76 additions & 0 deletions
76
src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/BaseEnumState.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,76 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Microsoft.CodeAnalysis; | ||
|
||
namespace Thinktecture.CodeAnalysis | ||
{ | ||
public class BaseEnumState : IBaseEnumState | ||
{ | ||
public bool IsSameAssembly => false; | ||
public INamedTypeSymbol Type { get; } | ||
public string? NullableQuestionMark => Type.IsReferenceType ? "?" : null; | ||
|
||
private IReadOnlyList<ISymbolState>? _items; | ||
|
||
public IReadOnlyList<ISymbolState> Items => _items ??= Type.EnumerateEnumItems().Select(DefaultSymbolState.CreateFrom).ToList(); | ||
|
||
private IReadOnlyList<ISymbolState>? _ctorExtraArgs; | ||
|
||
public IReadOnlyList<ISymbolState> ConstructorArguments | ||
{ | ||
get | ||
{ | ||
if (_ctorExtraArgs is null) | ||
{ | ||
var ctor = Type.Constructors | ||
.Where(c => c.MethodKind == MethodKind.Constructor && c.DeclaredAccessibility == Accessibility.Protected) | ||
.OrderBy(c => c.Parameters.Length) | ||
.FirstOrDefault(); | ||
|
||
if (ctor is null) | ||
throw new Exception($"'{Type.Name}' doesn't have a protected constructor."); | ||
|
||
var ctorAttrArgs = GetCtorParameterNames(ctor); | ||
|
||
_ctorExtraArgs = ctor.Parameters | ||
.Select((p, i) => | ||
{ | ||
var memberName = ctorAttrArgs[i]; | ||
|
||
if (memberName.Value is not string name) | ||
throw new Exception($"The parameter '{memberName.Value}' of the 'EnumConstructorAttribute' of '{Type.Name}' at index {i} must be a string."); | ||
|
||
return new DefaultSymbolState(name, p.Type, p.Name, false); | ||
}) | ||
.ToList(); | ||
} | ||
|
||
return _ctorExtraArgs; | ||
} | ||
} | ||
|
||
private IReadOnlyList<TypedConstant> GetCtorParameterNames(IMethodSymbol ctor) | ||
{ | ||
var ctorAttr = Type.FindEnumConstructorAttribute(); | ||
|
||
if (ctorAttr is null) | ||
throw new Exception($"'{Type.Name}' doesn't have an 'EnumConstructorAttribute'."); | ||
|
||
if (ctorAttr.ConstructorArguments.Length != 1) | ||
throw new Exception($"'EnumConstructorAttribute' of '{Type.Name}' must have exactly 1 argument."); | ||
|
||
var ctorAttrArgs = ctorAttr.ConstructorArguments[0].Values; | ||
|
||
if (ctorAttrArgs.Length != ctor.Parameters.Length) | ||
throw new Exception($"'EnumConstructorAttribute' of '{Type.Name}' specifies {ctorAttrArgs.Length} parameters but the constructor takes {ctor.Parameters.Length} arguments."); | ||
|
||
return ctorAttrArgs; | ||
} | ||
|
||
public BaseEnumState(INamedTypeSymbol type) | ||
{ | ||
Type = type; | ||
} | ||
} | ||
} |
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
30 changes: 30 additions & 0 deletions
30
src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/DefaultSymbolState.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,30 @@ | ||
using Microsoft.CodeAnalysis; | ||
|
||
namespace Thinktecture.CodeAnalysis | ||
{ | ||
public class DefaultSymbolState : ISymbolState | ||
{ | ||
public string Identifier { get; } | ||
public ITypeSymbol Type { get; } | ||
public string ArgumentName { get; } | ||
public bool IsStatic { get; } | ||
|
||
public DefaultSymbolState(string identifier, ITypeSymbol type, string argumentName, bool isStatic) | ||
{ | ||
Identifier = identifier; | ||
Type = type; | ||
ArgumentName = argumentName; | ||
IsStatic = isStatic; | ||
} | ||
|
||
public static DefaultSymbolState CreateFrom(IFieldSymbol field) | ||
{ | ||
return new(field.Name, field.Type, field.Name.MakeArgumentName(), field.IsStatic); | ||
} | ||
|
||
public static DefaultSymbolState CreateFrom(IPropertySymbol property) | ||
{ | ||
return new(property.Name, property.Type, property.Name.MakeArgumentName(), property.IsStatic); | ||
} | ||
} | ||
} |
Oops, something went wrong.