예제 #1
0
        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})");
        }
예제 #2
0
        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");
        }
예제 #3
0
        TypeDef MyStructWithMethod()
        {
            var thisP = ParameterExpression.CreateThisParam(MyStruct);

            var method = MethodDef.Create(MyStruct_Method, _ => Expression.Nop);

            return(MyStructDef.AddMember(method));
        }
예제 #4
0
        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)));
            }));
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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));
        }
예제 #8
0
        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" : "")}");
        }
예제 #9
0
        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));
        }
예제 #10
0
파일: Metadata.cs 프로젝트: exyi/coberec
        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);
        }