예제 #1
0
 public CodeMemberProperty GenerateProperty(Generator g)
 {
     var p = new CodeMemberProperty () { Name = Name, Attributes = MemberAttributes.Public|MemberAttributes.Final };
     p.Type = g.CppTypeToCodeDomType (Type);
     if (GetMethod != null) {
         p.GetStatements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), GetMethod.Name), new CodeExpression [] { new CodeFieldReferenceExpression (null, "Native") })));
     }
     if (SetMethod != null) {
         p.SetStatements.Add (new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), SetMethod.Name), new CodeExpression [] { new CodeFieldReferenceExpression (null, "Native"), new CodeArgumentReferenceExpression ("value") }));
     }
     return p;
 }
예제 #2
0
파일: Class.cs 프로젝트: shana/cppinterop
    public CodeTypeDeclaration GenerateClass(Generator g, CodeTypeDeclaration libDecl, string libFieldName)
    {
        var decl = new CodeTypeDeclaration (Name);
        decl.IsPartial = true;
        if (BaseClasses.Count > 0)
            decl.BaseTypes.Add (new CodeTypeReference (BaseClasses [0].Name));
        else
            decl.BaseTypes.Add (new CodeTypeReference ("ICppObject"));

        bool hasBase = BaseClasses.Count > 0;

        var layout = new CodeTypeDeclaration ("_" + Name);
        layout.IsStruct = true;
        layout.TypeAttributes = TypeAttributes.NotPublic;
        decl.Members.Add (layout);

        foreach (var f in Fields) {
            CodeMemberField field = new CodeMemberField { Name = f.Name, Type = g.CppTypeToCodeDomType (f.Type) };
            layout.Members.Add (field);
        }

        var iface = new CodeTypeDeclaration ("I" + Name);
        iface.IsInterface = true;
        layout.TypeAttributes = TypeAttributes.NotPublic;
        iface.BaseTypes.Add (new CodeTypeReference ("ICppClassOverridable", new CodeTypeReference [] { new CodeTypeReference (decl.Name) }));
        decl.Members.Add (iface);

        var layoutField = new CodeMemberField (new CodeTypeReference (typeof (Type)), "native_layout");
        layoutField.Attributes = MemberAttributes.Private|MemberAttributes.Static;
        layoutField.InitExpression = new CodeTypeOfExpression (layout.Name);
        decl.Members.Add (layoutField);

        var implField = new CodeMemberField (new CodeTypeReference (iface.Name), "impl");
        implField.Attributes = MemberAttributes.Private|MemberAttributes.Static;
        var getclass = new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (new CodeTypeReferenceExpression (libDecl.Name), libFieldName), "GetClass", new CodeTypeReference [] { new CodeTypeReference (iface.Name), new CodeTypeReference (layout.Name), new CodeTypeReference (decl.Name) });
        implField.InitExpression = new CodeMethodInvokeExpression (getclass, new CodeExpression [] { new CodePrimitiveExpression (Name) });
        decl.Members.Add (implField);
        //private static IClass impl = global::CppTests.Libs.Test.GetClass <IClass, _Class, Class>("Class");

        if (!hasBase) {
            var ptrField = new CodeMemberField (new CodeTypeReference ("CppInstancePtr"), "native_ptr");
            ptrField.Attributes = MemberAttributes.Family;
            decl.Members.Add (ptrField);
        }

        var allocCtor = new CodeConstructor () {
            };
        allocCtor.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference ("CppLibrary"), "dummy"));
        allocCtor.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (null, "native_ptr"), new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), "Alloc"), new CodeExpression [] { new CodeThisReferenceExpression () })));
        if (hasBase) {
            var implTypeInfo = new CodeFieldReferenceExpression (new CodeFieldReferenceExpression { FieldName = "impl" }, "TypeInfo");
            allocCtor.BaseConstructorArgs.Add (implTypeInfo);
        }
        decl.Members.Add (allocCtor);

        var subclassCtor = new CodeConstructor () {
                Attributes = MemberAttributes.Family
            };
        subclassCtor.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference ("CppTypeInfo"), "subClass"));
        subclassCtor.Statements.Add (new CodeExpressionStatement (new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeArgumentReferenceExpression ("subClass"), "AddBase"), new CodeExpression [] { new CodeFieldReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), "TypeInfo") })));
        if (hasBase) {
            var implTypeInfo = new CodeFieldReferenceExpression (new CodeFieldReferenceExpression { FieldName = "impl" }, "TypeInfo");
            subclassCtor.BaseConstructorArgs.Add (implTypeInfo);
        }
        decl.Members.Add (subclassCtor);

        if (!hasBase) {
            var nativeProperty = new CodeMemberProperty () {
                    Name = "Native",
                        Type = new CodeTypeReference ("CppInstancePtr"),
                        Attributes = MemberAttributes.Public|MemberAttributes.Final
                        };
            nativeProperty.GetStatements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), "native_ptr")));
            decl.Members.Add (nativeProperty);
        }

        var disposeMethod = new CodeMemberMethod () {
                Name = "Dispose",
                Attributes = MemberAttributes.Public
        };
        if (Methods.Any (m => m.IsDestructor))
            disposeMethod.Statements.Add (new CodeExpressionStatement (new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), "Destruct"), new CodeExpression [] { new CodeFieldReferenceExpression (null, "Native") })));
        disposeMethod.Statements.Add (new CodeExpressionStatement (new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "Native"), "Dispose"))));
        decl.Members.Add (disposeMethod);

        foreach (Method m in Methods) {
            iface.Members.Add (m.GenerateIFaceMethod (g));

            if (m.GenWrapperMethod) {
                var cm = m.GenerateWrapperMethod (g);
                if (m.IsConstructor && hasBase) {
                    var implTypeInfo = new CodeFieldReferenceExpression (new CodeFieldReferenceExpression { FieldName = "impl" }, "TypeInfo");
                    (cm as CodeConstructor).BaseConstructorArgs.Add (implTypeInfo);
                }
                decl.Members.Add (cm);
            }
        }

        foreach (Property p in Properties) {
            decl.Members.Add (p.GenerateProperty (g));
        }

        return decl;
    }
예제 #3
0
파일: Method.cs 프로젝트: shana/cppinterop
    public CodeMemberMethod GenerateWrapperMethod(Generator g)
    {
        CodeMemberMethod method;

        if (IsConstructor)
            method = new CodeConstructor () {
                    Name = GetCSharpMethodName (Name)
                        };
        else
            method = new CodeMemberMethod () {
                    Name = GetCSharpMethodName (Name)
                        };
        method.Attributes = MemberAttributes.Public;
        if (IsStatic)
            method.Attributes |= MemberAttributes.Static;

        CodeTypeReference rtype = g.CppTypeToCodeDomType (ReturnType);
        method.ReturnType = rtype;

        foreach (var p in Parameters) {
            bool byref;
            var ptype = g.CppTypeToCodeDomType (p.Type, out byref);
            var param = new CodeParameterDeclarationExpression (ptype, p.Name);
            if (byref)
                param.Direction = FieldDirection.Ref;
            method.Parameters.Add (param);
        }

        if (IsConstructor) {
            //this.native_ptr = impl.Alloc(this);
            method.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (null, "native_ptr"), new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), "Alloc"), new CodeExpression [] { new CodeThisReferenceExpression () })));
        }

        // Call the iface method
        CodeExpression[] args = new CodeExpression [Parameters.Count + (IsStatic ? 0 : 1)];
        if (!IsStatic)
            args [0] = new CodeFieldReferenceExpression (null, "Native");
        for (int i = 0; i < Parameters.Count; ++i) {
            bool byref;
            g.CppTypeToCodeDomType (Parameters [i].Type, out byref);
            CodeExpression arg = new CodeArgumentReferenceExpression (Parameters [i].Name);
            if (byref)
                arg = new CodeDirectionExpression (FieldDirection.Ref, arg);
            args [i + (IsStatic ? 0 : 1)] = arg;
        }

        var call = new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), Name), args);

        if (rtype.BaseType == "System.Void" || IsConstructor)
            method.Statements.Add (call);
        else
            method.Statements.Add (new CodeMethodReturnStatement (call));

        return method;
    }
예제 #4
0
파일: Method.cs 프로젝트: shana/cppinterop
    public CodeMemberMethod GenerateIFaceMethod(Generator g)
    {
        var method = new CodeMemberMethod () {
                Name = Name
                    };

        if (!IsStatic)
            method.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference ("CppInstancePtr"), "this"));

        CodeTypeReference rtype = g.CppTypeToCodeDomType (ReturnType);
        method.ReturnType = rtype;

        foreach (var p in Parameters) {
            CppType ptype = p.Type;
            bool byref;
            var ctype = g.CppTypeToCodeDomType (ptype, out byref);
            var param = new CodeParameterDeclarationExpression (ctype, p.Name);
            if (byref)
                param.Direction = FieldDirection.Ref;
            if (!IsVirtual && !ptype.ToString ().Equals (string.Empty))
                param.CustomAttributes.Add (new CodeAttributeDeclaration ("MangleAsAttribute", new CodeAttributeArgument (new CodePrimitiveExpression (ptype.ToString ()))));
            // FIXME: Structs too
            if (ptype.ElementType == CppTypes.Class && !ptype.Modifiers.Contains (CppModifiers.Reference) && !ptype.Modifiers.Contains (CppModifiers.Pointer))
                param.CustomAttributes.Add (new CodeAttributeDeclaration ("ByVal"));
            method.Parameters.Add (param);
        }

        // FIXME: Copy ctor

        if (IsVirtual)
            method.CustomAttributes.Add (new CodeAttributeDeclaration ("Virtual"));
        if (IsConstructor)
            method.CustomAttributes.Add (new CodeAttributeDeclaration ("Constructor"));
        if (IsDestructor)
            method.CustomAttributes.Add (new CodeAttributeDeclaration ("Destructor"));
        if (IsConst)
            method.CustomAttributes.Add (new CodeAttributeDeclaration ("Const"));
        if (IsInline)
            method.CustomAttributes.Add (new CodeAttributeDeclaration ("Inline"));
        if (IsArtificial)
            method.CustomAttributes.Add (new CodeAttributeDeclaration ("Artificial"));
        if (IsCopyCtor)
            method.CustomAttributes.Add (new CodeAttributeDeclaration ("CopyConstructor"));
        if (IsStatic)
            method.CustomAttributes.Add (new CodeAttributeDeclaration ("Static"));

        return method;
    }