public AddEnumClassMembersRewriter(QualifiedTypeName unionTypeName, bool addUnionTypeAttribute, string nestedEnumTypeName = DefaultNestedEnumTypeName) { m_UnionTypeName = unionTypeName; m_AddUnionTypeAttribute = addUnionTypeAttribute; m_NestedEnumTypeName = nestedEnumTypeName; }
public static MethodDeclarationSyntax GenerateFuncAsync(QualifiedTypeName baseTypeName, string baseTypeParameterName, string switchEnumMember, ImmutableList <DerivedType> derivedTypes) { return(GenerateFuncSync(baseTypeName, baseTypeParameterName, switchEnumMember, derivedTypes, "Task<T>", d => SyntaxFactory.ParseStatement($"return await {d.ParameterName}(({d.TypeName}){baseTypeParameterName}).ConfigureAwait(false);")) .Async()); }
static SyntaxNode AddOrUpdateEnumClass(SyntaxNode documentRoot, string stateClassName, string nestedEnumTypeName, IEnumerable <string> enumMemberNames, bool addUnionTypeAttribute) { var stateType = documentRoot.DescendantNodes().OfType <ClassDeclarationSyntax>() .FirstOrDefault(n => n.Name() == stateClassName); var oldEnumDeclaration = stateType?.DescendantNodes().OfType <EnumDeclarationSyntax>() .FirstOrDefault(e => e.Name() == nestedEnumTypeName); if (oldEnumDeclaration == null) { var newEnumDeclaration = SyntaxFactory.EnumDeclaration(stateClassName) .AddMembers(enumMemberNames.Select(SyntaxFactory.EnumMemberDeclaration).ToArray()).Public(); documentRoot = documentRoot.AddMemberToNamespace(newEnumDeclaration); documentRoot = documentRoot.GenerateEnumClass(QualifiedTypeName.NoParents(stateClassName), Option <ClassDeclarationSyntax> .None, addUnionTypeAttribute); } else { var newEnumDeclaration = oldEnumDeclaration .WithMembers(SyntaxFactory.SeparatedList( enumMemberNames.Select(SyntaxFactory.EnumMemberDeclaration).ToArray()) ); documentRoot = documentRoot.ReplaceNode(oldEnumDeclaration, newEnumDeclaration) .UpdateEnumClass(QualifiedTypeName.NoParents(stateClassName), addUnionTypeAttribute); } return(documentRoot); }
public static SyntaxNode GenerateEnumClass(this SyntaxNode node, QualifiedTypeName enumTypeName, Option <ClassDeclarationSyntax> unionTypeDeclaration, bool addUnionTypeAttribute, string nestedEnumTypeName = DefaultNestedEnumTypeName, string enumPropertyName = DefaultEnumPropertyName) { var withEnumNested = unionTypeDeclaration.Match(u => node, () => new EnumToClassRewriter(enumTypeName, nestedEnumTypeName, enumPropertyName).Visit(node)); return(withEnumNested.UpdateEnumClass(unionTypeDeclaration.Match(u => u.QualifiedName(), () => enumTypeName), addUnionTypeAttribute)); }
public static IEnumerable <MethodDeclarationSyntax> GenerateAll(QualifiedTypeName baseTypeName, string baseTypeParameterName, string switchEnumMember, ImmutableList <DerivedType> derivedTypes) { yield return(GenerateFuncSync(baseTypeName, baseTypeParameterName, switchEnumMember, derivedTypes)); yield return(GenerateFuncAsync(baseTypeName, baseTypeParameterName, switchEnumMember, derivedTypes)); yield return(GenerateFuncAsyncSync(baseTypeName, baseTypeParameterName, derivedTypes)); yield return(GenerateFuncAsyncAsync(baseTypeName, baseTypeParameterName, derivedTypes)); }
static SyntaxNode AddOrUpdateExtensionClass(SyntaxNode documentRoot, StateMachineModel names, bool funicularGeneratorsReferenced) { var applyMethod = GenerateApplyMethod(names); var doTransitionMethod = GenerateDoTransitionMethod(names); var classDeclaration = names.TryGetExtensionClass(documentRoot) .Match(ext => ext, () => { var extensionClass = SyntaxFactory.ClassDeclaration(names.ExtensionClassName) .Public() .Static(); documentRoot = documentRoot.AddMemberToNamespace(extensionClass); return(extensionClass); }); classDeclaration = classDeclaration.AddOrUpdateMethod(m => m.Identifier.ToString() == StateMachineModel.ApplyMethodName && m.ParameterList.Parameters.Count == 2, applyMethod); classDeclaration = classDeclaration.AddOrUpdateMethod(m => m.Identifier.ToString() == StateMachineModel.DoTransitionMethodName && m.ParameterList.Parameters.Count == 2, doTransitionMethod); if (!funicularGeneratorsReferenced) { classDeclaration = classDeclaration .AddMatchMethods( QualifiedTypeName.NoParents(names.BaseInterfaceName), names.BaseName.ToParameterName(), $"{StateMachineModel.StatePropertyName}.{StateMachineModel.EnumPropertyName}", names.VertexClasses.Select(v => new MatchMethods.DerivedType(v.ClassName, v.StateName.ToParameterName(), $"{names.OuterStateClassName}.{StateMachineModel.NestedEnumTypeName}.{v.StateName}")) .ToImmutableList()) .AddMatchMethods( QualifiedTypeName.NoParents(names.ParameterInterfaceName), "parameter", $"{StateMachineModel.TriggerPropertyName}.{StateMachineModel.EnumPropertyName}", names.VertexClasses.SelectMany(v => v.Transitions .Select(t => new MatchMethods.DerivedType(t.FullParameterClassName, t.MethodName.ToParameterName(), $"{names.OuterTriggerClassName}.{StateMachineModel.NestedEnumTypeName}.{t.MethodName}"))) .Distinct().ToImmutableList() ); } return(documentRoot.ReplaceNode(names.TryGetExtensionClass(documentRoot).GetValueOrThrow(), classDeclaration)); }
public static MethodDeclarationSyntax GenerateFuncSync(QualifiedTypeName baseTypeName, string baseTypeParameterName, string switchEnumMember, ImmutableList <DerivedType> derivedTypes, string returnType, Func <DerivedType, StatementSyntax> switchStatement) { var matchMethod = MatchMethodDeclaration(baseTypeName.QualifiedName(), baseTypeParameterName, derivedTypes, returnType) .WithBody(SyntaxFactory.Block() .AddStatements( SyntaxFactory.SwitchStatement(SyntaxFactory.ParseExpression($"{baseTypeParameterName}.{switchEnumMember}")) .AddSections(derivedTypes.Select(derivedType => SyntaxFactory.SwitchSection() .AddLabels(SyntaxFactory.CaseSwitchLabel(SyntaxFactory.ParseExpression($"{derivedType.EnumMember}"))) .AddStatements(switchStatement(derivedType)) ) .Concat(new[] { SyntaxFactory.SwitchSection() .AddLabels(SyntaxFactory.DefaultSwitchLabel()) .AddStatements(SyntaxFactory.ParseStatement($"throw new ArgumentException($\"Unknown type derived from {baseTypeName}: {{{baseTypeParameterName}.GetType().Name}}\");")) }) .ToArray() ) )); return(matchMethod); }
public EnumToClassRewriter(QualifiedTypeName enumTypeName, string nestedEnumTypeName = DefaultNestedEnumTypeName, string enumPropertyName = DefaultEnumPropertyName) { m_EnumTypeName = enumTypeName; m_NestedEnumTypeName = nestedEnumTypeName; m_EnumPropertyName = enumPropertyName; }
public static SyntaxNode UpdateEnumClass(this SyntaxNode node, QualifiedTypeName unionTypeName, bool addUnionTypeAttribute, string enumPropertyName = DefaultNestedEnumTypeName) => new AddEnumClassMembersRewriter(unionTypeName, addUnionTypeAttribute, enumPropertyName).Visit(node);
static SyntaxNode AddMatchExtensions(EnumDeclarationSyntax enumNode, SyntaxNode root, string extensionClassName, Option <ClassDeclarationSyntax> unionType, QualifiedTypeName unionTypeName, IEnumerable <string> caseTypeNames) { var classDeclaration = root .TryGetFirstDescendant <ClassDeclarationSyntax>(n => n.Name() == extensionClassName) .Match(ext => ext, () => { var extensionClass = SyntaxFactory.ClassDeclaration(extensionClassName) .WithModifiers(unionType.Match(u => u.Modifiers, () => enumNode.Modifiers)) .Static(); // ReSharper disable once AccessToModifiedClosure root = root.AddMemberToNamespace(extensionClass, m => m is ClassDeclarationSyntax clazz && clazz.QualifiedName() == unionTypeName); return(extensionClass); }); var derivedTypes = caseTypeNames.Select(n => new MatchMethods.DerivedType($"{unionTypeName}.{n}_", n.ToParameterName(), $"{unionTypeName}.{WrapEnumToClass.DefaultNestedEnumTypeName}.{n}")).ToImmutableList(); classDeclaration = classDeclaration.AddMatchMethods(unionTypeName, derivedTypes); var extClass = root.TryGetFirstDescendant <ClassDeclarationSyntax>(n => n.Name() == extensionClassName); root = root.ReplaceNode(extClass.GetValueOrThrow(), classDeclaration); return(root); }
public static ClassDeclarationSyntax AddMatchMethods(this ClassDeclarationSyntax classDeclaration, QualifiedTypeName unionTypeName, string baseTypeParameterName, string switchEnumMember, ImmutableList <DerivedType> derivedTypes) { return(GenerateAll(unionTypeName, baseTypeParameterName, switchEnumMember, derivedTypes) .Aggregate(classDeclaration, (dec, method) => dec.AddOrUpdateMethodMatchByFirstParameterType(method, m => AssertSecondParameterHasSameType(method, m)))); }
public static ClassDeclarationSyntax AddMatchMethods(this ClassDeclarationSyntax classDeclaration, QualifiedTypeName unionTypeName, ImmutableList <DerivedType> derivedTypes) { var baseTypeParameterName = unionTypeName.Name.FirstToLower(); var switchEnumMember = WrapEnumToClass.DefaultEnumPropertyName; return(AddMatchMethods(classDeclaration, unionTypeName, baseTypeParameterName, switchEnumMember, derivedTypes)); }
public static MethodDeclarationSyntax GenerateFuncAsyncSync(QualifiedTypeName baseTypeName, string baseTypeParameterName, ImmutableList <DerivedType> derivedTypes) { return(MatchMethodDeclaration($"Task<{baseTypeName}>", baseTypeParameterName, derivedTypes, "Task<T>", "T") .Async() .WithExpressionBody($"(await {baseTypeParameterName}.ConfigureAwait(false)).Match({string.Join(",", derivedTypes.Select(d => d.ParameterName))})")); }
public static MethodDeclarationSyntax GenerateFuncSync(QualifiedTypeName baseTypeName, string baseTypeParameterName, string switchEnumMember, ImmutableList <DerivedType> derivedTypes) { return(GenerateFuncSync(baseTypeName, baseTypeParameterName, switchEnumMember, derivedTypes, "T", d => SyntaxFactory.ParseStatement($"return {d.ParameterName}(({d.TypeName}){baseTypeParameterName});"))); }