예제 #1
0
 public AddEnumClassMembersRewriter(QualifiedTypeName unionTypeName, bool addUnionTypeAttribute,
                                    string nestedEnumTypeName = DefaultNestedEnumTypeName)
 {
     m_UnionTypeName         = unionTypeName;
     m_AddUnionTypeAttribute = addUnionTypeAttribute;
     m_NestedEnumTypeName    = nestedEnumTypeName;
 }
예제 #2
0
 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());
 }
예제 #3
0
        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);
        }
예제 #4
0
        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));
        }
예제 #5
0
        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));
        }
예제 #6
0
        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));
        }
예제 #7
0
        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);
        }
예제 #8
0
 public EnumToClassRewriter(QualifiedTypeName enumTypeName, string nestedEnumTypeName = DefaultNestedEnumTypeName, string enumPropertyName = DefaultEnumPropertyName)
 {
     m_EnumTypeName       = enumTypeName;
     m_NestedEnumTypeName = nestedEnumTypeName;
     m_EnumPropertyName   = enumPropertyName;
 }
예제 #9
0
 public static SyntaxNode UpdateEnumClass(this SyntaxNode node, QualifiedTypeName unionTypeName, bool addUnionTypeAttribute, string enumPropertyName = DefaultNestedEnumTypeName) =>
 new AddEnumClassMembersRewriter(unionTypeName, addUnionTypeAttribute, enumPropertyName).Visit(node);
예제 #10
0
        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);
        }
예제 #11
0
 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))));
 }
예제 #12
0
        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));
        }
예제 #13
0
 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))})"));
 }
예제 #14
0
 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});")));
 }