Exemplo n.º 1
0
        INsNode GetNode(TypeMapping mapping)
        {
            return(_ns.GetOrAddNode(mapping, tm =>
            {
                var source = tm.Source;
                var uniqueInScopeOldName = tm.UniqueName;
                var toMangle = _options.Type & ~_ns.Preserved(tm) & MetaType.NamespaceAndType;
                var preserveType = (toMangle & MetaType.Type) == 0;
                var preserveNs = (toMangle & MetaType.Namespace) == 0;
                INsNode scope;
                if (source.DeclaringType != null)
                {
                    var parent = GetNode(Context.MappedTypes[source.DeclaringType.CreateKey()]);
                    scope = GetNode(parent, tm, uniqueInScopeOldName, preserveType);
                }
                else
                {
                    INsNode node = _root;
                    if (preserveNs)
                    {
                        node = GetNode(node, null, tm.Source.Namespace, true);
                    }
                    else
                    {
                        var nsfolding = _options.NamespaceMangling;
                        switch (nsfolding)
                        {
                        // root -> types
                        case NamespaceMangling.Empty:
                            if (preserveType)
                            {
                                if (node.MembersByNewName.ContainsKey(uniqueInScopeOldName))
                                {
                                    goto case NamespaceMangling.Fold;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            if (tm.Source.Namespace.Length > 0)
                            {
                                // this will serve as a key only to prevent duplicates, it will be replaced by mangled name
                                uniqueInScopeOldName = tm.Source.Namespace + "." + uniqueInScopeOldName;
                            }
                            break;

                        // root -> namespaces -> types
                        case NamespaceMangling.Fold:
                            node = GetNode(node, null, tm.Source.Namespace);
                            break;

                        // root -> namespaces[0] -> namespaces[1] -> namespaces[...n] -> types
                        case NamespaceMangling.Parts:
                            foreach (var part in tm.Source.Namespace.ToString().Split('.'))
                            {
                                node = GetNode(node, null, part);
                            }
                            break;

                        case NamespaceMangling.Distribute:
                            node = (INsNode)node.Members.RandomElementOrDefault(_rng);
                            goto case NamespaceMangling.Empty;
                        }

                        if (tm.Target.Namespace != node.FullNewName)
                        {
                            tm.Target.Namespace = node.FullNewName;
                        }
                    }

                    scope = GetNode(node, tm, uniqueInScopeOldName, preserveType);
                }

                if (tm.Target.Name != scope.NewName)
                {
                    tm.Target.Name = scope.NewName;
                }
                return scope;
            }));
        }