コード例 #1
0
        public void PerformanceTest()
        {
            const string codeFile = @"D:\Projects\AgentRalph.hg\Ralph.Test.Project\Ralph.Test.Project\Menus.cs";
            string       codeText = File.ReadAllText(codeFile);

            IParser parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(codeText));

            parser.Parse();

            if (parser.Errors.Count > 0)
            {
                throw new ApplicationException(string.Format("Expected no errors in the input code. Code was: {0} ErrorOutput: {1}", codeText,
                                                             parser.Errors.ErrorOutput));
            }

            MethodsOnASingleClassCloneFinder cloneFinder = new MethodsOnASingleClassCloneFinder(new OscillatingExtractMethodExpansionFactory());

            cloneFinder.AddRefactoring(new LiteralToParameterExpansion());

            var replacements = cloneFinder.GetCloneReplacements(parser.CompilationUnit);

            TestLog.EmbedPlainText(replacements.Clones.Count + " clones found.");
            foreach (var clone in replacements.Clones)
            {
                TestLog.EmbedPlainText(string.Format("{0}-{1}: {2}", clone.ReplacementSectionStartLine, clone.ReplacementSectionEndLine, clone.TextForACallToJanga));
            }
        }
コード例 #2
0
        private ScanResult FindThemClones(string codeText)
        {
            CloneFinder = new MethodsOnASingleClassCloneFinder(new OscillatingExtractMethodExpansionFactory());
            CloneFinder.AddRefactoring(new LiteralToParameterExpansion());

            return(CloneFinder.GetCloneReplacements(codeText));
        }
コード例 #3
0
        public void PerfTest()
        {
            // The big method in this file has 263 children which translates to > 13000 permutations.  And we do it 4 times.
            string codeText = File.ReadAllText(@"..\..\SharpRefactoring\Src\CSharpMethodExtractor.cs");

            var files = Directory.GetFiles(@"..\..", "*.cs", SearchOption.AllDirectories);

            using (ProgressForm form = new ProgressForm())
            {
                form.Show();

                foreach (var file in files)
                {
                    form.Text = Path.GetFileName(file);

                    codeText = File.ReadAllText(file);

                    MethodsOnASingleClassCloneFinder finder = new MethodsOnASingleClassCloneFinder(new OscillatingExtractMethodExpansionFactory());
                    finder.AddRefactoring(new LiteralToParameterExpansion());

                    finder.MethodStart    += form.OnMethodStart;
                    finder.MethodProgress += form.OnMethodProgress;

                    finder.GetCloneReplacements(codeText);

                    finder.MethodStart    -= form.OnMethodStart;
                    finder.MethodProgress -= form.OnMethodProgress;
                }
            }


//            var replacements = cloneFinder.GetCloneReplacements(codeText);
//            Console.WriteLine(replacements.Clones.Count + " clones found.");
        }
コード例 #4
0
        public void Execute(Action <DaemonStageResult> commiter)
        {
            try
            {
                // GetText gives the unsaved file contents, unlike file.ProjectFile.GetReadStream().
                string codeText = myDaemonProcess.Document.GetText();

                // I do not remember anymore why I created the Shallow version...
                var cloneFinder = new MethodsOnASingleClassCloneFinder(new ShallowExpansionFactory());
                //var cloneFinder = new MethodsOnASingleClassCloneFinder(new OscillatingExtractMethodExpansionFactory());

                cloneFinder.AddRefactoring(new LiteralToParameterExpansion());

                ScanResult scan_result = cloneFinder.GetCloneReplacements(codeText);
                if (scan_result != null)
                {
                    var document = myDaemonProcess.SourceFile.Document;

                    var Highlightings = new List <HighlightingInfo>();

                    foreach (var info in scan_result.Clones)
                    {
                        // We basically highlight the first line of the clone.
                        var start = document.GetLineStartOffset(((Int32 <DocLine>)(info.HighlightStartLocationLine - 1))) + info.HighlightStartLocationColumn;
                        var end   = start + info.HighlightLength;// Hmm, HighlightLength seems sort of arbitrary.
                        var warningHighlightRange = new DocumentRange(document, new TextRange(start, end));

                        // And this defines the chunk that gets replaced.
                        var replacedCodeRange = new DocumentRange(document,
                                                                  new TextRange(
                                                                      document.GetLineStartOffset(
                                                                          (Int32 <DocLine>)
                                                                              (info.ReplacementSectionStartLine - 1)),
                                                                      document.GetLineStartOffset(
                                                                          (Int32 <DocLine>)
                                                                          info.ReplacementSectionEndLine)));



                        var highlight = new HighlightingInfo(warningHighlightRange,
                                                             new CloneDetectionHighlighting(info, replacedCodeRange));
                        Highlightings.Add(highlight);
                    }

                    // Creating container to put highlightings into.
                    DaemonStageResult ret = new DaemonStageResult(Highlightings);

                    commiter(ret);
                }
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.Write(e);
                throw;
            }
        }
コード例 #5
0
        private void TestCloneReplacementInvocation(string codeText, string expected_code)
        {
            var cloneFinder = new MethodsOnASingleClassCloneFinder(new OscillatingExtractMethodExpansionFactory());

            cloneFinder.AddRefactoring(new LiteralToParameterExpansion());
            ScanResult sr = cloneFinder.GetCloneReplacements(codeText);

            Assert.AreEqual(1, sr.Clones.Count, "Expected exactly one clone to be found.");
            Console.WriteLine(sr.Clones[0]);
            var c             = sr.Clones[0];
            var expected_call = ParseUtilCSharp.ParseStatement <Statement>(expected_code);
            var actual_cal    = ParseUtilCSharp.ParseStatement <Statement>(c.TextForACallToJanga);

            Assert.IsTrue(expected_call.MatchesPrint(actual_cal), "Expected Call: " + expected_call.Print() + "\n" + "Actual Call: " + actual_cal.Print());
        }
コード例 #6
0
        public void ExerciseOnExtractedCandidateEvent()
        {
            const string codeText = @"    
                                public class CloneInDoWhileBlock
                                {
                                    void Foo()
                                    {
                                        do
                                        {
                                            int i = 7 + 8;
                                            int j = 9 +10;
                                            Console.WriteLine(i + j);

                                            /* BEGIN */
                                            Console.WriteLine(7);
                                            /* END */
                                        }
                                        while (DateTime.Now < DateTime.Today);
                                    }

                                    private void Bar()
                                    {
                                        Console.WriteLine(7);
                                        Console.WriteLine(7);
                                        Console.WriteLine(7);
                                    }
                                }";

            MethodsOnASingleClassCloneFinder finder = new MethodsOnASingleClassCloneFinder(new OscillatingExtractMethodExpansionFactory());

            CloneDesc largest = null;

            finder.OnExtractedCandidate += ((sender, args) =>
            {
                TestLog.EmbedPlainText("Each: ", args.Candidate.PermutatedMethod.Print());

                if (largest == null || largest.PermutatedMethod.CountNodes() < args.Candidate.PermutatedMethod.CountNodes())
                {
                    largest = args.Candidate;
                }
            });

            finder.GetCloneReplacements(codeText);

            TestLog.EmbedPlainText("The largest:", largest.PermutatedMethod.Print());
        }
コード例 #7
0
        public void EmptyMethodsDoNotCauseExceptionNorMatch()
        {
            var codeText = @"    
                class EmptyMethods
                {
                    public void Foo() { }
                    public void Bar() { }
                }";

            var factory     = new ShallowExpansionFactory();
            var clonefinder = new MethodsOnASingleClassCloneFinder(factory);

            clonefinder.AddRefactoring(new LiteralToParameterExpansion());

            var scanResult = clonefinder.GetCloneReplacements(codeText);

            Assert.That(scanResult.Clones.Count, Is.EqualTo(0), "Empty methods should not match.");
        }
コード例 #8
0
        public void DoCloneDetection(string codefile, MethodsOnASingleClassCloneFinder cloneFinder)
        {
            string codeText = File.ReadAllText(codefile);

            TestLog.EmbedPlainText("The Code", codeText);

//            System.Diagnostics.Debugger.Break();

            IParser parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(codeText));

            parser.Parse();

            if (parser.Errors.Count > 0)
            {
                throw new ApplicationException(string.Format("Expected no errors in the input code. Code was: {0} ErrorOutput: {1}", codeText,
                                                             parser.Errors.ErrorOutput));
            }

            var comments = parser.Lexer.SpecialTracker.RetrieveSpecials().OfType <Comment>();

            if (comments.Any(x => x.CommentText.TrimStart().StartsWith("Ignore")))
            {
                throw new ApplicationException("Ignored.");
            }

            var begin_comment = comments.FirstOrDefault(x => x.CommentText.Contains("BEGIN"));
            var end_comment   = comments.FirstOrDefault(x => x.CommentText.Contains("END"));

            if (begin_comment == null)
            {
                throw new ApplicationException("There was no comment containing the BEGIN keyword.");
            }
            if (end_comment == null)
            {
                throw new ApplicationException("There was no comment containing the END keyword.");
            }

            CloneDesc largest = null;

            cloneFinder.OnExtractedCandidate += (finder, args) =>
            {
                if (largest == null)
                {
                    largest = args.Candidate;
                }
                else if (args.Candidate.ReplacementInvocationInfo.ReplacementSectionStartLine >= begin_comment.StartPosition.Line &&
                         args.Candidate.ReplacementInvocationInfo.ReplacementSectionEndLine <= end_comment.EndPosition.Line &&
                         args.Candidate.PermutatedMethod.CountNodes() > largest.PermutatedMethod.CountNodes())
                {
                    largest = args.Candidate;
                }
            };


            var replacements = cloneFinder.GetCloneReplacements(parser.CompilationUnit);

            int clone_count = replacements.Clones.Count;

            TestLog.EmbedPlainText(clone_count + " clones found.");
            for (int i = 0; i < replacements.Clones.Count; i++)
            {
                TestLog.EmbedPlainText("   ***** Clone #" + i + " *****", replacements.Clones[i].ToString());
            }

            TestLog.EmbedPlainText("The largest permutation found within the markers was:", largest.PermutatedMethod.Print());

            var quickFixInfos = replacements.Clones.Where(Predicate(begin_comment, end_comment));

            Assert.IsTrue(quickFixInfos.Count() > 0, "None of the clones found (there were " + clone_count + ") fell inbetween the BEGIN/END markers.");

            var expected_call_snippet = begin_comment.CommentText.Substring(begin_comment.CommentText.IndexOf("BEGIN") + 5).Trim();

            if (!string.IsNullOrEmpty(expected_call_snippet))
            {
                var expected_call = ParseUtilCSharp.ParseStatement <Statement>(expected_call_snippet);
                var actual_cal    = ParseUtilCSharp.ParseStatement <Statement>(quickFixInfos.First().TextForACallToJanga);
                Assert.IsTrue(expected_call.MatchesPrint(actual_cal), "The expected call did not match the actual call.  \n\tExpected Call: " + expected_call.Print() + "\n\t" + "Actual Call: " + actual_cal.Print());
            }
        }
コード例 #9
0
        public void RestrictsScopeToDuplicateMembersOnASingleClass()
        {
            const string codeText =
                @"
                public class One
                {
                    void Foo()
                    {
                        Console.Write(""zippy"");
                    }
                    void Bar()
                    {
                        Console.Write(""foo"");
                    }
                }
                public class Two
                {
                    void Foo()
                    {
                        Console.Write(""zippy"");
                    }
                    void Bar()
                    {
                        Console.Write(""foo"");
                    }
                } ";
            var clones = cloneFinder.GetCloneReplacements(codeText).Clones;

            PrintClones(clones);
            Assert.AreEqual(0, clones.Count, "While the input does have duplicates, they are not however within a single class.");
        }