예제 #1
0
        public void Namespaces_MultipleTypesWithDifferentNamespaces()
        {
            //-- arrange

            var generatorUnderTest = new CSharpSyntaxGenerator();
            var typesToCompile     = new TypeMember[] {
                new TypeMember("My.Namespace1", MemberVisibility.Public, TypeMemberKind.Class, "ClassOne"),
                new TypeMember("My.Namespace2", MemberVisibility.Public, TypeMemberKind.Class, "ClassTwo"),
                new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassA"),
                new TypeMember("My.Namespace1", MemberVisibility.Public, TypeMemberKind.Class, "ClassThree"),
                new TypeMember("My.Namespace2", MemberVisibility.Public, TypeMemberKind.Class, "ClassFour"),
                new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassB"),
            };

            //-- act

            SyntaxTree syntax = generatorUnderTest.GenerateSyntax(typesToCompile);

            //-- assert

            syntax.Should().BeEquivalentToCode(@"
                public class ClassA { }
                public class ClassB { }
                namespace My.Namespace1
                {
                    public class ClassOne { }
                    public class ClassThree { }
                }
                namespace My.Namespace2
                {
                    public class ClassTwo { }
                    public class ClassFour { }
                }
            ");
        }
        public override TDeclarationNode AddParameters <TDeclarationNode>(
            TDeclarationNode destination,
            IEnumerable <IParameterSymbol> parameters,
            CodeGenerationOptions options,
            CancellationToken cancellationToken)
        {
            var currentParameterList = CSharpSyntaxGenerator.GetParameterList(destination);

            if (currentParameterList == null)
            {
                return(destination);
            }

            var currentParamsCount = currentParameterList.Parameters.Count;
            var seenOptional       = currentParamsCount > 0 && currentParameterList.Parameters[currentParamsCount - 1].Default != null;
            var isFirstParam       = currentParamsCount == 0;
            var newParams          = ArrayBuilder <SyntaxNode> .GetInstance();

            foreach (var parameter in parameters)
            {
                var parameterSyntax = ParameterGenerator.GetParameter(parameter, options, isExplicit: false, isFirstParam: isFirstParam, seenOptional: seenOptional);

                isFirstParam = false;
                seenOptional = seenOptional || parameterSyntax.Default != null;
                newParams.Add(parameterSyntax);
            }

            var finalMember = CSharpSyntaxGenerator.Instance.AddParameters(destination, newParams.ToImmutableAndFree());

            return(Cast <TDeclarationNode>(finalMember));
        }
예제 #3
0
        public void Usings_SomeTypeNamesDuplicate_OnlyDuplicatesReferredByQualifiedName()
        {
            //-- arrange

            var generatorUnderTest = new CSharpSyntaxGenerator();

            var typeFirstClassA  = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "ClassA");
            var typeFirstClassB  = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "ClassB");
            var typeSecondClassA = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Second", MemberVisibility.Public, TypeMemberKind.Class, "ClassA");
            var typeSecondClassC = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Second", MemberVisibility.Public, TypeMemberKind.Class, "ClassC");
            var typeThirdClassD  = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Third", MemberVisibility.Public, TypeMemberKind.Class, "ClassD");

            typeThirdClassD.Members.Add(new PropertyMember(typeThirdClassD, MemberVisibility.Public, MemberModifier.None, typeFirstClassA, "FirstA"));
            typeThirdClassD.Members.Add(new PropertyMember(typeThirdClassD, MemberVisibility.Public, MemberModifier.None, typeFirstClassB, "FirstB"));
            typeThirdClassD.Members.Add(new PropertyMember(typeThirdClassD, MemberVisibility.Public, MemberModifier.None, typeSecondClassA, "SecondA"));
            typeThirdClassD.Members.Add(new PropertyMember(typeThirdClassD, MemberVisibility.Public, MemberModifier.None, typeSecondClassC, "SecondC"));

            //-- act

            SyntaxTree syntax = generatorUnderTest.GenerateSyntax(
                typesToCompile: new[] { typeFirstClassA, typeFirstClassB, typeSecondClassA, typeSecondClassC, typeThirdClassD },
                allReferencedTypes: new[] { typeFirstClassA, typeFirstClassB, typeSecondClassA, typeSecondClassC });

            //-- assert

            syntax.Should().BeEquivalentToCode(@"
                using My.First;
                using My.Second;

                namespace My.First
                {
                    public class ClassA 
                    {
                    }
                    public class ClassB
                    {
                    }
                }
                namespace My.Second
                {
                    public class ClassA
                    {
                    }
                    public class ClassC
                    {
                    }
                }
                namespace My.Third
                {
                    public class ClassD
                    {
                        public My.First.ClassA FirstA { get; }
                        public ClassB FirstB { get; }
                        public My.Second.ClassA SecondA { get; }
                        public ClassC SecondC { get; }
                    }
                }
            ");
        }
예제 #4
0
        protected override SyntaxNode CreateExplicitlyCastedLiteralValue(
            INamedTypeSymbol enumType,
            SpecialType underlyingSpecialType,
            object constantValue)
        {
            var expression = ExpressionGenerator.GenerateNonEnumValueExpression(
                enumType.EnumUnderlyingType, constantValue, canUseFieldReference: true);

            var constantValueULong = EnumUtilities.ConvertEnumUnderlyingTypeToUInt64(constantValue, underlyingSpecialType);
            if (constantValueULong == 0)
            {
                // 0 is always convertible to an enum type without needing a cast.
                return expression;
            }

            var factory = new CSharpSyntaxGenerator();
            return factory.CastExpression(enumType, expression);
        }
예제 #5
0
        private static SyntaxTokenList GenerateModifiers(
            IParameterSymbol parameter, bool isFirstParam)
        {
            SyntaxTokenList list = CSharpSyntaxGenerator.GetParameterModifiers(parameter.RefKind);

            if (isFirstParam &&
                parameter.ContainingSymbol is IMethodSymbol methodSymbol &&
                methodSymbol.IsExtensionMethod)
            {
                list = list.Add(SyntaxFactory.Token(SyntaxKind.ThisKeyword));
            }

            if (parameter.IsParams)
            {
                list = list.Add(SyntaxFactory.Token(SyntaxKind.ParamsKeyword));
            }

            return(list);
        }
예제 #6
0
        protected override SyntaxNode CreateExplicitlyCastedLiteralValue(
            INamedTypeSymbol enumType,
            SpecialType underlyingSpecialType,
            object constantValue)
        {
            var expression = ExpressionGenerator.GenerateNonEnumValueExpression(
                enumType.EnumUnderlyingType, constantValue, canUseFieldReference: true);

            var constantValueULong = EnumUtilities.ConvertEnumUnderlyingTypeToUInt64(constantValue, underlyingSpecialType);

            if (constantValueULong == 0)
            {
                // 0 is always convertible to an enum type without needing a cast.
                return(expression);
            }

            var factory = new CSharpSyntaxGenerator();

            return(factory.CastExpression(enumType, expression));
        }
예제 #7
0
        public void Namespaces_SingleTypeWithNamespace()
        {
            //-- arrange

            var generatorUnderTest = new CSharpSyntaxGenerator();
            var typesToCompile     = new TypeMember[] {
                new TypeMember("My.Namespace", MemberVisibility.Public, TypeMemberKind.Class, "MyClass")
            };

            //-- act

            SyntaxTree syntax = generatorUnderTest.GenerateSyntax(typesToCompile);

            //-- assert

            syntax.Should().BeEquivalentToCode(@"
                namespace My.Namespace
                {
                    public class MyClass { }
                }
            ");
        }
예제 #8
0
        public void Usings_UniqueTypeNames_ReferredByShortName()
        {
            //-- arrange

            var generatorUnderTest = new CSharpSyntaxGenerator();
            var type1 = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "ClassOne");
            var type2 = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Second", MemberVisibility.Public, TypeMemberKind.Class, "ClassTwo");

            type1.Members.Add(new PropertyMember(type1, MemberVisibility.Public, MemberModifier.None, typeof(DateTime), "Time"));
            type2.BaseType = type1;

            //-- act

            SyntaxTree syntax = generatorUnderTest.GenerateSyntax(
                typesToCompile: new[] { type1, type2 },
                allReferencedTypes: new[] { type1, (TypeMember)typeof(DateTime) });

            //-- assert

            syntax.Should().BeEquivalentToCode(@"
                using System;
                using My.First;

                namespace My.First
                {
                    public class ClassOne 
                    {
                        public DateTime Time { get; }
                    }
                }
                namespace My.Second
                {
                    public class ClassTwo : ClassOne { }
                }
            ");
        }
예제 #9
0
 protected override BaseParameterListSyntax TryGetApplicableList(SyntaxNode node)
 => CSharpSyntaxGenerator.GetParameterList(node);
예제 #10
0
        protected void AddSyntax(TextWriter writer)
        {
            var csharpSyntax = new CSharpSyntaxGenerator(this._version).GenerateSyntax(this._versionType);

            base.AddSyntax(writer, csharpSyntax);
        }
            public override TypeSyntax VisitFunctionPointerType(IFunctionPointerTypeSymbol symbol)
            {
                // TODO(https://github.com/dotnet/roslyn/issues/39865): generate the calling convention once exposed through the API
                var parameters = symbol.Signature.Parameters.Select(p => (p.Type, RefKindModifiers: CSharpSyntaxGenerator.GetParameterModifiers(p.RefKind)))
                                 .Concat(SpecializedCollections.SingletonEnumerable((
                                                                                        Type: symbol.Signature.ReturnType,
                                                                                        RefKindModifiers: CSharpSyntaxGenerator.GetParameterModifiers(symbol.Signature.RefKind, forFunctionPointerReturnParameter: true))))
                                 .SelectAsArray(t => SyntaxFactory.Parameter(SyntaxFactory.MissingToken(SyntaxKind.IdentifierToken)).WithModifiers(t.RefKindModifiers).WithType(t.Type.GenerateTypeSyntax()));

                return(AddInformationTo(
                           SyntaxFactory.FunctionPointerType(SyntaxFactory.SeparatedList(parameters)), symbol));
            }
예제 #12
0
        public void Usings_DuplicateTypeNamesWithDifferentGenericArity_ReferredByShortName()
        {
            //-- arrange

            var generatorUnderTest = new CSharpSyntaxGenerator();

            var typeClassList      = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "List");
            var typeClassListInOut =
                new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "List",
                               new TypeMember(MemberVisibility.Public, TypeMemberKind.GenericParameter, "TInner"),
                               new TypeMember(MemberVisibility.Public, TypeMemberKind.GenericParameter, "TOuter"))
            {
                IsGenericType           = true,
                IsGenericTypeDefinition = true
            };
            var typeSecondClassA =
                new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Second", MemberVisibility.Public, TypeMemberKind.Class, "ClassA")
            {
                BaseType = typeClassList
            };
            var typeListOfInt = ((TypeMember)typeof(List <>)).MakeGenericType(typeof(int));

            typeSecondClassA.Members.Add(new PropertyMember(
                                             typeSecondClassA,
                                             MemberVisibility.Public,
                                             MemberModifier.None,
                                             typeListOfInt,
                                             "Numbers"));

            //-- act

            SyntaxTree syntax = generatorUnderTest.GenerateSyntax(
                typesToCompile: new[] {
                typeClassList, typeClassListInOut, typeSecondClassA
            },
                allReferencedTypes: new[] {
                typeClassList, typeClassListInOut, typeSecondClassA, typeof(List <>)
            });

            //-- assert

            syntax.Should().BeEquivalentToCode(@"
                using System.Collections.Generic;
                using My.First;
                using My.Second;

                namespace My.First
                {
                    public class List
                    {
                    }
                    public class List<TInner,TOuter>
                    {
                    }
                }
                namespace My.Second
                {
                    public class ClassA : List
                    {
                        public List<int> Numbers { get; }
                    }
                }
            ");
        }
예제 #13
0
        public void Usings_GenericTypeNames_RulesApplyRecursively()
        {
            //-- arrange

            var generatorUnderTest = new CSharpSyntaxGenerator();

            var typeFirstClassA    = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "ClassA");
            var typeFirstClassList = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "List",
                                                    new TypeMember(new TypeGeneratorInfo(this.GetType()), null, MemberVisibility.Public, TypeMemberKind.GenericParameter, "T"));
            var typeSecondClassA = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Second", MemberVisibility.Public, TypeMemberKind.Class, "ClassA");
            var typeSecondClassB = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Second", MemberVisibility.Public, TypeMemberKind.Class, "ClassB");
            var typeThirdClassC  = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Third", MemberVisibility.Public, TypeMemberKind.Class, "ClassC");

            TypeMember typeGenericDictionary = typeof(Dictionary <,>);
            TypeMember typeGenericList       = typeof(List <>);

            var typeDictionaryOfFirstClassASecondClassA = typeGenericDictionary.MakeGenericType(typeFirstClassA, typeSecondClassA);
            var typeListOfSecondClassB = typeGenericList.MakeGenericType(typeSecondClassB);

            typeThirdClassC.Members.Add(new PropertyMember(
                                            typeThirdClassC,
                                            MemberVisibility.Public,
                                            MemberModifier.None,
                                            typeDictionaryOfFirstClassASecondClassA,
                                            "SecondByFirst"));

            typeThirdClassC.Members.Add(new PropertyMember(
                                            typeThirdClassC,
                                            MemberVisibility.Public,
                                            MemberModifier.None,
                                            typeListOfSecondClassB,
                                            "ListOfB"));

            //-- act

            SyntaxTree syntax = generatorUnderTest.GenerateSyntax(
                typesToCompile: new[] {
                typeFirstClassA, typeFirstClassList, typeSecondClassA, typeSecondClassB, typeThirdClassC
            },
                allReferencedTypes: new[] {
                typeFirstClassA, typeFirstClassList, typeSecondClassA, typeSecondClassB, typeDictionaryOfFirstClassASecondClassA, typeListOfSecondClassB
            });

            //-- assert

            syntax.Should().BeEquivalentToCode(@"
                using System.Collections.Generic;
                using My.Second;

                namespace My.First
                {
                    public class ClassA 
                    {
                    }
                    public class List<T>
                    {
                    }
                }
                namespace My.Second
                {
                    public class ClassA
                    {
                    }
                    public class ClassB
                    {
                    }
                }
                namespace My.Third
                {
                    public class ClassC
                    {
                        public Dictionary<My.First.ClassA, My.Second.ClassA> SecondByFirst { get; }
                        public System.Collections.Generic.List<ClassB> ListOfB { get; }
                    }
                }
            ");
        }