_GetMatchingEntriesForModule(Dictionary <string, TypeNameMatchList <DbgValueConverterInfo> > entryDict,
                                         string templateFilter,
                                         bool exactMatchOnly,
                                         bool throwIfNoResult)
            {
                if (String.IsNullOrEmpty(templateFilter))
                {
                    if (exactMatchOnly)
                    {
                        throw new ArgumentException("You asked for exact matches only, but gave no templateFilter.");
                    }

                    foreach (var tml in entryDict.Values)
                    {
                        foreach (var converter in tml)
                        {
                            yield return(converter);
                        }
                    }
                }
                else
                {
                    TypeNameMatchList <DbgValueConverterInfo> tml;
                    DbgTemplateNode crackedName = DbgTemplate.CrackTemplate(templateFilter);
                    if (!entryDict.TryGetValue(crackedName.TemplateName, out tml))
                    {
                        if (throwIfNoResult)
                        {
                            throw new DbgProviderException(Util.Sprintf("Could not find converter info matching '{0}'.",
                                                                        templateFilter),
                                                           "NoConverterForTemplateFilter",
                                                           ErrorCategory.ObjectNotFound,
                                                           templateFilter);
                        }
                    }
                    else
                    {
                        if (exactMatchOnly)
                        {
                            int count = 0;
                            foreach (var converter in tml.FindMatchingItemsExact(crackedName))
                            {
                                count++;
                                yield return(converter);
                            }
                            Util.Assert(count <= 1);   // shouldn't be able to have more than one exact match
                        }
                        else
                        {
                            foreach (var converter in tml.FindMatchingItems(crackedName))
                            {
                                yield return(converter);
                            }
                        }
                    }
                }
            } // end _GetMatchingEntriesForModule()
示例#2
0
        } // end _VerifyParamsAndBuildFullTypeName()

        public override bool Matches(DbgTemplateNode other)
        {
            // Special typename wildcard:
            if (IsEitherNameSingleTypeWildcard(other.FullName, FullName))
            {
                return(true);
            }

            if (!other.IsTemplate)
            {
                return(false);
            }

            DbgTemplate dtOther = (DbgTemplate)other;

            // TODO: PS Wildcard? Regex?
            if (0 != Util.Strcmp_OI(dtOther.TemplateName, TemplateName))
            {
                return(false);
            }

            for (int i = 0; i < dtOther.Parameters.Count; i++)
            {
                if (i >= Parameters.Count)
                {
                    return(false);
                }

                // Special typename wildcard:
                if (IsMultiMatchWildcard(dtOther.Parameters[i]))
                {
                    if (i != (dtOther.Parameters.Count - 1))
                    {
                        Util.Fail("Not reachable.");   // construction of such now disallowed.
                        throw new ArgumentException(Util.Sprintf("The '{0}' placeholder can only come last in a template parameter list.",
                                                                 c_MultiTypeWildcard),
                                                    "other");
                    }
                    break;
                }

                // Special typename wildcard:
                if (IsMultiMatchWildcard(Parameters[i]))
                {
                    if (i != (Parameters.Count - 1))
                    {
                        throw new ArgumentException(Util.Sprintf("The '{0}' placeholder can only come last in a template parameter list.",
                                                                 c_MultiTypeWildcard),
                                                    "this");
                    }

                    break;
                }

                if (!Parameters[i].Matches(dtOther.Parameters[i]))
                {
                    return(false);
                }
            }

            if ((null == NestedNode) != (null == dtOther.NestedNode))
            {
                // One has a nested node, and the other doesn't.
                return(false);
            }

            if (null != NestedNode)
            {
                return(NestedNode.Matches(dtOther.NestedNode));
            }
            else
            {
                return(true);
            }
        } // end Matches()
示例#3
0
        } // end _HasTwoColonsPreceding()

        private static bool _TryCrackTemplate(string name,
                                              int startIdx,
                                              out DbgTemplateNode templatePart,
                                              out string problem)
        {
            templatePart = null;
            problem      = null;
            name         = name.Trim();

            bool hasConst = false;

            if (name.StartsWith("const ", StringComparison.OrdinalIgnoreCase))
            {
                // I haven't actually observed any type names with "const" at the
                // beginning, but it seems like it could be possible.
                hasConst = true;
                name     = name.Substring(6).Trim();
            }
            else if (name.EndsWith(" const", StringComparison.OrdinalIgnoreCase))
            {
                hasConst = true;
                name     = name.Substring(0, name.Length - 6).Trim();
            }

            int idx;

            if (!_LooksLikeATemplateName(name, startIdx, /* angleBracketIdx */ out idx))
            {
                templatePart = new DbgTemplateLeaf(name.Substring(startIdx), hasConst);
                return(true);
            }

            var             templateName   = name.Substring(startIdx, idx - startIdx);
            StringBuilder   sb             = new StringBuilder();
            DbgTemplateNode nestedType     = null;
            int             depth          = 1;
            var             templateParams = new List <DbgTemplateNode>();

            for (idx = idx + 1; idx < name.Length; idx++)  // start after the first '<'
            {
                char c = name[idx];
                if ('<' == c)
                {
                    depth++;
                }
                else if ('>' == c)
                {
                    depth--;
                    if (depth < 0)
                    {
                        problem = Util.Sprintf("Unbalanced closing angle bracket at position {0}.", idx);
                        return(false);
                    }

                    if (0 == depth)
                    {
                        if (sb.Length > 0)
                        {
                            templateParams.Add(CrackTemplate(sb.ToString().Trim()));
                        }

                        if (idx != (name.Length - 1))
                        {
                            // TODO: '+' for nested types in managed generic types?

                            if ((name.Length < (idx + 4)) || // there has to be at least "::X"
                                (name[idx + 1] != ':') ||
                                (name[idx + 2] != ':'))
                            {
                                problem = Util.Sprintf("Unexpected characters at position {0}.", idx);
                                return(false);
                            }
                            idx += 3; // skip the "::"

                            if (!_TryCrackTemplate(name, idx, out nestedType, out problem))
                            {
                                Util.Assert(!String.IsNullOrEmpty(problem));
                                return(false);
                            }
                        }
                        break;
                    }
                }

                if (depth > 1)
                {
                    sb.Append(c);
                }
                else
                {
                    Util.Assert(1 == depth);
                    if (',' == c)
                    {
                        // TODO: Hmm... I wonder if it's possible to get a symbol with ",," (which
                        // would lead to an empty part name, which will throw).
                        templateParams.Add(CrackTemplate(sb.ToString().Trim()));
                        sb.Clear();
                    }
                    else
                    {
                        sb.Append(c);
                    }
                }
            } // end for( each character )

            templatePart = new DbgTemplate(templateName,
                                           templateParams.AsReadOnly(),
                                           nestedType,
                                           hasConst);
            return(true);
        } // end _TryCrackTemplate()