Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Add generation of abstract GInterface base class #131

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion generator/GObjectVM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,26 @@ protected void GenerateMethodBody (StreamWriter sw, ClassBase implementor)
sw.Write ("\t\t{0} ", this.Protection);
if (this.modifiers != "")
sw.Write ("{0} ", this.modifiers);
sw.WriteLine ("virtual {0} On{1} ({2})", retval.CSType, this.Name, Signature.ToString ());
string ret, signature;
if (IsAccessor) {
ret = Signature.AccessorType;
signature = Signature.AsAccessor;
} else {
ret = retval.CSType;
signature = Signature.ToString ();
}

sw.WriteLine ("virtual {0} On{1} ({2})", ret, this.Name, signature);
sw.WriteLine ("\t\t{");
var accessorParamName = Signature.AccessorName;
if (IsAccessor) {
sw.WriteLine ("\t\t\t{0} {1};", ret, accessorParamName);
}

sw.WriteLine ("\t\t\t{0}Internal{1} ({2});", retval.IsVoid ? "" : "return ", this.Name, Signature.GetCallString (false));
if (IsAccessor) {
sw.WriteLine ("\t\t\treturn {0};", accessorParamName);
}
sw.WriteLine ("\t\t}");
sw.WriteLine ();
// This method is to be invoked from existing VM implementations in the custom code
Expand Down
4 changes: 3 additions & 1 deletion generator/InterfaceVM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ public void GenerateDeclaration (StreamWriter sw, InterfaceVM complement)
}
} else if (IsSetter)
sw.WriteLine ("\t\t" + parms[0].CSType + " " + Name.Substring (3) + " { set; }");
else
else if (IsAccessor) {
sw.WriteLine ("\t\t" + Signature.AccessorType + " " + Name + " (" + Signature.AsAccessor + ");");
} else
sw.WriteLine ("\t\t" + retval.CSType + " " + Name + " (" + Signature + ");");
}

Expand Down
46 changes: 36 additions & 10 deletions generator/ManagedCallString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace GtkSharp.Generation {
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

public class ManagedCallString {

Expand All @@ -34,9 +35,18 @@ public class ManagedCallString {
string destroy_param = null;

public ManagedCallString (Parameters parms)
: this (parms, false)
{
}

private ManagedCallString (Parameters parms, bool stripAccessorParameter)
{
for (int i = 0; i < parms.Count; i ++) {
Parameter p = parms [i];
if (stripAccessorParameter && p.PassAs == "out") {
continue;
}

if (p.IsLength && i > 0 && parms [i-1].IsString)
continue;
else if (p.Scope == "notified") {
Expand Down Expand Up @@ -90,6 +100,14 @@ public string Unconditional (string indent) {
return ret;
}

public static ManagedCallString CreateWithoutAccessorParameter (Parameters parms,
out Parameter accessorParam)
{
var call = new ManagedCallString (parms, true);
accessorParam = parms.FirstOrDefault (p => p.PassAs == "out");
return call;
}

public string Setup (string indent)
{
string ret = "";
Expand Down Expand Up @@ -158,21 +176,29 @@ public string Finish (string indent)
continue;
}

IGeneratable igen = p.Generatable;

if (igen is CallbackGen)
continue;
else if (igen is StructBase || igen is ByRefGen)
ret += indent + String.Format ("if ({0} != IntPtr.Zero) System.Runtime.InteropServices.Marshal.StructureToPtr (my{0}, {0}, false);\n", p.Name);
else if (igen is IManualMarshaler)
ret += String.Format ("{0}{1} = {2};", indent, p.Name, (igen as IManualMarshaler).AllocNative ("my" + p.Name));
else
ret += indent + p.Name + " = " + igen.CallByName ("my" + p.Name) + ";\n";
ret += GetParamAssignmentStatement ("my" + p.Name, p, indent);
}

return ret;
}

public static string GetParamAssignmentStatement (string srcParameterName, Parameter p, string indent)
{
var ret = string.Empty;
IGeneratable igen = p.Generatable;

if (igen is CallbackGen)
return string.Empty;
else if (igen is StructBase || igen is ByRefGen)
ret += indent + String.Format ("if ({0} != IntPtr.Zero) System.Runtime.InteropServices.Marshal.StructureToPtr ({1}, {0}, false);\n", p.Name, srcParameterName);
else if (igen is IManualMarshaler)
ret += String.Format ("{0}{1} = {2};", indent, p.Name, (igen as IManualMarshaler).AllocNative (srcParameterName));
else
ret += indent + p.Name + " = " + igen.CallByName (srcParameterName) + ";\n";

return ret;
}

public string DisposeParams (string indent)
{
string ret = "";
Expand Down
51 changes: 51 additions & 0 deletions generator/VMSignature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,57 @@ public VMSignature (Parameters parms)
}
}

public bool IsAccessor {
get {
int count = 0;
foreach (Parameter p in parms) {
if (p.PassAs == "out")
count++;

if (count > 1)
return false;
}
return count == 1;
}
}

public string AccessorType {
get {
foreach (Parameter p in parms)
if (p.PassAs == "out")
return p.CSType;

return null;
}
}

public string AccessorName {
get {
foreach (Parameter p in parms)
if (p.PassAs == "out")
return p.Name;

return null;
}
}

public string AsAccessor {
get {
string[] result = new string [parms.Count - 1];
int i = 0;

foreach (Parameter p in parms) {
if (p.PassAs == "out")
continue;

result [i] = p.PassAs != "" ? p.PassAs + " " : "";
result [i++] += p.CSType + " " + p.Name;
}

return String.Join (", ", result);
}
}

public string GetCallString (bool use_place_holders)
{
if (parms.Count == 0)
Expand Down
24 changes: 21 additions & 3 deletions generator/VirtualMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace GtkSharp.Generation {
public abstract class VirtualMethod : MethodBase {
protected ReturnValue retval;
protected ManagedCallString call;
private Parameter accessorParam;

protected string modifiers = "";

Expand All @@ -56,6 +57,12 @@ protected abstract string CallString {
}
}

protected bool IsAccessor {
get {
return retval.IsVoid && Signature.IsAccessor;
}
}

/* Creates a callback method which invokes the corresponding virtual method
* @implementor is the class that implements the virtual method(e.g. the class that derives from an interface) or NULL if containing and declaring type are equal
*/
Expand Down Expand Up @@ -99,16 +106,22 @@ public void GenerateCallback (StreamWriter sw, ClassBase implementor)
}

string indent = "\t\t\t\t";
if (!retval.IsVoid)
if (IsAccessor) {
sw.WriteLine (indent + Signature.AccessorType + " __result;");
} else if (!retval.IsVoid)
sw.WriteLine (indent + retval.CSType + " __result;");
sw.Write (call.Setup (indent));
sw.Write (indent);
if (!retval.IsVoid)
if (!retval.IsVoid || IsAccessor)
sw.Write ("__result = ");
if (!this.IsStatic)
sw.Write ("__obj.");
sw.WriteLine (this.CallString + ";");
sw.Write (call.Finish (indent));
if (IsAccessor) {
sw.Write (ManagedCallString.GetParamAssignmentStatement ("__result", accessorParam, indent));
}

if (!retval.IsVoid)
sw.WriteLine ("\t\t\t\treturn " + retval.ToNative ("__result") + ";");

Expand Down Expand Up @@ -149,7 +162,12 @@ public override bool Validate (LogWriter log)
return false;
}

call = new ManagedCallString (parms);
if (IsAccessor) {
call = ManagedCallString.CreateWithoutAccessorParameter (parms, out accessorParam);
} else {
call = new ManagedCallString (parms);
}

return true;
}
}
Expand Down