/// <summary> /// Selects that code reference from given list of options, that best matches given namespace. /// </summary> protected virtual CodeReferenceInfo GetInfoWithNamespace(List <CodeReferenceInfo> list, string nmspc) { CodeReferenceInfo nfo = null; foreach (var item in list) { if (item.Origin.Namespace == nmspc) { if (prefferedResXItem != null) { if (nfo == null || prefferedResXItem == item.Origin) { nfo = item; } } else { if (nfo == null || nfo.Origin.IsCultureSpecific()) { nfo = item; } } } } return(nfo); }
/// <summary> /// Attempts to determine which resource key the reference points to /// </summary> protected override CodeReferenceInfo ResolveReference(string prefix, string className, List <CodeReferenceInfo> trieElementInfos) { CodeReferenceInfo info = null; // prepend "My" with root namespace string newPrefix = null; if (prefix != null) { int myIndex = prefix.IndexOf("My"); if (myIndex != -1 && (myIndex + 2 == prefix.Length || prefix[myIndex + 2] == '.')) { newPrefix = prefix.Replace("My", Project.GetRootNamespace() + ".My"); } } // try various combinations to lookup the reference info = TryResolve(prefix, className, trieElementInfos); if (info == null && !string.IsNullOrEmpty(prefix)) { info = TryResolve(prefix + "." + className, className, trieElementInfos); } if (info == null && newPrefix != null) { info = TryResolve(newPrefix, className, trieElementInfos); } if (info == null && string.IsNullOrEmpty(prefix)) { info = TryResolve(className, className, trieElementInfos); } if (info == null && newPrefix != null) { info = TryResolve(newPrefix + "." + className, className, trieElementInfos); } return(info); }
/// <summary> /// Resolves given reference to a resource to a qualified name /// </summary> /// <param name="prefix">Namespace in the reference</param> /// <param name="className">Class in the reference</param> /// <param name="trieElementInfos">List of resource files entries - possible targets of this reference</param> /// <returns>Resolved reference</returns> protected CodeReferenceInfo TryResolve(string prefix, string className, List <CodeReferenceInfo> trieElementInfos) { CodeReferenceInfo info = null; if (string.IsNullOrEmpty(prefix)) // no namespace // get namespace where this class belongs { UsedNamespaceItem item = UsedNamespaces.ResolveNewReference(className, Project); if (item != null) // namespace found { info = GetInfoWithNamespace(trieElementInfos, item.Namespace); } } else { string aliasNamespace = UsedNamespaces.GetNamespace(prefix); // suppose prefix is alias - try get actual namespace if (!string.IsNullOrEmpty(aliasNamespace)) // really, it was just alias { info = GetInfoWithNamespace(trieElementInfos, aliasNamespace); } else // no, it was full name of namespace { info = GetInfoWithNamespace(trieElementInfos, prefix); if (info == null) // try adding prefix to the class name - in case prefix is just part of namespace { UsedNamespaceItem item = UsedNamespaces.ResolveNewReference(prefix + "." + className, Project); if (item != null) { info = GetInfoWithNamespace(trieElementInfos, item.Namespace + "." + prefix); } } } } return(info); }
/// <summary> /// Adds reference to a resource result item to the list /// </summary> /// <param name="list">Result list</param> /// <param name="referenceText">Full text of the reference</param> /// <param name="trieElementInfos">Info about reference, taken from terminal state of the trie</param> /// <returns>New result item</returns> protected virtual T AddReferenceResult(List <T> list, string referenceText, List <CodeReferenceInfo> trieElementInfos) { string[] t = referenceText.Split('.'); if (t.Length < 2) { throw new Exception("Code parse error - invalid token " + referenceText); } string referenceClass; string prefix; string key; if (t.Length == 2) // reference has format Class.key { key = t[1]; // get key referenceClass = t[0]; // get class prefix = null; // no preceding namespace } else // reference looks like Namespace.Class.key { key = t[t.Length - 1]; // get key referenceClass = t[t.Length - 2]; // get class prefix = string.Join(".", t, 0, t.Length - 2); // the rest is namespace } CodeReferenceInfo info = ResolveReference(prefix, referenceClass, trieElementInfos); if (info != null) { // calculate position of the reference TextSpan span = new TextSpan(); span.iStartLine = ReferenceStartLine - 1; span.iStartIndex = ReferenceStartIndex; span.iEndLine = CurrentLine - 1; span.iEndIndex = CurrentIndex + 1; // generate new result item var resultItem = new T(); resultItem.Value = info.Value; resultItem.SourceItem = this.SourceItem; resultItem.ReplaceSpan = span; resultItem.AbsoluteCharOffset = ReferenceStartOffset; resultItem.AbsoluteCharLength = CurrentAbsoluteOffset - ReferenceStartOffset + 1; resultItem.DestinationItem = info.Origin; resultItem.IsWithinLocalizableFalse = IsWithinLocFalse; resultItem.Key = info.Key; CodeReferenceResultItem refItem = (resultItem as CodeReferenceResultItem); refItem.FullReferenceText = string.Format("{0}.{1}.{2}", info.Origin.Namespace, info.Origin.Class, key); if (string.IsNullOrEmpty(prefix)) { refItem.OriginalReferenceText = string.Format("{0}.{1}", referenceClass, key); } else { refItem.OriginalReferenceText = string.Format("{0}.{1}.{2}", prefix, referenceClass, key); } list.Add(resultItem); return(resultItem); } else { return(null); } }