private void ImplementSortedChildrenInterface()
            {
                this.baseTypes.Add(SyntaxFactory.SimpleBaseType(Syntax.GetTypeSyntax(typeof(IRecursiveParentWithSortedChildren))));

                // int IRecursiveParentWithSortedChildren.Compare(IRecursiveType first, IRecursiveType second)
                var firstParameterName  = SyntaxFactory.IdentifierName("first");
                var secondParameterName = SyntaxFactory.IdentifierName("second");

                this.innerMembers.Add(SyntaxFactory.MethodDeclaration(
                                          SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)),
                                          nameof(IRecursiveParentWithSortedChildren.Compare))
                                      .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(SyntaxFactory.IdentifierName(nameof(IRecursiveParentWithSortedChildren))))
                                      .AddParameterListParameters(
                                          SyntaxFactory.Parameter(firstParameterName.Identifier).WithType(Syntax.GetTypeSyntax(typeof(IRecursiveType))),
                                          SyntaxFactory.Parameter(secondParameterName.Identifier).WithType(Syntax.GetTypeSyntax(typeof(IRecursiveType))))
                                      .WithBody(SyntaxFactory.Block(
                                                    // return this.Children.KeyComparer.Compare((<#= templateType.RecursiveType.TypeName #>)first, (<#= templateType.RecursiveType.TypeName #>)second);
                                                    SyntaxFactory.ReturnStatement(
                                                        SyntaxFactory.InvocationExpression(
                                                            SyntaxFactory.MemberAccessExpression(
                                                                SyntaxKind.SimpleMemberAccessExpression,
                                                                SyntaxFactory.MemberAccessExpression(
                                                                    SyntaxKind.SimpleMemberAccessExpression,
                                                                    Syntax.ThisDot(SyntaxFactory.IdentifierName(this.generator.applyToMetaType.RecursiveField.Name.ToPascalCase())),
                                                                    SyntaxFactory.IdentifierName(nameof(ImmutableSortedSet <int> .KeyComparer))),
                                                                SyntaxFactory.IdentifierName(nameof(IComparer <int> .Compare))),
                                                            SyntaxFactory.ArgumentList(Syntax.JoinSyntaxNodes(SyntaxKind.CommaToken,
                                                                                                              SyntaxFactory.Argument(SyntaxFactory.CastExpression(this.generator.applyToMetaType.RecursiveType.TypeSyntax, firstParameterName)),
                                                                                                              SyntaxFactory.Argument(SyntaxFactory.CastExpression(this.generator.applyToMetaType.RecursiveType.TypeSyntax, secondParameterName)))))))));
            }
            private void ImplementOrderedChildrenInterface()
            {
                // We only need to declare this interface if the children are not sorted,
                // since sorted children merit a derived interface making this redundant.
                if (!this.generator.applyToMetaType.ChildrenAreSorted)
                {
                    this.baseTypes.Add(SyntaxFactory.SimpleBaseType(Syntax.GetTypeSyntax(typeof(IRecursiveParentWithOrderedChildren))));
                }

                // int IRecursiveParentWithOrderedChildren.IndexOf(IRecursiveType value)
                var valueParameterName = SyntaxFactory.IdentifierName("value");

                this.innerMembers.Add(SyntaxFactory.MethodDeclaration(
                                          SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)),
                                          nameof(IRecursiveParentWithOrderedChildren.IndexOf))
                                      .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(SyntaxFactory.IdentifierName(nameof(IRecursiveParentWithOrderedChildren))))
                                      .AddParameterListParameters(SyntaxFactory.Parameter(valueParameterName.Identifier).WithType(Syntax.GetTypeSyntax(typeof(IRecursiveType))))
                                      .WithBody(SyntaxFactory.Block(
                                                    // return this.Children.IndexOf((<#= templateType.RecursiveType.TypeName #>)value);
                                                    SyntaxFactory.ReturnStatement(
                                                        SyntaxFactory.InvocationExpression(
                                                            SyntaxFactory.MemberAccessExpression(
                                                                SyntaxKind.SimpleMemberAccessExpression,
                                                                Syntax.ThisDot(SyntaxFactory.IdentifierName(this.generator.applyToMetaType.RecursiveField.Name.ToPascalCase())),
                                                                SyntaxFactory.IdentifierName(nameof(IList <int> .IndexOf))),
                                                            SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(
                                                                                           SyntaxFactory.Argument(
                                                                                               SyntaxFactory.CastExpression(
                                                                                                   this.generator.applyToMetaType.RecursiveType.TypeSyntax,
                                                                                                   valueParameterName)))))))));
            }
            protected override void GenerateCore()
            {
                this.baseTypes.Add(SyntaxFactory.SimpleBaseType(Syntax.GetTypeSyntax(typeof(IRecursiveType))));

                ////<#= templateType.RequiredIdentityField.TypeName #> IRecursiveType.Identity {
                ////	get { return this.Identity; }
                ////}
                this.innerMembers.Add(SyntaxFactory.PropertyDeclaration(
                                          IdentityFieldTypeSyntax,
                                          nameof(IRecursiveType.Identity))
                                      .WithExplicitInterfaceSpecifier(
                                          SyntaxFactory.ExplicitInterfaceSpecifier(Syntax.GetTypeSyntax(typeof(IRecursiveType))))
                                      .AddAccessorListAccessors(
                                          SyntaxFactory.AccessorDeclaration(
                                              SyntaxKind.GetAccessorDeclaration,
                                              SyntaxFactory.Block(SyntaxFactory.ReturnStatement(Syntax.ThisDot(IdentityPropertyName))))));
            }
Пример #4
0
            private MethodDeclarationSyntax CreateSyncImmediateChildToCurrentVersionMethod()
            {
                var childParameterName  = SyntaxFactory.IdentifierName("child");
                var childType           = GetFullyQualifiedSymbolName(this.generator.applyToMetaType.RecursiveField.ElementType);
                var currentValueVarName = SyntaxFactory.IdentifierName("currentValue");

                return(SyntaxFactory.MethodDeclaration(
                           childType,
                           SyncImmediateChildToCurrentVersionMethodName.Identifier)
                       .AddParameterListParameters(SyntaxFactory.Parameter(childParameterName.Identifier).WithType(childType))
                       .AddModifiers(SyntaxFactory.Token(SyntaxKind.ProtectedKeyword))
                       .WithBody(SyntaxFactory.Block(
                                     // ElementTypeName currentValue;
                                     SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.VariableDeclaration(
                                                                                 childType,
                                                                                 SyntaxFactory.SingletonSeparatedList(SyntaxFactory.VariableDeclarator(currentValueVarName.Identifier)))),
                                     // if (!this.TryFindImmediateChild(child.<#= templateType.RequiredIdentityField.NamePascalCase #>, out currentValue)) {
                                     SyntaxFactory.IfStatement(
                                         SyntaxFactory.PrefixUnaryExpression(
                                             SyntaxKind.LogicalNotExpression,
                                             SyntaxFactory.InvocationExpression(
                                                 Syntax.ThisDot(SyntaxFactory.IdentifierName(nameof(RecursiveTypeExtensions.TryFindImmediateChild))),
                                                 SyntaxFactory.ArgumentList(Syntax.JoinSyntaxNodes(
                                                                                SyntaxKind.CommaToken,
                                                                                SyntaxFactory.Argument(
                                                                                    SyntaxFactory.MemberAccessExpression(
                                                                                        SyntaxKind.SimpleMemberAccessExpression,
                                                                                        childParameterName,
                                                                                        IdentityPropertyName)),
                                                                                SyntaxFactory.Argument(
                                                                                    null,
                                                                                    SyntaxFactory.Token(SyntaxKind.OutKeyword),
                                                                                    currentValueVarName))))),
                                         SyntaxFactory.Block(
                                             SyntaxFactory.ThrowStatement(SyntaxFactory.ObjectCreationExpression(
                                                                              Syntax.GetTypeSyntax(typeof(ArgumentException)),
                                                                              SyntaxFactory.ArgumentList(),
                                                                              null)))),
                                     SyntaxFactory.ReturnStatement(currentValueVarName))));
            }
            private void ImplementIEnumerableInterfaces()
            {
                this.baseTypes.Add(SyntaxFactory.SimpleBaseType(Syntax.IEnumerableOf(this.generator.applyToMetaType.RecursiveType.TypeSyntax)));

                // return this.<#=templateType.RecursiveField.NameCamelCase#>.GetEnumerator();
                var body = SyntaxFactory.Block(
                    SyntaxFactory.ReturnStatement(
                        SyntaxFactory.InvocationExpression(
                            SyntaxFactory.MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                Syntax.ThisDot(SyntaxFactory.IdentifierName(this.generator.applyToMetaType.RecursiveField.Name)),
                                SyntaxFactory.IdentifierName(nameof(IEnumerable <int> .GetEnumerator))),
                            SyntaxFactory.ArgumentList())));

                // public System.Collections.Generic.IEnumerator<RecursiveType> GetEnumerator()
                this.innerMembers.Add(
                    SyntaxFactory.MethodDeclaration(
                        Syntax.IEnumeratorOf(GetFullyQualifiedSymbolName(this.generator.applyToMetaType.RecursiveField.ElementType)),
                        nameof(IEnumerable <int> .GetEnumerator))
                    .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
                    .WithBody(body));

                // System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
                this.innerMembers.Add(
                    SyntaxFactory.MethodDeclaration(
                        Syntax.GetTypeSyntax(typeof(System.Collections.IEnumerator)),
                        nameof(IEnumerable <int> .GetEnumerator))
                    .WithExplicitInterfaceSpecifier(
                        SyntaxFactory.ExplicitInterfaceSpecifier(
                            SyntaxFactory.QualifiedName(
                                SyntaxFactory.QualifiedName(
                                    SyntaxFactory.IdentifierName(nameof(System)),
                                    SyntaxFactory.IdentifierName(nameof(System.Collections))),
                                SyntaxFactory.IdentifierName(nameof(System.Collections.IEnumerable)))))
                    .WithBody(body));
            }
Пример #6
0
            private MethodDeclarationSyntax CreateReplaceDescendentDifferentIdentityMethod()
            {
                var currentParameter     = SyntaxFactory.IdentifierName("current");
                var replacementParameter = SyntaxFactory.IdentifierName("replacement");
                var spineVar             = SyntaxFactory.IdentifierName("spine");

                // public TemplateType ReplaceDescendent(TRecursiveType current, TRecursiveType replacement) {
                return(SyntaxFactory.MethodDeclaration(
                           this.applyTo.TypeSyntax,
                           ReplaceDescendentMethodName.Identifier)
                       .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
                       .AddParameterListParameters(
                           SyntaxFactory.Parameter(currentParameter.Identifier).WithType(this.applyTo.RecursiveType.TypeSyntax),
                           SyntaxFactory.Parameter(replacementParameter.Identifier).WithType(this.applyTo.RecursiveType.TypeSyntax))
                       .WithBody(SyntaxFactory.Block(
                                     // var spine = this.GetSpine(current);
                                     SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.VariableDeclaration(varType).AddVariables(
                                                                                 SyntaxFactory.VariableDeclarator(spineVar.Identifier).WithInitializer(SyntaxFactory.EqualsValueClause(
                                                                                                                                                           SyntaxFactory.InvocationExpression(Syntax.ThisDot(FastSpineGen.GetSpineMethodName))
                                                                                                                                                           .AddArgumentListArguments(
                                                                                                                                                               SyntaxFactory.Argument(currentParameter)))))),
                                     // if (spine.IsEmpty) {
                                     SyntaxFactory.IfStatement(
                                         SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, spineVar, SyntaxFactory.IdentifierName(nameof(ImmutableStack <int> .IsEmpty))),
                                         //     // The descendent was not found.
                                         //     throw new System.ArgumentException("Old value not found");
                                         SyntaxFactory.Block(
                                             SyntaxFactory.ThrowStatement(
                                                 SyntaxFactory.ObjectCreationExpression(Syntax.GetTypeSyntax(typeof(ArgumentException))).AddArgumentListArguments(
                                                     SyntaxFactory.Argument(SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal("Old value not found."))))))),
                                     // return (TemplateType)this.ReplaceDescendent(spine, ImmutableStack.Create(replacement), spineIncludesDeletedElement: false).Peek();
                                     SyntaxFactory.ReturnStatement(
                                         SyntaxFactory.CastExpression(
                                             this.applyTo.TypeSyntax,
                                             SyntaxFactory.InvocationExpression(
                                                 SyntaxFactory.MemberAccessExpression(
                                                     SyntaxKind.SimpleMemberAccessExpression,
                                                     SyntaxFactory.InvocationExpression(Syntax.ThisDot(ReplaceDescendentMethodName))
                                                     .AddArgumentListArguments(
                                                         SyntaxFactory.Argument(spineVar),
                                                         SyntaxFactory.Argument(SyntaxFactory.InvocationExpression(Syntax.CreateImmutableStack()).AddArgumentListArguments(
                                                                                    SyntaxFactory.Argument(replacementParameter))),
                                                         SyntaxFactory.Argument(SyntaxFactory.NameColon("spineIncludesDeletedElement"), NoneToken, SyntaxFactory.LiteralExpression(SyntaxKind.FalseLiteralExpression))
                                                         ),
                                                     SyntaxFactory.IdentifierName(nameof(ImmutableStack <int> .Peek))),
                                                 SyntaxFactory.ArgumentList()))))));
            }
            private void ImplementRecursiveParentInterface()
            {
                var irecursiveParentOfT = CreateIRecursiveParentOfTSyntax(GetFullyQualifiedSymbolName(this.generator.applyToMetaType.RecursiveType.TypeSymbol));

                this.baseTypes.Add(SyntaxFactory.SimpleBaseType(irecursiveParentOfT));

                // return this.Children;
                var returnThisDotChildren = SyntaxFactory.ReturnStatement(Syntax.ThisDot(SyntaxFactory.IdentifierName(this.generator.applyToMetaType.RecursiveField.Name.ToPascalCase())));

                // System.Collections.Generic.IEnumerable<IRecursiveType> IRecursiveParent.Children
                this.innerMembers.Add(
                    SyntaxFactory.PropertyDeclaration(
                        Syntax.GetTypeSyntax(typeof(IEnumerable <IRecursiveType>)),
                        nameof(IRecursiveParent.Children))
                    .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(Syntax.GetTypeSyntax(typeof(IRecursiveParent))))
                    .AddAccessorListAccessors(SyntaxFactory.AccessorDeclaration(
                                                  SyntaxKind.GetAccessorDeclaration,
                                                  SyntaxFactory.Block(returnThisDotChildren))));

                // public ParentedRecursiveType<TRecursiveParent, TRecursiveType> GetParentedNode(uint identity)
                this.innerMembers.Add(
                    SyntaxFactory.MethodDeclaration(
                        SyntaxFactory.GenericName(nameof(ParentedRecursiveType <IRecursiveParent <IRecursiveType>, IRecursiveType>)).AddTypeArgumentListArguments(
                            this.applyTo.RecursiveParent.TypeSyntax,
                            this.applyTo.RecursiveType.TypeSyntax),
                        nameof(IRecursiveParent.GetParentedNode))
                    .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
                    //.WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(Syntax.GetTypeSyntax(typeof(IRecursiveParent))))
                    .AddParameterListParameters(RequiredIdentityParameter)
                    .WithBody(SyntaxFactory.Block(
                                  // return this.GetParentedNode<TRecursiveParent, TRecursiveType>(identity);
                                  SyntaxFactory.ReturnStatement(
                                      SyntaxFactory.InvocationExpression(
                                          Syntax.ThisDot(SyntaxFactory.GenericName(nameof(RecursiveTypeExtensions.GetParentedNode)).AddTypeArgumentListArguments(
                                                             this.applyTo.RecursiveParent.TypeSyntax,
                                                             this.applyTo.RecursiveType.TypeSyntax)))
                                      .AddArgumentListArguments(SyntaxFactory.Argument(IdentityParameterName))))));

                // ParentedRecursiveType<IRecursiveParent<IRecursiveType>, IRecursiveType> IRecursiveParent.GetParentedNode(<#= templateType.RequiredIdentityField.TypeName #> identity) {
                var parentedVar = SyntaxFactory.IdentifierName("parented");
                var returnType  = Syntax.GetTypeSyntax(typeof(ParentedRecursiveTypeNonGeneric));

                this.innerMembers.Add(
                    SyntaxFactory.MethodDeclaration(
                        returnType,
                        nameof(IRecursiveParent.GetParentedNode))
                    .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(Syntax.GetTypeSyntax(typeof(IRecursiveParent))))
                    .AddParameterListParameters(RequiredIdentityParameter)
                    .WithBody(SyntaxFactory.Block(
                                  // var parented = this.GetParentedNode(identity);
                                  SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.VariableDeclaration(varType).AddVariables(
                                                                              SyntaxFactory.VariableDeclarator(parentedVar.Identifier).WithInitializer(SyntaxFactory.EqualsValueClause(
                                                                                                                                                           SyntaxFactory.InvocationExpression(Syntax.ThisDot(SyntaxFactory.IdentifierName(nameof(RecursiveTypeExtensions.GetParentedNode))))
                                                                                                                                                           .AddArgumentListArguments(SyntaxFactory.Argument(IdentityParameterName)))))),
                                  // return new ParentedRecursiveType<IRecursiveParent<IRecursiveType>, IRecursiveType>(parented.Value, parented.Parent);
                                  SyntaxFactory.ReturnStatement(SyntaxFactory.ObjectCreationExpression(returnType).AddArgumentListArguments(
                                                                    SyntaxFactory.Argument(SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, parentedVar, SyntaxFactory.IdentifierName(nameof(ParentedRecursiveTypeNonGeneric.Value)))),
                                                                    SyntaxFactory.Argument(SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, parentedVar, SyntaxFactory.IdentifierName(nameof(ParentedRecursiveTypeNonGeneric.Parent)))))))));

                ////System.Collections.Generic.IEnumerable<<#= templateType.RecursiveType.TypeName #>> IRecursiveParent<<#= templateType.RecursiveType.TypeName #>>.Children {
                ////	get { return this.Children; }
                ////}
                this.innerMembers.Add(
                    SyntaxFactory.PropertyDeclaration(
                        Syntax.IEnumerableOf(this.generator.applyToMetaType.RecursiveType.TypeSyntax),
                        nameof(IRecursiveParent <IRecursiveType> .Children))
                    .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(irecursiveParentOfT))
                    .AddAccessorListAccessors(SyntaxFactory.AccessorDeclaration(
                                                  SyntaxKind.GetAccessorDeclaration,
                                                  SyntaxFactory.Block(returnThisDotChildren))));
            }