Пример #1
0
        /// <inheritdoc />
        public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node)
        {
            if (node is null)
            {
                throw new System.ArgumentNullException(nameof(node));
            }

            if (!node.Modifiers.Any(SyntaxKind.StaticKeyword) &&
                node.TryGetBackingField(out var field) &&
                node.Parent is TypeDeclarationSyntax containingType)
            {
                if (containingType.Members.IndexOf(node) is int pi &&
                    containingType.Members.IndexOf(field) is int fi &&
                    fi == pi - 1)
                {
                    if (fi == 0 ||
                        containingType.Members[fi - 1].IsKind(SyntaxKind.FieldDeclaration))
                    {
                        return;
                    }

                    this.newLineBetween = node.HasLeadingTrivia && node.GetLeadingTrivia().Any(SyntaxKind.EndOfLineTrivia);
                    this.Update(CodeStyleResult.Yes);
                }
        public static MethodDeclarationSyntax ReplacePropertyWithMethod(PropertyDeclarationSyntax property, string methodName)
        {
            AccessorDeclarationSyntax getter = property.Getter();

            BlockSyntax getterBody = getter.Body;

            BlockSyntax methodBody = null;

            if (getterBody != null)
            {
                methodBody = Block(getterBody.Statements)
                             .WithTrailingTrivia(property.GetTrailingTrivia());
            }
            else
            {
                methodBody = Block(
                    ReturnStatement(property.Initializer.Value)
                    .WithTrailingTrivia(property.GetTrailingTrivia()));
            }

            MethodDeclarationSyntax method = MethodDeclaration(
                property.AttributeLists,
                property.Modifiers,
                property.Type,
                property.ExplicitInterfaceSpecifier,
                Identifier(methodName).WithLeadingTrivia(property.Identifier.LeadingTrivia),
                default(TypeParameterListSyntax),
                ParameterList().WithTrailingTrivia(property.Identifier.TrailingTrivia),
                default(SyntaxList <TypeParameterConstraintClauseSyntax>),
                methodBody,
                default(ArrowExpressionClauseSyntax));

            return(method
                   .WithLeadingTrivia(property.GetLeadingTrivia())
                   .WithFormatterAnnotation());
        }
Пример #3
0
 public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node) =>
 node.NormalizeWhitespace(indentation: "", eol: " ")
 .WithLeadingTrivia(node.GetLeadingTrivia())
 .WithTrailingTrivia(node.GetTrailingTrivia());
Пример #4
0
        public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node)
        {
            node = (PropertyDeclarationSyntax)base.VisitPropertyDeclaration(node);
            var newNode = node;

            if (node.ExpressionBody != null)
            {
                newNode = SyntaxHelper.ToStatementBody(node);
            }

            if (node.IsAutoProperty() && node.AccessorList != null)
            {
                var setter = node.AccessorList.Accessors.SingleOrDefault(a => a.Keyword.Kind() == SyntaxKind.SetKeyword);

                if (setter == null)
                {
                    var getter = node.AccessorList.Accessors.Single(a => a.Keyword.Kind() == SyntaxKind.GetKeyword);
                    setter = SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                             .WithModifiers(SyntaxTokenList.Create(SyntaxFactory.Token(SyntaxKind.PrivateKeyword).WithTrailingTrivia(SyntaxFactory.Space)))
                             .WithBody(null)
                             .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
                             .WithLeadingTrivia(getter.GetLeadingTrivia())
                             .WithTrailingTrivia(getter.GetTrailingTrivia());

                    newNode = newNode.AddAccessorListAccessors(setter);
                }

                if (newNode.Initializer != null)
                {
                    var modifiers = SyntaxTokenList.Create(SyntaxFactory.Token(SyntaxKind.PrivateKeyword).WithTrailingTrivia(SyntaxFactory.Space));

                    if (node.Modifiers.Any(m => m.Kind() == SyntaxKind.StaticKeyword))
                    {
                        modifiers = modifiers.Add(SyntaxFactory.Token(SyntaxKind.StaticKeyword).WithTrailingTrivia(SyntaxFactory.Space));
                    }

                    var field = SyntaxFactory.FieldDeclaration(SyntaxFactory.List <AttributeListSyntax>(),
                                                               modifiers,
                                                               SyntaxFactory.VariableDeclaration(
                                                                   node.Type,
                                                                   SyntaxFactory.SeparatedList(new[] {
                        SyntaxFactory.VariableDeclarator(
                            SyntaxFactory.Identifier(AutoInitFieldPrefix + node.Identifier.Text),
                            null,
                            newNode.Initializer
                            )
                    })
                                                                   ),
                                                               SyntaxFactory.Token(SyntaxKind.SemicolonToken)
                                                               );
                    field = field.WithLeadingTrivia(node.GetLeadingTrivia()).WithTrailingTrivia(node.GetTrailingTrivia());
                    fields.Add(field);
                    newNode = newNode.ReplaceNode(newNode.Initializer, (SyntaxNode)null);
                    newNode = SyntaxHelper.RemoveSemicolon(newNode, newNode.SemicolonToken, t => newNode.WithSemicolonToken(t));
                }

                return(newNode);
            }

            return(newNode.Equals(node) ? node : newNode);
        }
Пример #5
0
            PropertyDeclarationSyntax ConvertProperty(PropertyDeclarationSyntax propertyDeclaration, FieldDeclarationSyntax relatedField)
            {
                var leadingList = new SyntaxTriviaList();

                if (relatedField.Declaration.Variables.Count == 1)
                {
                    leadingList = leadingList.AddRange(relatedField.GetLeadingTrivia());
                }

                var propertyDeclaration_GetLeadingTrivia = propertyDeclaration.GetLeadingTrivia();

                if (leadingList.Any() && propertyDeclaration_GetLeadingTrivia.First().IsKind(SyntaxKind.EndOfLineTrivia) == false)
                {
                    var endOfLine = relatedField.GetLeadingTrivia().FirstOrDefault(x => x.IsKind(SyntaxKind.EndOfLineTrivia));

                    if (endOfLine != null)
                    {
                        leadingList = leadingList.Add(endOfLine);
                    }
                }

                leadingList = leadingList.AddRange(propertyDeclaration.GetLeadingTrivia());

                var getNode = propertyDeclaration.AccessorList.Accessors.FirstOrDefault(x => x.Keyword.IsKind(SyntaxKind.GetKeyword));
                var setNode = propertyDeclaration.AccessorList.Accessors.FirstOrDefault(x => x.Keyword.IsKind(SyntaxKind.SetKeyword));

                propertyDeclaration =
                    propertyDeclaration
                    .WithAccessorList
                    (
                        propertyDeclaration.AccessorList.WithAccessors(

                            new SyntaxList <AccessorDeclarationSyntax>()
                            .Add(
                                getNode
                                .WithBody(null)
                                .WithTrailingTrivia()
                                .WithSemicolonToken(
                                    SyntaxFactory.ParseToken(";")
                                    .WithTrailingTrivia(SyntaxFactory.Space)
                                    )
                                .WithLeadingTrivia(SyntaxFactory.Space)

                                )
                            .Add(
                                setNode
                                .WithBody(null)
                                .WithTrailingTrivia()
                                .WithSemicolonToken(
                                    SyntaxFactory.ParseToken(";")
                                    .WithTrailingTrivia(SyntaxFactory.Space)

                                    )
                                .WithLeadingTrivia(SyntaxFactory.Space)
                                )
                            )
                        .WithOpenBraceToken(propertyDeclaration.AccessorList.OpenBraceToken.WithLeadingTrivia().WithTrailingTrivia())
                        .WithCloseBraceToken(propertyDeclaration.AccessorList.CloseBraceToken.WithLeadingTrivia())
                    )
                    .WithIdentifier(propertyDeclaration.Identifier.WithTrailingTrivia(SyntaxFactory.Space))
                    .WithLeadingTrivia(leadingList);

                return(propertyDeclaration);
            }
Пример #6
0
        public static SyntaxNode Do(Compilation compilation, Compilation interfacesCompilation, SyntaxNode root, SyntaxNode targetTypeDeclaration)
        {
            // Couldn't get SymbolFinder.FindImplementedInterfaceMembersAsync or .FindImplementations working, so doing it the hard hacky way.

            if (targetTypeDeclaration is StructDeclarationSyntax)
            {
                return(root); // not propagating documentation into the structs (used for enumeration entry definitions)
            }

            // collect all interfaces and the methods/properties they declare
            Dictionary <InterfaceDeclarationSyntax, List <MemberDeclarationSyntax> > interfaces = new Dictionary <InterfaceDeclarationSyntax, List <MemberDeclarationSyntax> >();

            foreach (Compilation compilation1 in new Compilation[] { interfacesCompilation, compilation })
            {
                foreach (SyntaxTree interfaceTree in compilation1.SyntaxTrees)
                {
                    foreach (SyntaxNode node in interfaceTree.GetRoot().DescendantNodesAndSelf().Where(
                                 delegate(SyntaxNode candidate) { return(candidate.IsKind(SyntaxKind.InterfaceDeclaration)); }))
                    {
                        if (AttributeMatchUtil.HasAttributeSimple(((InterfaceDeclarationSyntax)node).AttributeLists, DocSourceAttributeName))
                        {
                            List <MemberDeclarationSyntax> members = new List <MemberDeclarationSyntax>();
                            foreach (SyntaxNode decl in node.DescendantNodesAndSelf().Where(delegate(SyntaxNode candidate)
                                                                                            { return(candidate.IsKind(SyntaxKind.MethodDeclaration) || candidate.IsKind(SyntaxKind.PropertyDeclaration)); }))
                            {
                                members.Add((MemberDeclarationSyntax)decl);
                            }
                            InterfaceDeclarationSyntax ifaceDecl = (InterfaceDeclarationSyntax)node;
                            interfaces.Add(ifaceDecl, members);
                        }
                    }
                }
            }

            // enumrate base types of generated class
            List <BaseTypeSyntax> baseTypes = new List <BaseTypeSyntax>();
            {
                IEnumerable <BaseTypeSyntax> baseTypeList = ((ClassDeclarationSyntax)targetTypeDeclaration).BaseList.Types;
                foreach (BaseTypeSyntax baseType in baseTypeList)
                {
                    baseTypes.Add(baseType);
                }
            }

            Dictionary <SyntaxNode, SyntaxNode> replacements = new Dictionary <SyntaxNode, SyntaxNode>();

            foreach (BaseTypeSyntax baseType in baseTypes)
            {
                // can we find an interface that matches this?
                foreach (KeyValuePair <InterfaceDeclarationSyntax, List <MemberDeclarationSyntax> > interfaceItem in interfaces)
                {
                    InterfaceDeclarationSyntax interfaceDeclaration = interfaceItem.Key;
                    // hack
                    string baseTypeString = GetStringForBaseTypeComparison(baseType);
                    string patternString  = GetStringForInterfaceComparison(interfaceDeclaration);
                    //Console.WriteLine("{2}  {0}  ?  {1}", baseTypeString, patternString, String.Equals(baseTypeString, patternString) ? "*" : " ");
                    if (String.Equals(baseTypeString, patternString))
                    {
                        // can we find any members we implemented that are in the interface?
                        foreach (SyntaxNode node in targetTypeDeclaration.DescendantNodes(delegate(SyntaxNode descendInto) { return((descendInto == targetTypeDeclaration) || descendInto.IsKind(SyntaxKind.MethodDeclaration) || descendInto.IsKind(SyntaxKind.PropertyDeclaration)); })
                                 .Where(delegate(SyntaxNode candidate) { return(candidate.IsKind(SyntaxKind.MethodDeclaration) || candidate.IsKind(SyntaxKind.PropertyDeclaration)); }))
                        {
                            if (node.IsKind(SyntaxKind.MethodDeclaration))
                            {
                                MethodDeclarationSyntax implementation = (MethodDeclarationSyntax)node;
                                if (default(SyntaxToken) == implementation.Modifiers.FirstOrDefault(delegate(SyntaxToken candidate) { return(candidate.IsKind(SyntaxKind.PublicKeyword)); }))
                                {
                                    continue; // non-public can't be from an interface
                                }
                                foreach (MemberDeclarationSyntax prototype1 in interfaceItem.Value)
                                {
                                    if (prototype1.IsKind(SyntaxKind.MethodDeclaration))
                                    {
                                        MethodDeclarationSyntax prototype = (MethodDeclarationSyntax)prototype1;
                                        // HACK: should check argument and return types
                                        if (SyntaxFactory.AreEquivalent(implementation.Identifier, prototype.Identifier) &&
                                            (implementation.ParameterList.Parameters.Count == prototype.ParameterList.Parameters.Count))
                                        {
                                            // copy documentation
                                            SyntaxNode replacement =
                                                node.WithLeadingTrivia(
                                                    node.GetLeadingTrivia()
                                                    .Add(SyntaxFactory.EndOfLine(Environment.NewLine))
                                                    .AddRange(CookDocumentationTrivia(prototype.GetLeadingTrivia())));
                                            if (!replacements.ContainsKey(node)) // in case exposed by multiple interfaces
                                            {
                                                replacements.Add(node, replacement);
                                            }

                                            break;
                                        }
                                    }
                                }
                            }
                            else if (node.IsKind(SyntaxKind.PropertyDeclaration))
                            {
                                PropertyDeclarationSyntax implementation = (PropertyDeclarationSyntax)node;
                                if (default(SyntaxToken) == implementation.Modifiers.FirstOrDefault(delegate(SyntaxToken candidate) { return(candidate.IsKind(SyntaxKind.PublicKeyword)); }))
                                {
                                    continue; // non-public can't be from an interface
                                }
                                foreach (MemberDeclarationSyntax prototype1 in interfaceItem.Value)
                                {
                                    if (prototype1.IsKind(SyntaxKind.PropertyDeclaration))
                                    {
                                        PropertyDeclarationSyntax prototype = (PropertyDeclarationSyntax)prototype1;
                                        // HACK
                                        if (SyntaxFactory.AreEquivalent(implementation.Identifier, prototype.Identifier))
                                        {
                                            // copy documentation
                                            SyntaxNode replacement =
                                                node.WithLeadingTrivia(
                                                    node.GetLeadingTrivia()
                                                    .Add(SyntaxFactory.EndOfLine(Environment.NewLine))
                                                    .AddRange(CookDocumentationTrivia(prototype.GetLeadingTrivia())));
                                            if (!replacements.ContainsKey(node)) // in case exposed by multiple interfaces
                                            {
                                                replacements.Add(node, replacement);
                                            }

                                            break;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                throw new ArgumentException();
                            }
                        }

                        break;
                    }
                }
            }
            SyntaxNodeReplacementRewriter syntaxNodeReplacementRewriter = new SyntaxNodeReplacementRewriter(replacements);

            root = syntaxNodeReplacementRewriter.Visit(root);

            // This is probably really slow - but we can use AreEquivalent() since we've only changed trivia
            targetTypeDeclaration = root.DescendantNodes().First(delegate(SyntaxNode candidate) { return(SyntaxFactory.AreEquivalent(targetTypeDeclaration, candidate)); });

            replacements.Clear();
            foreach (BaseTypeSyntax baseType in baseTypes)
            {
                // can we find an interface that matches this?
                foreach (KeyValuePair <InterfaceDeclarationSyntax, List <MemberDeclarationSyntax> > interfaceItem in interfaces)
                {
                    InterfaceDeclarationSyntax interfaceDeclaration = interfaceItem.Key;
                    // hack
                    if (String.Equals(baseType.Type.ToString(), String.Concat(interfaceDeclaration.Identifier.Text, interfaceDeclaration.TypeParameterList != null ? interfaceDeclaration.TypeParameterList.ToString() : null)))
                    {
                        // propagate interface comment to class
                        if (!replacements.ContainsKey(targetTypeDeclaration))
                        {
                            replacements.Add(
                                targetTypeDeclaration,
                                targetTypeDeclaration.WithLeadingTrivia(
                                    targetTypeDeclaration.GetLeadingTrivia()
                                    .Add(SyntaxFactory.EndOfLine(Environment.NewLine))
                                    .AddRange(CookDocumentationTrivia(interfaceDeclaration.GetLeadingTrivia()))));
                        }

                        break;
                    }
                }
            }
            syntaxNodeReplacementRewriter = new SyntaxNodeReplacementRewriter(replacements);
            root = syntaxNodeReplacementRewriter.Visit(root);

            return(root);
        }
        public static SyntaxNode RemoveModifierFromNode(SyntaxNode node, SyntaxKind modifier)
        {
            //there seem to be no base classes to support WithModifiers.
            //dynamic modifiersNode = node;
            //return modifiersNode.WithModifiers(SyntaxFactory.TokenList(modifiersNode.Modifiers.Where(m => !m.IsKind(SyntaxKind.PrivateKeyword))));

            MethodDeclarationSyntax methodNode = node as MethodDeclarationSyntax;

            if (methodNode != null)
            {
                return(methodNode.WithModifiers(SyntaxFactory.TokenList(methodNode.Modifiers.Where(m => !m.IsKind(modifier))))
                       .WithLeadingTrivia(methodNode.GetLeadingTrivia()));
            }

            FieldDeclarationSyntax fieldNode = node as FieldDeclarationSyntax;

            if (fieldNode != null)
            {
                return(fieldNode.WithModifiers(SyntaxFactory.TokenList(fieldNode.Modifiers.Where(m => !m.IsKind(modifier))))
                       .WithLeadingTrivia(fieldNode.GetLeadingTrivia()));
            }

            PropertyDeclarationSyntax propertyNode = node as PropertyDeclarationSyntax;

            if (propertyNode != null)
            {
                return(propertyNode.WithModifiers(SyntaxFactory.TokenList(propertyNode.Modifiers.Where(m => !m.IsKind(modifier))))
                       .WithLeadingTrivia(propertyNode.GetLeadingTrivia()));
            }

            IndexerDeclarationSyntax indexerNode = node as IndexerDeclarationSyntax;

            if (indexerNode != null)
            {
                return(indexerNode.WithModifiers(SyntaxFactory.TokenList(indexerNode.Modifiers.Where(m => !m.IsKind(modifier))))
                       .WithLeadingTrivia(indexerNode.GetLeadingTrivia()));
            }

            EventDeclarationSyntax eventNode = node as EventDeclarationSyntax;

            if (eventNode != null)
            {
                return(eventNode.WithModifiers(SyntaxFactory.TokenList(eventNode.Modifiers.Where(m => !m.IsKind(modifier))))
                       .WithLeadingTrivia(eventNode.GetLeadingTrivia()));
            }

            ConstructorDeclarationSyntax ctrNode = node as ConstructorDeclarationSyntax;

            if (ctrNode != null)
            {
                return(ctrNode.WithModifiers(SyntaxFactory.TokenList(ctrNode.Modifiers.Where(m => !m.IsKind(modifier))))
                       .WithLeadingTrivia(ctrNode.GetLeadingTrivia()));
            }

            OperatorDeclarationSyntax opNode = node as OperatorDeclarationSyntax;

            if (opNode != null)
            {
                return(opNode.WithModifiers(SyntaxFactory.TokenList(opNode.Modifiers.Where(m => !m.IsKind(modifier))))
                       .WithLeadingTrivia(opNode.GetLeadingTrivia()));
            }

            ClassDeclarationSyntax classNode = node as ClassDeclarationSyntax;

            if (classNode != null)
            {
                return(classNode.WithModifiers(SyntaxFactory.TokenList(classNode.Modifiers.Where(m => !m.IsKind(modifier))))
                       .WithLeadingTrivia(classNode.GetLeadingTrivia()));
            }

            InterfaceDeclarationSyntax interfaceNode = node as InterfaceDeclarationSyntax;

            if (interfaceNode != null)
            {
                return(interfaceNode.WithModifiers(SyntaxFactory.TokenList(interfaceNode.Modifiers.Where(m => !m.IsKind(modifier))))
                       .WithLeadingTrivia(interfaceNode.GetLeadingTrivia()));
            }

            StructDeclarationSyntax structNode = node as StructDeclarationSyntax;

            if (structNode != null)
            {
                return(structNode.WithModifiers(SyntaxFactory.TokenList(structNode.Modifiers.Where(m => !m.IsKind(modifier))))
                       .WithLeadingTrivia(structNode.GetLeadingTrivia()));
            }

            var enumNode = node as EnumDeclarationSyntax;

            if (enumNode != null)
            {
                return(enumNode.WithModifiers(SyntaxFactory.TokenList(enumNode.Modifiers.Where(m => !m.IsKind(modifier))))
                       .WithLeadingTrivia(enumNode.GetLeadingTrivia()));
            }

            var delegateNode = node as DelegateDeclarationSyntax;

            if (delegateNode != null)
            {
                return(delegateNode.WithModifiers(SyntaxFactory.TokenList(delegateNode.Modifiers.Where(m => !m.IsKind(modifier))))
                       .WithLeadingTrivia(delegateNode.GetLeadingTrivia()));
            }
            return(node);
        }
Пример #8
0
        private async Task <Document> CreatePrismProperty(Document document, PropertyDeclarationSyntax propertyDeclaration, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var classDeclaration = propertyDeclaration.FirstAncestorOrSelf <ClassDeclarationSyntax>();
            var fields           = classDeclaration?.DescendantNodes().OfType <FieldDeclarationSyntax>();

            var backingFieldName = propertyDeclaration.Identifier.ValueText;

            if (char.IsUpper(backingFieldName, 0))
            {
                backingFieldName = char.ToLower(backingFieldName[0]) + backingFieldName.Substring(1);
            }
            else
            {
                backingFieldName = "_" + backingFieldName;
            }

            if (fields != null)
            {
                int i = 1;
                while (fields.Any(f => f.Declaration.Variables.Any(v => v.Identifier.ValueText == backingFieldName)))
                {
                    i++;
                    backingFieldName = backingFieldName + i.ToString("D");
                }
            }

            var indentation = propertyDeclaration.GetLeadingTrivia().LastOrDefault(t => t.Kind() == SyntaxKind.WhitespaceTrivia);

            var newFieldDeclaration =
                SyntaxFactory.FieldDeclaration(
                    SyntaxFactory.VariableDeclaration(
                        propertyDeclaration.Type.WithTrailingTrivia(SyntaxFactory.Space),
                        SyntaxFactory.SingletonSeparatedList(SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(backingFieldName)))))
                .WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxFactory.TriviaList(indentation), SyntaxKind.PrivateKeyword, SyntaxFactory.TriviaList(SyntaxFactory.Space))));

            var newPropertyDeclaration = propertyDeclaration
                                         .WithAccessorList(SyntaxFactory.AccessorList(SyntaxFactory.List(new[] { CreateGetter(backingFieldName), CreateSetter(backingFieldName) })));

            var newRoot = root.ReplaceNode(propertyDeclaration, newPropertyDeclaration);

            classDeclaration = classDeclaration != null?newRoot.DescendantNodes().OfType <ClassDeclarationSyntax>().FirstOrDefault(c => c.Identifier.ValueText == classDeclaration.Identifier.ValueText) : null;

            if (classDeclaration != null)
            {
                var ctor = classDeclaration.DescendantNodes().OfType <ConstructorDeclarationSyntax>().FirstOrDefault();
                if (ctor != null)
                {
                    newRoot = newRoot.InsertNodesBefore(ctor, new[] { newFieldDeclaration });
                }
                else
                {
                    var lastFieldDeclaration = classDeclaration.DescendantNodes().OfType <FieldDeclarationSyntax>().LastOrDefault();
                    if (lastFieldDeclaration != null)
                    {
                        newRoot = newRoot.InsertNodesAfter(lastFieldDeclaration, new[] { newFieldDeclaration });
                    }
                    else
                    {
                        var newMembers = classDeclaration.Members.Insert(0, newFieldDeclaration);
                        newRoot = newRoot.ReplaceNode(classDeclaration, classDeclaration.WithMembers(newMembers));
                    }
                }
            }
            else
            {
                newRoot = newRoot.InsertNodesBefore(newRoot.DescendantNodes().OfType <PropertyDeclarationSyntax>().FirstOrDefault(), new[] { newFieldDeclaration });
            }

            return(document.WithSyntaxRoot(newRoot));
        }
Пример #9
0
        public static PropertyDeclarationSyntax ConvertToExpressionBodiedHelper(PropertyDeclarationSyntax propertyDeclaration)
        {
            if (propertyDeclaration.AccessorList == null)
            {
                return(propertyDeclaration);
            }

            var getNode =
                propertyDeclaration.AccessorList.Accessors.FirstOrDefault(
                    x => x.Keyword.IsKind(SyntaxKind.GetKeyword));

            var setNode =
                propertyDeclaration.AccessorList.Accessors.FirstOrDefault(
                    x => x.Keyword.IsKind(SyntaxKind.SetKeyword));

            if (setNode != null || getNode.Body == null)
            {
                return(propertyDeclaration);
            }
            if (getNode.Body == null)
            {
                return(propertyDeclaration);
            }
            if (getNode.Body.Statements.Count > 1)
            {
                return(propertyDeclaration);
            }
            if (getNode.Body.ContainsDirectives)
            {
                return(propertyDeclaration);
            }

            var returnStatements = getNode.Body.Statements.OfType <ReturnStatementSyntax>().ToList();

            if (returnStatements.Count() != 1)
            {
                return(propertyDeclaration);
            }
            var expression = returnStatements.FirstOrDefault().Expression.WithoutTrivia();

            var length =
                expression.Span.Length +
                propertyDeclaration.Span.Length -
                propertyDeclaration.AccessorList.FullSpan.Length;

            if (length >= 100)
            {
                return(propertyDeclaration);
            }

            propertyDeclaration =
                propertyDeclaration
                .WithIdentifier(propertyDeclaration.Identifier.WithTrailingTrivia(_spaceTrivia))
                .WithLeadingTrivia(propertyDeclaration.GetLeadingTrivia())
                .WithExpressionBody(
                    SyntaxFactory.ArrowExpressionClause(expression.WithLeadingTrivia(_spaceTrivia)))
                .WithAccessorList(null)
                .WithSemicolonToken(GetSemicolon(propertyDeclaration.AccessorList))
                .WithAdditionalAnnotations(Formatter.Annotation);

            return(propertyDeclaration);
        }
Пример #10
0
        private PropertyInfo GetPropertyInfo(PropertyDeclarationSyntax node, SemanticModel semanticModel)
        {
            // 得到备注
            var singleLineComment = node.GetLeadingTrivia().Where(x => x.Kind() == SyntaxKind.SingleLineDocumentationCommentTrivia);

            var isEnumerable = false;
            var isGeneric    = false;
            var typeInfo     = semanticModel.GetTypeInfo(node.Type);

            var propertyName = node.Identifier.ValueText;
            var hasSetter    = node.AccessorList?.Accessors.FirstOrDefault(
                a => a.IsKind(SyntaxKind.SetAccessorDeclaration) &&
                !a.Modifiers.Any(m => m.IsKind(SyntaxKind.PrivateKeyword))) != null;
            var            typeName = "";
            PropertyMapper mapper   = new UnknownTypePropertyMapper(propertyName, hasSetter);

            if (typeInfo.ConvertedType is INamedTypeSymbol namedType)
            {
                var namedTypeFullName = namedType.ToString().Replace(" ", string.Empty);
                isEnumerable = namedType.ConstructedFrom.MemberNames.Contains("GetEnumerator");
                var simpleTypeKinds = new[] { TypeKind.Enum, TypeKind.Struct, TypeKind.Interface };
                var isSimple        = namedType.IsValueType ||
                                      simpleTypeKinds.Any(t => namedType.TypeKind == t) ||
                                      namedType.Name.Equals("object", StringComparison.CurrentCultureIgnoreCase) ||
                                      namedType.Name.Equals("string", StringComparison.CurrentCultureIgnoreCase);

                if (isSimple)
                {
                    mapper = new SimplePropertyMapper(propertyName, hasSetter);
                }
                else
                {
                    isGeneric = namedType.ConstructedFrom.IsGenericType;
                    if (isEnumerable)
                    {
                        if (namedType.Name.Equals("List", StringComparison.InvariantCultureIgnoreCase))
                        {
                            typeName = namedTypeFullName.Substring(namedTypeFullName.LastIndexOf(".List", StringComparison.InvariantCultureIgnoreCase) + 1);
                            var fullGenericPart = $"{typeName.Replace("List<", string.Empty).Replace(">", string.Empty)}";
                            var genericPart     = fullGenericPart.Substring(fullGenericPart.LastIndexOf('.') + 1);

                            if (Constants.SimpleTypeNames.Any(t => genericPart.Equals(t)))
                            {
                                mapper = new SimpleGenericListPropertyMapper(propertyName, hasSetter);
                            }
                            else
                            {
                                genericPart = $"{genericPart}{Constants.DtoSuffix}";
                                mapper      = new ListPropertyMapper(genericPart, propertyName, hasSetter);
                            }
                            typeName = $"List<{genericPart}>";
                        }
                    }
                    else
                    {
                        typeName = $"{namedType.Name}{Constants.DtoSuffix}";
                        mapper   = new ClassPropertyMapper(typeName, propertyName, hasSetter);
                    }
                }
            }
            else
            {
                if (typeInfo.ConvertedType.Kind == SymbolKind.ArrayType && typeInfo.ConvertedType is IArrayTypeSymbol arrayType)
                {
                    if (arrayType.ElementType.IsValueType || arrayType.ElementType.Name.ToLowerInvariant().Contains("string"))
                    {
                        mapper = new SimpleArrayPropertyMapper(propertyName, hasSetter);
                    }
                    else
                    {
                        typeName = $"{arrayType.ElementType.Name}{Constants.DtoSuffix}[]";
                        mapper   = new ArrayPropertyMapper($"{arrayType.ElementType.Name}{Constants.DtoSuffix}", propertyName, hasSetter);
                    }

                    isEnumerable = true;
                }
            }

            return(new PropertyInfo
            {
                Name = propertyName,
                Type = node.Type,
                TypeName = typeName,
                IsEnumerableType = isEnumerable,
                IsGenericType = isGeneric,
                Mapper = mapper,
                HasSetter = hasSetter,
                CommentTrivias = singleLineComment
            });
        }
Пример #11
0
        public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node)
        {
            var hasMatch = NodeHelper.HasMatch(node.AttributeLists, Constants.Data.PROPERTY_ATTRIBUTE_NAME, Constants.Data.PROPERTY_IGNORE_ATTRIBUTE_NAME);

            if (!hasMatch)
            {
                var name      = SyntaxFactory.ParseName(Constants.Data.PROPERTY_ATTRIBUTE_NAME);
                var arguments = SyntaxFactory.ParseAttributeArgumentList($"(Order = {_startIndex})");
                var attribute = SyntaxFactory.Attribute(name, arguments); //DataMember(Order = 1)

                node = TriviaMaintainer.Apply(node, (innerNode, wp) =>
                {
                    var newAttributes = BuildAttribute(attribute, innerNode.AttributeLists, wp);

                    return(innerNode.WithAttributeLists(newAttributes).WithAdditionalAnnotations(Formatter.Annotation));
                });

                _startIndex++;
            }
            else
            {
                //renumber
                if (node.AttributeLists.Count > 0)
                {
                    var newAttributeLists = new SyntaxList <AttributeListSyntax>();
                    foreach (var attributeList in node.AttributeLists)
                    {
                        var attributeSyntaxes = attributeList.Attributes.Where(attribute => NodeHelper.AttributeNameMatches(attribute, Constants.Data.PROPERTY_ATTRIBUTE_NAME)).ToArray();

                        var modifiedAttributeList = attributeList.Attributes;
                        foreach (var attributeSyntax in attributeSyntaxes)
                        {
                            var attributeArguementSyntax = attributeSyntax.ArgumentList?.Arguments.FirstOrDefault(f => f.NameEquals.Name.Identifier.ValueText.Equals("Order"));

                            var newToken      = SyntaxFactory.Literal(_startIndex);
                            var spaceTrivia   = SyntaxFactory.TriviaList(SyntaxFactory.Space);
                            var newExpression = SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, newToken);
                            var equalsToken   = SyntaxFactory.Token(SyntaxFactory.TriviaList(), SyntaxKind.EqualsToken, spaceTrivia);
                            SeparatedSyntaxList <AttributeArgumentSyntax> newSeparatedArgList;
                            if (attributeArguementSyntax?.Expression?.Kind() == SyntaxKind.NumericLiteralExpression)
                            {
                                var oldToken = attributeArguementSyntax.Expression.ChildTokens().FirstOrDefault(f => f.Kind() == SyntaxKind.NumericLiteralToken);
                                if (oldToken == default)
                                {
                                    continue;
                                }
                                var newIdentifier           = attributeArguementSyntax.NameEquals.Name.Identifier.WithLeadingTrivia().WithTrailingTrivia(spaceTrivia);
                                var newIdentifierNameSyntax = attributeArguementSyntax.NameEquals.Name.Update(newIdentifier);
                                var newName = attributeArguementSyntax.NameEquals.Update(newIdentifierNameSyntax, equalsToken);
                                var newAttributeArguementSyntax = attributeArguementSyntax.Update(newName, null, newExpression);
                                newSeparatedArgList = attributeSyntax.ArgumentList.Arguments.Replace(attributeArguementSyntax, newAttributeArguementSyntax);
                            }
                            else
                            {
                                //No order attribute add it
                                var newIdentifierNameSyntax = SyntaxFactory.IdentifierName("Order").WithTrailingTrivia(spaceTrivia);
                                var newName = SyntaxFactory.NameEquals(newIdentifierNameSyntax, equalsToken);
                                var newAttributeArguementSyntax = SyntaxFactory.AttributeArgument(newName, null, newExpression);
                                if (attributeSyntax.ArgumentList == null)
                                {
                                    var arguments = SyntaxFactory.AttributeArgumentList();
                                    newSeparatedArgList = arguments.Arguments.Add(newAttributeArguementSyntax);
                                }
                                else
                                {
                                    newSeparatedArgList = attributeSyntax.ArgumentList.Arguments.Add(newAttributeArguementSyntax);
                                }
                            }
                            var newAttributeArgumentListSyntax = attributeSyntax.ArgumentList?.WithArguments(newSeparatedArgList);
                            if (newAttributeArgumentListSyntax == null)
                            {
                                newAttributeArgumentListSyntax = attributeSyntax.WithArgumentList(SyntaxFactory.AttributeArgumentList(newSeparatedArgList)).ArgumentList;
                            }

                            var newAttributeSyntax = attributeSyntax.Update(attributeSyntax.Name, newAttributeArgumentListSyntax);
                            modifiedAttributeList = modifiedAttributeList.Replace(attributeSyntax, newAttributeSyntax);
                            _startIndex++;
                        }
                        newAttributeLists = newAttributeLists.Add(attributeList.WithAttributes(modifiedAttributeList));
                    }
                    var leadTriv = node.GetLeadingTrivia();
                    node = node.WithAttributeLists(newAttributeLists);
                    node = node.WithLeadingTrivia(leadTriv);
                }
            }

            return(base.VisitPropertyDeclaration(node));
        }
Пример #12
0
        private void AddProperty(PropertyDeclarationSyntax modelProperty, string propertyName, string propertyDescriptorName,
                                 TypeSyntax sourcePropertyType, TypeSyntax destinationPropertyType, List <MemberDeclarationSyntax> destinationMembers)
        {
            IdentifierNameSyntax propertyDescriptorIdentifier = IdentifierName(propertyDescriptorName);

            bool classPropertyTypeDiffersFromInterface = sourcePropertyType.ToString() != destinationPropertyType.ToString();

            SyntaxTrivia xmlCommentTrivia = modelProperty.GetLeadingTrivia().FirstOrDefault(t =>
                                                                                            t.Kind() == SyntaxKind.SingleLineDocumentationCommentTrivia ||
                                                                                            t.Kind() == SyntaxKind.MultiLineDocumentationCommentTrivia);
            bool includeXmlComment = classPropertyTypeDiffersFromInterface && xmlCommentTrivia.Kind() != SyntaxKind.None;

            SyntaxTokenList modifiers;

            if (includeXmlComment)
            {
                modifiers = TokenList(
                    Token(
                        TriviaList(xmlCommentTrivia),
                        SyntaxKind.PublicKeyword,
                        TriviaList()));
            }
            else
            {
                modifiers = TokenList(Token(SyntaxKind.PublicKeyword));
            }

            PropertyDeclarationSyntax propertyDeclaration;

            if (_outputType is XamlOutputType)
            {
                propertyDeclaration = PropertyDeclaration(destinationPropertyType, propertyName)
                                      .WithModifiers(modifiers)
                                      .WithAccessorList(
                    AccessorList(
                        List(new[]
                {
                    AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                    .WithExpressionBody(
                        ArrowExpressionClause(
                            CastExpression(
                                destinationPropertyType,
                                InvocationExpression(IdentifierName("GetValue"))
                                .WithArgumentList(ArgumentList(
                                                      SingletonSeparatedList(
                                                          Argument(propertyDescriptorIdentifier)))))))
                    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
                    AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                    .WithExpressionBody(
                        ArrowExpressionClause(InvocationExpression(IdentifierName("SetValue"))
                                              .WithArgumentList(ArgumentList(
                                                                    SeparatedList <ArgumentSyntax>(
                                                                        new SyntaxNodeOrToken[]
                    {
                        Argument(propertyDescriptorIdentifier),
                        Token(SyntaxKind.CommaToken),
                        Argument(IdentifierName("value"))
                    })))))
                    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
                })))
                                      .NormalizeWhitespace();
            }
            else
            {
                ExpressionSyntax defaultValue = GetDefaultValue(modelProperty, destinationPropertyType);

                propertyDeclaration = PropertyDeclaration(destinationPropertyType, propertyName)
                                      .WithModifiers(modifiers)
                                      .WithAccessorList(
                    AccessorList(
                        List(new[]
                {
                    AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
                    AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
                })))
                                      .WithInitializer(
                    EqualsValueClause(defaultValue))
                                      .WithSemicolonToken(
                    Token(SyntaxKind.SemicolonToken));
            }

            //if (!includeXmlComment)
            propertyDeclaration = propertyDeclaration.WithLeadingTrivia(
                TriviaList(propertyDeclaration.GetLeadingTrivia()
                           .Insert(0, CarriageReturnLineFeed)
                           .Insert(0, CarriageReturnLineFeed)));

            destinationMembers.Add(propertyDeclaration);

            // If the interface property has a different type, add another property that explicitly implements it
            if (classPropertyTypeDiffersFromInterface)
            {
                ExpressionSyntax arrowRightHandSide;
                if (sourcePropertyType is IdentifierNameSyntax identifierName &&
                    IsWrappedType(identifierName.Identifier.Text))
                {
                    string wrapperTypeName = identifierName.Identifier.Text;

                    arrowRightHandSide =
                        MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            IdentifierName(propertyName),
                            IdentifierName($"Wrapped{wrapperTypeName}"));
                }
                else
                {
                    arrowRightHandSide = IdentifierName(propertyName);
                }

                PropertyDeclarationSyntax explicitInterfaceProperty =
                    PropertyDeclaration(sourcePropertyType, propertyName)
                    .WithExplicitInterfaceSpecifier(
                        ExplicitInterfaceSpecifier(IdentifierName(_sourceInterfaceDeclaration.Identifier)))
                    .WithExpressionBody(
                        ArrowExpressionClause(arrowRightHandSide))
                    .WithSemicolonToken(Token(SyntaxKind.SemicolonToken));

                destinationMembers.Add(explicitInterfaceProperty);
            }
Пример #13
0
        internal static DocumentedElement LoadFromSyntaxNode(PropertyDeclarationSyntax node)
        {
            SyntaxToken syntaxToken = node.ChildTokens().First(token => token.IsKind(SyntaxKind.IdentifierToken));

            return(DocumentedElement.LoadFromSyntaxTokenAndTrivia(syntaxToken, node.GetLeadingTrivia()));
        }