Beispiel #1
0
        public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(TransformationContext context, IProgress <Diagnostic> progress, CancellationToken cancellationToken)
        {
            var results = SyntaxFactory.List <MemberDeclarationSyntax>();

            // Our generator is applied to any class that our attribute is applied to.
            var applyToClass = (ClassDeclarationSyntax)context.ProcessingNode;

            // Apply a suffix to the name of a copy of the class.
            var partialClass = SyntaxFactory.ClassDeclaration($"{applyToClass.Identifier}")
                               .WithModifiers(
                SyntaxFactory.TokenList(
                    SyntaxFactory.Token(SyntaxKind.PublicKeyword),
                    SyntaxFactory.Token(SyntaxKind.PartialKeyword)));

            var returnType = CodeGenUtil.TypeFromClass(applyToClass);

            var fields = applyToClass.Members.Where(m => m is FieldDeclarationSyntax)
                         .Select(m => m as FieldDeclarationSyntax)
                         .Where(m => m.Modifiers.Any(SyntaxKind.PublicKeyword))
                         .Where(m => m.Modifiers.Any(SyntaxKind.ReadOnlyKeyword))
                         .Where(m => !m.Modifiers.Any(SyntaxKind.StaticKeyword))
                         .ToList();

            partialClass = CodeGenUtil.AddWith(partialClass, returnType, fields);

            return(Task.FromResult <SyntaxList <MemberDeclarationSyntax> >(results.Add(partialClass)));
        }
        public static (ClassDeclarationSyntax PartialClass, TypeSyntax ReturnType, List <FieldDeclarationSyntax> Fields) GetState(TransformationContext context)
        {
            // Our generator is applied to any class that our attribute is applied to.
            var applyToClass = (ClassDeclarationSyntax)context.ProcessingNode;

            var classModifiers = SyntaxFactory.TokenList(
                Enumerable.Concat(
                    applyToClass.Modifiers
                    .Where(t => !t.IsKind(SyntaxKind.PartialKeyword)).AsEnumerable(),
                    new[] { SyntaxFactory.Token(SyntaxKind.PartialKeyword) }));

            // Apply a suffix to the name of a copy of the class.
            var partialClass = SyntaxFactory.ClassDeclaration($"{applyToClass.Identifier}")
                               .WithModifiers(classModifiers);

            if (applyToClass.TypeParameterList != null)
            {
                partialClass = partialClass.WithTypeParameterList(applyToClass.TypeParameterList);
            }

            if (applyToClass.ConstraintClauses != null)
            {
                partialClass = partialClass.WithConstraintClauses(applyToClass.ConstraintClauses);
            }

            var returnType = CodeGenUtil.TypeFromClass(applyToClass);

            var fields = applyToClass.Members
                         .Where(m => m is FieldDeclarationSyntax)
                         .Select(m => m as FieldDeclarationSyntax)
                         .Where(f => f.Declaration.Variables.Count > 0)
                         .Where(f => FirstCharIsUpper(f.Declaration.Variables[0].Identifier.ToString()))
                         .Where(f => f.Modifiers.Any(SyntaxKind.PublicKeyword))
                         .Where(f => f.Modifiers.Any(SyntaxKind.ReadOnlyKeyword))
                         .Where(f => !f.Modifiers.Any(SyntaxKind.StaticKeyword))
                         .ToList();

            return(partialClass, returnType, fields);
        }
        public static (ClassDeclarationSyntax PartialClass, TypeSyntax ReturnType, List <(SyntaxToken Identifier, TypeSyntax Type, SyntaxTokenList Modifiers)> Fields) GetState(TransformationContext context)
        {
            // Our generator is applied to any class that our attribute is applied to.
            var applyToClass = (ClassDeclarationSyntax)context.ProcessingNode;

            var classModifiers = SyntaxFactory.TokenList(
                Enumerable.Concat(
                    applyToClass.Modifiers
                    .Where(t => !t.IsKind(SyntaxKind.PartialKeyword)).AsEnumerable(),
                    new[] { SyntaxFactory.Token(SyntaxKind.PartialKeyword) }));

            // Apply a suffix to the name of a copy of the class.
            var partialClass = SyntaxFactory.ClassDeclaration($"{applyToClass.Identifier}")
                               .WithModifiers(classModifiers);

            if (applyToClass.TypeParameterList != null)
            {
                partialClass = partialClass.WithTypeParameterList(applyToClass.TypeParameterList);
            }

            if (applyToClass.ConstraintClauses != null)
            {
                partialClass = partialClass.WithConstraintClauses(applyToClass.ConstraintClauses);
            }

            var returnType = CodeGenUtil.TypeFromClass(applyToClass);

            var indexedMembers = applyToClass.Members.Select((m, i) => (m, i));

            var fields = indexedMembers.Where(m => m.m is FieldDeclarationSyntax)
                         .Select(m => (f: m.m as FieldDeclarationSyntax, m.i))
                         .Where(m => m.f.Declaration.Variables.Count > 0)
                         .Where(m => FirstCharIsUpper(m.f.Declaration.Variables[0].Identifier.ToString()))
                         .Where(m => m.f.Modifiers.Any(SyntaxKind.PublicKeyword))
                         .Where(m => m.f.Modifiers.Any(SyntaxKind.ReadOnlyKeyword))
                         .Where(m => !m.f.Modifiers.Any(SyntaxKind.StaticKeyword))
                         .Select(m => (
                                     m.f.Declaration.Variables[0].Identifier,
                                     m.f.Declaration.Type,
                                     m.f.Modifiers,
                                     m.i
                                     ));

            var properties = indexedMembers.Where(m => m.m is PropertyDeclarationSyntax)
                             .Select(m => (p: m.m as PropertyDeclarationSyntax, m.i))
                             .Where(m => FirstCharIsUpper(m.p.Identifier.ToString()))
                             .Where(m => m.p.Modifiers.Any(SyntaxKind.PublicKeyword))
                             .Where(m => !m.p.Modifiers.Any(SyntaxKind.StaticKeyword))
                             .Where(m => m.p.AccessorList.Accessors.Count == 1)
                             .Where(m => m.p.AccessorList.Accessors[0].Kind() == SyntaxKind.GetAccessorDeclaration)
                             .Where(m => m.p.AccessorList.Accessors[0].ExpressionBody == null)
                             .Where(m => m.p.AccessorList.Accessors[0].Body == null)
                             .Where(m => m.p.Initializer == null)
                             .Select(m => (
                                         m.p.Identifier,
                                         m.p.Type,
                                         m.p.Modifiers,
                                         m.i
                                         ));

            var members = fields.Concat(properties)
                          .OrderBy(m => m.i) // Preserve the order between properties and fields.
                          .Select(m => (m.Identifier, m.Type, m.Modifiers))
                          .ToList();

            return(partialClass, returnType, members);
        }