Example #1
0
        private static void ExtractAliases(ModelConfigurationNode node, CompositionPerformer performer, List <KeyValuePair <Expression, Expression> > aliases)
        {
            if (node.GetMutators().Any())
            {
                var conditionalSetters = performer.GetConditionalSetters(node.Path);
                if (conditionalSetters != null && conditionalSetters.Count == 1)
                {
                    var setter = conditionalSetters.Single();
                    if (setter.Value == null)
                    {
                        var chains = setter.Key.CutToChains(true, true);
                        if (chains.Length == 1)
                        {
                            var chain = chains.Single();
                            aliases.Add(new KeyValuePair <Expression, Expression>(node.Path, chain));
                            if (IsEachOrCurrent(node.Path))
                            {
                                aliases.Add(new KeyValuePair <Expression, Expression>(Expression.Call(MutatorsHelperFunctions.CurrentIndexMethod.MakeGenericMethod(node.Path.Type), node.Path), Expression.Call(MutatorsHelperFunctions.CurrentIndexMethod.MakeGenericMethod(chain.Type), chain)));
                            }
                        }
                    }
                }
            }
            else if (IsEachOrCurrent(node.Path))
            {
                var conditionalSetters = performer.GetConditionalSetters(((MethodCallExpression)node.Path).Arguments.Single());
                if (conditionalSetters != null && conditionalSetters.Count == 1)
                {
                    var setter = conditionalSetters.Single();
                    if (setter.Value == null)
                    {
                        var chains = setter.Key.CutToChains(true, true);
                        if (chains.Length == 1)
                        {
                            var chain = chains.Single();
                            chain = Expression.Call(MutatorsHelperFunctions.CurrentMethod.MakeGenericMethod(chain.Type.GetItemType()), chain);
                            aliases.Add(new KeyValuePair <Expression, Expression>(Expression.Call(MutatorsHelperFunctions.CurrentIndexMethod.MakeGenericMethod(node.Path.Type), node.Path), Expression.Call(MutatorsHelperFunctions.CurrentIndexMethod.MakeGenericMethod(chain.Type), chain)));
                        }
                    }
                }
            }

            foreach (var child in node.Children)
            {
                ExtractAliases(child, performer, aliases);
            }
        }
Example #2
0
        private static void MigrateNode(this ModelConfigurationNode node, Type to, ModelConfigurationNode destTree, ModelConfigurationNode convertationRoot, Expression path)
        {
            var performer  = new CompositionPerformer(node.RootType, to, convertationRoot);
            var parameters = new List <PathPrefix> {
                new PathPrefix(path, path.ExtractParameters().Single())
            };
            var abstractPathResolver = new AbstractPathResolver(parameters, false);

            foreach (var mutator in node.Mutators)
            {
                var mutatedMutator = mutator.Value.Mutate(to, path, performer);
                if (mutatedMutator == null)
                {
                    continue;
                }
                var resolvedKey        = abstractPathResolver.Resolve(mutator.Key);
                var conditionalSetters = performer.GetConditionalSetters(resolvedKey);
                if (conditionalSetters != null)
                {
                    Qxx(destTree, conditionalSetters, mutatedMutator, performer, resolvedKey);
                }
                else
                {
                    Expression mutatedPath = Expression.Constant(null);
                    if (resolvedKey.NodeType == ExpressionType.NewArrayInit && resolvedKey.Type == typeof(object[]))
                    {
                        var paths = new List <Expression>();
                        // Mutator is set to a number of nodes
                        foreach (var item in ((NewArrayExpression)resolvedKey).Expressions)
                        {
                            var mutatedItem = performer.Perform(item);
                            if (mutatedItem.NodeType != ExpressionType.Constant || ((ConstantExpression)mutatedItem).Value != null)
                            {
                                paths.Add(mutatedItem);
                            }
                            else
                            {
                                // Mutator is set to a node that is either not a leaf or a leaf that is not convertible
                                var primaryDependencies = Expression.Lambda(item, item.ExtractParameters()).ExtractPrimaryDependencies().Select(lambda => lambda.Body).ToArray();
                                if (primaryDependencies.Length > 1)
                                {
                                    throw new NotSupportedException("More than one primary dependency is not supported while migrating a mutator from a non-leaf node");
                                }
                                var subRoot = convertationRoot.Traverse(primaryDependencies[0], false);
                                if (subRoot != null)
                                {
                                    var keyLeaf = subRoot.FindKeyLeaf();
                                    if (keyLeaf != null)
                                    {
                                        var keyLeafPath = abstractPathResolver.Resolve(keyLeaf.Path);
                                        conditionalSetters = performer.GetConditionalSetters(keyLeafPath);
                                        if (conditionalSetters != null)
                                        {
                                            paths.Add(performer.Perform(keyLeafPath));
                                            continue;
                                        }
                                    }

                                    // The key leaf is missing or is not convertible - list all convertible subnodes
                                    var subNodes = new List <ModelConfigurationNode>();
                                    subRoot.FindSubNodes(subNodes);
                                    paths.AddRange(subNodes.Select(subNode => performer.Perform(abstractPathResolver.Resolve(subNode.Path))));
                                }
                            }
                        }

                        if (paths.Count > 0)
                        {
                            mutatedPath = Expression.NewArrayInit(typeof(object), paths.Select(exp => Expression.Convert(exp, typeof(object))));
                        }
                    }
                    else
                    {
                        mutatedPath = performer.Perform(resolvedKey);
                        if (mutatedPath.NodeType == ExpressionType.Constant && ((ConstantExpression)mutatedPath).Value == null)
                        {
                            // Mutator is set to a node that is either not a leaf or a leaf that is not convertible
                            var primaryDependencies = Expression.Lambda(resolvedKey, resolvedKey.ExtractParameters()).ExtractPrimaryDependencies().Select(lambda => lambda.Body).ToArray();
                            if (primaryDependencies.Length > 1)
                            {
                                throw new NotSupportedException("More than one primary dependency is not supported while migrating a mutator from a non-leaf node");
                            }
                            if (primaryDependencies.Length > 0)
                            {
                                var subRoot = convertationRoot.Traverse(primaryDependencies[0], false);
                                if (subRoot != null)
                                {
                                    var keyLeaf = subRoot.FindKeyLeaf();
                                    if (keyLeaf != null)
                                    {
                                        conditionalSetters = performer.GetConditionalSetters(abstractPathResolver.Resolve(keyLeaf.Path));
                                    }
                                    if (conditionalSetters != null)
                                    {
                                        Qxx(destTree, conditionalSetters, mutatedMutator, performer, resolvedKey);
                                        continue;
                                    }

                                    // The key leaf is missing or is not convertible - list all convertible subnodes
                                    var subNodes = new List <ModelConfigurationNode>();
                                    subRoot.FindSubNodes(subNodes);
                                    mutatedPath = Expression.NewArrayInit(typeof(object), subNodes.Select(subNode => Expression.Convert(performer.Perform(abstractPathResolver.Resolve(subNode.Path)), typeof(object))));
                                }
                            }
                        }
                    }

                    var commonPath = Expression.Lambda(mutatedPath, mutatedPath.ExtractParameters()).ExtractPrimaryDependencies().Select(lambda => lambda.Body).FindLCP();
                    var destNode   = commonPath == null ? destTree : destTree.Traverse(commonPath, true);
                    destNode.mutators.Add(new KeyValuePair <Expression, MutatorConfiguration>(mutatedPath, mutatedMutator));
                }
            }
        }