private async Task <Document> SortMembersAsync(Document document, TypeDeclarationSyntax clsDecl, CancellationToken cancellationToken)
        {
            // Sort Fields
            var fieldsOld = clsDecl.ChildNodes().OfType <FieldDeclarationSyntax>().ToArray();
            var fieldsNew = fieldsOld.OrderBy(m => m.Declaration.Variables.First().Identifier.Value).ToArray();

            // Sort Properties
            var allProperties = clsDecl.ChildNodes().OfType <PropertyDeclarationSyntax>().ToArray();

            var propOld = allProperties.Where(p => p.ExpressionBody != null || p.AccessorList.Accessors.All(a => a.ChildNodes().OfType <BlockSyntax>().Any())).ToArray();
            var propNew = propOld.OrderBy(m => m.Identifier.Value).ToArray();

            var autoPropOld = allProperties.Except(propNew).ToArray();
            var autoPropNew = autoPropOld.OrderBy(m => m.Identifier.Value).ToArray();

            // Sort Events
            var eventsOld = clsDecl.ChildNodes().OfType <EventFieldDeclarationSyntax>().ToArray();
            var eventsNew = eventsOld.OrderBy(m => m.Declaration.Variables.First().Identifier.Value).ToArray();

            // Sort Constructors
            var ctorsOld = clsDecl.ChildNodes().OfType <ConstructorDeclarationSyntax>().ToArray();
            var ctorsNew = ctorsOld.OrderBy(m => m.ParameterList.Parameters.Count).ToArray();

            // Sort Methods
            var methodsOld = clsDecl.ChildNodes().OfType <MethodDeclarationSyntax>().ToArray();
            var methodsNew = methodsOld.OrderBy(m => m.Identifier.Value).ThenBy(m => m.ParameterList.Parameters.Count).ToArray();

            // Append members
            var oldMembers = new List <MemberDeclarationSyntax>();

            oldMembers.AddRange(fieldsOld);
            oldMembers.AddRange(autoPropOld);
            oldMembers.AddRange(eventsOld);
            oldMembers.AddRange(ctorsOld);
            oldMembers.AddRange(propOld);
            oldMembers.AddRange(methodsOld);

            var newMembers = new List <MemberDeclarationSyntax>();

            newMembers.AddRange(fieldsNew);
            newMembers.AddRange(autoPropNew);
            newMembers.AddRange(eventsNew);
            newMembers.AddRange(ctorsNew);
            newMembers.AddRange(propNew);
            newMembers.AddRange(methodsNew);

            // Replace old with new
            var oldRoot = await document.GetSyntaxRootAsync(cancellationToken)
                          .ConfigureAwait(false);

            var index   = 0;
            var newRoot = oldRoot.ReplaceNodes(oldMembers,
                                               (o, n) => newMembers[index++]
                                               );

            return(document.WithSyntaxRoot(newRoot));
        }
        private static SyntaxNode FindInsertionPointBelowFieldGroup(TypeDeclarationSyntax typeDeclaration)
        {
            SyntaxNode insertionPoint = null;

            var tracking = false;

            foreach (var node in typeDeclaration.ChildNodes())
            {
                if (tracking)
                {
                    if (node is FieldDeclarationSyntax)
                    {
                        insertionPoint = node;
                        continue;
                    }

                    break;
                }
                else if (node is FieldDeclarationSyntax)
                {
                    insertionPoint = node;
                    tracking       = true;
                }
            }

            return(insertionPoint);
        }
        private ClassModel ExtractClassModel(TypeDeclarationSyntax syntax)
        {
            var allowedModifiers = GetAllowedModifiers(syntax);

            var model = new ClassModel(syntax, SemanticModel, false);

            AddModels <ConstructorDeclarationSyntax, IConstructorModel>(syntax, x => x.Modifiers, ExtractConstructorModel, allowedModifiers, model.Constructors);
            AddModels <OperatorDeclarationSyntax, IOperatorModel>(syntax, x => x.Modifiers, ExtractOperatorModel, allowedModifiers, model.Operators);
            AddModels <MethodDeclarationSyntax, IMethodModel>(syntax, x => x.Modifiers, ExtractMethodModel, allowedModifiers, model.Methods);
            AddModels <PropertyDeclarationSyntax, IPropertyModel>(syntax, x => x.Modifiers, ExtractPropertyModel, allowedModifiers, model.Properties);
            AddModels <IndexerDeclarationSyntax, IIndexerModel>(syntax, x => x.Modifiers, ExtractIndexerModel, allowedModifiers, model.Indexers);

            foreach (var methodModel in syntax.ChildNodes().OfType <MethodDeclarationSyntax>().Where(x => x.ExplicitInterfaceSpecifier != null).Select(ExtractMethodModel))
            {
                model.Methods.Add(methodModel);
            }

            model.DefaultConstructor = model.Constructors.OrderByDescending(x => x.Parameters.Count).FirstOrDefault();

            // populate interface models
            if (syntax is ClassDeclarationSyntax classDeclaration)
            {
                var declaredSymbol = SemanticModel.GetDeclaredSymbol(classDeclaration);
                foreach (var declaredSymbolInterface in declaredSymbol.Interfaces)
                {
                    model.Interfaces.Add(new InterfaceModel(declaredSymbolInterface));
                }
            }

            return(model);
        }
 private void AddModels <TIn, TOut>(TypeDeclarationSyntax type, Func <TIn, SyntaxTokenList> modifiersSelector, Func <TIn, TOut> converter, ICollection <SyntaxKind> allowedModifiers, ICollection <TOut> target)
 {
     foreach (var model in type.ChildNodes().OfType <TIn>().Where(x => modifiersSelector(x).Any(m => allowedModifiers.Contains(m.Kind()))).Select(converter))
     {
         target.Add(model);
     }
 }
        private void AddObject(TypeDeclarationSyntax node, CSharpSyntaxTree syntaxTree, SemanticModel semanticModel, SyntaxTokenList modifiers, AddObjectCallbackMethod callback)
        {
            var    symbol   = semanticModel.GetDeclaredSymbol(node);
            string fullname = Tools.GetFullTypeName(symbol);

            bool addNew = false;

            if (Tools.HasKind(modifiers, SyntaxKind.PartialKeyword))
            {
                ObjectType obj;
                if (DoesPartialObjectExist(fullname, out obj))
                {
                    obj.MergePartial(node, semanticModel);
                }
                else
                {
                    addNew = true;
                }
            }
            else
            {
                addNew = true;
            }

            if (addNew)
            {
                callback?.Invoke();
            }
            AddObjects(node.ChildNodes(), syntaxTree, semanticModel);
        }
        private async Task <Document> AllowMembersOrderingAsync(Document document, TypeDeclarationSyntax typeDeclarationSyntax, CancellationToken cancellationToken)
        {
            var membersDeclaration =
                typeDeclarationSyntax
                .ChildNodes()
                .OfType <MemberDeclarationSyntax>();

            var root = await document.GetSyntaxRootAsync(cancellationToken) as CompilationUnitSyntax;

            TypeDeclarationSyntax newTypeDeclarationSyntax;
            var orderChanged = TryReplaceTypeMembers(
                typeDeclarationSyntax,
                membersDeclaration,
                membersDeclaration.OrderBy(member => member, GetMemberDeclarationComparer(document, cancellationToken)),
                out newTypeDeclarationSyntax);

            if (!orderChanged)
            {
                return(null);
            }

            var newDocument = document.WithSyntaxRoot(root
                                                      .ReplaceNode(typeDeclarationSyntax, newTypeDeclarationSyntax)
                                                      .WithAdditionalAnnotations(Formatter.Annotation)
                                                      );

            return(newDocument);
        }
        private TypeDeclarationSyntax GetNewTypeDeclaration()
        {
            var oldBuilder = _type
                             .ChildNodes()
                             .OfType <TypeDeclarationSyntax>()
                             .Where(t => t.Identifier.Text == "Builder")
                             .FirstOrDefault();

            var newBuilder = GetBuilderClass();

            if (oldBuilder != null)
            {
                return(_type.ReplaceNode(oldBuilder, newBuilder));
            }
            else
            {
                return(_type.InsertAfter(_type.ChildNodes().Last(), newBuilder));
            }
        }
Beispiel #8
0
 public RootTypeNode Convert(TypeDeclarationSyntax type)
 => new RootTypeNode(
     name: type.Identifier.Text,
     fields: ConvertProperties(
         type.ChildNodes()
         .OfType <PropertyDeclarationSyntax>()
         .Where(property => IsSerializable(property, type))),
     genericTypeParameters: type.TypeParameterList?.Parameters
     .Select(p => p.Identifier.Text)
     .Where(p => !string.IsNullOrWhiteSpace(p)) ?? Enumerable.Empty <string>(),
     baseTypes: ConvertBaseTypes(
         type.BaseList?.Types ?? Enumerable.Empty <BaseTypeSyntax>(),
         type));
Beispiel #9
0
        private static TypeDeclarationSyntax WithBackingField(this TypeDeclarationSyntax node, ITypeSymbol typeSymbol, string backingFieldName, SemanticModel model, Workspace workspace)
        {
            PropertyDeclarationSyntax property = node.ChildNodes().Where(n => n.HasAnnotation(UpdatedPropertyAnnotation)).FirstOrDefault() as PropertyDeclarationSyntax;

            if (property == null)
            {
                return(null);
            }

            MemberDeclarationSyntax fieldDecl = GenerateBackingField(typeSymbol, backingFieldName, workspace);

            node = node.InsertNodesBefore(property, new[] { fieldDecl });
            return(node);
        }
Beispiel #10
0
        public TypeDeclarationSyntax AddGeneratedCodeAttributeOnMembers(
            TypeDeclarationSyntax typeDeclaration)
        {
            var nodesToBeReplaced = typeDeclaration
                                    .ChildNodes()
                                    .Where(node => Updates.Keys.Any(key => key.IsAssignableFrom(node.GetType())));

            SyntaxNode calculateReplacement(SyntaxNode rootNode, SyntaxNode toBeReplacedNode)
            {
                var context = new MemberReplacementContext(toBeReplacedNode, this, attributeGenerator);
                var updater = Updates[toBeReplacedNode.GetType()];

                return(updater(context));
            }

            return(typeDeclaration.ReplaceNodes(nodesToBeReplaced, calculateReplacement));
        }
        /// <summary>
        /// Warning, this method does not hanlde Partial classes
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static MemberDeclarationSyntax[] GetFieldAndPropertyDeclarations(
            this TypeDeclarationSyntax type,
            bool aknowledgePartialDeclarationLimitation = false)
        {
            if (type.IsPartial() && !aknowledgePartialDeclarationLimitation)
            {
                throw new ArgumentException($"Type {type.Identifier.TrimmedText()} is partial, " +
                                            $"its members are contained in multiple graphs in multiple files. " +
                                            $"To aknowledge this limitation and allow method to proceed, " +
                                            $"pass true to {nameof(aknowledgePartialDeclarationLimitation)}");
            }

            return(type
                   .ChildNodes()
                   .Where(node => node.Fits(SyntaxKind.PropertyDeclaration,
                                            SyntaxKind.FieldDeclaration))
                   .OfType <MemberDeclarationSyntax>()
                   .ToArray());
        }
Beispiel #12
0
 public static IEnumerable <ConstructorDeclarationSyntax> GetConstructors(this TypeDeclarationSyntax typeDecl)
 {
     return(typeDecl.ChildNodes().OfType <ConstructorDeclarationSyntax>());
 }
Beispiel #13
0
 public static bool TypeDeclarationIncludesParameterlessConstructor(this TypeDeclarationSyntax typeDeclaration)
 {
     return(typeDeclaration.ChildNodes().OfType <ConstructorDeclarationSyntax>().Cast <ConstructorDeclarationSyntax>().Any(x => !x.ParameterList.Parameters.Any()));
 }