Beispiel #1
0
 //A move looks like a deleted method and then an added method in
 // another place, this find the added methods
 private static IEnumerable <MethodDeclarationSyntax> GetInsertedMethods(IEnumerable <Diff> diffs)
 {
     return(diffs
            .Where(diff => TriviaCompare.IsSpanInNodeTrivia(diff.Ancestor.Span, diff.Ancestor.Node))
            .Select(diff => diff.Changed.Node as MethodDeclarationSyntax)
            .Where(node => node != null).CacheEnumerable());
 }
Beispiel #2
0
        /// <summary>
        /// Given a Repo and a Tree find any possible FalsePositives
        /// </summary>
        /// <param name="repo">Repo that has the remote changes that need to be checked</param>
        /// <param name="local">The syntax tree that will be compared with syntax trees from repo</param>
        public static IEnumerable <DetectedFalsePositive> ForFalsePositive(Repo repo, SyntaxTree local)
        {
            var relativePath = GetRelativePath(repo.LocalRepoDirectory, local.FilePath);
            var pulls        = GetPulls(repo, relativePath);

            foreach (var pull in pulls)
            {
                var conflicts = Diff3.Compare(pull.File.BaseTree, local, pull.File.HeadTree);
                var locs      = GetInsertedMethods(conflicts.Local);
                var rems      = GetInsertedMethods(conflicts.Remote);

                var methodConflicts = conflicts.Conflicts.Where(con => con.Ancestor.Node is MethodDeclarationSyntax);

                foreach (var c in methodConflicts)
                {
                    var ancestor = (MethodDeclarationSyntax)c.Ancestor.Node;

                    var conflict = GetInnerMethodConflicts(ancestor, c.Remote, c.Local, locs, InnerMethodConflict.Local.Moved);

                    //If the local was not moved, the local could have still been changed
                    if (conflict == null)
                    {
                        conflict = GetInnerMethodConflicts(ancestor, c.Local, c.Remote, rems, InnerMethodConflict.Local.Changed);
                        if (conflict == null)
                        {
                            continue;
                        }
                    }

                    if (!conflict.DiffResult.Conflicts.Any(con => TriviaCompare.IsSemanticChange(con.Local.Node, con.Remote.Node)))
                    {
                        yield return(new DetectedFalsePositive
                        {
                            Location = Location.Create(local, conflict.GetLocal().Identifier.Span),
                            MethodName = ancestor.Identifier.ToString(),
                            RemoteFile = pull.File,
                            RemoteChange = pull.Change,
                            ConflictType = conflict.LocalLocation == InnerMethodConflict.Local.Changed
                                         ? DetectedFalsePositive.ConflictTypes.LocalMethodChanged
                                         : DetectedFalsePositive.ConflictTypes.LocalMethodRemoved,
                        });
                    }
                }
            }
        }
Beispiel #3
0
        //Given the base class and a file that contains another version of the file
        private static IEnumerable <Diff> DiffClassVersion(ClassDeclarationSyntax b, RepoFile f)
        {
            var ancestorDecs = f.BaseTree
                               .GetRoot()
                               .DescendantNodes()
                               .OfType <ClassDeclarationSyntax>();

            var remoteDecs = f.HeadTree
                             .GetRoot()
                             .DescendantNodes()
                             .OfType <ClassDeclarationSyntax>();

            var merged = MergeClassDeclarationSyntaxes(ancestorDecs, remoteDecs)
                         .FirstOrDefault(t => AreSameClass(t.Item1, b));

            return(Diff.Compare(merged.Item1, merged.Item2)
                   .Where(d => TriviaCompare.IsSemanticChange(d.Ancestor.Node, d.Changed.Node)));
        }
Beispiel #4
0
        private static InnerMethodConflict GetInnerMethodConflicts(MethodDeclarationSyntax ancestor, SpanDetails changed, SpanDetails removed, IEnumerable <MethodDeclarationSyntax> insertedMethods, InnerMethodConflict.Local type)
        {
            if (!TriviaCompare.IsSpanInNodeTrivia(removed.Span, removed.Node))
            {
                return(null);
            }
            var change = changed.Node as MethodDeclarationSyntax;

            if (change == null)
            {
                return(null);
            }
            var moved = GetMovedMethod(insertedMethods, change);

            if (moved == null)
            {
                return(null);
            }
            var diffRes = Diff3.Compare(ancestor, moved, change);

            return(new InnerMethodConflict(ancestor, change, moved, diffRes, type));
        }