Exemplo n.º 1
0
        /// <summary>
        /// Removes optional members for types while adding them to the library.
        /// </summary>
        /// <param name="walker">The walker.</param>
        /// <returns></returns>
        private Result <Project> ExtractInterwovenTypeMembers(IDependencyWalker dependencyWalker)
        {
            //this rewriter will collect the information it removed during the rewrite.
            var rewriter = new ExtractInterwovenTypeMembersRewriter(_contentSelector);

            var result = rewriter.Rewrite(dependencyWalker);

            if (result.IsFailure)
            {
                return(result);
            }

            var membersAndDependencies =
                rewriter
                .ExtractedMembers
                .Select(x => new
            {
                Member       = x,
                Descriptions = new InterweaveDescriptions(dependencyWalker.GetTypeDependencies(x).OnlyInterweaves())
            })
                .GroupBy(x => x.Descriptions.Key)
                .ToList();

            foreach (var memberAndDependency in membersAndDependencies)
            {
                foreach (var item in memberAndDependency)
                {
                    _library.AddOrMerge(new InterwovenTypeMembersPackage(item.Member.ContainingTypeContext.Value.Key, item.Member.Declaration.ToFormattedCode(), item.Descriptions));
                }
            }

            return(result);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Removes optional members for types while adding them to the library.
        /// </summary>
        /// <param name="walker">The walker.</param>
        /// <returns></returns>
        private Result <Project> ExtractInterwovenExtensionMethods(IDependencyWalker dependencyWalker)
        {
            var rewriter = new ExtractInterwovenExtensionMethodsRewriter(_contentSelector);

            var result = rewriter.Rewrite(dependencyWalker);

            if (result.IsFailure)
            {
                return(result);
            }

            var membersAndDependencies =
                rewriter.
                ExtractedMembers
                .Select(x => new
            {
                ExtensionMethod = x,
                Descriptions    = new InterweaveDescriptions(dependencyWalker.GetTypeDependencies(x).OnlyInterweaves())
            })
                .GroupBy(x => x.Descriptions.Key)
                .ToList();

            foreach (var memberAndDependencies in membersAndDependencies)
            {
                foreach (var item in memberAndDependencies)
                {
                    _library.AddOrMerge(new InterwovenExtensionMethodsPackage(item.ExtensionMethod.Declaration.ToFormattedCode(), item.Descriptions));
                }
            }

            return(result);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Gets the extension methods that are interwoven with non CLR types.
        /// </summary>
        /// <param name="dependencyWalker"></param>
        /// <returns></returns>
        public Result <IEnumerable <MethodContext> > GetInterwovenExtensionMethods(IDependencyWalker dependencyWalker)
        {
            var result = dependencyWalker
                         .ProjectContext
                         .GetExtensionMethods()
                         .Where(x => dependencyWalker.GetTypeDependencies(x).AnyInterweaves());

            return(Result.Ok(result));
        }
Exemplo n.º 4
0
 /// <summary>
 /// Extracts extension methods and also removes them from the project.
 /// </summary>
 /// <param name="dependencyWalker">The dependency walker.</param>
 /// <returns></returns>
 public Result <Project> Rewrite(IDependencyWalker dependencyWalker)
 {
     return(_contentSelector
            .GetInterwovenExtensionMethods(dependencyWalker)
            //store what's being extracted
            .OnSuccessTee(extracted => ExtractedMembers = extracted)
            //remove extracted items from the project
            .OnSuccess(extracted => ExtractInterwovenTypeMembersRewriter.RemoveObjectsFromProject(dependencyWalker, extracted)));
 }
Exemplo n.º 5
0
        /// <summary>
        /// Removes the objects from project.
        /// </summary>
        /// <returns></returns>
        internal static Result <Project> RemoveObjectsFromProject(IDependencyWalker dependencyWalker, IEnumerable <ExtractedClassInfo> classes, IEnumerable <ExtractedStructInfo> structs)
        {
            //Unfortunately the Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter only rewrites a single document at a time.
            //The extracted members came from multiple documents (which have references to the SyntaxNodes they came from.)
            //The easiesy way to rewrite all the documents without other hassles is to precompute all the new roots for the documents
            //that we need to remove nodes from.

            var documents =
                dependencyWalker
                .ProjectContext
                .Documents
                .Select(x => x.Document)
                .ToList();

            //todo: validate the classes/structs actually belong to the documents in the dependencywalker.

            var modifications =
                documents
                //get each document and the declarations to remove in each
                .Select(x => new
            {
                Document = x,

                //combine the class and struct declarations for each document
                Declarations =
                    classes
                    .Where(c => c.Document.Document == x)
                    .Select(c => c.Class.Declaration)
                    .OfType <SyntaxNode>()
                    .Union(
                        structs
                        .Where(s => s.Document.Document == x)
                        .Select(s => s.Struct.Declaration)
                        )
            })
                .Select(x => new
            {
                DocumentId = x.Document.Id,
                NewRoot    = x.Document.GetRootSync().RemoveNodes(x.Declarations, SyntaxRemoveOptions.KeepNoTrivia)
            })
                .ToList();

            var newProject = dependencyWalker.ProjectContext.Project;

            foreach (var modification in modifications)
            {
                newProject =
                    newProject
                    .GetDocument(modification.DocumentId)
                    .AlterRoot(_ => modification.NewRoot)
                    .Project;
            }

            return(newProject);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Removes the objects from project.
        /// </summary>
        /// <param name="dependencyWalker">The dependency walker.</param>
        /// <param name="extractedMembers">The extracted members.</param>
        /// <returns></returns>
        internal static Result <Project> RemoveObjectsFromProject(IDependencyWalker dependencyWalker, IEnumerable <ITypeMemberContext> extractedMembers)
        {
            //Unfortunately the Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter only rewrites a single document at a time.
            //The extracted members came from multiple documents (which have references to the SyntaxNodes they came from.)
            //The easiesy way to rewrite all the documents without other hassles is to precompute all the new roots for the documents
            //that we need to remove nodes from.

            var documents =
                dependencyWalker
                .ProjectContext
                .Documents
                .Select(x => x.Document)
                .ToList();

            var ensureResult = extractedMembers.EnsureExistInDocuments(documents);

            if (ensureResult.IsFailure)
            {
                return(ensureResult.ToTypedResult <Project>());
            }

            var modifications =
                extractedMembers
                .Select(m => new
            {
                Member = m,
                Doc    = documents.Where(d => d.ContainsNode(m.Declaration)).Single()
            })
                .GroupBy(x => x.Doc)
                .Select(x => new
            {
                Document     = x.Key,
                Declarations = x.Select(mc => mc.Member.Declaration).ToList()
            })
                .Select(x => new
            {
                DocumentId = x.Document.Id,
                NewRoot    = x.Document.GetRootSync().RemoveNodes(x.Declarations, SyntaxRemoveOptions.KeepNoTrivia)
            })
                .ToList();

            var newProject = dependencyWalker.ProjectContext.Project;

            foreach (var modification in modifications)
            {
                newProject =
                    newProject
                    .GetDocument(modification.DocumentId)
                    .AlterRoot(_ => modification.NewRoot)
                    .Project;
            }

            return(newProject);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Extracts dependent members of a type and also removes them from the project.
        /// </summary>
        /// <param name="dependencyWalker">The dependency walker.</param>
        /// <returns></returns>
        public Result <Project> Rewrite(IDependencyWalker dependencyWalker)
        {
            var extracted = _contentSelector.GetMemberContainers(dependencyWalker);

            if (extracted.IsFailure)
            {
                return(Result.Fail <Project>(extracted.Error));
            }

            this.ExtractedClasses = extracted.Value.classes;
            this.ExtractedStructs = extracted.Value.structs;

            return(RemoveObjectsFromProject(dependencyWalker, extracted.Value.classes, extracted.Value.structs));
        }
Exemplo n.º 8
0
        /// <summary>
        /// Extracts dependent members of a type and also removes them from the project.
        /// </summary>
        /// <param name="dependencyWalker">The dependency walker.</param>
        /// <returns></returns>
        public Result <Project> Rewrite(IDependencyWalker dependencyWalker)
        {
            var extracted = _contentSelector.GetInterwovenTypeMembersExceptExtensions(dependencyWalker);

            if (extracted.IsFailure)
            {
                return(Result.Fail <Project>(extracted.Error));
            }
            else
            {
                ExtractedMembers = extracted.Value;
            }

            return(RemoveObjectsFromProject(dependencyWalker, ExtractedMembers));
        }
Exemplo n.º 9
0
        /// <summary>
        /// Removes member containers while adding them to the library.
        /// </summary>
        /// <param name="walker">The walker.</param>
        /// <returns></returns>
        private Result <Project> ExtractMemberContainers(IDependencyWalker dependencyWalker)
        {
            var rewriter = new ExtractMemberContainersRewriter(_contentSelector);

            var result = rewriter.Rewrite(dependencyWalker);

            if (result.IsFailure)
            {
                return(result);
            }

            Func <Document, IEnumerable <string> > getUsings = doc => doc.GetUsings().Select(x => x.Name.ToString());

            foreach (var cls in rewriter.ExtractedClasses)
            {
                var usings          = getUsings(cls.Document.Document);
                var name            = cls.Class.Name;
                var genericArgCount = cls.Class.TypeArguments.Count();
                var members         = cls.Class.Declaration.DescendantNodesOfFirstLevel();
                var declaration     = cls.Class.Declaration.RemoveNodes(members, SyntaxRemoveOptions.KeepNoTrivia).ToFullString();
                var content         = string.Join(Environment.NewLine + Environment.NewLine, members.Select(x => x.ToFullString()));

                _library.AddOrMerge(new MemberContainerPackage(MemberContainerKind.Class, usings, name, (byte)genericArgCount, declaration, content));
            }

            foreach (var str in rewriter.ExtractedStructs)
            {
                var usings          = getUsings(str.Document.Document);
                var name            = str.Struct.Name;
                var genericArgCount = str.Struct.TypeArguments.Count();
                var members         = str.Struct.Declaration.DescendantNodesOfFirstLevel();
                var declaration     = str.Struct.Declaration.RemoveNodes(members, SyntaxRemoveOptions.KeepNoTrivia).ToFullString();
                var content         = string.Join(Environment.NewLine + Environment.NewLine, members.Select(x => x.ToFullString()));

                _library.AddOrMerge(new MemberContainerPackage(MemberContainerKind.Struct, usings, name, (byte)genericArgCount, declaration, content));
            }

            return(result);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Gets the member containers for the DependencyWalker
        /// </summary>
        /// <param name="dependencyWalker"></param>
        /// <returns></returns>
        public Result <(IEnumerable <ExtractedClassInfo> classes, IEnumerable <ExtractedStructInfo> structs)> GetMemberContainers(IDependencyWalker dependencyWalker)
        {
            var classes = dependencyWalker
                          .ProjectContext
                          .Documents
                          .SelectMany(d => d.Classes.Select(c => new ExtractedClassInfo(d, c)));

            var structs = dependencyWalker
                          .ProjectContext
                          .Documents
                          .SelectMany(d => d.Structs.Select(s => new ExtractedStructInfo(d, s)));

            return(classes, structs);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Gets the instance and static type members that are interwoven with non CLR types.
        /// Excludes extension methods.
        /// </summary>
        /// <param name="dependencyWalker"></param>
        /// <returns></returns>
        public Result <IEnumerable <ITypeMemberContext> > GetInterwovenTypeMembersExceptExtensions(IDependencyWalker dependencyWalker)
        {
            var result =
                dependencyWalker
                .ProjectContext
                .GetTypeMembersExcludingExtensions()
                .Select(x => new
            {
                Member       = x,
                Dependencies = dependencyWalker.GetTypeDependencies(x).Where(d => d.IsInterweave && d.FullNameWithoutGenericNames != x.ContainingTypeContext.Value.FullNameWithoutGenericNames)
            })
                .Where(x => x.Dependencies.Any())
                .Select(x => x.Member)
                .ToList();

            //Because we're getting only type members, eg: methods/delegates/etc.. of a struct/class/interface
            //then we can be sure that we've only retrieved items where the containing type is available.
            var missingContainingDeclaration =
                result
                .Where(x => x.ContainingTypeContext.HasNoValue);

            if (missingContainingDeclaration.Any())
            {
                return(Result.Fail <IEnumerable <ITypeMemberContext> >("Some type members are missing a containing type: " + missingContainingDeclaration.Select(x => x.Declaration.ToString())));
            }

            return(result);
        }