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 GenerateCommandParameterProperties(List <ExpressionContainer> expressionContainers) { foreach (IGrouping <string, ExpressionContainer> expressions in expressionContainers.GroupBy(x => x.TargetObject)) { const string attributeName = "CommandParameter"; Regex commandParameterEventRegex = new Regex("^(?<eventName>[a-zA-Z0-9_]+)\\." + attributeName, RegexOptions.Compiled | RegexOptions.IgnoreCase); List <ExpressionContainer> commandParameterEventExpressions = expressions.Where(x => commandParameterEventRegex.IsMatch(x.TargetField)).ToList(); ExpressionContainer commandParameterExpression = expressions.SingleOrDefault(x => attributeName.Equals(x.TargetField, StringComparison.InvariantCultureIgnoreCase)); commandParameterEventExpressions.ForEach(x => x.IsCommandParameterExpression = true); if (commandParameterExpression != null) { commandParameterExpression.IsCommandParameterExpression = true; } foreach (ExpressionContainer expression in commandParameterEventExpressions) { //find associated event (if exists) string eventName = commandParameterEventRegex.Match(expression.TargetField).Groups["eventName"].Value; ExpressionContainer associatedExpression = expressions.FirstOrDefault(x => eventName.Equals(x.TargetField, StringComparison.InvariantCultureIgnoreCase) && !x.IsCommandParameterExpression); if (associatedExpression != null) { // create proxy property CommandParameterProxy to handle this var result = CodeGeneratorHelper.GenerateProxyProperty(NameGeneratorHelper.GetCommandParameterName(), "CommandParameterProxy"); Properties.Add(result.Item2); Fields.Add(result.Item1); string propertyName = CodeGeneratorHelper.GetPropertyReference(result.Item2).PropertyName; // retarget the binding expression to this new property and to the Value field expression.TargetObject = propertyName; expression.TargetField = "Value"; associatedExpression.CommandParameterTarget = propertyName; } } if (commandParameterExpression != null) { // create proxy property CommandParameterProxy to handle this var result = CodeGeneratorHelper.GenerateProxyProperty(NameGeneratorHelper.GetCommandParameterName(), "CommandParameterProxy"); Properties.Add(result.Item2); Fields.Add(result.Item1); string propertyName = CodeGeneratorHelper.GetPropertyReference(result.Item2).PropertyName; // retarget the binding expression to this new property and to the Value field commandParameterExpression.TargetObject = propertyName; commandParameterExpression.TargetField = "Value"; foreach (ExpressionContainer associatedExpression in expressions.Where(x => string.IsNullOrEmpty(x.CommandParameterTarget) && !x.IsCommandParameterExpression)) { associatedExpression.CommandParameterTarget = propertyName; } } } }
protected override CodeMethodReferenceExpression GetFindViewByIdReference(string typeName) { return(new CodeMethodReferenceExpression( CodeGeneratorHelper.GetPropertyReference("RootView"), "FindViewById", CodeGeneratorHelper.GetTypeReferenceFromName(typeName) )); }
private CodeMethodReferenceExpression CreateSetupResourcesMethod(List <ExpressionContainer> expressions, Dictionary <string, CodePropertyReferenceExpression> resourceReferences) { CodeMemberMethod method = new CodeMemberMethod { Attributes = MemberAttributes.Private, Name = NameGeneratorHelper.ASSIGN_RESOURCE_TO_RESOURCE_METHOD_NAME, }; // Create dependency graph to check for cycle in resource assignment Dictionary <string, DependencyNode> dependencies = resourceReferences.ToDictionary(x => x.Value.PropertyName, x => new DependencyNode(x.Value.PropertyName)); foreach (ExpressionContainer expression in expressions) { string source = expression.TargetObject; string targetKey = expression.Expression.GetValue(ResourceExpression.KEY); string target = resourceReferences[targetKey].PropertyName; dependencies[source].Add(dependencies[target]); } // Check for cycle List <DependencyNode> processedNodes = new List <DependencyNode>(); List <DependencyNode> waitingNodes = dependencies.Values.ToList(); while (waitingNodes.Any()) { DependencyNode node = waitingNodes.FirstOrDefault(x => x.Dependencies.All(o => o.IsMarked)); if (node == null) { Log.LogError("Error : Circular references in Resources"); throw new InvalidOperationException("Cirular references"); } node.IsMarked = true; processedNodes.Add(node); waitingNodes.Remove(node); } // If no cycles, we have the order to assign all resources in correct order Dictionary <DependencyNode, IEnumerable <ExpressionContainer> > orderedExpressions = processedNodes.ToDictionary(x => x, x => expressions.Where(o => o.TargetObject == x.Id)); foreach (DependencyNode node in processedNodes) { foreach (ExpressionContainer expression in orderedExpressions[node]) { string resourceKey = expression.Expression.GetValue(ResourceExpression.KEY); method.Statements.Add(SetValueStatement(CodeGeneratorHelper.GetPropertyReference(expression.TargetObject), expression.TargetField, resourceReferences[resourceKey])); } } Methods.Add(method); return(CodeGeneratorHelper.GetMethodReference(method)); }
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 CodeMethodReferenceExpression CreateSetupResourceForViewElementMethod(List <ExpressionContainer> expressions, Dictionary <string, CodePropertyReferenceExpression> resourceReferences) { CodeMemberMethod method = new CodeMemberMethod { Attributes = MemberAttributes.Private, Name = NameGeneratorHelper.ASSIGN_RESOURCE_TO_VIEW_METHOD_NAME, }; foreach (ExpressionContainer expression in expressions) { string resourceKey = expression.Expression.GetValue(ResourceExpression.KEY); method.Statements.Add(SetValueStatement(CodeGeneratorHelper.GetPropertyReference(expression.TargetObject), expression.TargetField, resourceReferences[resourceKey])); } Methods.Add(method); return(CodeGeneratorHelper.GetMethodReference(method)); }
private CodeMethodReferenceExpression CreateAssignTranslationMethod(List <ExpressionContainer> expressions, CodePropertyReferenceExpression localizationServiceReference) { CodeMemberMethod method = new CodeMemberMethod { Attributes = MemberAttributes.Private, Name = NameGeneratorHelper.ASSIGN_TRANSLATION_METHOD_NAME, }; foreach (ExpressionContainer expression in expressions) { CodeMethodInvokeExpression valueReference = GenerateStatementToGetTranslation(localizationServiceReference, expression.Expression); method.Statements.Add(SetValueStatement(CodeGeneratorHelper.GetPropertyReference(expression.TargetObject), expression.TargetField, valueReference)); } Methods.Add(method); return(CodeGeneratorHelper.GetMethodReference(method)); }
protected override CodePropertyReferenceExpression GetLayoutInflaterReference() { return(CodeGeneratorHelper.GetPropertyReference("LayoutInflater")); }
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); }