Skip to content

Commit 230685b

Browse files
committed
Extended Qt# and updated C++# so that the entire Qt can be wrapped.
Signed-off-by: Dimitar Dobrev <[email protected]>
1 parent 36c5f0e commit 230685b

File tree

7 files changed

+110
-63
lines changed

7 files changed

+110
-63
lines changed

CHANGELOG

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
0.5.0 - 12.6.2016
2+
Added:
3+
- Wrapped the entire Qt.
4+
15
0.0.8 - 21.12.2015
26
Added:
37
- Properly wrapped non-virtual destructors in derived types.

QtSharp.CLI/Program.cs

+9-29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
34
using System.IO;
45
using System.IO.Compression;
56
using System.Linq;
@@ -168,6 +169,7 @@ static void ProcessGeneratedInlines ()
168169

169170
public static int Main(string[] args)
170171
{
172+
Stopwatch s = Stopwatch.StartNew();
171173
var qts = FindQt();
172174
bool found = qts.Count != 0;
173175
bool debug = false;
@@ -195,36 +197,14 @@ public static int Main(string[] args)
195197
if (!QueryQt(qt, debug))
196198
return 1;
197199

198-
var modules = new List<string>
199-
{
200-
"QtCore",
201-
"QtGui",
202-
"QtWidgets",
203-
"QtXml",
204-
"QtDesigner",
205-
"QtNetwork",
206-
"QtQml",
207-
"QtNfc",
208-
"QtOpenGL",
209-
"QtScriptTools",
210-
"QtSensors",
211-
"QtSerialPort",
212-
"QtSvg",
213-
"QtMultimedia",
214-
"QtMultimediaWidgets",
215-
"QtQuick",
216-
"QtQuickWidgets"
217-
};
218-
if (debug)
219-
{
220-
for (var i = 0; i < modules.Count; i++)
221-
{
222-
modules[i] += "d";
223-
}
224-
}
225200
for (int i = qt.LibFiles.Count - 1; i >= 0; i--)
226201
{
227-
if (!modules.Contains(QtSharp.GetModuleNameFromLibFile(qt.LibFiles[i])))
202+
var libFile = qt.LibFiles[i];
203+
var libFileName = Path.GetFileNameWithoutExtension(libFile);
204+
if (Path.GetExtension(libFile) == ".exe" ||
205+
libFileName == "QtDeclarative" || libFileName == "Qt5Declarative" ||
206+
// QtQuickTest is a QML module but has 3 main C++ functions and is not auto-ignored
207+
libFileName == "QtQuickTest" || libFileName == "Qt5QuickTest")
228208
{
229209
qt.LibFiles.RemoveAt(i);
230210
}
@@ -260,7 +240,7 @@ public static int Main(string[] args)
260240
zipArchive.CreateEntryFromFile("CppSharp.Runtime.dll", "CppSharp.Runtime.dll");
261241
}
262242
}
263-
243+
Console.WriteLine("Done in: " + s.Elapsed);
264244
return 0;
265245
}
266246

QtSharp/CompileInlinesPass.cs

+16-4
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,22 @@ private bool CompileInlines(Module module)
7070
var pro = string.Format("{0}.pro", module.InlinesLibraryName);
7171
var path = Path.Combine(this.Driver.Options.OutputDir, pro);
7272
var proBuilder = new StringBuilder();
73-
proBuilder.AppendFormat("QT += {0}\n",
74-
string.Join(" ", from header in module.Headers
75-
where !header.EndsWith(".h", StringComparison.Ordinal)
76-
select header.Substring("Qt".Length).ToLowerInvariant()));
73+
var qtModules = string.Join(" ", from header in module.Headers
74+
where !header.EndsWith(".h", StringComparison.Ordinal)
75+
select header.Substring("Qt".Length).ToLowerInvariant());
76+
switch (qtModules)
77+
{
78+
// QtTest is only library which has a "lib" suffix to its module alias for qmake
79+
case "test":
80+
qtModules += "lib";
81+
break;
82+
// HACK: work around https://bugreports.qt.io/browse/QTBUG-54030
83+
case "bluetooth":
84+
qtModules += " network";
85+
break;
86+
}
87+
88+
proBuilder.AppendFormat("QT += {0}\n", qtModules);
7789
proBuilder.Append("CONFIG += c++11\n");
7890
proBuilder.Append("QMAKE_CXXFLAGS += -fkeep-inline-functions\n");
7991
proBuilder.AppendFormat("TARGET = {0}\n", module.InlinesLibraryName);

QtSharp/DocGeneration/Documentation.cs

+25-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@ public class Documentation
2121
{
2222
public Documentation(string docsPath, IEnumerable<string> modules)
2323
{
24-
foreach (var module in modules)
24+
// HACK: work around https://bugreports.qt.io/browse/QTBUG-54025
25+
var documentationModules = new List<string>(modules);
26+
const string qt3d = "Qt3D";
27+
documentationModules.RemoveAll(d => d.StartsWith(qt3d, StringComparison.Ordinal));
28+
documentationModules.Add(qt3d);
29+
foreach (var module in documentationModules)
2530
{
2631
var entries = Get(docsPath, module);
2732
foreach (var entry in entries)
@@ -238,7 +243,10 @@ private void CollectTypesDocumentation(HtmlNode documentRoot, string docFile)
238243
}
239244
node = node.NextSibling;
240245
}
241-
this.typesDocumentation.Add(docFile, nodes);
246+
if (nodes.Count > 0)
247+
{
248+
this.typesDocumentation.Add(docFile, nodes);
249+
}
242250
}
243251
}
244252

@@ -254,15 +262,28 @@ public void DocumentFunction(Function function)
254262
var functions = this.functionNodes[function.OriginalName];
255263
var unit = function.OriginalNamespace.TranslationUnit;
256264
var location = unit.FileName;
257-
var node = functions.Find(
265+
FunctionDocIndexNode node = null;
266+
var nodes = functions.FindAll(
258267
f => f.Location == location &&
259268
(f.LineNumber == lineStart || f.LineNumber == lineEnd));
269+
// incredible but we actually have a case of different functions with the same name in headers with the same name at the same line
270+
if (nodes.Count > 0)
271+
{
272+
if (nodes.Count == 1)
273+
{
274+
node = nodes[0];
275+
}
276+
else
277+
{
278+
node = nodes.Find(n => n.FullName == function.QualifiedOriginalName);
279+
}
280+
}
260281
var @params = function.Parameters.Where(p => p.Kind == ParameterKind.Regular).ToList();
261282
int realParamsCount = @params.Count(p => !string.IsNullOrWhiteSpace(p.OriginalName) || p.DefaultArgument == null);
262283
// functions can have different line numbers because of #defines
263284
if (node == null || node.HRef == null)
264285
{
265-
var nodes = functions.FindAll(
286+
nodes = functions.FindAll(
266287
f => CheckLocation(f.Location, location) &&
267288
(f.FullName == function.QualifiedOriginalName || f.Name == function.OriginalName) &&
268289
f.Access != "private" && f.ParametersModifiers.Count == realParamsCount);

QtSharp/GenerateEventEventsPass.cs

+15-9
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,23 @@ public override bool VisitMethodDecl(Method method)
6767
return false;
6868
}
6969

70-
if (!method.IsConstructor && (method.Name.EndsWith("Event") || method.Name == "event") &&
71-
method.Parameters.Count == 1 && method.Parameters[0].Type.ToString().EndsWith("Event"))
70+
if (!method.IsConstructor && (method.Name.EndsWith("Event", StringComparison.Ordinal) || method.Name == "event") &&
71+
method.Parameters.Count == 1)
7272
{
73-
var name = char.ToUpperInvariant(method.Name[0]) + method.Name.Substring(1);
74-
method.Name = "on" + name;
75-
Method baseMethod;
76-
if (!method.IsOverride ||
77-
(baseMethod = ((Class) method.Namespace).GetBaseMethod(method, true, true)) == null ||
78-
baseMethod.IsPure)
73+
var type = method.Parameters[0].Type;
74+
type = type.GetFinalPointee() ?? type;
75+
Class @class;
76+
if (type.TryGetClass(out @class) && @class.Name.EndsWith("Event", StringComparison.Ordinal))
7977
{
80-
this.events.Add(method);
78+
var name = char.ToUpperInvariant(method.Name[0]) + method.Name.Substring(1);
79+
method.Name = "on" + name;
80+
Method baseMethod;
81+
if (!method.IsOverride ||
82+
(baseMethod = ((Class) method.Namespace).GetBaseMethod(method, true, true)) == null ||
83+
baseMethod.IsPure)
84+
{
85+
this.events.Add(method);
86+
}
8187
}
8288
}
8389
return true;

QtSharp/QFlags.cs

+27-10
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,7 @@ public override string CSharpConstruct()
1616

1717
public override Type CSharpSignatureType(CSharpTypePrinterContext ctx)
1818
{
19-
var type = ctx.Type.Desugar();
20-
ClassTemplateSpecialization classTemplateSpecialization;
21-
var templateSpecializationType = type as TemplateSpecializationType;
22-
if (templateSpecializationType != null)
23-
classTemplateSpecialization = templateSpecializationType.GetClassTemplateSpecialization();
24-
else
25-
classTemplateSpecialization = (ClassTemplateSpecialization) ((TagType) type).Declaration;
26-
return classTemplateSpecialization.Arguments[0].Type.Type;
19+
return GetEnumType(ctx.Type);
2720
}
2821

2922
public override string CSharpSignature(CSharpTypePrinterContext ctx)
@@ -33,12 +26,36 @@ public override string CSharpSignature(CSharpTypePrinterContext ctx)
3326

3427
public override void CSharpMarshalToNative(MarshalContext ctx)
3528
{
36-
ctx.Return.Write(ctx.Parameter.Name);
29+
if (ctx.Parameter.Type.Desugar().IsAddress())
30+
ctx.Return.Write("new global::System.IntPtr(&{0})", ctx.Parameter.Name);
31+
else
32+
ctx.Return.Write(ctx.Parameter.Name);
3733
}
3834

3935
public override void CSharpMarshalToManaged(MarshalContext ctx)
4036
{
41-
ctx.Return.Write(ctx.ReturnVarName);
37+
if (ctx.ReturnType.Type.Desugar().IsAddress())
38+
{
39+
var finalType = ctx.ReturnType.Type.GetFinalPointee() ?? ctx.ReturnType.Type;
40+
var enumType = GetEnumType(finalType);
41+
ctx.Return.Write("*({0}*) {1}", enumType, ctx.ReturnVarName);
42+
}
43+
else
44+
{
45+
ctx.Return.Write(ctx.ReturnVarName);
46+
}
47+
}
48+
49+
private static Type GetEnumType(Type mappedType)
50+
{
51+
var type = mappedType.Desugar();
52+
ClassTemplateSpecialization classTemplateSpecialization;
53+
var templateSpecializationType = type as TemplateSpecializationType;
54+
if (templateSpecializationType != null)
55+
classTemplateSpecialization = templateSpecializationType.GetClassTemplateSpecialization();
56+
else
57+
classTemplateSpecialization = (ClassTemplateSpecialization) ((TagType) type).Declaration;
58+
return classTemplateSpecialization.Arguments[0].Type.Type;
4259
}
4360
}
4461
}

QtSharp/QtSharp.cs

+14-7
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public void Preprocess(Driver driver, ASTContext lib)
6565
method.ExplicitlyIgnore();
6666
}
6767

68-
// HACK: forward declarations can enable declarations to use types from other modules; ignore such declarations until properly fixed
68+
// HACK: work around https://github.com/mono/CppSharp/issues/657
6969
var qSignalMapper = lib.FindCompleteClass("QSignalMapper");
7070
for (int i = qSignalMapper.Methods.Count - 1; i >= 0; i--)
7171
{
@@ -98,7 +98,8 @@ public void Preprocess(Driver driver, ASTContext lib)
9898
method.ExplicitlyIgnore();
9999
}
100100
}
101-
var qCamera = lib.FindCompleteClass("QCamera");
101+
var qCamera = lib.FindClass("QCamera").FirstOrDefault(c => !c.IsIncomplete &&
102+
c.TranslationUnit.Module.OutputNamespace == "QtMultimedia");
102103
var qMediaPlayer = lib.FindCompleteClass("QMediaPlayer");
103104
foreach (var method in qCamera.Methods.Union(qMediaPlayer.Methods).Where(m => m.Parameters.Any()))
104105
{
@@ -164,7 +165,9 @@ public void Postprocess(Driver driver, ASTContext lib)
164165
{
165166
new ClearCommentsPass().VisitLibrary(driver.ASTContext);
166167
var modules = this.qtInfo.LibFiles.Select(l => GetModuleNameFromLibFile(l));
168+
var s = System.Diagnostics.Stopwatch.StartNew();
167169
new GetCommentsFromQtDocsPass(this.qtInfo.Docs, modules).VisitLibrary(driver.ASTContext);
170+
System.Console.WriteLine("Documentation done in: {0}", s.Elapsed);
168171
new CaseRenamePass(
169172
RenameTargets.Function | RenameTargets.Method | RenameTargets.Property | RenameTargets.Delegate |
170173
RenameTargets.Field | RenameTargets.Variable,
@@ -187,6 +190,15 @@ public void Postprocess(Driver driver, ASTContext lib)
187190
{
188191
method.ExplicitlyIgnore();
189192
}
193+
194+
foreach (var module in driver.Options.Modules)
195+
{
196+
var prefix = Platform.IsWindows ? string.Empty : "lib";
197+
var extension = Platform.IsWindows ? ".dll" : Platform.IsMacOS ? ".dylib" : ".so";
198+
var inlinesLibraryFile = string.Format("{0}{1}{2}", prefix, module.InlinesLibraryName, extension);
199+
var inlinesLibraryPath = Path.Combine(driver.Options.OutputDir, Platform.IsWindows ? "release" : string.Empty, inlinesLibraryFile);
200+
this.wrappedModules.Add(new KeyValuePair<string, string>(module.LibraryName + ".dll", inlinesLibraryPath));
201+
}
190202
}
191203

192204
public void Setup(Driver driver)
@@ -257,11 +269,6 @@ public void Setup(Driver driver)
257269
}
258270

259271
driver.Options.Modules.Add(module);
260-
var prefix = Platform.IsWindows ? string.Empty : "lib";
261-
var extension = Platform.IsWindows ? ".dll" : Platform.IsMacOS ? ".dylib" : ".so";
262-
var inlinesLibraryFile = string.Format("{0}{1}{2}", prefix, module.InlinesLibraryName, extension);
263-
var inlinesLibraryPath = Path.Combine(driver.Options.OutputDir, Platform.IsWindows ? "release" : string.Empty, inlinesLibraryFile);
264-
this.wrappedModules.Add(new KeyValuePair<string, string>(module.LibraryName + ".dll", inlinesLibraryPath));
265272
}
266273

267274
foreach (var systemIncludeDir in this.qtInfo.SystemIncludeDirs)

0 commit comments

Comments
 (0)