Beispiel #1
0
            public bool TryAdd(WriteEventOverloadInfo overload)
            {
                if (overload.Parameters.Any(p => !p.IsSupported))
                {
                    return(false);
                }

                if (m_eventSourceTypeInfo.WriteEventOverloads.Any(ol => ol.Select(p => p.Type).SequenceEqual(overload.Parameters.Select(p => p.TargetType))))
                {
                    return(false);
                }

                if (m_overloads.Any(ol => ol.Parameters.Select(p => p.TargetType).SequenceEqual(overload.Parameters.Select(p => p.TargetType))))
                {
                    return(false);
                }

                m_overloads.Add(overload);

                return(true);
            }
      private IEnumerable<SyntaxNode> GenerateEventSourceMethods(INamedTypeSymbol sourceClass, EventSourceTypeInfo eventSourceTypeInfo, CollectedGenerationInfo overloads, GenerationOptions options)
      {
         var templateMethods = GetEventSourceTemplateMethods(sourceClass, eventSourceTypeInfo);
         foreach (var sourceMethodEntry in templateMethods.AsSmartEnumerable())
         {
            IMethodSymbol sourceMethod = sourceMethodEntry.Value;

            TemplateEventMethodInfo eventAttributeInfo = TranslateMethodAttributes(sourceMethod, eventSourceTypeInfo, overloads);

            WriteEventOverloadInfo overloadInfo = new WriteEventOverloadInfo(sourceMethodEntry.Value, options, m_parameterConverters);

            if (overloadInfo.Parameters.Any(p => p.IsSupported == false))
            {
               throw new CodeGeneratorException(sourceMethod, $"The parameter(s) {StringUtils.Join(overloadInfo.Parameters.Where(p => !p.IsSupported).Select(p => $"{p.Parameter.Name} ({p.Parameter.Type.Name})"), ", ", " and ")} are not supported.");
            }

            overloads.TryAdd(overloadInfo);

            // Check if this method has needs a wrapper method to perform parameter conversion into a natively supported parameter type.            
            if (overloadInfo.NeedsConverter)
            {
               // Create the wrapper method
               SyntaxNode wrapperMethod = m_generator.MethodDeclaration(sourceMethod);
               
               // This method should only have the [NonEvent] attribute.
               wrapperMethod = m_generator.AddAttributes(m_generator.RemoveAllAttributes(wrapperMethod), m_generator.Attribute(eventSourceTypeInfo.EventSourceNamespace.GetFullName() + ".NonEvent"));

               wrapperMethod = m_generator.WithAccessibility(wrapperMethod, sourceMethod.DeclaredAccessibility);
               wrapperMethod = m_generator.WithModifiers(wrapperMethod, DeclarationModifiers.Override);

               // And it should call the overload of the same method that is generated below (the actual event method)
               wrapperMethod = m_generator.WithStatements(wrapperMethod,
                  new[]
                  {
                     m_generator.IfStatement(
                        // Condition
                        m_generator.InvocationExpression(m_generator.IdentifierName("IsEnabled")),

                        // True-Statements
                        new[]
                        {
                           m_generator.ExpressionStatement(
                              m_generator.InvocationExpression(m_generator.IdentifierName(sourceMethod.Name),
                                 overloadInfo.Parameters.Select(parameter => m_generator.Argument(
                                          parameter.HasConverter ?
                                             parameter.Converter.GetConversionExpression(m_generator.IdentifierName(parameter.Parameter.Name)) :
                                             m_generator.IdentifierName(parameter.Parameter.Name)
                                    )
                                 )
                              )
                           )
                        }
                     )
                  }
               );

               // And let's add some warning comments about this being generated code.
               wrapperMethod = wrapperMethod.WithLeadingTrivia(wrapperMethod.GetLeadingTrivia().AddRange(CreateWarningComment()));

               yield return wrapperMethod;
            }

            // Generate the actual event method.
            SyntaxNode eventMethod = m_generator.MethodDeclaration(sourceMethod.Name);

            if (overloadInfo.NeedsConverter)
            {
               // If we have a wrapper method converting parameters, this will be a private method.
               eventMethod = m_generator.WithAccessibility(eventMethod, Accessibility.Private);
            }
            else
            {
               // Otherwise it has the same accessibility as the base class method, except this is an override of course.
               eventMethod = m_generator.WithAccessibility(eventMethod, sourceMethod.DeclaredAccessibility);
               eventMethod = m_generator.WithModifiers(eventMethod, DeclarationModifiers.Override);
            }

            // The parameter list may be modified from the source method to account for any conversions performed by the wrapper method.
            eventMethod = m_generator.AddParameters(eventMethod,
               overloadInfo.Parameters.Select(pi => m_generator.ParameterDeclaration(pi.Parameter.Name, m_generator.TypeExpression(pi.TargetType)))
            );

            // Statement to call the WriteEvent() method.
            SyntaxNode writeEventStatement = m_generator.ExpressionStatement(
                                       m_generator.InvocationExpression(m_generator.IdentifierName("WriteEvent"),
                                          new[] {
                                             m_generator.Argument(m_generator.LiteralExpression(eventAttributeInfo.EventId)),
                                          }.Concat(overloadInfo.Parameters.Select(parameter => m_generator.Argument(
                                                        m_generator.IdentifierName(parameter.Parameter.Name))
                                             )
                                          )
                                       )
                                    );

            if (overloadInfo.NeedsConverter)
            {
               // If this method has a wrapper method, then the IsEnabled() check has already been made, so we skip that here
               // and just call the WriteEvent() method.
               eventMethod = m_generator.WithStatements(eventMethod, new[] { writeEventStatement });
            }
            else
            {
               // Otherwise we want to check the IsEnabled() flag first.
               eventMethod = m_generator.WithStatements(eventMethod,
                  new[]
                  {
                     m_generator.IfStatement(
                        // Condition
                        m_generator.InvocationExpression(m_generator.IdentifierName("IsEnabled")),

                        // True-Statements
                        new[]
                        {
                           writeEventStatement
                        }
                     )
                  }
               );
            }

            // Add all attributes from the source method. (Well, with translation of the TemplateEventAttribute).
            eventMethod = m_generator.AddAttributes(eventMethod, eventAttributeInfo.Attributes);

            // And some warning comments as usual.
            eventMethod = eventMethod.WithLeadingTrivia(eventMethod.GetLeadingTrivia().AddRange(CreateWarningComment()));

            yield return eventMethod;
         }
      }
            public bool TryAdd(WriteEventOverloadInfo overload)
            {
                if (overload.Parameters.Any(p => !p.IsSupported))
                   return false;

                if (m_eventSourceTypeInfo.WriteEventOverloads.Any(ol => ol.Select(p => p.Type).SequenceEqual(overload.Parameters.Select(p => p.TargetType))))
                   return false;

                if (m_overloads.Any(ol => ol.Parameters.Select(p => p.TargetType).SequenceEqual(overload.Parameters.Select(p => p.TargetType))))
                   return false;

                m_overloads.Add(overload);

                return true;
            }