/// <summary> /// Parses given ASP .NET resource expression, returning result item /// </summary> public IList ParseResourceExpression(string text, BlockSpan blockSpan, LANGUAGE language) { if (text == null) { throw new ArgumentNullException("text"); } if (blockSpan == null) { throw new ArgumentNullException("blockSpan"); } List <AspNetCodeReferenceResultItem> list = new List <AspNetCodeReferenceResultItem>(); // test if is valid resource expression string regex = @"\s*(" + StringConstants.GlobalWebSiteResourcesNamespace + @")\s*:\s*(\w+)\s*,\s*(\w+)\s*"; Match match = Regex.Match(text, regex); if (!match.Success || match.Groups.Count != 4) { return(list); } string prefix = StringConstants.GlobalWebSiteResourcesNamespace; string className = match.Groups[2].Value; string key = match.Groups[3].Value; // create standard reference from the class name and key string reference = string.Format("{0}.{1}", className, key); // run trie lookup on standard reference Trie <CodeReferenceTrieElement> trie = GetActualTrie(); CodeReferenceTrieElement e = trie.Root; foreach (char c in reference) { e = trie.Step(e, c); } if (!e.IsTerminal) { return(list); // no result was found, return empty list } // select culture neutral result item CodeReferenceInfo info = null; foreach (var nfo in e.Infos) { if (nfo.Origin.Namespace == prefix) { if (info == null || info.Origin.IsCultureSpecific()) { info = nfo; } } } if (info == null) { return(list); // no result was found, return empty list } int startLineOffset, startIndex; GetLineOffset(text, match.Groups[1].Index, out startLineOffset, out startIndex); int endLineOffset, endIndex; GetLineOffset(text, match.Groups[3].Index + match.Groups[3].Length, out endLineOffset, out endIndex); // build result item AspNetCodeReferenceResultItem resultItem = new AspNetCodeReferenceResultItem(); TextSpan span = new TextSpan(); span.iStartLine = blockSpan.StartLine + startLineOffset; span.iStartIndex = startLineOffset == 0 ? blockSpan.StartIndex + startIndex : startIndex; span.iEndLine = blockSpan.StartLine + endLineOffset; span.iEndIndex = endLineOffset == 0 ? blockSpan.StartIndex + endIndex : endIndex; resultItem.Value = info.Value; resultItem.SourceItem = currentlyProcessedItem; resultItem.ReplaceSpan = span; resultItem.AbsoluteCharOffset = blockSpan.AbsoluteCharOffset + match.Groups[1].Index; resultItem.AbsoluteCharLength = match.Groups[3].Index + match.Groups[3].Length - match.Groups[1].Index; resultItem.DestinationItem = info.Origin; resultItem.FullReferenceText = string.Format("{0}.{1}.{2}", info.Origin.Namespace, info.Origin.Class, key); resultItem.IsWithinLocalizableFalse = false; resultItem.Key = key; resultItem.OriginalReferenceText = string.Format("{0}:{1},{2}", info.Origin.Namespace, info.Origin.Class, key); resultItem.ComesFromWebSiteResourceReference = true; resultItem.Language = language; list.Add(resultItem); Results.Add(resultItem); return(list); }
/// <summary> /// Generic test method /// </summary> /// <param name="openFiles">True if the files should be opened first</param> /// <param name="fullName">True if the "Use full names" policy should be applied</param> /// <param name="mark">True if the "Mark with VL_NO_LOC policy should be applied"</param> /// <param name="testFiles">Files to test</param> /// <param name="targetFiles">ResX files where resources can be moved</param> private void InternalFileMoveTest(bool openFiles, bool fullName, bool mark, string[] testFiles, string[] targetFiles) { // backup the files Dictionary <string, string> backups = CreateBackupsOf(testFiles); // run the "batch move" command to get result items List <CodeStringResultItem> items = BatchMoveLookup(testFiles); // open the necessary files SetFilesOpened(testFiles, openFiles); // initialize ResX destination files Dictionary <string, ResXProjectItem> resxItems = InitResxItems(targetFiles, Agent.GetDTE().Solution.FindProjectItem(testFiles[0]).ContainingProject); // initialize the "batch move" tool window and grid Dictionary <ResXProjectItem, int> resxCounts; Dictionary <ProjectItem, int> sourceItemCounts; int expectedToBeMarked; BatchMoveToResourcesToolWindow_Accessor window = InitBatchToolWindow(resxItems.Values.ToList(), items, fullName, mark, out resxCounts, out sourceItemCounts, out expectedToBeMarked); try { // execute window.RunClick(null, null); VLDocumentViewsManager.CloseInvisibleWindows(typeof(BatchMoveCommand), false); // verify every ResX file contains the correct number of resources foreach (ResXProjectItem target in resxItems.Values) { Assert.AreEqual(resxCounts.ContainsKey(target) ? resxCounts[target] : 0, GetResourcesCountIn(target)); } // run the "inline" command to verify all references are valid int checkedCount = resxCounts.Sum((pair) => { return(pair.Value); }); List <CodeReferenceResultItem> inlineResults = BatchInlineLookup(testFiles); VLDocumentViewsManager.CloseInvisibleWindows(typeof(BatchInlineCommand), false); Assert.AreEqual(checkedCount, inlineResults.Count); // test if every unchecked string result item was marked if (mark) { int markedAfter = BatchMoveLookup(testFiles).Count((item) => { return(item.IsMarkedWithUnlocalizableComment); }); VLDocumentViewsManager.CloseInvisibleWindows(typeof(BatchMoveCommand), false); Assert.AreEqual(expectedToBeMarked, markedAfter, "mark"); } // test if qualified name was really used if (fullName) { foreach (var result in inlineResults) { AspNetCodeReferenceResultItem citem = result as AspNetCodeReferenceResultItem; if (citem == null || !citem.ComesFromWebSiteResourceReference) { Assert.AreEqual(result.OriginalReferenceText, result.FullReferenceText); } } } // check if no import statement has been added twice foreach (string path in testFiles) { CheckForDuplicateUsings(path); } if (openFiles) { // use undo manager to revert the changes foreach (string file in testFiles) { var win = VsShellUtilities.GetWindowObject(VLDocumentViewsManager.GetWindowFrameForFile(file, false)); ProjectItem pitem = Agent.GetDTE().Solution.FindProjectItem(file); int count = sourceItemCounts.ContainsKey(pitem) ? sourceItemCounts[pitem] : 0; IOleUndoManager manager; VLDocumentViewsManager.GetTextLinesForFile(file, false).GetUndoManager(out manager); List <IOleUndoUnit> list = manager.RemoveTopFromUndoStack(count); foreach (AbstractUndoUnit unit in list) { unit.Undo(); } Assert.AreEqual(File.ReadAllText(backups[file]), File.ReadAllText(file)); } // check that all changes were fully reverted int sum = resxItems.Values.Sum((item) => { return(GetResourcesCountIn(item)); }); Assert.AreEqual(0, sum); } } finally { // close the files SetFilesOpened(testFiles, false); // restore the backups RestoreBackups(backups); // clear ResX files foreach (ResXProjectItem target in resxItems.Values) { ClearFile(target); } VLDocumentViewsManager.CloseInvisibleWindows(typeof(BatchMoveCommand), false); } }
/// <summary> /// Compares expected and actual result item /// </summary> internal static void ValidateItems(AbstractResultItem a, AbstractResultItem b) { if (b is NetStringResultItem) { NetStringResultItem an = a as NetStringResultItem; NetStringResultItem bn = b as NetStringResultItem; Assert.AreEqual(an.VariableElementName, bn.VariableElementName, "Variable names are not equal, " + a.Value); Assert.AreEqual(an.MethodElementName, bn.MethodElementName, "Method names are not equal, " + a.Value); } if (b is CSharpStringResultItem) { TestCSharpStringResultItem an = a as TestCSharpStringResultItem; CSharpStringResultItem bn = b as CSharpStringResultItem; if (an.NamespaceElementName == null) { Assert.IsNull(bn.NamespaceElement, "Namespace null, " + a.Value); } else { Assert.AreEqual(an.NamespaceElementName, bn.NamespaceElement.FullName, "Namespace names are not equal, " + a.Value); } } if (b is VBStringResultItem) { TestVBStringResultItem an = a as TestVBStringResultItem; VBStringResultItem bn = b as VBStringResultItem; if (an.NamespaceElementName == null) { Assert.IsNull(bn.NamespaceElement, "Namespace null, " + a.Value); } else { Assert.AreEqual(an.NamespaceElementName, bn.NamespaceElement.FullName, "Namespace names are not equal, " + a.Value); } } if (b is AspNetStringResultItem) { TestAspNetStringResultItem an = a as TestAspNetStringResultItem; AspNetStringResultItem bn = b as AspNetStringResultItem; Assert.AreEqual(an.ComesFromClientComment, bn.ComesFromClientComment, "ComesFromClientComment are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.ComesFromCodeBlock, bn.ComesFromCodeBlock, "ComesFromCodeBlock are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.ComesFromDirective, bn.ComesFromDirective, "ComesFromDirective are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.ComesFromElement, bn.ComesFromElement, "ComesFromElement are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.ComesFromInlineExpression, bn.ComesFromInlineExpression, "ComesFromInlineExpression are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.ComesFromPlainText, bn.ComesFromPlainText, "ComesFromPlainText are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.ElementName, bn.ElementName, "ElementName are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.ElementPrefix, bn.ElementPrefix, "ElementPrefix are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.LocalizabilityProved, bn.LocalizabilityProved, "LocalizabilityProved are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.Language, bn.Language, "Language are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); } if (b is CodeStringResultItem) { CodeStringResultItem an = a as CodeStringResultItem; CodeStringResultItem bn = b as CodeStringResultItem; Assert.AreEqual(an.WasVerbatim, bn.WasVerbatim, "Verbatim options are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.ClassOrStructElementName, bn.ClassOrStructElementName, "Class names are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); } if (b is CodeReferenceResultItem) { CodeReferenceResultItem an = a as CodeReferenceResultItem; CodeReferenceResultItem bn = b as CodeReferenceResultItem; Assert.AreEqual(an.FullReferenceText, bn.FullReferenceText, "FullReferenceText are not equal" + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.OriginalReferenceText, bn.OriginalReferenceText, "OriginalReferenceText are not equal" + " on line " + a.ReplaceSpan.iStartLine); } if (b is AspNetCodeReferenceResultItem) { AspNetCodeReferenceResultItem an = a as AspNetCodeReferenceResultItem; AspNetCodeReferenceResultItem bn = b as AspNetCodeReferenceResultItem; Assert.AreEqual(an.ComesFromInlineExpression, bn.ComesFromInlineExpression, "ComesFromInlineExpression are not equal" + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.ComesFromWebSiteResourceReference, bn.ComesFromWebSiteResourceReference, "ComesFromWebSiteResourceReference are not equal" + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.Language, bn.Language, "Language are not equal" + " on line " + a.ReplaceSpan.iStartLine); if (an.ComesFromInlineExpression) { Assert.IsNotNull(an.InlineReplaceSpan); Assert.IsNotNull(bn.InlineReplaceSpan); Assert.AreEqual(an.InlineReplaceSpan.StartLine, bn.InlineReplaceSpan.StartLine, "StartLine are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.InlineReplaceSpan.StartIndex, bn.InlineReplaceSpan.StartIndex, "StartIndex are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.InlineReplaceSpan.EndLine, bn.InlineReplaceSpan.EndLine, "EndLine are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.InlineReplaceSpan.EndIndex, bn.InlineReplaceSpan.EndIndex, "EndIndex are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.InlineReplaceSpan.AbsoluteCharOffset, bn.InlineReplaceSpan.AbsoluteCharOffset, "Offsets are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(an.InlineReplaceSpan.AbsoluteCharLength, bn.InlineReplaceSpan.AbsoluteCharLength, "AbsoluteLengths are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); } else { Assert.IsNull(an.InlineReplaceSpan); Assert.IsNull(bn.InlineReplaceSpan); } } Assert.AreEqual(a.Value, b.Value, "Values are not equal on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(a.SourceItem, b.SourceItem, "Source items are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(a.IsWithinLocalizableFalse, b.IsWithinLocalizableFalse, "[Localizable(false)] options are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(a.IsMarkedWithUnlocalizableComment, b.IsMarkedWithUnlocalizableComment, "/*VL_NO_LOC*/ options are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(a.ComesFromDesignerFile, b.ComesFromDesignerFile, "Designer file options are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.IsNotNull(a.ReplaceSpan); Assert.IsNotNull(b.ReplaceSpan); Assert.AreEqual(a.ReplaceSpan.iStartLine, b.ReplaceSpan.iStartLine, "iStartLine are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(a.ReplaceSpan.iStartIndex, b.ReplaceSpan.iStartIndex, "iStartIndex are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(a.ReplaceSpan.iEndLine, b.ReplaceSpan.iEndLine, "iEndLine are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(a.ReplaceSpan.iEndIndex, b.ReplaceSpan.iEndIndex, "iEndIndex are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(a.AbsoluteCharOffset, b.AbsoluteCharOffset, "Offsets are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(a.AbsoluteCharLength, b.AbsoluteCharLength, "AbsoluteLengths are not equal, " + a.Value + " on line " + a.ReplaceSpan.iStartLine); Assert.AreEqual(a.IsConst, b.IsConst, "IsConst are not equal on line " + a.ReplaceSpan.iStartLine); }