Пример #1
0
        public override SyntaxNode VisitClassBlock(ClassBlockSyntax node)
        {
            var result = generator.AddInterfaceType(
                base.VisitClassBlock(node),
                generator.IdentifierName(nameof(IMocked)));

            result = generator.AddMembers(result,
                                          generator.FieldDeclaration("_mock", ParseTypeName(nameof(IMock)))
                                          .WithLeadingTrivia(Whitespace(Environment.NewLine)));

            var property = (PropertyBlockSyntax)generator.PropertyDeclaration(
                nameof(IMocked.Mock),
                ParseTypeName(nameof(IMock)),
                modifiers: DeclarationModifiers.ReadOnly,
                getAccessorStatements: new[]
            {
                generator.ReturnStatement(
                    generator.InvocationExpression(
                        generator.MemberAccessExpression(
                            generator.IdentifierName(nameof(LazyInitializer)),
                            nameof(LazyInitializer.EnsureInitialized)),
                        generator.Argument(
                            RefKind.Ref,
                            generator.IdentifierName("_mock")),
                        ParenthesizedExpression(
                            SingleLineFunctionLambdaExpression(
                                FunctionLambdaHeader(List <AttributeListSyntax>(), TokenList(), ParameterList(), null),
                                ObjectCreationExpression(
                                    List <AttributeListSyntax>(),
                                    IdentifierName(nameof(MockInfo)),
                                    ArgumentList(SingletonSeparatedList <ArgumentSyntax>(
                                                     SimpleArgument(MeExpression())
                                                     )),
                                    null
                                    )
                                )
                            )
                        )
                    )
            });

            property = property.WithPropertyStatement(
                property.PropertyStatement.WithImplementsClause(
                    ImplementsClause(QualifiedName(IdentifierName(nameof(IMocked)), IdentifierName(nameof(IMocked.Mock))))));

            result = generator.AddMembers(result, property);

            return(result);
        }
      public InterfaceDeclarationSyntax GenerateProxyInterface(SemanticModel semanticModel, SyntaxGenerator generator, INamedTypeSymbol sourceServiceInterface, string targetInterfaceName, Accessibility accessibility = Accessibility.Public, bool inheritServiceInterface = false, bool suppressAsyncMethodGeneration = false, bool suppressWarningComments = false)
      {
         SyntaxNode targetInterface = generator.InterfaceDeclaration(targetInterfaceName, accessibility: accessibility);

         targetInterface = generator.AddAttributes(targetInterface, sourceServiceInterface.GetAttributes().Select(attr => generator.Attribute(attr)));

         foreach (SyntaxNode method in GetOperationContractMethodDeclarations(semanticModel, generator, sourceServiceInterface, true, !inheritServiceInterface, suppressAsyncMethodGeneration))
         {
            targetInterface = generator.AddMembers(targetInterface, generator.AddWarningCommentIf(!suppressWarningComments, method));
         }

         if (inheritServiceInterface)
         {
            targetInterface = generator.AddInterfaceType(targetInterface, generator.TypeExpression(sourceServiceInterface));
         }

         targetInterface = AddGeneratedCodeAttribute(generator, targetInterface);

         targetInterface = generator.AddWarningCommentIf(!suppressWarningComments, targetInterface);

         return (InterfaceDeclarationSyntax)targetInterface;
      }
        public InterfaceDeclarationSyntax GenerateProxyInterface(SemanticModel semanticModel, SyntaxGenerator generator, INamedTypeSymbol sourceServiceInterface, string targetInterfaceName, Accessibility accessibility = Accessibility.Public, bool inheritServiceInterface = false, bool suppressAsyncMethodGeneration = false, bool suppressWarningComments = false)
        {
            SyntaxNode targetInterface = generator.InterfaceDeclaration(targetInterfaceName, accessibility: accessibility);

            targetInterface = generator.AddAttributes(targetInterface, sourceServiceInterface.GetAttributes().Select(attr => generator.Attribute(attr)));

            foreach (SyntaxNode method in GetOperationContractMethodDeclarations(semanticModel, generator, sourceServiceInterface, true, !inheritServiceInterface, suppressAsyncMethodGeneration))
            {
                targetInterface = generator.AddMembers(targetInterface, generator.AddWarningCommentIf(!suppressWarningComments, method));
            }

            if (inheritServiceInterface)
            {
                targetInterface = generator.AddInterfaceType(targetInterface, generator.TypeExpression(sourceServiceInterface));
            }

            targetInterface = AddGeneratedCodeAttribute(generator, targetInterface);

            targetInterface = generator.AddWarningCommentIf(!suppressWarningComments, targetInterface);

            return((InterfaceDeclarationSyntax)targetInterface);
        }
        internal static TypeDeclarationSyntax WithIDisposableInterface(this TypeDeclarationSyntax typeDeclaration, SyntaxGenerator syntaxGenerator, ITypeSymbol type)
        {
            var baseList = typeDeclaration.BaseList;

            if (baseList != null)
            {
                foreach (var baseType in baseList.Types)
                {
                    if ((baseType.Type as IdentifierNameSyntax)?.Identifier.ValueText.Contains("IDisposable") == true)
                    {
                        return(typeDeclaration);
                    }
                }
            }

            if (!Disposable.IsAssignableTo(type))
            {
                return((TypeDeclarationSyntax)syntaxGenerator.AddInterfaceType(typeDeclaration, IDisposableInterface));
            }

            return(typeDeclaration);
        }
Пример #5
0
        public Task <ClassDeclarationSyntax> GenerateClientClass(SemanticModel semanticModel, SyntaxGenerator gen, INamedTypeSymbol proxyInterface, string name, Accessibility accessibility, bool includeCancellableAsyncMethods, bool suppressWarningComments, MemberAccessibility constructorAccessibility, bool withInternalProxy)
        {
            if (name == null)
            {
                if (proxyInterface.Name.StartsWith("I"))
                {
                    name = proxyInterface.Name.Substring(1);
                }

                if (name.EndsWith("Proxy"))
                {
                    name = name.Substring(0, name.Length - "Proxy".Length);
                }

                if (!name.EndsWith("Client"))
                {
                    name = name + "Client";
                }
            }


            SyntaxNode targetClass = gen.ClassDeclaration(name,
                                                          baseType: gen.TypeExpression(semanticModel.Compilation.RequireType <MarshalByRefObject>()),
                                                          accessibility: accessibility,
                                                          modifiers: DeclarationModifiers.Sealed);

            targetClass = gen.AddWarningCommentIf(!suppressWarningComments, targetClass);

            targetClass = gen.AddInterfaceType(targetClass, gen.TypeExpression(semanticModel.Compilation.GetSpecialType(SpecialType.System_IDisposable)));
            targetClass = gen.AddInterfaceType(targetClass, gen.TypeExpression(proxyInterface));

            IEnumerable <IMethodSymbol> methods = GetOperationContractMethods(semanticModel.Compilation, proxyInterface).ToArray();

            GenerationNameTable nameTable = new GenerationNameTable(methods.Select(m => m.Name).Concat(new[] { name }));


            #region Private Fields

            // ==> private IProxy m_cachedProxy;
            SyntaxNode cachedProxyField =
                gen.FieldDeclaration(nameTable[MemberNames.CachedProxyField], gen.TypeExpression(proxyInterface), Accessibility.Private, DeclarationModifiers.None)
                .PrependLeadingTrivia(gen.CreateRegionTrivia("Private Fields"));

            targetClass = gen.AddMembers(targetClass, cachedProxyField);

            // ==> private readonly Func<IProxy> m_proxyFactory;
            SyntaxNode proxyFactoryTypeExpression = gen.TypeExpression(semanticModel.Compilation.RequireTypeByMetadataName("System.Func`1").Construct(proxyInterface));

            targetClass = gen.AddMembers(targetClass, gen.FieldDeclaration(nameTable[MemberNames.ProxyFactoryField], proxyFactoryTypeExpression, Accessibility.Private, DeclarationModifiers.ReadOnly)
                                         .AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia());

            #endregion


            #region Constructors

            // Constructor
            SyntaxNode constructor = gen.ConstructorDeclaration(
                parameters: new[] { gen.ParameterDeclaration("proxyFactory", proxyFactoryTypeExpression) },
                accessibility: withInternalProxy?Accessibility.Private: ToAccessibility(constructorAccessibility)
                );

            constructor = gen.AddWarningCommentIf(!suppressWarningComments, constructor);
            constructor = constructor.PrependLeadingTrivia(gen.CreateRegionTrivia("Constructors"));

            constructor = gen.WithStatements(constructor,
                                             new[]
            {
                // ==> if (proxyFactory == null)
                // ==>   throw new System.ArgumentNullException("proxyFactory");
                gen.ThrowIfNullStatement("proxyFactory"),

                // ==> m_proxyFactory = proxyFactory
                gen.AssignmentStatement(
                    gen.MemberAccessExpression(
                        gen.ThisExpression(),
                        gen.IdentifierName(nameTable[MemberNames.ProxyFactoryField])),
                    gen.IdentifierName("proxyFactory")
                    )
            }
                                             ).AddNewLineTrivia();

            if (!withInternalProxy)
            {
                constructor = constructor.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia();
            }

            targetClass = gen.AddMembers(targetClass, constructor);

            ClassDeclarationSyntax proxyClass = null;
            if (withInternalProxy)
            {
                IEnumerable <IMethodSymbol> ctors;
                proxyClass = GenerateProxyClass(semanticModel, gen, proxyInterface, nameTable[MemberNames.ProxyClass], Accessibility.Private, suppressWarningComments, MemberAccessibility.Public, out ctors)
                             .PrependLeadingTrivia(gen.CreateRegionTrivia("Proxy Class").Insert(0, gen.NewLine()))
                             .AddTrailingTrivia(gen.CreateEndRegionTrivia());

                // Generate one constructor for each of the proxy's constructors.
                foreach (var ctorEntry in ctors.AsSmartEnumerable())
                {
                    var ctor       = ctorEntry.Value;
                    var targetCtor = gen.ConstructorDeclaration(ctor);

                    var lambda = gen.ValueReturningLambdaExpression(
                        gen.ObjectCreationExpression(gen.IdentifierName(gen.GetName(proxyClass)), ctor.Parameters.Select(p => gen.IdentifierName(p.Name)))
                        );

                    targetCtor = gen.WithThisConstructorInitializer(targetCtor, new[] { lambda });

                    targetCtor = gen.AddWarningCommentIf(!suppressWarningComments, targetCtor);
                    targetCtor = gen.WithAccessibility(targetCtor, ToAccessibility(constructorAccessibility));

                    if (ctorEntry.IsLast)
                    {
                        targetCtor = targetCtor.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia();
                    }

                    targetClass = gen.AddMembers(targetClass, targetCtor.AddNewLineTrivia());
                }
            }

            #endregion

            #region Operation Contract Methods

            // ==> catch
            // ==> {
            // ==>    this.CloseProxy(false);
            // ==>    throw;
            // ==> }
            var catchAndCloseProxyStatement = gen.CatchClause(new SyntaxNode[]
            {
                // ==> this.CloseProxy(false);
                gen.ExpressionStatement(
                    gen.InvocationExpression(
                        gen.MemberAccessExpression(
                            gen.ThisExpression(),
                            nameTable[MemberNames.CloseProxyMethod]
                            ),
                        gen.FalseLiteralExpression()
                        )
                    ),

                // throw;
                gen.ThrowStatement()
            });


            foreach (var sourceMethodEntry in methods.AsSmartEnumerable())
            {
                var sourceMethod = sourceMethodEntry.Value;

                using (nameTable.PushScope(sourceMethod.Parameters.Select(p => p.Name)))
                {
                    bool isAsync = ReturnsTask(semanticModel.Compilation, sourceMethod);
                    bool isVoid  = sourceMethod.ReturnType.SpecialType == SpecialType.System_Void || sourceMethod.ReturnType.Equals(semanticModel.Compilation.RequireType <Task>());

                    SyntaxNode targetMethod = gen.MethodDeclaration(sourceMethod);

                    if (sourceMethodEntry.IsFirst)
                    {
                        targetMethod = targetMethod.PrependLeadingTrivia(gen.CreateRegionTrivia("Contract Methods")).AddLeadingTrivia(gen.NewLine());
                    }

                    targetMethod = gen.AddWarningCommentIf(!suppressWarningComments, targetMethod);

                    targetMethod = gen.WithModifiers(targetMethod, isAsync ? DeclarationModifiers.Async : DeclarationModifiers.None);


                    targetMethod = gen.WithStatements(targetMethod, new SyntaxNode[]
                    {
                        // ==> try {
                        gen.TryCatchStatement(new SyntaxNode[]
                        {
                            CreateProxyVaraibleDeclaration(gen, nameTable, isAsync),
                            CreateProxyInvocationStatement(semanticModel.Compilation, gen, nameTable, sourceMethod)
                        }, new SyntaxNode[]
                        {
                            catchAndCloseProxyStatement
                        }
                                              )
                    });

                    targetMethod = targetMethod.AddNewLineTrivia();

                    if (sourceMethodEntry.IsLast && !(isAsync && includeCancellableAsyncMethods))
                    {
                        targetMethod = targetMethod.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia();
                    }

                    targetClass = gen.AddMembers(targetClass, targetMethod);

                    if (isAsync && includeCancellableAsyncMethods)
                    {
                        targetMethod = gen.MethodDeclaration(sourceMethod);
                        targetMethod = gen.AddParameters(targetMethod, new[] { gen.ParameterDeclaration(nameTable[MemberNames.CancellationTokenParameter], gen.TypeExpression(semanticModel.Compilation.RequireType <CancellationToken>())) });
                        targetMethod = gen.WithModifiers(targetMethod, isAsync ? DeclarationModifiers.Async : DeclarationModifiers.None);


                        targetMethod = gen.WithStatements(targetMethod, new SyntaxNode[]
                        {
                            // ==> try {
                            gen.TryCatchStatement(new SyntaxNode[]
                            {
                                CreateProxyVaraibleDeclaration(gen, nameTable, isAsync),
                                CreateCancellableProxyInvocationStatement(semanticModel.Compilation, gen, nameTable, sourceMethod)
                            }, new SyntaxNode[]
                            {
                                catchAndCloseProxyStatement
                            }
                                                  )
                        });


                        targetMethod = gen.AddWarningCommentIf(!suppressWarningComments, targetMethod.AddNewLineTrivia());

                        if (sourceMethodEntry.IsLast)
                        {
                            targetMethod = targetMethod.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia();
                        }

                        targetClass = gen.AddMembers(targetClass, targetMethod);
                    }
                }
            }

            #endregion

            #region Internal Methods

            targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateGetProxyMethod(semanticModel.Compilation, gen, proxyInterface, nameTable, false).AddLeadingTrivia(gen.CreateRegionTrivia("Private Methods")).AddNewLineTrivia()));
            targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateGetProxyMethod(semanticModel.Compilation, gen, proxyInterface, nameTable, true).AddNewLineTrivia()));
            targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateStaticCloseProxyMethod(semanticModel.Compilation, gen, nameTable, false).AddNewLineTrivia()));
            targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateStaticCloseProxyMethod(semanticModel.Compilation, gen, nameTable, true).AddNewLineTrivia()));
            targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateCloseProxyMethod(semanticModel.Compilation, gen, nameTable, false).AddNewLineTrivia()));
            targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateCloseProxyMethod(semanticModel.Compilation, gen, nameTable, true).AddNewLineTrivia()));
            targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateEnsureProxyMethod(semanticModel.Compilation, gen, nameTable, false).AddNewLineTrivia()));
            targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateEnsureProxyMethod(semanticModel.Compilation, gen, nameTable, true).AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia()));
            targetClass = gen.AddMembers(targetClass, CreateDisposeMethods(semanticModel.Compilation, gen, nameTable, suppressWarningComments));

            if (withInternalProxy)
            {
                targetClass = gen.AddMembers(targetClass, proxyClass);
            }

            #endregion


            targetClass = AddGeneratedCodeAttribute(gen, targetClass);
            return(Task.FromResult((ClassDeclarationSyntax)targetClass));
        }
Пример #6
0
        public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node)
        {
            var result = generator.AddInterfaceType(
                base.VisitClassDeclaration(node),
                generator.IdentifierName(nameof(IMocked)));

            result = generator.AddMembers(result,
                                          generator.FieldDeclaration("mock", ParseTypeName(nameof(IMock)))
                                          // #region IMocked
                                          .WithLeadingTrivia(
                                              CarriageReturnLineFeed,
                                              Trivia(RegionDirectiveTrivia(true)
                                                     .WithRegionKeyword(Token(
                                                                            TriviaList(),
                                                                            SyntaxKind.RegionKeyword,
                                                                            TriviaList(Space)))
                                                     .WithEndOfDirectiveToken(Token(
                                                                                  TriviaList(PreprocessingMessage(nameof(IMocked))),
                                                                                  SyntaxKind.EndOfDirectiveToken,
                                                                                  TriviaList(CarriageReturnLineFeed))
                                                                              )
                                                     )
                                              )
                                          );

            var prop = PropertyDeclaration(IdentifierName(nameof(IMock)), nameof(IMocked.Mock))
                       // Make IMocked properties explicit.
                       .WithExplicitInterfaceSpecifier(
                ExplicitInterfaceSpecifier(
                    IdentifierName(nameof(IMocked))))
                       .WithModifiers(TokenList())
                       // => LazyInitializer.EnsureInitialized(ref mock, () => new MockInfo(pipeline.Behaviors));
                       .WithExpressionBody(ArrowExpressionClause(
                                               InvocationExpression(
                                                   MemberAccessExpression(
                                                       SyntaxKind.SimpleMemberAccessExpression,
                                                       IdentifierName(nameof(LazyInitializer)),
                                                       IdentifierName(nameof(LazyInitializer.EnsureInitialized))),
                                                   ArgumentList(SeparatedList(new ArgumentSyntax[]
            {
                Argument(RefExpression(IdentifierName("mock"))),
                Argument(ParenthesizedLambdaExpression(
                             ObjectCreationExpression(
                                 IdentifierName(nameof(MockInfo)))
                             .WithArgumentList(ArgumentList(SingletonSeparatedList(Argument(
                                                                                       ThisExpression()
                                                                                       ))))
                             ))
            }))
                                                   )
                                               ))
                       .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
                       // #endregion
                       .WithTrailingTrivia(
                CarriageReturnLineFeed,
                Trivia(EndRegionDirectiveTrivia(false)),
                CarriageReturnLineFeed);

            result = generator.AddMembers(result, prop);

            return(result);
        }
      public Task<ClassDeclarationSyntax> GenerateClientClass(SemanticModel semanticModel, SyntaxGenerator gen, INamedTypeSymbol proxyInterface, string name, Accessibility accessibility, bool includeCancellableAsyncMethods, bool suppressWarningComments, MemberAccessibility constructorAccessibility, bool withInternalProxy)
      {
         if (name == null)
         {
            if (proxyInterface.Name.StartsWith("I"))
               name = proxyInterface.Name.Substring(1);

            if (name.EndsWith("Proxy"))
               name = name.Substring(0, name.Length - "Proxy".Length);

            if (!name.EndsWith("Client"))
               name = name + "Client";
         }

         
         SyntaxNode targetClass = gen.ClassDeclaration(name, 
            baseType: gen.TypeExpression(semanticModel.Compilation.RequireType<MarshalByRefObject>()), 
            accessibility: accessibility, 
            modifiers: DeclarationModifiers.Sealed);

         targetClass = gen.AddWarningCommentIf(!suppressWarningComments, targetClass);

         targetClass = gen.AddInterfaceType(targetClass, gen.TypeExpression(semanticModel.Compilation.GetSpecialType(SpecialType.System_IDisposable)));
         targetClass = gen.AddInterfaceType(targetClass, gen.TypeExpression(proxyInterface));

         IEnumerable<IMethodSymbol> methods = GetOperationContractMethods(semanticModel.Compilation, proxyInterface).ToArray();

         GenerationNameTable nameTable = new GenerationNameTable(methods.Select(m => m.Name).Concat(new[] { name }));


         #region Private Fields

         // ==> private IProxy m_cachedProxy;
         SyntaxNode cachedProxyField =
            gen.FieldDeclaration(nameTable[MemberNames.CachedProxyField], gen.TypeExpression(proxyInterface), Accessibility.Private, DeclarationModifiers.None)
            .PrependLeadingTrivia(gen.CreateRegionTrivia("Private Fields"));

         targetClass = gen.AddMembers(targetClass, cachedProxyField);

         // ==> private readonly Func<IProxy> m_proxyFactory;
         SyntaxNode proxyFactoryTypeExpression = gen.TypeExpression(semanticModel.Compilation.RequireTypeByMetadataName("System.Func`1").Construct(proxyInterface));

         targetClass = gen.AddMembers(targetClass, gen.FieldDeclaration(nameTable[MemberNames.ProxyFactoryField], proxyFactoryTypeExpression, Accessibility.Private, DeclarationModifiers.ReadOnly)
            .AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia());

         #endregion


         #region Constructors

         // Constructor         
         SyntaxNode constructor = gen.ConstructorDeclaration(
            parameters: new[] { gen.ParameterDeclaration("proxyFactory", proxyFactoryTypeExpression) },
            accessibility: withInternalProxy ? Accessibility.Private : ToAccessibility(constructorAccessibility)
         );

         constructor = gen.AddWarningCommentIf(!suppressWarningComments, constructor);
         constructor = constructor.PrependLeadingTrivia(gen.CreateRegionTrivia("Constructors"));

         constructor = gen.WithStatements(constructor,
            new[]
            {
               // ==> if (proxyFactory == null)
               // ==>   throw new System.ArgumentNullException("proxyFactory");
               gen.ThrowIfNullStatement("proxyFactory"),
               
               // ==> m_proxyFactory = proxyFactory
               gen.AssignmentStatement(
                  gen.MemberAccessExpression(
                     gen.ThisExpression(),
                     gen.IdentifierName(nameTable[MemberNames.ProxyFactoryField])),
                  gen.IdentifierName("proxyFactory")
               )
            }
         ).AddNewLineTrivia();

         if (!withInternalProxy)
            constructor = constructor.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia();

         targetClass = gen.AddMembers(targetClass, constructor);

         ClassDeclarationSyntax proxyClass = null;
         if (withInternalProxy)
         {
            IEnumerable<IMethodSymbol> ctors;
            proxyClass = GenerateProxyClass(semanticModel, gen, proxyInterface, nameTable[MemberNames.ProxyClass], Accessibility.Private, suppressWarningComments, MemberAccessibility.Public, out ctors)
                                                   .PrependLeadingTrivia(gen.CreateRegionTrivia("Proxy Class").Insert(0, gen.NewLine()))
                                                   .AddTrailingTrivia(gen.CreateEndRegionTrivia());

            // Generate one constructor for each of the proxy's constructors.
            foreach (var ctorEntry in ctors.AsSmartEnumerable())
            {
               var ctor = ctorEntry.Value;
               var targetCtor = gen.ConstructorDeclaration(ctor);

               var lambda = gen.ValueReturningLambdaExpression(                  
                  gen.ObjectCreationExpression(gen.IdentifierName(gen.GetName(proxyClass)), ctor.Parameters.Select(p => gen.IdentifierName(p.Name)))
               );

               targetCtor = gen.WithThisConstructorInitializer(targetCtor, new[] { lambda });

               targetCtor = gen.AddWarningCommentIf(!suppressWarningComments, targetCtor);
               targetCtor = gen.WithAccessibility(targetCtor, ToAccessibility(constructorAccessibility));
               
               if (ctorEntry.IsLast)
               {
                  targetCtor = targetCtor.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia();
               }

               targetClass = gen.AddMembers(targetClass, targetCtor.AddNewLineTrivia());
            }


         }

         #endregion

         #region Operation Contract Methods

         // ==> catch
         // ==> {
         // ==>    this.CloseProxy(false);
         // ==>    throw;
         // ==> }
         var catchAndCloseProxyStatement = gen.CatchClause(new SyntaxNode[]
            {
               // ==> this.CloseProxy(false);
               gen.ExpressionStatement(
                  gen.InvocationExpression(
                     gen.MemberAccessExpression(
                        gen.ThisExpression(),
                        nameTable[MemberNames.CloseProxyMethod]
                     ),
                     gen.FalseLiteralExpression()
                  )
               ),

               // throw;
               gen.ThrowStatement()
            });


         foreach (var sourceMethodEntry in methods.AsSmartEnumerable())
         {
            var sourceMethod = sourceMethodEntry.Value;

            using (nameTable.PushScope(sourceMethod.Parameters.Select(p => p.Name)))
            {
               bool isAsync = ReturnsTask(semanticModel.Compilation, sourceMethod);
               bool isVoid = sourceMethod.ReturnType.SpecialType == SpecialType.System_Void || sourceMethod.ReturnType.Equals(semanticModel.Compilation.RequireType<Task>());

               SyntaxNode targetMethod = gen.MethodDeclaration(sourceMethod);

               if (sourceMethodEntry.IsFirst)
                  targetMethod = targetMethod.PrependLeadingTrivia(gen.CreateRegionTrivia("Contract Methods")).AddLeadingTrivia(gen.NewLine());

               targetMethod = gen.AddWarningCommentIf(!suppressWarningComments, targetMethod);

               targetMethod = gen.WithModifiers(targetMethod, isAsync ? DeclarationModifiers.Async : DeclarationModifiers.None);


               targetMethod = gen.WithStatements(targetMethod, new SyntaxNode[]
                  {
                  // ==> try {
                  gen.TryCatchStatement(new SyntaxNode[]
                     {
                        CreateProxyVaraibleDeclaration(gen, nameTable, isAsync),
                        CreateProxyInvocationStatement(semanticModel.Compilation, gen, nameTable, sourceMethod)

                     }, new SyntaxNode[]
                     {
                        catchAndCloseProxyStatement
                     }
                  )
                  });

               targetMethod = targetMethod.AddNewLineTrivia();

               if (sourceMethodEntry.IsLast && !(isAsync && includeCancellableAsyncMethods))
                  targetMethod = targetMethod.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia();

               targetClass = gen.AddMembers(targetClass, targetMethod);

               if (isAsync && includeCancellableAsyncMethods)
               {
                  targetMethod = gen.MethodDeclaration(sourceMethod);
                  targetMethod = gen.AddParameters(targetMethod, new[] { gen.ParameterDeclaration(nameTable[MemberNames.CancellationTokenParameter], gen.TypeExpression(semanticModel.Compilation.RequireType<CancellationToken>())) });
                  targetMethod = gen.WithModifiers(targetMethod, isAsync ? DeclarationModifiers.Async : DeclarationModifiers.None);


                  targetMethod = gen.WithStatements(targetMethod, new SyntaxNode[]
                     {
                     // ==> try {
                     gen.TryCatchStatement(new SyntaxNode[]
                        {
                           CreateProxyVaraibleDeclaration(gen, nameTable, isAsync),
                           CreateCancellableProxyInvocationStatement(semanticModel.Compilation, gen, nameTable, sourceMethod)

                        }, new SyntaxNode[]
                        {
                           catchAndCloseProxyStatement
                        }
                     )
                     });


                  targetMethod = gen.AddWarningCommentIf(!suppressWarningComments, targetMethod.AddNewLineTrivia());

                  if (sourceMethodEntry.IsLast)
                     targetMethod = targetMethod.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia();

                  targetClass = gen.AddMembers(targetClass, targetMethod);
               }
            }
         }

         #endregion

         #region Internal Methods

         targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateGetProxyMethod(semanticModel.Compilation, gen, proxyInterface, nameTable, false).AddLeadingTrivia(gen.CreateRegionTrivia("Private Methods")).AddNewLineTrivia()));
         targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateGetProxyMethod(semanticModel.Compilation, gen, proxyInterface, nameTable, true).AddNewLineTrivia()));
         targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateStaticCloseProxyMethod(semanticModel.Compilation, gen, nameTable, false).AddNewLineTrivia()));
         targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateStaticCloseProxyMethod(semanticModel.Compilation, gen, nameTable, true).AddNewLineTrivia()));
         targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateCloseProxyMethod(semanticModel.Compilation, gen, nameTable, false).AddNewLineTrivia()));
         targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateCloseProxyMethod(semanticModel.Compilation, gen, nameTable, true).AddNewLineTrivia()));
         targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateEnsureProxyMethod(semanticModel.Compilation, gen, nameTable, false).AddNewLineTrivia()));
         targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateEnsureProxyMethod(semanticModel.Compilation, gen, nameTable, true).AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia()));
         targetClass = gen.AddMembers(targetClass, CreateDisposeMethods(semanticModel.Compilation, gen, nameTable, suppressWarningComments));

         if (withInternalProxy)
         {
            targetClass = gen.AddMembers(targetClass, proxyClass);
         }

         #endregion


         targetClass = AddGeneratedCodeAttribute(gen, targetClass);
         return Task.FromResult((ClassDeclarationSyntax)targetClass);
      }