Beispiel #1
0
        } // end _TryCrackTemplate()

        /// <summary>
        ///    Converts a name into either a DbgTemplateLeaf or a DbgTemplate.
        /// </summary>
        public static DbgTemplateNode CrackTemplate(string name)
        {
            string          problem;
            DbgTemplateNode templatePart;

            if (!_TryCrackTemplate(name, 0, out templatePart, out problem))
            {
                // TODO: SQM? I think that this can only happen if there are unbalanced brackets.
                LogManager.Trace("Warning: weird type name: {0}", name);
                LogManager.Trace("Warning: Problem: {0}", problem);
                Util.Fail(Util.Sprintf("Weird type name ({0}): {1}", problem, name));
                templatePart = new DbgTemplateLeaf(name, false);
            }
            return(templatePart);
        } // end CrackTemplate()
Beispiel #2
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()