Ejemplo n.º 1
0
        public override IEnumerable <SyntaxNode> BuildSyntax(IDom item)
        {
            var itemAsT = item as IClass;

            Guardian.Assert.IsNotNull(itemAsT, nameof(itemAsT));

            var modifiers = item.BuildModfierSyntax();

            if (itemAsT.IsAbstract)
            {
                modifiers = modifiers.Add(SyntaxFactory.Token(SyntaxKind.AbstractKeyword));
            }
            if (itemAsT.IsSealed)
            {
                modifiers = modifiers.Add(SyntaxFactory.Token(SyntaxKind.SealedKeyword));
            }
            if (itemAsT.IsPartial)
            {
                modifiers = modifiers.Add(SyntaxFactory.Token(SyntaxKind.PartialKeyword));
            }
            var identifier = SyntaxFactory.Identifier(itemAsT.Name);

            var node = SyntaxFactory.ClassDeclaration(identifier)
                       .WithModifiers(modifiers);

            node = BuildSyntaxHelpers.AttachWhitespace(node, item.Whitespace2Set, whitespaceLookup);

            var baseList = BuildSyntaxHelpers.GetBaseList(itemAsT);

            if (baseList != null)
            {
                node = node.WithBaseList(baseList);
            }

            var attributes = BuildSyntaxWorker.BuildAttributeSyntax(itemAsT.Attributes);

            if (attributes.Any())
            {
                node = node.WithAttributeLists(BuildSyntaxHelpers.WrapInAttributeList(attributes));
            }

            var membersSyntax = itemAsT.Members
                                .SelectMany(x => RDom.CSharp.GetSyntaxGroup(x))
                                .ToList();

            node = node.WithMembers(SyntaxFactory.List(membersSyntax));

            node = BuildSyntaxHelpers.BuildTypeParameterSyntax(
                itemAsT, node, whitespaceLookup,
                (x, p) => x.WithTypeParameterList(p),
                (x, c) => x.WithConstraintClauses(c));

            return(node.PrepareForBuildSyntaxOutput(item, OutputContext));
        }
Ejemplo n.º 2
0
        public override IEnumerable <SyntaxNode> BuildSyntax(IDom item)
        {
            var itemAsT    = item as IMethod;
            var nameSyntax = SyntaxFactory.Identifier(itemAsT.Name);

            var returnTypeSyntax = (TypeSyntax)RDom.CSharp.GetSyntaxGroup(itemAsT.ReturnType).First();
            var modifiers        = BuildSyntaxHelpers.BuildModfierSyntax(itemAsT);
            var node             = SyntaxFactory.MethodDeclaration(returnTypeSyntax, nameSyntax)
                                   .WithModifiers(modifiers);

            node = BuildSyntaxHelpers.AttachWhitespace(node, itemAsT.Whitespace2Set, WhitespaceLookup);

            var attributes = BuildSyntaxWorker.BuildAttributeSyntax(itemAsT.Attributes);

            if (attributes.Any())
            {
                node = node.WithAttributeLists(BuildSyntaxHelpers.WrapInAttributeList(attributes));
            }

            var parameterList = itemAsT.Parameters
                                .SelectMany(x => RDom.CSharp.GetSyntaxGroup(x))
                                .OfType <ParameterSyntax>()
                                .ToList();

            if (itemAsT.IsExtensionMethod)
            {
                // this this is a normal list, ref semantics
                var firstParam = parameterList.FirstOrDefault();
                parameterList.Remove(firstParam);
                if (firstParam == null)
                {
                    throw new InvalidOperationException("Extension methods must have at least one parameter");
                }
                // I'm cheating a bit here. Since the This keyword is an indicator of extension state on the method
                // I'm hardcoding a single space. I don't see the complexity of dealing with this as worth it unless
                // there's gnashing of teeth over this single space. The use of "this" on the parameter is not universal
                // and VB marks the method.
                var thisModifier = SyntaxFactory.Token(SyntaxKind.ThisKeyword)
                                   .WithTrailingTrivia(SyntaxFactory.ParseTrailingTrivia(" "));
                var paramModifiers = firstParam.Modifiers.Insert(0, thisModifier);
                firstParam = firstParam.WithModifiers(paramModifiers);
                parameterList.Insert(0, firstParam);
            }
            var parameterListSyntax = SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList(parameterList));

            parameterListSyntax = BuildSyntaxHelpers.AttachWhitespace(parameterListSyntax, itemAsT.Whitespace2Set, WhitespaceLookup);
            node = node.WithParameterList(parameterListSyntax);

            node = node.WithBody((BlockSyntax)RoslynCSharpUtilities.BuildStatement(itemAsT.Statements, itemAsT, WhitespaceLookup));

            // This works oddly because it uncollapses the list
            // This code is largely repeated in interface and class factories, but is very hard to refactor because of shallow Roslyn (Microsoft) architecture
            var typeParamsAndConstraints = itemAsT.TypeParameters
                                           .SelectMany(x => RDom.CSharp.GetSyntaxGroup(x))
                                           .ToList();

            node = BuildSyntaxHelpers.BuildTypeParameterSyntax(
                itemAsT, node, WhitespaceLookup,
                (x, p) => x.WithTypeParameterList(p),
                (x, c) => x.WithConstraintClauses(c));
            //var typeParameterSyntaxList = BuildSyntaxHelpers.GetTypeParameterSyntaxList(
            //            typeParamsAndConstraints, itemAsT.Whitespace2Set, WhitespaceLookup);
            //if (typeParameterSyntaxList != null)
            //{
            //    node = node.WithTypeParameterList(typeParameterSyntaxList);
            //    var clauses = BuildSyntaxHelpers.GetTypeParameterConstraintList(
            //              typeParamsAndConstraints, itemAsT.Whitespace2Set, WhitespaceLookup);
            //    if (clauses.Any())
            //    { node = node.WithConstraintClauses(clauses); }
            //}

            return(node.PrepareForBuildSyntaxOutput(item, OutputContext));
        }