Пример #1
0
 protected override CodeMethodReferenceExpression GetFindViewByIdReference(string typeName)
 {
     return(new CodeMethodReferenceExpression(
                new CodeThisReferenceExpression(),
                "FindViewById",
                CodeGeneratorHelper.GetTypeReferenceFromName(typeName)));
 }
        private CodePropertyReferenceExpression CreateLocalizationServiceProperty()
        {
            CodeMethodReferenceExpression resolveMethodReference = new CodeMethodReferenceExpression(
                new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(CodeGeneratorHelper.GetTypeReferenceFromName("DependencyService")), "Container"),
                "Resolve",
                CodeGeneratorHelper.GetTypeReferenceFromName("ILocalizationService")
                );
            CodeMethodInvokeExpression invokeMethod = new CodeMethodInvokeExpression(resolveMethodReference);

            Tuple <CodeMemberField, CodeMemberProperty> result = CodeGeneratorHelper.GenerateProxyProperty(NameGeneratorHelper.LOCALIZATION_SERVICE_PROPERTY_NAME, "ILocalizationService", invokeMethod);

            Fields.Add(result.Item1);
            Properties.Add(result.Item2);

            return(CodeGeneratorHelper.GetPropertyReference(result.Item2));
        }
 private Dictionary <string, CodePropertyReferenceExpression> CreatePropertiesForResources(IEnumerable <Resource> resources)
 {
     return(resources.ToDictionary(resource => resource.Key, resource =>
     {
         DataTemplateResource dataTemplateResource = resource as DataTemplateResource;
         Tuple <CodeMemberField, CodeMemberProperty> result;
         if (dataTemplateResource != null)                 // in case of data templates
         {
             const string type = "Storm.Mvvm.DataTemplate";
             result = CodeGeneratorHelper.GenerateProxyProperty(resource.PropertyName, type, fieldReference => new List <CodeStatement>
             {
                 // _field = new DataTemplate();
                 new CodeAssignStatement(fieldReference, new CodeObjectCreateExpression(CodeGeneratorHelper.GetTypeReferenceFromName(type))),
                 // _field.ViewId = Resource.Id.***
                 new CodeAssignStatement(new CodePropertyReferenceExpression(fieldReference, "ViewId"), CodeGeneratorHelper.GetAndroidResourceReference(ResourcePart.Layout, dataTemplateResource.ViewId)),
                 // _field.LayoutInflater = LayoutInflater;
                 new CodeAssignStatement(new CodePropertyReferenceExpression(fieldReference, "LayoutInflater"), GetLayoutInflaterReference()),
                 // _field.ViewHolderType = typeof(viewholder class)
                 new CodeAssignStatement(new CodePropertyReferenceExpression(fieldReference, "ViewHolderType"), new CodeTypeOfExpression(string.Format("{0}.{1}", Configuration.GeneratedNamespace, dataTemplateResource.ViewHolderClassName))),
             });
         }
         else
         {
             // create a proxy property to handle the resource
             string type = resource.Type;
             Dictionary <string, string> assignments = resource.Properties;
             result = CodeGeneratorHelper.GenerateProxyProperty(resource.PropertyName, type, fieldReference => CodeGeneratorHelper.GenerateStatementsCreateAndAssign(fieldReference, type, assignments));
         }
         Fields.Add(result.Item1);
         Properties.Add(result.Item2);
         return CodeGeneratorHelper.GetPropertyReference(result.Item2);
     }));
 }
        private void CreateBindingOverrideMethod(List <ExpressionContainer> bindingExpressions, CodePropertyReferenceExpression localizationServiceReference, Dictionary <string, CodePropertyReferenceExpression> resourceReferences, params CodeMethodReferenceExpression[] preCallMethods)
        {
            CodeTypeReference listOfBindingObjectTypeReference = CodeGeneratorHelper.GetTypeReferenceFromName("List<BindingObject>");
            CodeTypeReference bindingObjectTypeReference       = CodeGeneratorHelper.GetTypeReferenceFromName("BindingObject");
            CodeTypeReference bindingExpressionTypeReference   = CodeGeneratorHelper.GetTypeReferenceFromName("BindingExpression");

            CodeMemberMethod method = new CodeMemberMethod
            {
                Attributes = MemberAttributes.Family | MemberAttributes.Override,
                Name       = NameGeneratorHelper.GET_BINDING_METHOD_NAME,
                ReturnType = listOfBindingObjectTypeReference
            };

            foreach (CodeMethodReferenceExpression preCallMethod in preCallMethods)
            {
                method.Statements.Add(new CodeMethodInvokeExpression(preCallMethod));
            }

            var variableCreationResult = CodeGeneratorHelper.CreateVariable(listOfBindingObjectTypeReference, "result");

            method.Statements.Add(variableCreationResult.Item1);
            CodeVariableReferenceExpression resultReference = variableCreationResult.Item2;

            // group binding expression by target object to simplify
            foreach (IGrouping <string, ExpressionContainer> groupedExpressions in bindingExpressions.GroupBy(x => x.TargetObject))
            {
                // create a variable for this binding object and build it with the Property of the view element
                variableCreationResult = CodeGeneratorHelper.CreateVariable(bindingObjectTypeReference, NameGeneratorHelper.GetBindingObjectName(), CodeGeneratorHelper.GetPropertyReference(groupedExpressions.Key));                //viewElementReferences[groupedExpressions.Key]);
                method.Statements.Add(variableCreationResult.Item1);

                CodeVariableReferenceExpression objectReference = variableCreationResult.Item2;
                method.Statements.Add(new CodeMethodInvokeExpression(resultReference, "Add", objectReference));


                foreach (ExpressionContainer expressionContainer in groupedExpressions)
                {
                    Expression expression = expressionContainer.Expression;
                    // create a binding expression for this
                    variableCreationResult = CodeGeneratorHelper.CreateVariable(bindingExpressionTypeReference, NameGeneratorHelper.GetBindingExpressionName(), new CodePrimitiveExpression(expressionContainer.TargetField),
                                                                                new CodePrimitiveExpression(expression.GetValue(BindingExpression.PATH)));
                    method.Statements.Add(variableCreationResult.Item1);

                    CodeVariableReferenceExpression expressionReference = variableCreationResult.Item2;

                    if (expression.Has(BindingExpression.MODE) && expression.Get <ModeExpression>(BindingExpression.MODE).Value != BindingMode.OneWay)
                    {
                        // Expression could only be of type ModeExpression
                        BindingMode mode = expression.Get <ModeExpression>(BindingExpression.MODE).Value;
                        method.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(expressionReference, "Mode"),
                                                                      new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("BindingMode"), mode.ToString())));
                    }
                    if (expression.Has(BindingExpression.UPDATE_EVENT) && !string.IsNullOrWhiteSpace(expression.GetValue(BindingExpression.UPDATE_EVENT)))
                    {
                        // Expression could only be of type Text
                        string updateEvent = expression.GetValue(BindingExpression.UPDATE_EVENT);
                        method.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(expressionReference, "UpdateEvent"), new CodePrimitiveExpression(updateEvent)));
                    }
                    if (expression.Has(BindingExpression.CONVERTER))
                    {
                        // Expression could be type Resource or (Binding : not implemented for now)
                        Expression converterExpression = expression[BindingExpression.CONVERTER];
                        if (converterExpression.IsOfType(ExpressionType.Binding))
                        {
                            Log.LogError("Binding expression for converter is not implemented yet");
                            throw new NotImplementedException("Binding expression for converter is not implemented yet");
                        }
                        else if (converterExpression.IsOfType(ExpressionType.Resource))
                        {
                            string resourceKey = converterExpression.GetValue(ResourceExpression.KEY);
                            CodePropertyReferenceExpression resourceReference = resourceReferences[resourceKey];

                            method.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(expressionReference, "Converter"), resourceReference));
                        }
                    }
                    if (expression.Has(BindingExpression.CONVERTER_PARAMETER))
                    {
                        // Expression could be of type Resource, Translation, Text or (Binding : not implemented for now)
                        Expression converterParameterExpression = expression[BindingExpression.CONVERTER_PARAMETER];
                        if (converterParameterExpression.IsOfType(ExpressionType.Binding))
                        {
                            Log.LogError("Binding expression for converter parameter is not implemented yet");
                            throw new NotImplementedException("Binding expression for converter parameter is not implemented yet");
                        }
                        else if (converterParameterExpression.IsOfType(ExpressionType.Resource))
                        {
                            string resourceKey = converterParameterExpression.GetValue(ResourceExpression.KEY);
                            CodePropertyReferenceExpression resourceReference = resourceReferences[resourceKey];

                            method.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(expressionReference, "ConverterParameter"), resourceReference));
                        }
                        else if (converterParameterExpression.IsOfType(ExpressionType.Translation))
                        {
                            CodeMethodInvokeExpression valueReference = GenerateStatementToGetTranslation(localizationServiceReference, converterParameterExpression);
                            method.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(expressionReference, "ConverterParameter"), valueReference));
                        }
                        else if (converterParameterExpression.IsOfType(ExpressionType.Value))
                        {
                            TextExpression textExpression = converterParameterExpression as TextExpression;
                            if (textExpression != null)
                            {
                                string converterParameterValue = textExpression.Value;
                                method.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(expressionReference, "ConverterParameter"), new CodePrimitiveExpression(converterParameterValue)));
                            }
                            else
                            {
                                throw new InvalidOperationException("Can't get a textExpression from a ExpressionType.Value expression...");
                            }
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(expressionContainer.CommandParameterTarget))
                    {
                        method.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(expressionReference, "CommandParameter"),
                                                                      CodeGeneratorHelper.GetPropertyReference(expressionContainer.CommandParameterTarget)));
                    }

                    method.Statements.Add(new CodeMethodInvokeExpression(objectReference, "AddExpression", expressionReference));
                }
            }

            method.Statements.Add(new CodeMethodReturnStatement(resultReference));

            Methods.Add(method);
        }
        public void Generate(string outputFile)
        {
            CodeCompileUnit codeUnit = new CodeCompileUnit();
            // for all using statements
            CodeNamespace globalNamespace = new CodeNamespace("");
            // for class declaration
            CodeNamespace codeNamespace = new CodeNamespace(NamespaceName);

            codeUnit.Namespaces.AddRange(new [] { globalNamespace, codeNamespace });

            // add all using statements
            globalNamespace.Imports.AddRange(Configuration.Namespaces.Select(x => new CodeNamespaceImport(x)).ToArray());

            // create class
            CodeTypeDeclaration classDeclaration = new CodeTypeDeclaration(ClassName)
            {
                IsClass        = true,
                IsPartial      = IsPartialClass,
                TypeAttributes = TypeAttributes.Public,
            };

            if (BaseClassType != null)
            {
                classDeclaration.BaseTypes.Add(CodeGeneratorHelper.GetTypeReferenceFromName(BaseClassType));
            }
            codeNamespace.Types.Add(classDeclaration);

            classDeclaration.Members.AddRange(Events.Select(x => (CodeTypeMember)x).ToArray());
            classDeclaration.Members.AddRange(Fields.Select(x => (CodeTypeMember)x).ToArray());
            classDeclaration.Members.AddRange(Properties.Select(x => (CodeTypeMember)x).ToArray());
            classDeclaration.Members.AddRange(Methods.Select(x => (CodeTypeMember)x).ToArray());

            #region File writing

            CodeDomProvider      provider = CodeDomProvider.CreateProvider("CSharp");
            CodeGeneratorOptions options  = new CodeGeneratorOptions
            {
                BlankLinesBetweenMembers = true,
                BracingStyle             = "C",
                IndentString             = "\t"
            };

            string contentString;
            using (StringWriter stringWriter = new StringWriter())
            {
                provider.GenerateCodeFromCompileUnit(codeUnit, stringWriter, options);

                string content = stringWriter.GetStringBuilder().ToString();

                Regex commentRegex = new Regex("<auto-generated>.*</auto-generated>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
                contentString = commentRegex.Replace(content, "This file was generated by binding preprocessing system for Android");
            }

            if (File.Exists(outputFile))
            {
                using (StreamReader reader = new StreamReader(outputFile))
                {
                    string actualContent = reader.ReadToEnd();
                    if (actualContent == contentString)
                    {
                        return;
                    }
                }
                File.Delete(outputFile);
            }

            using (StreamWriter writer = new StreamWriter(File.OpenWrite(outputFile)))
            {
                writer.Write(contentString);
            }

            #endregion
        }