Exemplo n.º 1
0
        private static async Task <Document> GenerateConstructor(
            Document document,
            ClassDeclarationSyntax classDeclarationSyntax,
            IList <PropertyDeclarationSyntax> properties,
            ConstructorDeclarationSyntax nonTrivialConstructorCandidate,
            CancellationToken cancellationToken)
        {
            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            if (properties.Count == 0)
            {
                return(document);
            }

            var constructorDeclaration = ConstructorGenerationHelper.FromPropertiesWithAssignments(
                classDeclarationSyntax.Identifier.WithoutTrivia(),
                properties);

            var newClassDeclaration = nonTrivialConstructorCandidate != null?
                                      classDeclarationSyntax.ReplaceNode(nonTrivialConstructorCandidate, constructorDeclaration)
                                          : classDeclarationSyntax.AddMembers(constructorDeclaration);

            var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            var newRoot     = root.ReplaceNode(classDeclarationSyntax, newClassDeclaration);
            var newDocument = document.WithSyntaxRoot(newRoot);

            return(newDocument);
        }
Exemplo n.º 2
0
        private static async Task <Document> GenerateDiscriminatedUnion(
            Document document,
            ClassDeclarationSyntax classDeclarationSyntax,
            CancellationToken cancellationToken)
        {
            var rootNode = classDeclarationSyntax.Parent;

            if (rootNode == null)
            {
                return(document);
            }

            var duMembers = GetCandidateMethods(classDeclarationSyntax);

            if (duMembers.Count == 0)
            {
                return(document);
            }

            var factoryMethodRewriter = new FactoryMethodRewriter();
            var newClassDeclaration   = factoryMethodRewriter.Visit(classDeclarationSyntax);

            rootNode = rootNode.ReplaceNode(classDeclarationSyntax, newClassDeclaration);

            List <(MethodDeclarationSyntax method, ClassDeclarationSyntax cl)> candidates =
                duMembers.Select(m => (m, FindCurrentCaseDeclaration(rootNode, GetGeneratedClassName(m))))
                .ToList();

            var declarationsCleaner = new ClassOccurencesCleaner(candidates.Select(p => p.cl).Where(p => p != null).ToList());

            rootNode = declarationsCleaner.Visit(rootNode);

            // TODO: Methods returning types defined in other assemblies should probably be rejected,
            // but lets say it is user's responsibility to use this refactoring wisely.

            var baseClassIdentifier = SF.IdentifierName(classDeclarationSyntax.Identifier);

            foreach (var(duCandidate, prevDeclaration) in candidates)
            {
                var generatedClassName = GetGeneratedClassName(duCandidate);
                if (generatedClassName == default)
                {
                    return(document);
                }

                var properties             = duCandidate.ParameterList.Parameters.Select(ToProperty).ToList();
                var constructorDeclaration = properties.Count > 0 ?
                                             ConstructorGenerationHelper.FromPropertiesWithAssignments(
                    generatedClassName,
                    properties)
                    : null;
                var members = new List <MemberDeclarationSyntax>(properties);
                rootNode = UpdateOrAddCaseDefinition(rootNode, generatedClassName, baseClassIdentifier, properties, constructorDeclaration, prevDeclaration);
            }

            // Update document
            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            var newRoot     = root.ReplaceNode(classDeclarationSyntax.Parent, rootNode);
            var newDocument = document.WithSyntaxRoot(newRoot);

            return(newDocument);
        }