public void WithProperties() { //-- arrange var classMember = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassOne"); classMember.Members.Add(new PropertyMember(classMember, MemberVisibility.Public, MemberModifier.None, typeof(int), "Number")); classMember.Members.Add(new PropertyMember(classMember, MemberVisibility.Public, MemberModifier.None, typeof(string), "Text")); var emitter = new ClassSyntaxEmitter(classMember); //-- act var syntax = emitter.EmitSyntax(); //-- assert syntax.Should().BeEquivalentToCode(@" public class ClassOne { public int Number { get; } public string Text { get; } } "); }
public void FieldWithInitializer() { //-- arrange var classMember = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassOne"); var fieldMember = new FieldMember(classMember, MemberVisibility.Private, MemberModifier.None, typeof(int), "_number") { IsReadOnly = true, Initializer = new ConstantExpression { Value = 123 } }; classMember.Members.Add(fieldMember); var emitter = new ClassSyntaxEmitter(classMember); //-- act var syntax = emitter.EmitSyntax(); //-- assert syntax.Should().BeEquivalentToCode(@" public class ClassOne { private readonly int _number = 123; } "); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- private MemberDeclarationSyntax EmitTypeSyntax(TypeMember type) { MemberDeclarationSyntax typeSyntax; switch (type.TypeKind) { case TypeMemberKind.Class: var classEmitter = new ClassSyntaxEmitter(type); typeSyntax = classEmitter.EmitSyntax(); break; case TypeMemberKind.Enum: var enumEmitter = new EnumSyntaxEmitter(type); typeSyntax = enumEmitter.EmitSyntax(); break; default: throw new NotSupportedException($"TypeMember of kind '{type.TypeKind}' is not supported."); } var annotation = new SyntaxAnnotation(); typeSyntax = typeSyntax.WithAdditionalAnnotations(annotation); type.SafeBackendTag().Annotation = annotation; return(typeSyntax); }
public void WithMultipleAttributes() { //-- arrange var classMember = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassOne"); classMember.Attributes.Add(new AttributeDescription() { AttributeType = new TypeMember(typeof(System.Diagnostics.DebuggerStepThroughAttribute)) }); classMember.Attributes.Add(new AttributeDescription() { AttributeType = new TypeMember(typeof(System.ComponentModel.LocalizableAttribute)) }); var emitter = new ClassSyntaxEmitter(classMember); //-- act var syntax = emitter.EmitSyntax(); //-- assert syntax.Should().BeEquivalentToCode(@" [System.Diagnostics.DebuggerStepThroughAttribute, System.ComponentModel.LocalizableAttribute] public class ClassOne { } "); }
public void WithMethods() { //-- arrange var classMember = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassOne"); classMember.Members.Add(new MethodMember(MemberVisibility.Public, "First")); classMember.Members.Add(new MethodMember(MemberVisibility.Public, "Second")); var emitter = new ClassSyntaxEmitter(classMember); //-- act var syntax = emitter.EmitSyntax(); //-- assert syntax.Should().BeEquivalentToCode(@" public class ClassOne { public void First() { } public void Second() { } } "); }
public void WithGenericTypeParameters() { //-- arrange var classMember = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassOne", new TypeMember(MemberVisibility.Public, TypeMemberKind.GenericParameter, "T"), new TypeMember(MemberVisibility.Public, TypeMemberKind.GenericParameter, "K")); //classMember.BaseType = new TypeMember(typeof(List<string>)); //classMember.Interfaces.Add(new TypeMember(typeof(IDictionary<int, DateTime>))); var emitter = new ClassSyntaxEmitter(classMember); //-- act var syntax = emitter.EmitSyntax(); //-- assert syntax.Should().BeEquivalentToCode(@" public class ClassOne<T, K> { } "); }
public void CanEmitConstructorDeclaration( string expectedCode, MemberVisibility visibility, MemberModifier modifier, Delegate signaturePrototype, Action <ConstructorMember> constructorSetup) { //-- arrange var constructor = new ConstructorMember(visibility, modifier, "ClassOne", new MethodSignature(signaturePrototype.GetMethodInfo())); if (constructorSetup != null) { constructorSetup(constructor); } var enclosingClassMember = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassOne"); enclosingClassMember.Members.Add(constructor); var enclosingClassEmitter = new ClassSyntaxEmitter(enclosingClassMember); var expectedClassCode = "public class ClassOne { " + expectedCode + " }"; //-- act var actualClassSyntax = enclosingClassEmitter.EmitSyntax(); //-- assert actualClassSyntax.Should().BeEquivalentToCode(expectedClassCode); }
public void Empty() { //-- arrange var classMember = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassOne"); var emitter = new ClassSyntaxEmitter(classMember); //-- act var syntax = emitter.EmitSyntax(); //-- assert syntax.Should().BeEquivalentToCode( "public class ClassOne { }" ); }
public void ClassWithFields() { //-- arrange var classMember = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassOne"); classMember.Members.Add(new FieldMember(classMember, MemberVisibility.Public, MemberModifier.None, typeof(int), "PublicNumber")); classMember.Members.Add(new FieldMember(classMember, MemberVisibility.Protected, MemberModifier.None, typeof(int), "ProtectedNumber")); classMember.Members.Add(new FieldMember(classMember, MemberVisibility.Internal, MemberModifier.None, typeof(int), "InternalNumber")); classMember.Members.Add(new FieldMember(classMember, MemberVisibility.InternalProtected, MemberModifier.None, typeof(int), "InternalProtectedNumber")); classMember.Members.Add(new FieldMember(classMember, MemberVisibility.Private, MemberModifier.None, typeof(int), "_privateNumber")); classMember.Members.Add(new FieldMember(classMember, MemberVisibility.Public, MemberModifier.Static, typeof(string), "PublicString")); classMember.Members.Add(new FieldMember(classMember, MemberVisibility.Protected, MemberModifier.Static, typeof(string), "ProtectedString")); classMember.Members.Add(new FieldMember(classMember, MemberVisibility.Internal, MemberModifier.Static, typeof(string), "InternalString")); classMember.Members.Add(new FieldMember(classMember, MemberVisibility.InternalProtected, MemberModifier.Static, typeof(string), "InternalProtectedString")); classMember.Members.Add(new FieldMember(classMember, MemberVisibility.Private, MemberModifier.Static, typeof(string), "_s_privateString")); var emitter = new ClassSyntaxEmitter(classMember); //-- act var syntax = emitter.EmitSyntax(); //-- assert syntax.Should().BeEquivalentToCode(@" public class ClassOne { public int PublicNumber; internal protected int InternalProtectedNumber; protected int ProtectedNumber; internal int InternalNumber; private int _privateNumber; public static string PublicString; internal protected static string InternalProtectedString; protected static string ProtectedString; internal static string InternalString; private static string _s_privateString; } "); }
public void WithOneInterface() { //-- arrange var classMember = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassOne"); classMember.Interfaces.Add(new TypeMember(typeof(System.IDisposable))); var emitter = new ClassSyntaxEmitter(classMember); //-- act var syntax = emitter.EmitSyntax(); //-- assert syntax.Should().BeEquivalentToCode( "public class ClassOne : System.IDisposable { }" ); }
public void WithBase() { //-- arrange var classMember = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassOne"); classMember.BaseType = new TypeMember(typeof(System.IO.Stream)); var emitter = new ClassSyntaxEmitter(classMember); //-- act var syntax = emitter.EmitSyntax(); //-- assert syntax.Should().BeEquivalentToCode( "public class ClassOne : System.IO.Stream { }" ); }
public void WithGenericBaseTypes() { //-- arrange var classMember = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassOne"); classMember.BaseType = new TypeMember(typeof(List <string>)); classMember.Interfaces.Add(new TypeMember(typeof(IDictionary <int, DateTime>))); var emitter = new ClassSyntaxEmitter(classMember); //-- act var syntax = emitter.EmitSyntax(); //-- assert syntax.Should().BeEquivalentToCode(@" public class ClassOne : System.Collections.Generic.List<string>, System.Collections.Generic.IDictionary<int, System.DateTime> { } "); }
public void CanGenerateHardCodedArtifactCatalogClass() { //-- arrange var firstArtifactType = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "FirstArtifact"); var secondArtifactType = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "SecondArtifact"); var catalogType = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ThisAssemblyArtifactCatalog"); catalogType.BaseType = typeof(RuntimeTypeFactoryArtifactCatalog); var getArtifactsMethod = new MethodMember( MemberVisibility.Public, MemberModifier.Override, nameof(RuntimeTypeFactoryArtifactCatalog.GetArtifacts), new MethodSignature { ReturnValue = new MethodParameter { Type = typeof(RuntimeTypeFactoryArtifact[]) } }); var artifactsVariable = new LocalVariable { Name = "artifacts" }; getArtifactsMethod.Body = new BlockStatement( new VariableDeclarationStatement { Variable = artifactsVariable, InitialValue = new NewArrayExpression { ElementType = typeof(RuntimeTypeFactoryArtifact), Length = new ConstantExpression { Value = 2 } }, }, new ExpressionStatement { Expression = new AssignmentExpression { Left = new IndexerExpression { Target = new LocalVariableExpression { Variable = artifactsVariable }, Index = new ConstantExpression { Value = 0 } }, Right = new NewObjectExpression { Type = firstArtifactType } } }, new ExpressionStatement { Expression = new AssignmentExpression { Left = new IndexerExpression { Target = new LocalVariableExpression { Variable = artifactsVariable }, Index = new ConstantExpression { Value = 1 } }, Right = new NewObjectExpression { Type = secondArtifactType } } }, new ReturnStatement { Expression = new LocalVariableExpression { Variable = artifactsVariable } } ); catalogType.Members.Add(getArtifactsMethod); //-- act var syntaxEmitter = new ClassSyntaxEmitter(catalogType); SyntaxNode actualSyntax; using (TypeMemberTagCache.CreateOnCurrentThread()) { actualSyntax = syntaxEmitter.EmitSyntax(); } //-- assert var expectedCode = @" public class ThisAssemblyArtifactCatalog : NWheels.Compilation.Mechanism.Factories.RuntimeTypeFactoryArtifactCatalog { public override NWheels.Compilation.Mechanism.Factories.RuntimeTypeFactoryArtifact[] GetArtifacts() { var artifacts = new NWheels.Compilation.Mechanism.Factories.RuntimeTypeFactoryArtifact[2]; artifacts[0] = new FirstArtifact(); artifacts[1] = new SecondArtifact(); return artifacts; } } "; actualSyntax.Should().BeEquivalentToCode(expectedCode); }
public void CanGenerateHardCodedArtifactClass() { //-- arrange var artifactType = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "FirstArtifact"); artifactType.BaseType = new TypeMember(typeof(RuntimeTypeFactoryArtifact <>).MakeGenericType(typeof(IFirstContract))); artifactType.Interfaces.Add(new TypeMember(typeof(IConstructor <>).MakeGenericType(typeof(IFirstContract)))); var constructor = new ConstructorMember(MemberVisibility.Public, MemberModifier.None, "FirstArtifact", new MethodSignature()); constructor.CallBaseConstructor = new MethodCallExpression(); var typeKeyConstructorCall = new MethodCallExpression(); typeKeyConstructorCall.Arguments.Add(new Argument { Expression = new ConstantExpression { Value = typeof(TestFactory) } }); typeKeyConstructorCall.Arguments.Add(new Argument { Expression = new ConstantExpression { Value = typeof(IFirstContract) } }); typeKeyConstructorCall.Arguments.Add(new Argument { Expression = new ConstantExpression() }); typeKeyConstructorCall.Arguments.Add(new Argument { Expression = new ConstantExpression() }); typeKeyConstructorCall.Arguments.Add(new Argument { Expression = new ConstantExpression { Value = 0 } }); typeKeyConstructorCall.Arguments.Add(new Argument { Expression = new ConstantExpression { Value = 0 } }); typeKeyConstructorCall.Arguments.Add(new Argument { Expression = new ConstantExpression { Value = 0 } }); constructor.CallBaseConstructor.Arguments.Add(new Argument { Expression = new NewObjectExpression { Type = typeof(TypeKey), ConstructorCall = typeKeyConstructorCall } }); constructor.CallBaseConstructor.Arguments.Add(new Argument { Expression = new ConstantExpression { Value = typeof(FirstContractImplementation) } }); var factoryMethod = new MethodMember( MemberVisibility.Public, MemberModifier.None, nameof(IConstructor <object> .NewInstance), new MethodSignature { ReturnValue = new MethodParameter { Type = typeof(IFirstContract) } }); factoryMethod.Body = new BlockStatement( new ReturnStatement { Expression = new NewObjectExpression { Type = typeof(FirstContractImplementation) } } ); var singletonMethod = new MethodMember( MemberVisibility.Public, MemberModifier.None, nameof(IConstructor <object> .GetOrCreateSingleton), new MethodSignature { ReturnValue = new MethodParameter { Type = typeof(IFirstContract) } }); singletonMethod.Body = new BlockStatement( new ThrowStatement { Exception = new NewObjectExpression { Type = typeof(NotSupportedException) } } ); artifactType.Members.Add(constructor); artifactType.Members.Add(factoryMethod); artifactType.Members.Add(singletonMethod); //-- act var syntaxEmitter = new ClassSyntaxEmitter(artifactType); SyntaxNode actualSyntax; using (TypeMemberTagCache.CreateOnCurrentThread()) { actualSyntax = syntaxEmitter.EmitSyntax(); } //-- assert var expectedCode = @" public class FirstArtifact : NWheels.Compilation.Mechanism.Factories.RuntimeTypeFactoryArtifact<NWheels.Compilation.Adapters.Roslyn.UnitTests.RoslynTypeFactoryBackendTests.IFirstContract>, NWheels.Compilation.Mechanism.Factories.IConstructor<NWheels.Compilation.Adapters.Roslyn.UnitTests.RoslynTypeFactoryBackendTests.IFirstContract> { public FirstArtifact() : base( new NWheels.Compilation.Mechanism.Factories.TypeKey( typeof(NWheels.Compilation.Adapters.Roslyn.UnitTests.RoslynTypeFactoryBackendTests.TestFactory), typeof(NWheels.Compilation.Adapters.Roslyn.UnitTests.RoslynTypeFactoryBackendTests.IFirstContract), null, null, 0, 0, 0), typeof(NWheels.Compilation.Adapters.Roslyn.UnitTests.RoslynTypeFactoryBackendTests.FirstContractImplementation)) { } public NWheels.Compilation.Adapters.Roslyn.UnitTests.RoslynTypeFactoryBackendTests.IFirstContract NewInstance() { return new NWheels.Compilation.Adapters.Roslyn.UnitTests.RoslynTypeFactoryBackendTests.FirstContractImplementation(); } public NWheels.Compilation.Adapters.Roslyn.UnitTests.RoslynTypeFactoryBackendTests.IFirstContract GetOrCreateSingleton() { throw new System.NotSupportedException(); } } "; actualSyntax.Should().BeEquivalentToCode(expectedCode); }
public void CanOrderMembersOfType() { //-- arrange #region Expected Code var expectedCode = @" public class ClassOne { public int PublicField; internal protected int _protectedInternalField; protected int _protectedField; internal int _internalField; private int _privateField; public ClassOne(string s) { } internal protected ClassOne(byte b) { } protected ClassOne(int n) { } internal ClassOne(float f) { } private ClassOne(decimal m) { } public void M1() { } public int P1 { get; } internal protected void M2() { } internal protected int P2 { get; } protected void M3() { } protected int P3 { get; } internal void M4() { } internal int P4 { get; } private void M5() { } private int P5 { get; } public static int PublicStaticField; internal protected static int _s_protectedInternalStaticField; protected static int _s_protectedStaticField; internal static int _s_internalStaticField; private static int _s_privateStaticField; static ClassOne() { } public static void StaticM1() { } public static int StaticP1 { get; } internal protected static void StaticM2() { } internal protected static int StaticP2 { get; } protected static void StaticM3() { } protected static int StaticP3 { get; } internal static void StaticM4() { } internal static int StaticP4 { get; } private static void StaticM5() { } private static int StaticP5 { get; } }"; #endregion var classMember = new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassOne"); #region Add Members classMember.Members.AddRange(new PropertyMember[] { new PropertyMember(classMember, MemberVisibility.Protected, MemberModifier.Static, typeof(int), "StaticP3"), new PropertyMember(classMember, MemberVisibility.Private, MemberModifier.Static, typeof(int), "StaticP5"), new PropertyMember(classMember, MemberVisibility.InternalProtected, MemberModifier.Static, typeof(int), "StaticP2"), new PropertyMember(classMember, MemberVisibility.Public, MemberModifier.Static, typeof(int), "StaticP1"), new PropertyMember(classMember, MemberVisibility.Internal, MemberModifier.Static, typeof(int), "StaticP4"), }); classMember.Members.AddRange(new AbstractMember[] { new ConstructorMember(MemberVisibility.Public, MemberModifier.Static, "ClassOne", new MethodSignature()), new ConstructorMember(MemberVisibility.Protected, MemberModifier.None, "ClassOne", new MethodSignature( new[] { new MethodParameter("n", 1, typeof(int)) }, returnValue: null, isAsync: false )), new ConstructorMember(MemberVisibility.Private, MemberModifier.None, "ClassOne", new MethodSignature( new[] { new MethodParameter("m", 1, typeof(decimal)) }, returnValue: null, isAsync: false )), new ConstructorMember(MemberVisibility.InternalProtected, MemberModifier.None, "ClassOne", new MethodSignature( new[] { new MethodParameter("b", 1, typeof(byte)) }, returnValue: null, isAsync: false )), new ConstructorMember(MemberVisibility.Public, MemberModifier.None, "ClassOne", new MethodSignature( new[] { new MethodParameter("s", 1, typeof(string)) }, returnValue: null, isAsync: false )), new ConstructorMember(MemberVisibility.Internal, MemberModifier.None, "ClassOne", new MethodSignature( new[] { new MethodParameter("f", 1, typeof(float)) }, returnValue: null, isAsync: false )), }); classMember.Members.AddRange(new AbstractMember[] { new MethodMember(MemberVisibility.Protected, MemberModifier.Static, "StaticM3", new MethodSignature()), new MethodMember(MemberVisibility.Private, MemberModifier.Static, "StaticM5", new MethodSignature()), new MethodMember(MemberVisibility.Internal, MemberModifier.Static, "StaticM4", new MethodSignature()), new MethodMember(MemberVisibility.Public, MemberModifier.Static, "StaticM1", new MethodSignature()), new MethodMember(MemberVisibility.InternalProtected, MemberModifier.Static, "StaticM2", new MethodSignature()), }); classMember.Members.AddRange(new AbstractMember[] { new FieldMember(classMember, MemberVisibility.Protected, MemberModifier.Static, typeof(int), "_s_protectedStaticField"), new FieldMember(classMember, MemberVisibility.Private, MemberModifier.Static, typeof(int), "_s_privateStaticField"), new FieldMember(classMember, MemberVisibility.InternalProtected, MemberModifier.Static, typeof(int), "_s_protectedInternalStaticField"), new FieldMember(classMember, MemberVisibility.Public, MemberModifier.Static, typeof(int), "PublicStaticField"), new FieldMember(classMember, MemberVisibility.Internal, MemberModifier.Static, typeof(int), "_s_internalStaticField"), }); classMember.Members.AddRange(new AbstractMember[] { new FieldMember(classMember, MemberVisibility.Protected, MemberModifier.None, typeof(int), "_protectedField"), new FieldMember(classMember, MemberVisibility.Private, MemberModifier.None, typeof(int), "_privateField"), new FieldMember(classMember, MemberVisibility.InternalProtected, MemberModifier.None, typeof(int), "_protectedInternalField"), new FieldMember(classMember, MemberVisibility.Public, MemberModifier.None, typeof(int), "PublicField"), new FieldMember(classMember, MemberVisibility.Internal, MemberModifier.None, typeof(int), "_internalField"), }); classMember.Members.AddRange(new PropertyMember[] { new PropertyMember(classMember, MemberVisibility.Private, MemberModifier.None, typeof(int), "P5"), new PropertyMember(classMember, MemberVisibility.Protected, MemberModifier.None, typeof(int), "P3"), new PropertyMember(classMember, MemberVisibility.Internal, MemberModifier.None, typeof(int), "P4"), new PropertyMember(classMember, MemberVisibility.Public, MemberModifier.None, typeof(int), "P1"), new PropertyMember(classMember, MemberVisibility.InternalProtected, MemberModifier.None, typeof(int), "P2"), }); classMember.Members.AddRange(new AbstractMember[] { new MethodMember(MemberVisibility.Private, MemberModifier.None, "M5", new MethodSignature()), new MethodMember(MemberVisibility.Protected, MemberModifier.None, "M3", new MethodSignature()), new MethodMember(MemberVisibility.Internal, MemberModifier.None, "M4", new MethodSignature()), new MethodMember(MemberVisibility.Public, MemberModifier.None, "M1", new MethodSignature()), new MethodMember(MemberVisibility.InternalProtected, MemberModifier.None, "M2", new MethodSignature()), }); #endregion var emitter = new ClassSyntaxEmitter(classMember); //-- act var syntax = emitter.EmitSyntax(); //-- assert syntax.Should().BeEquivalentToCode(expectedCode); }