internal static bool Traverse([NotNull] this ModelConfigurationNode node, [NotNull] Expression path, [CanBeNull] ModelConfigurationNode subRoot, [CanBeNull] out ModelConfigurationNode child, bool create) { var traverseResult = ModelConfigurationTreeTraveler.Traverse(node, path, subRoot, create); child = traverseResult.Child; return(traverseResult.SubRootIsVisited); }
private List <KeyValuePair <Expression, Expression> > GetConditionalSettersInternal(Expression node, out bool onlyLeavesAreConvertible) { onlyLeavesAreConvertible = false; var traverseResult = ModelConfigurationTreeTraveler.Traverse(convertationTree, node, subRoot: null, create: false); var convertationNode = traverseResult.Child; var arrayAliases = traverseResult.ArrayAliases; if (convertationNode == null) { return(null); } var resolver = new AliasesResolver(arrayAliases); var setters = convertationNode.GetMutators().OfType <EqualsToConfiguration>().ToArray(); if (setters.Length == 0) { onlyLeavesAreConvertible = true; if (node.Type.IsArray /* || node.Type.IsDictionary()*/) { var arrays = convertationNode.GetArrays(); Expression array; if (arrays.TryGetValue(To, out array) && array != null) { var arrayItemConvertationNode = convertationNode.GotoEachArrayElement(false); if (arrayItemConvertationNode != null) { var setter = (EqualsToConfiguration)arrayItemConvertationNode.GetMutators().SingleOrDefault(mutator => mutator is EqualsToConfiguration); if (setter != null) { var convertedArray = ConvertArray(array, setter.Value.Body); return(new List <KeyValuePair <Expression, Expression> > { new KeyValuePair <Expression, Expression>(convertedArray, null) }); } } return(new List <KeyValuePair <Expression, Expression> > { new KeyValuePair <Expression, Expression>(array, null) }); } } var children = new List <ModelConfigurationNode>(); convertationNode.FindSubNodes(children); children = children.Where(child => child.GetMutators().Any(mutator => mutator is EqualsToConfiguration)).ToList(); if (children.Count > 0) { var leaves = new List <KeyValuePair <Expression, Expression> >(); foreach (var child in children) { var leaf = Perform(child.Path); if (leaf != null) { leaves.Add(new KeyValuePair <Expression, Expression>(child.Path, leaf)); } } var constructedByLeaves = ConstructByLeaves(node, leaves); if (constructedByLeaves == null) { return(null); } return(new List <KeyValuePair <Expression, Expression> > { new KeyValuePair <Expression, Expression>(constructedByLeaves, null) }); } return(null); } var result = new List <KeyValuePair <Expression, Expression> >(); bool wasUnconditionalSetter = false; for (int index = setters.Length - 1; index >= 0; --index) { var mutator = setters[index]; LambdaExpression value; Expression condition; StaticValidatorConfiguration validator; var equalsToIfConfiguration = mutator as EqualsToIfConfiguration; if (equalsToIfConfiguration == null) { if (wasUnconditionalSetter) { continue; } wasUnconditionalSetter = true; value = mutator.Value; condition = null; validator = mutator.Validator; } else { value = equalsToIfConfiguration.Value; condition = lambda.Merge(Perform(equalsToIfConfiguration.Condition)).Body; validator = equalsToIfConfiguration.Validator; } if (validator != null) { if (arrayAliases != null) { var validationResult = validator.Apply(mutator.ConverterType, arrayAliases); if (validationResult != null) { validationResult = Expression.Coalesce(validationResult, Expression.Constant(ValidationResult.Ok)); var valueIsValid = Expression.NotEqual(Expression.MakeMemberAccess(validationResult, validationResultTypeProperty), Expression.Constant(ValidationResultType.Error)); condition = condition == null ? valueIsValid : Expression.AndAlso(Convert(condition, typeof(bool)), valueIsValid).CanonizeParameters(); } } } result.Add(new KeyValuePair <Expression, Expression>(resolver.Visit(lambda.Merge(Perform(value)).Body), resolver.Visit(condition))); } return(result); }
public static ModelConfigurationNode Traverse([NotNull] this ModelConfigurationNode node, [NotNull] Expression path, bool create) { return(ModelConfigurationTreeTraveler.Traverse(node, path, subRoot: null, create: create).Child); }