_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()
} // 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()
} // 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()