You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdebindings/qtsharp/src/generator/Printer.cs

527 lines
17 KiB

// A Qt to C# binding generator.
//
// Copyright (C) 2002 Adam Treat (manyoso@yahoo.com)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
using System;
using System.IO;
using System.Text;
using System.Collections;
namespace QtCSharp {
public class Printer {
TQType qtype;
string tab, directory;
public Printer (TQType qtype, string directory)
{
this.qtype = qtype;
this.directory = directory;
tab = "\t";
if (qtype.IsInterface)
PrintInterface ();
else
Print ();
}
public void Print ()
{
StreamWriter writer = new StreamWriter(directory + Path.DirectorySeparatorChar +
qtype.Name + ".cs", false, new ASCIIEncoding());
writer.Write(Header);
writer.Write(StartClass(qtype.Name, qtype.Access, new ArrayList(qtype.TQAncestors)));
foreach (TQEnum qenum in qtype.TQEnums) {
writer.Write(StartEnum(qenum.Name, qenum.Access, qenum.Type));
writer.Write(Items(qenum.TQItems));
writer.Write(EndMember);
}
foreach (TQCtor qctor in qtype.TQCtors) {
if (qctor.Throttle) {
} else if (qctor.Inherited) {
writer.Write (WriteInherited (qctor.Name, qctor.Access));
} else if (qctor.Dummy) {
writer.Write (WriteDummy (qctor.Name, qctor.Access));
} else if (qctor.Boxer) {
writer.Write (WriteBoxer (qctor.Name, qctor.Access));
} else if (!qctor.Overload) {
writer.Write (ImportAttrib);
writer.Write (ImportCtorCall (qctor.Name, qctor.Id, qctor.PinvokeParams));
writer.Write (StartCtor (qctor.Name, qctor.Access, qctor.CSharpParams));
writer.Write (RawObject (qctor.Name, qctor.Id, qctor.PinvokeCallParams));
writer.Write (CheckParent (qctor.Parent));
writer.Write (Register);
writer.Write (DefaultConnections ());
writer.Write (EndMember);
} else {
writer.Write (OverLoadCtor(qctor.Name, qctor.Access, qctor.CSharpParams, qctor.OverloadParams));
}
}
writer.Write (StartDCtor (qtype.Name));
writer.Write (DCtorCall);
writer.Write (EndMember);
//writer.Write (DisposePublic ());
foreach (TQDCtor qdctor in qtype.TQDCtors) {
writer.Write (ImportAttrib);
writer.Write (ImportDCtorCall (qdctor.Name));
}
//writer.Write (DisposeProtected ());
writer.Write (Delete ());
foreach (TQMethod qmethod in qtype.TQMethods) {
if (qmethod.Throttle) {
} else if (!qmethod.Overload) {
writer.Write(ImportAttrib);
if (qmethod.Access == "public" || qmethod.Access == "protected" || qmethod.Access == "internal") {
writer.Write(ImportMethodCall(qtype.Name, qmethod.Name, qmethod.Id, qmethod.PinvokeReturn, qmethod.PinvokeParams));
writer.Write(StartMethod(qmethod.PascalName, qmethod.Access, qmethod.Return, qmethod.CSharpParams));
writer.Write(MethodCall(qmethod.TQStringReturn, qmethod.Boxer, qtype.Name, qmethod.Name, "rawObject", qmethod.Id, qmethod.Return, qmethod.PinvokeCallParams));
} else {
writer.Write(StaticImportMethodCall(qtype.Name, qmethod.Name, qmethod.Id, qmethod.PinvokeReturn, qmethod.PinvokeParams));
writer.Write(StartMethod(qmethod.PascalName, qmethod.Access, qmethod.Return, qmethod.CSharpParams));
writer.Write(StaticMethodCall(qmethod.TQStringReturn, qmethod.Boxer, qtype.Name, qmethod.Name, qmethod.Id, qmethod.Return, qmethod.PinvokeCallParams));
}
writer.Write(EndMember);
} else {
writer.Write(OverLoadMethod(qmethod.PascalName, qmethod.Access, qmethod.Return, qmethod.CSharpParams, qmethod.OverloadParams));
}
}
foreach (TQAncestor qancestor in qtype.TQAncestors) {
writer.Write("\n\n"+tab+tab+"// Begin interface methods.\n");
if (qancestor.IsInterface) {
Printer printer = new Printer (qancestor, directory);
foreach (TQMethod qmethod in qancestor.TQMethods) {
if (qmethod.Throttle) {
} else if (!qmethod.Overload) {
writer.Write(ImportAttrib);
if (qmethod.Access == "public" || qmethod.Access == "protected") {
writer.Write(ImportMethodCall(qancestor.Name, qmethod.Name, qmethod.Id, qmethod.PinvokeReturn, qmethod.PinvokeParams));
writer.Write(StartMethod(qmethod.PascalName, qmethod.Access, qmethod.Return, qmethod.CSharpParams));
writer.Write(MethodCall(qmethod.TQStringReturn, qmethod.Boxer, qancestor.Name, qmethod.Name, qancestor.Name+" ()", qmethod.Id, qmethod.Return, qmethod.PinvokeCallParams));
} else {
writer.Write(StaticImportMethodCall(qancestor.Name, qmethod.Name, qmethod.Id, qmethod.PinvokeReturn, qmethod.PinvokeParams));
writer.Write(StartMethod(qmethod.PascalName, qmethod.Access, qmethod.Return, qmethod.CSharpParams));
writer.Write(StaticMethodCall(qmethod.TQStringReturn, qmethod.Boxer, qancestor.Name, qmethod.Name, qmethod.Id, qmethod.Return, qmethod.PinvokeCallParams));
}
writer.Write(EndMember);
} else {
writer.Write(OverLoadMethod(qmethod.PascalName, qmethod.Access, qmethod.Return, qmethod.CSharpParams, qmethod.OverloadParams));
}
}
}
}
writer.Write(EndClass);
writer.Write(Footer);
writer.Close();
}
public void PrintInterface ()
{
StreamWriter writer = new StreamWriter(directory + Path.DirectorySeparatorChar +
qtype.IName + ".cs", false, new ASCIIEncoding());
writer.Write(Header);
writer.Write(StartClass(qtype.IName, "public", qtype.TQAncestors));
foreach (TQMethod qmethod in qtype.TQMethods) {
if (qmethod.Throttle || qmethod.Access == "public static" || qmethod.Access == "protected") {
} else {
writer.Write(IMethod(qmethod.PascalName, qmethod.Return, qmethod.CSharpParams));
}
}
writer.Write("\n"+tab+tab+" IntPtr "+qtype.Name+" ();");
writer.Write(EndClass);
writer.Write(Footer);
writer.Close();
}
public string StartClass (string name, string access, ArrayList qancestors)
{
StringBuilder sb = new StringBuilder ();
if (qtype.IsInterface) {
sb.Append(tab+access+" interface "+name+" {");
return sb.ToString ();
}
sb.Append(tab+access+" class "+name+" : ");
if (qancestors.Count == 0) sb.Append ("QtSupport");
foreach (TQAncestor qancestor in qancestors) {
if (!qancestor.IsInterface) {
if (qancestor.Name == "Qt") {
sb.Append ("QtSupport");
break;
} else {
sb.Append (qancestor.Name);
qancestors.Remove (qancestor);
break;
}
}
}
foreach (TQAncestor qancestor in qancestors) {
if (qancestor.IsInterface) {
sb.Append (", "+qancestor.IName);
}
}
sb.Append (", IDisposable {");
return sb.ToString ();
}
public string EndClass
{
get {return "\n"+tab+"}";}
}
public string StartEnum (string name, string access, string type)
{
if (type != null)
return "\n\n"+tab+tab+access+" enum "+name+" : "+type+" {";
else
return "\n\n"+tab+tab+access+" enum "+name+" {";
}
public string WriteInherited (string name, string access)
{
return "\n\n"+tab+tab+access+" "+name+" () : this (TQNull.Instance) {}";
}
public string WriteDummy (string name, string access)
{
return "\n\n"+tab+tab+access+" "+name+" (TQNull dummy) : base (TQNull.Instance) {}";
}
public string WriteBoxer (string name, string access)
{
return "\n\n" +
tab+tab+access+" "+name+" (IntPtr ptr) : this (TQNull.Instance)\n"+tab+tab+"{\n" +
tab+tab+tab+"rawObject = ptr;\n" +
tab+tab+tab+"RegisterObject(this);\n" +
tab+tab+"}";
}
public string CheckParent (bool check)
{
if (check)
return "\n\n\t\t\tif ((qparent = parent) != null)\n" +
"\t\t\tparent.AddChild (this);\n";
else
return "";
}
public string StartCtor (string name, string access, ArrayList csharpparams)
{
return "\n"+tab+tab+access+" "+name+" ("+Params(csharpparams)+") : this (TQNull.Instance)\n"+tab+tab+"{\n";
}
public string StartDCtor (string name)
{
return "\n\n"+tab+tab+"~"+name+" ()\n"+tab+tab+"{\n";
}
public string StartMethod (string name, string access, string returntype, ArrayList csharpparams)
{
string str = "\n"+tab+tab+access+" "+returntype+" "+name+" ("+Params(csharpparams)+")\n"+tab+tab+"{\n";
// TQEvents should never be disposed inside C#
if (access.IndexOf ("static") <= 0)
str += "\t\t\tif (disposed)\n\t\t\t\tthrow new ObjectDisposedException (this+\": Attempted use of disposed object\");\n\n";
return str;
}
public string IMethod (string name, string returntype, ArrayList csharpparams)
{
return "\n"+tab+tab+" "+returntype+" "+name+" ("+Params(csharpparams)+");";
}
public string EndMember
{
get {return "\n"+tab+tab+"}";}
}
public string OverLoadCtor (string name, string access, ArrayList csharpparams, ArrayList overloadparams)
{
return "\n\n"+tab+tab+access+" "+name+" ("+Params(csharpparams)+") : this ("+Params(overloadparams)+") {}";
}
public string OverLoadMethod (string name, string access, string returntype, ArrayList csharpparams, ArrayList overloadparams)
{
string str;
if (returntype == "void")
str = name + "(" + Params(overloadparams) + ");\n" + tab + tab;
else
str = "return "+name+"("+Params(overloadparams)+");\n" + tab+tab;
return "\n\n"+tab+tab+access+" "+returntype+" "+name +
" ("+Params(csharpparams)+")\n" + tab+tab+"{\n" + tab+tab+tab+ str + "}";
}
public string Items (ArrayList qitems)
{
int count = 0;
StringBuilder sb = new StringBuilder();
foreach (TQItem qitem in qitems) {
count++;
sb.Append("\n"+tab+tab+tab+qitem.Name+" = "+qitem.Value);
if (count != qitems.Count)
sb.Append(",");
}
return sb.ToString();
}
public string Params (ArrayList qparams)
{
int count = 0;
StringBuilder sb = new StringBuilder();
foreach (TQParam qparam in qparams) {
count++;
if (qparam.Type != "")
sb.Append(qparam.Type+" "+qparam.Name);
else
sb.Append(qparam.Name);
if (count != qparams.Count)
sb.Append(", ");
}
return sb.ToString();
}
public string ImportCtorCall (string name, string id, ArrayList qparams)
{
if (id != "0")
return "\n"+tab+tab+"private static extern IntPtr qt_new_"+name+id+" ("+Params(qparams)+");";
else
return "\n"+tab+tab+"private static extern IntPtr qt_new_"+name+" ("+Params(qparams)+");";
}
public string ImportDCtorCall (string name)
{
return "\n"+tab+tab+"private static extern void qt_del_"+name+" (IntPtr raw);";
}
public string ImportMethodCall (string type, string name, string id, string returntype, ArrayList qparams)
{
if (name.StartsWith ("Q_"))
name = name.Replace ("Q_", "");
string comma = "";
if (qparams.Count != 0) comma = ", ";
if (id != "0")
return "\n"+tab+tab+"private static extern "+returntype+" qt_"+type+"_"+name+id+" (IntPtr raw"+comma+Params(qparams)+");";
else
return "\n"+tab+tab+"private static extern "+returntype+" qt_"+type+"_"+name+" (IntPtr raw"+comma+Params(qparams)+");";
}
public string StaticImportMethodCall (string type, string name, string id, string returntype, ArrayList qparams)
{
if (name.StartsWith ("Q_"))
name = name.Replace ("Q_", "");
if (id != "0")
return "\n"+tab+tab+"private static extern "+returntype+" qt_"+type+"_"+name+id+" ("+Params(qparams)+");";
else
return "\n"+tab+tab+"private static extern "+returntype+" qt_"+type+"_"+name+" ("+Params(qparams)+");";
}
public string RawObject (string name, string id, ArrayList qparams)
{
if (qtype.IsTQObject) {
ArrayList newparams = new ArrayList ();
foreach (TQParam parm in qparams) {
//Console.WriteLine ("--> {0}", parm.Name);
if (parm.Name == "parent.RawObject") {
TQParam newparm = parm.Clone() as TQParam;
newparm.Name = "parent != null ? parent.RawObject : IntPtr.Zero";
newparams.Add (newparm);
}
else
newparams.Add (parm);
}
if (id != "0")
return tab+tab+tab+"rawObject = qt_new_"+name+id+" ("+Params(newparams)+");";
else
return tab+tab+tab+"rawObject = qt_new_"+name+" ("+Params(newparams)+");";
}
else {
if (id != "0")
return tab+tab+tab+"rawObject = qt_new_"+name+id+" ("+Params(qparams)+");";
else
return tab+tab+tab+"rawObject = qt_new_"+name+" ("+Params(qparams)+");";
}
}
public string DCtorCall {
get {
return tab+tab+tab+"Dispose (false);";
}
}
public string MethodCall (bool qstring, bool boxer, string type, string name, string instPtr, string id, string ReturnType, ArrayList qparams)
{
if (name.StartsWith ("Q_"))
name = name.Replace ("Q_", "");
string ret = "";
string comma = qparams.Count == 0 ? "" : ", ";
string newid = id == "0" ? "" : id;
if (boxer && qstring) {
ret = "\t\t\treturn new TQString (qt_"+type+"_"+name+newid+" ("+instPtr+comma+Params (qparams)+"));\n";
}
else if (boxer) {
ret = "\t\t\treturn LookupObject (qt_"+type+"_"+name+newid+" ("+instPtr+comma+Params (qparams)+"), typeof ("+ReturnType+")) as "+ReturnType+";";
}
else {
ret = "qt_"+type+"_"+name+newid+" ("+instPtr+comma+Params (qparams)+");";
if (ReturnType != "void")
ret = "return " + ret;
ret = "\t\t\t" + ret;
}
return ret;
}
public string StaticMethodCall (bool qstring, bool boxer, string type, string name, string id, string ReturnType, ArrayList qparams)
{
if (name.StartsWith ("Q_"))
name = name.Replace ("Q_", "");
string ret;
string newid = id == "0" ? "" : id;
if (boxer && qstring) {
ret = "\t\t\treturn new TQString (qt_"+type+"_"+name+newid+" ("+Params (qparams)+"));\n";
}
else if (boxer) {
ret = "\t\t\treturn LookupObject (qt_"+type+"_"+name+newid+" ("+Params (qparams)+"), typeof ("+ReturnType+")) as "+ReturnType+";\n";
}
else {
ret = "qt_"+type+"_"+name+newid+" ("+Params (qparams)+");";
if (ReturnType != "void")
ret = "return " + ret;
ret = "\t\t\t" + ret;
}
return ret;
}
public string ImportAttrib
{
get {return "\n\n"+tab+tab+"[DllImport(\"libtqtc\", CharSet=CharSet.Ansi)]";}
}
public string Import () {
if (!qtype.IsInterface) {
return tab + "using System.Runtime.InteropServices;\n\n";
} else {
return "\n";
}
}
public string Header
{
get {
return "// "+qtype.Name+".cs - A Qt to C# binding.\n" +
"//\n" +
"// Copyright (C) 2002 Adam Treat (manyoso@yahoo.com)\n" +
"//\n" +
"// This program is free software; you can redistribute it and/or\n" +
"// modify it under the terms of the GNU General Public License\n" +
"// as published by the Free Software Foundation; either version 2\n" +
"// of the License, or (at your option) any later version.\n" +
"//\n" +
"// This program is distributed in the hope that it will be useful,\n" +
"// but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +
"// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +
"// GNU General Public License for more details.\n" +
"//\n" +
"// You should have received a copy of the GNU General Public License\n" +
"// along with this program; if not, write to the Free Software\n" +
"// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" +
"//\n" +
"// Generated File. Do Not Modify.\n" +
"\n" +
"namespace Qt {\n" +
"\n" +
tab + "using Qt;\n" +
tab + "using System;\n" + Import ();
}
}
public string Footer
{
get {return "\n}";}
}
public string Register
{
get
{
return "\n"+tab+tab+tab+"RegisterObject (this);";
}
}
public string Delete ()
{
string ret = "\n" +
"\t\tinternal override void Delete ()\n" +
"\t\t{\n";
// Let Qt manage TQEvents
if (! (qtype.Name.StartsWith ("Q") && qtype.Name.EndsWith ("Event")))
{
ret += "\t\t\tif (deleted) return;\n\n";
if (qtype.TQDCtors.Count > 0)
ret += "\t\t\tqt_del_"+qtype.Name+" (rawObject);\n";
else
ret = "\n" + ret + "\t\t\t// libtqtc lacks a qt_del_"+qtype.Name+" function\n";
ret += "\t\t\tdeleted = true;\n";
}
ret += "\t\t}";
return ret;
}
public string DefaultConnections ()
{
if (qtype.IsTQObject)
return "\n\t\t\tConnect (this, TQ_SIGNAL (\"destroyed ()\"), TQ_SLOT (\"NativeDestroyed ()\"));";
else
return "";
}
}
}