Exemple #1
0
        public void MakeGenericTypeOfBoundTypesResultsInBoundType()
        {
            //-- arrange

            TypeMember typeInt             = typeof(int);
            TypeMember typeString          = typeof(string);
            TypeMember typeIDictionaryOpen = typeof(IDictionary <,>);

            //-- act

            TypeMember constructedType = typeIDictionaryOpen.MakeGenericType(typeInt, typeString);

            //-- assert

            constructedType.ClrBinding.Should().NotBeNull();
            constructedType.ClrBinding.Should().BeSameAs(typeof(IDictionary <int, string>));

            constructedType.Should().NotBeNull();
            constructedType.IsGenericType.Should().BeTrue();
            constructedType.IsGenericTypeDefinition.Should().BeFalse();
            constructedType.GenericTypeDefinition.Should().BeSameAs(typeIDictionaryOpen);
            constructedType.GenericTypeArguments.Count.Should().Be(2);
            constructedType.GenericTypeArguments[0].Should().BeSameAs(typeInt);
            constructedType.GenericTypeArguments[1].Should().BeSameAs(typeString);
        }
Exemple #2
0
        //-----------------------------------------------------------------------------------------------------------------------------------------------------

        private void ImplementActivationInterface(
            TypeMember productType,
            TypeMember activationContract,
            MethodSignature constructorSignature,
            TypeMember artifactType)
        {
            var parameterCount = constructorSignature.Parameters.Count;

            var iConstructorGenericParameters =
                constructorSignature.Parameters.Select(p => p.Type)
                .Append(activationContract);

            TypeMember iConstructorInterfaceOpen   = _s_iConstructorByParameterCount[parameterCount];
            TypeMember iConstructorInterfaceClosed = iConstructorInterfaceOpen.MakeGenericType(iConstructorGenericParameters.ToArray());

            artifactType.Interfaces.Add(iConstructorInterfaceClosed);

            var factoryMethod = new MethodMember(
                MemberVisibility.Public,
                MemberModifier.None,
                nameof(IConstructor <object> .NewInstance),
                new MethodSignature {
                ReturnValue = new MethodParameter {
                    Type = activationContract
                }
            }
                );

            factoryMethod.Signature.Parameters.AddRange(constructorSignature.Parameters);

            var newObjectExpression = new NewObjectExpression {
                Type            = productType,
                ConstructorCall = new MethodCallExpression()
            };

            newObjectExpression.ConstructorCall.Arguments.AddRange(
                constructorSignature.Parameters.Select(p => new Argument {
                Expression = new ParameterExpression {
                    Parameter = p
                }
            }));

            factoryMethod.Body = new BlockStatement(
                new ReturnStatement {
                Expression = newObjectExpression
            }
                );

            ImplementSingletonMethod(productType, activationContract, constructorSignature, artifactType);

            artifactType.Members.Add(factoryMethod);
        }
Exemple #3
0
        public void MakeGenericTypeOfMixedBoundAndGeneratedTypesResultsInGeneratedType()
        {
            //-- arrange

            TypeMember typeKey             = typeof(int);
            TypeMember typeValue           = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassValue");
            TypeMember typeIDictionaryOpen = typeof(IDictionary <,>);

            //-- act

            TypeMember constructedType = typeIDictionaryOpen.MakeGenericType(typeKey, typeValue);

            //-- assert

            constructedType.ClrBinding.Should().BeNull();

            constructedType.Should().NotBeNull();
            constructedType.IsGenericType.Should().BeTrue();
            constructedType.IsGenericTypeDefinition.Should().BeFalse();
            constructedType.GenericTypeDefinition.Should().BeSameAs(typeIDictionaryOpen);
            constructedType.GenericTypeArguments.Count.Should().Be(2);
            constructedType.GenericTypeArguments[0].Should().BeSameAs(typeKey);
            constructedType.GenericTypeArguments[1].Should().BeSameAs(typeValue);
        }
Exemple #4
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; }
                    }
                }
            ");
        }