public void Overrides(bool isInterface, bool isSealed, bool isAbstract) { var mGenerics = Enumerable.Range(0, 2).Select(i => GenericParameter.Create("U" + i)).ToArray(); var baseType = isInterface ? TypeSignature.Interface("Base", ns, Accessibility.APublic) : TypeSignature.Class("BaseC", ns, Accessibility.APublic, isAbstract: true); var baseMethod1 = MethodSignature.Abstract("M1", baseType, isInterface ? Accessibility.APublic : Accessibility.AProtected, TypeSignature.Object).With(isAbstract: isInterface); var baseMethod2 = MethodSignature.Abstract("M2", baseType, Accessibility.APublic, mGenerics[0], new MethodParameter(mGenerics[1], "a")).With(typeParameters: mGenerics.ToImmutableArray()); var baseProperty = PropertySignature.Abstract("P1", baseType, TypeSignature.Boolean, Accessibility.APublic, null); cx.AddType(TypeDef.Empty(baseType).AddMember( isInterface ? MethodDef.InterfaceDef(baseMethod1) : MethodDef.Create(baseMethod1, _ => Expression.Constant <object>(null)), MethodDef.InterfaceDef(baseMethod2), PropertyDef.InterfaceDef(baseProperty) )); var type = TypeSignature.Class("C", ns, Accessibility.APublic, canOverride: !isSealed, isAbstract: isAbstract); var method1 = MethodSignature.Override(type, baseMethod1, isAbstract: isAbstract); var method2 = MethodSignature.Override(type, baseMethod2); var property = PropertySignature.Override(type, baseProperty); cx.AddType(TypeDef.Empty(type, isInterface ? null : baseType.Specialize()) .AddImplements(isInterface ? new [] { baseType.Specialize() } : new SpecializedType[0]) .AddMember( isAbstract ? MethodDef.InterfaceDef(method1) : MethodDef.Create(method1, _ => Expression.Constant(1).Box()), MethodDef.Create(method2, (_, __) => Expression.Default(method2.TypeParameters[0])), PropertyDef.Create(property, @this => Expression.Default(property.Type)) )); check.CheckOutput(cx, $"ifc({isInterface})-sealed({isSealed})-abstract({isAbstract})"); }
public void HelloWorld() { // declare // namespace MyApp.HelloWorld { var ns = NamespaceSignature.Parse("MyApp.HelloWorld"); // public class Program { var programType = TypeSignature.Class("Program", ns, Accessibility.APublic); // public static int Main() { var mainMethod = MethodSignature.Static("Main", programType, Accessibility.APublic, returnType: TypeSignature.Int32); // get the Console.WriteLine reference var writeLineRef = MethodReference.FromLambda(() => Console.WriteLine("")); var body = new [] { Expression.StaticMethodCall(writeLineRef, Expression.Constant("Hello world!")) }.ToBlock( result: Expression.Constant(0) ); var type = TypeDef.Empty(programType).AddMember( MethodDef.Create(mainMethod, body) ); var cx = MetadataContext.Create(); cx.AddType(type); var csharp = cx.EmitToString(); check.CheckString(csharp, fileExtension: "cs"); }
TypeDef MyStructWithMethod() { var thisP = ParameterExpression.CreateThisParam(MyStruct); var method = MethodDef.Create(MyStruct_Method, _ => Expression.Nop); return(MyStructDef.AddMember(method)); }
public static MethodDef ImplementToString(TypeSignature declaringType) { var method = MethodSignature.Override(declaringType, MethodSignature.Object_ToString); return(MethodDef.Create(method, @this => { return @this.Ref() .CallMethod(FormatMethodSignature(declaringType)) .CallMethod(MethodReference.FromLambda <FmtToken>(x => x.ToString("\t", null))); })); }
public void GenericMethodInGenericTypes() { var ns = NamespaceSignature.Parse("MyNamespace"); var t1 = new GenericParameter(Guid.NewGuid(), "T1"); var t2 = new GenericParameter(Guid.NewGuid(), "T2"); var tresult = new GenericParameter(Guid.NewGuid(), "TResult"); var rootType = TypeSignature.Class("MyType", ns, Accessibility.APublic, true, false, t1); var(f, p) = PropertyBuilders.CreateAutoProperty(rootType, "A", t1, isReadOnly: false); var map_fn_type = new FunctionType(new [] { new MethodParameter(t1, "a") }, tresult); var map_sgn = MethodSignature.Instance("Map", rootType, Accessibility.APublic, rootType.Specialize(tresult), new [] { tresult }, new MethodParameter(map_fn_type.TryGetDelegate(), "func") ); var tmp = ParameterExpression.Create(map_sgn.ResultType, "result"); var map_def = MethodDef.Create(map_sgn, (@this, fn) => Expression.Block( new [] { tmp.Ref() .CallMethod(p.Setter.Signature.Specialize(new TypeReference[] { tresult }, null), fn.Read().FunctionConvert(map_fn_type).Invoke(@this.Ref().CallMethod(p.Getter.Signature.SpecializeFromDeclaringType())) ) }, result: tmp ) .Where(tmp, Expression.NewObject(MethodSignature.ImplicitConstructor(rootType).Specialize(new TypeReference[] { tresult }, null))) ); var type = TypeSignature.Class("MyNestedType", rootType, Accessibility.APublic, true, false, t2); var t3 = new GenericParameter(Guid.NewGuid(), "T3"); var method = MethodSignature.Instance( "M", type, Accessibility.APublic, returnType: type.Specialize(t1, t3), typeParameters: new [] { t3 }); var td = TypeDef.Empty(type) .AddMember(MethodDef.Create(method, @this => Expression.NewObject( MethodSignature.ImplicitConstructor(type).Specialize(new TypeReference[] { t1, t3 }, null), ImmutableArray <Expression> .Empty ) )) ; cx.AddType(TypeDef.Empty(rootType).AddMember(td, f, p, map_def)); check.CheckOutput(cx); }
public void StandardProperties() { // TODO: remove those CompilerGenerated attributes var type = TypeSignature.Class("MyType", ns, Accessibility.APublic); var prop = PropertySignature.Create("A", type, TypeSignature.String, Accessibility.APublic, Accessibility.AProtected); var td = TypeDef.Empty(type).AddMember( new PropertyDef(prop, getter: MethodDef.Create(prop.Getter, thisP => Expression.Constant("abcd")), setter: MethodDef.Create(prop.Setter, (thisP, xP) => Expression.While(FluentExpression.Box(thisP).CallMethod(MethodSignature.Object_Equals, Expression.Default(TypeSignature.Object)), Expression.Nop)) ) ); cx.AddType(td); check.CheckOutput(cx); }
private TypeDef ImplementToString(TypeDef declaringType) { var properties = declaringType.Members .OfType <PropertyDef>() .Select(p => p.Signature) .Where(p => !p.IsStatic); var toStringSgn = MethodSignature.Override(declaringType.Signature, MethodSignature.Object_ToString); var toStringDef = MethodDef.Create(toStringSgn, @this => { Expression formatProperty(PropertySignature property) { return(@this.Read().ReadProperty(property)); } IEnumerable <Expression> stringFragments() { yield return(Expression.Constant(declaringType.Signature.Name)); yield return(Expression.Constant(" {")); var first = true; foreach (var property in properties) { if (first) { first = false; } else { yield return(Expression.Constant(",")); } yield return(Expression.Constant(" " + property.Name + " = ")); yield return(formatProperty(property)); } yield return(Expression.Constant(" }")); } return(ExpressionFactory.String_Concat(stringFragments())); }); return(declaringType.AddMember(toStringDef)); }
public void IEquatableImplementation(bool isStruct, bool isExplicit) { var type = isStruct ? TypeSignature.Struct("MyType", ns, Accessibility.APublic) : TypeSignature.Class("MyType", ns, Accessibility.APublic); var iequatableT = TypeSignature.FromType(typeof(IEquatable <>)).Specialize(type); var interfaceMethod = cx.GetMemberMethods(iequatableT, "Equals").Single(); var method = new MethodSignature(type, ImmutableArray.Create(new MethodParameter(type, "obj")), "Equals", TypeReference.FromType(typeof(bool)), false, isExplicit ? Accessibility.APrivate : Accessibility.APublic, false, false, false, false, ImmutableArray <GenericParameter> .Empty); var methodDef = MethodDef.Create(method, (_thisP, _objP) => new ConstantExpression(true, TypeReference.FromType(typeof(bool)))) .AddImplements(interfaceMethod); var typeDef = TypeDef.Empty(type).With( implements: ImmutableArray.Create(iequatableT), members: ImmutableArray.Create <MemberDef>(methodDef)); cx.AddType(typeDef); check.CheckOutput(cx, $"{(isStruct ? "struct" : "class")}{(isExplicit ? "-explicit" : "")}"); }
TypeDef MyStructWithConstructor() { var methodSignature = MethodSignature.Constructor(MyStruct, Accessibility.APublic, new MethodParameter(GuidType, "id"), new MethodParameter(TypeSignature.Int32, "count")); var thisP = ParameterExpression.CreateThisParam(MyStruct); var idP = ParameterExpression.Create(GuidType, "id"); var countP = ParameterExpression.Create(TypeSignature.Int32, "count"); var method = MethodDef.Create(methodSignature, (thisP, idP, countP) => Expression.Block( ImmutableArray.Create( Expression.FieldAccess(MyStruct_GuidField, thisP).ReferenceAssign(idP), Expression.FieldAccess(MyStruct_IntField, thisP).ReferenceAssign(countP) ), result: Expression.Nop ) ); return(MyStructDef.AddMember(method)); }
public void GenericClass() { var paramT = GenericParameter.Create("T"); var myContainerSgn = TypeSignature.Class( "MyContainer", NamespaceSignature.Parse("NS"), Accessibility.APublic, genericParameters: new [] { paramT } ); var(item_field, item_prop) = PropertyBuilders.CreateAutoProperty( myContainerSgn, name: "Item", propertyType: paramT, isReadOnly: false ); var listType = TypeSignature.FromType(typeof(List <>)) .Specialize(paramT); var toListSgn = MethodSignature.Instance( "ToList", myContainerSgn, Accessibility.APublic, returnType: listType ); var toListDef = MethodDef.Create(toListSgn, thisParam => { var resultVar = ParameterExpression.Create(listType, "result"); var listCtor = MethodReference.FromLambda(() => new List <int>()) .Signature .Specialize(paramT); var listAdd = MethodReference.FromLambda <List <int> >(l => l.Add(0)) .Signature .Specialize(paramT); return(Expression.LetIn( // result = new List<T>() resultVar, Expression.NewObject(listCtor), new [] { // result.Add(this.Item) resultVar.Read().CallMethod(listAdd, thisParam.Read().ReadField(item_field.Signature.SpecializeFromDeclaringType()) ) }.ToBlock(resultVar) )); }); var copyFromSgn = MethodSignature.Instance( "CopyFrom", myContainerSgn, Accessibility.APublic, returnType: TypeSignature.Void, new MethodParameter( myContainerSgn.SpecializeByItself(), "other" ) ); var copyFromDef = MethodDef.Create(copyFromSgn, (thisParam, otherParam) => { var field = item_field.Signature.SpecializeFromDeclaringType(); return(thisParam.Read().AssignField( field, otherParam.Read().ReadField(field) )); }); var myContainerDef = TypeDef.Empty(myContainerSgn) .AddMember(item_field, item_prop, toListDef, copyFromDef); cx.AddType(myContainerDef); check.CheckOutput(cx); }