public CodeGenMethod Create(DecoratorMethodInformation factoryInformation)
        {
            IEnumerable <CodeGenGeneric> genericTypes = factoryInformation.GenericTypes?.Select(
                parameter => FactoryHelpers.GenerateMethodParameter(parameter, factoryInformation.TypeConstraints));

            IEnumerable <string> parameters = factoryInformation.Parameters?.Select(parameter => $"{parameter.Type} {parameter.Name}");

            MethodTemplate matchingTemplate = _SelectorFactory
                                              .Create(factoryInformation.Templates)
                                              .Select(
                factoryInformation.MethodName,
                factoryInformation.ReturnType,
                factoryInformation.Parameters?.Select(parameter => parameter.Type)?.ToArray(),
                factoryInformation.IsAsync);

            string body = matchingTemplate != null
                ? GenerateDecoratorMethodBodyFromCondition(
                factoryInformation.MethodName,
                factoryInformation.ReturnType,
                matchingTemplate,
                factoryInformation.Parameters)
                : GenerateUndecoratedMethodBody(
                factoryInformation.MethodName,
                factoryInformation.Parameters);

            return(new CodeGenMethod(
                       factoryInformation.MethodName,
                       factoryInformation.ReturnType,
                       Scope.Public,
                       MethodType.Normal,
                       genericTypes,
                       parameters,
                       body,
                       matchingTemplate?.Async ?? false));
        }
        private string GenerateDecoratorPropertySetterBodyFromCondition(string propertyName, PropertyTemplate template)
        {
            string body = template.SetterBody.Clone() as string;

            body = body.Replace("Decorated.Property.Any.Value", $"_Decorated.{propertyName}");

            return(FactoryHelpers.CleanBody(body));
        }
Exemplo n.º 3
0
        public CodeGenClass Create(DecoratorClassInformation factoryInformation)
        {
            var generatedExtensionClass = new CodeGenClass(
                $"{factoryInformation.ParentInformation.DecoratorName}Extensions",
                Scope.Public,
                ClassType.Static);

            IEnumerable <CodeGenGeneric> genericTypes = factoryInformation.GenericTypes?.Select(
                parameter => FactoryHelpers.GenerateMethodParameter(parameter, factoryInformation.TypeConstraints));

            var extensionParams            = new List <string>(new[] { $"this {factoryInformation.DecoratedType} decorated" });
            var decoratedConstructorParams = new List <string>(new[] { "decorated" });

            if (factoryInformation.Template.ConstructorParams != null)
            {
                foreach (ConstructorParam constructorParam in factoryInformation.Template.ConstructorParams)
                {
                    extensionParams.Add($"{constructorParam.Type} {constructorParam.Name}");
                    decoratedConstructorParams.Add(constructorParam.Name);
                }
            }

            string genericTypesString = factoryInformation.GenericTypes.ToTypeParamList();
            string paramNames         = string.Join(", ", decoratedConstructorParams);
            string body = $"return new {factoryInformation.ParentInformation.DecoratorName}{genericTypesString}({paramNames});";

            string returnType = factoryInformation.DerviedFrom != null
                ? factoryInformation.DerviedFrom
                : $"{factoryInformation.ParentInformation.DecoratorName}{genericTypesString}";

            var generatedExtensionMethod = new CodeGenMethod(
                $"DecorateWith{factoryInformation.Template.Label}",
                returnType,
                Scope.Public,
                MethodType.Static,
                genericTypes,
                extensionParams,
                body);

            generatedExtensionClass.Methods.Add(generatedExtensionMethod);
            return(generatedExtensionClass);
        }
        private string GenerateDecoratorMethodBodyFromCondition(
            string methodName,
            string returnType,
            MethodTemplate template,
            IEnumerable <MethodParameter> parameters)
        {
            IEnumerable <string> paramNameList = parameters?.Select(parameter => parameter.Name) ?? new string[0];
            string invocation = $"_Decorated.{methodName}({string.Join(", ", paramNameList)})";

            string body = template.Body.Clone() as string;

            if (returnType == "void" && template.MatchCondition.ReturnTypeRule == ReturnTypeRule.Any)
            {
                body = VoidReturnMethodInvokeRegex.Replace(body, invocation);
            }
            else
            {
                body = MethodInvokeRegex.Replace(body, invocation);
            }

            return(FactoryHelpers.CleanBody(body));
        }
        public CodeGenClass Create(DecoratorClassInformation factoryInformation)
        {
            IEnumerable <CodeGenGeneric> genericTypes = factoryInformation.GenericTypes?.Select(
                parameter => FactoryHelpers.GenerateMethodParameter(parameter, factoryInformation.TypeConstraints));

            string[] derivedFrom = !string.IsNullOrEmpty(factoryInformation.DerviedFrom)
                ? new[] { factoryInformation.DerviedFrom }
                : null;

            var generatedDecoratorClass = new CodeGenClass(
                factoryInformation.ParentInformation.DecoratorName,
                Scope.Public,
                ClassType.Normal,
                genericTypes,
                derivedFrom);

            generatedDecoratorClass.Comment = new CodeGenComment($@"Generated {factoryInformation.Template.Label} decorator for the {factoryInformation.DecoratedType } type. Auto-generated on {DateTimeOffset.Now}");

            var constructorParams      = new List <string>(new[] { $"{factoryInformation.DecoratedType} decorated" });
            var constructorBodyBuilder = new StringBuilder();

            constructorBodyBuilder.AppendLine("_Decorated = decorated ?? throw new ArgumentNullException(nameof(decorated));");

            if (factoryInformation.Template.ConstructorParams != null)
            {
                foreach (ConstructorParam constructorParam in factoryInformation.Template.ConstructorParams)
                {
                    constructorParams.Add($"{constructorParam.Type} {constructorParam.Name}");
                    constructorBodyBuilder.AppendLine($"_{constructorParam.Name} = {constructorParam.Name};");

                    generatedDecoratorClass.Variables.Add(new CodeGenVariable(
                                                              $"_{constructorParam.Name}",
                                                              constructorParam.Type,
                                                              Scope.Private,
                                                              readOnly: true));
                }
            }

            // Constructor
            generatedDecoratorClass.Constructors.Add(new CodeGenConstructor(
                                                         factoryInformation.ParentInformation.DecoratorName,
                                                         Scope.Public,
                                                         constructorParams,
                                                         constructorBodyBuilder.ToString()));

            // Decorated variable
            generatedDecoratorClass.Variables.Add(new CodeGenVariable(
                                                      "_Decorated",
                                                      factoryInformation.DecoratedType,
                                                      Scope.Private,
                                                      readOnly: true));

            foreach (DecoratorMethodInformation methodInformation in factoryInformation.MethodInformation)
            {
                CodeGenMethod method = _MethodFactory.Create(methodInformation);
                generatedDecoratorClass.Methods.Add(method);
            }

            foreach (DecoratorPropertyInformation propertyInformation in factoryInformation.PropertyInformation)
            {
                CodeGenProperty property = _PropertyFactory.Create(propertyInformation);
                generatedDecoratorClass.Properties.Add(property);
            }

            return(generatedDecoratorClass);
        }