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; }
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; }
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; }
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; }