Browse Source

preprocess classes to set up template arguments and create all types

before processing fields, methods and arguments that might use them
pull/1/head
Andreia Gaita 15 years ago
parent
commit
c9da14bd4e
  1. 20
      src/CPPInterop.sln
  2. 2
      src/Mono.VisualC.Code/Atoms/Class.cs
  3. 147
      src/generator/Main.cs
  4. 2
      src/generator/generator.csproj

20
src/CPPInterop.sln

@ -53,8 +53,9 @@ Global @@ -53,8 +53,9 @@ Global
{B01E6282-144E-481A-8E1F-95F708DFBC2D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = QtTest\QtTest.csproj
StartupItem = generator\generator.csproj
Policies = $0
$0.TextStylePolicy = $1
$1.inheritsSet = null
$1.scope = text/x-csharp
$0.CSharpFormattingPolicy = $2
@ -63,19 +64,16 @@ Global @@ -63,19 +64,16 @@ Global
$2.InterfaceBraceStyle = EndOfLine
$2.StructBraceStyle = EndOfLine
$2.EnumBraceStyle = EndOfLine
$2.SpacesAfterTypecast = True
$2.inheritsSet = Mono
$2.inheritsScope = text/x-csharp
$2.scope = text/x-csharp
$3.Text =
$3.inheritsSet = Apache2License
$0.TextStylePolicy = $4
$4.FileWidth = 120
$4.TabWidth = 4
$4.RemoveTrailingWhitespace = True
$4.inheritsSet = Mono
$4.inheritsScope = text/plain
$4.scope = text/plain
$0.TextStylePolicy = $3
$3.FileWidth = 120
$3.TabWidth = 4
$3.RemoveTrailingWhitespace = True
$3.inheritsSet = Mono
$3.inheritsScope = text/plain
$3.scope = text/plain
name = CPPInterop
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution

2
src/Mono.VisualC.Code/Atoms/Class.cs

@ -29,6 +29,8 @@ namespace Mono.VisualC.Code.Atoms { @@ -29,6 +29,8 @@ namespace Mono.VisualC.Code.Atoms {
public IList<BaseClass> Bases { get; set; }
public IList<string> TemplateArguments { get; set; }
public string GenericName {get; set;}
public CppType OriginalType {get; set;}
public Class (string name)
{

147
src/generator/Main.cs

@ -128,10 +128,10 @@ namespace Mono.VisualC.Tools.Generator { @@ -128,10 +128,10 @@ namespace Mono.VisualC.Tools.Generator {
List<Entry> entries = Preprocess (xmldoc);
Console.WriteLine ("\tPreprocessing Classes");
PreprocessClasses (entries);
List<Entry> removed = PreprocessClasses (entries);
Console.WriteLine ("\tProcessing Classes");
ProcessClasses (entries);
ProcessClasses (entries, removed);
// save files
Console.WriteLine ("\tSaving Classes");
@ -224,69 +224,69 @@ namespace Mono.VisualC.Tools.Generator { @@ -224,69 +224,69 @@ namespace Mono.VisualC.Tools.Generator {
return data;
}
void PreprocessClasses (List<Entry> entries)
List<Entry> PreprocessClasses (List<Entry> entries)
{
List<Entry> removed = new List<Entry> (entries.Where (o => (o.type == "Class" || o.type == "Struct") && (o.IsTrue ("incomplete") || !o.HasValue ("name") || (Entry.idlist[o["file"]].name.StartsWith ("/")))));
entries.RemoveAll (o => (o.type == "Class" || o.type == "Struct") && (o.IsTrue ("incomplete") || !o.HasValue ("name") || (Entry.idlist[o["file"]].name.StartsWith ("/"))));
}
void ProcessClasses (List<Entry> entries)
{
foreach (Entry clas in entries.Where (o => o.type == "Class" || o.type == "Struct")) {
//onsole.WriteLine (clas.name);
//bool bb;
//if (clas.name.StartsWith ("QGraphicsBlurEffect"))
// bb = true;
clas.computedName = clas.name;
string ns = GetNamespace (clas);
CppType currentType = new CppType (clas.type.ToLower (), ns != null ? ns + "::" + clas.computedName : clas.computedName);
IEnumerable<CodeAtom> nested = null;
// FIXME: better way to do this (GCC-XML output doesn't seem to leave much choice)
CppType [] replaceArgs = null;
var templated = currentType.Modifiers.OfType<CppModifiers.TemplateModifier> ().SingleOrDefault ();
if (templated != null) {
clas.isTemplate = true;
string baseName = currentType.ElementTypeName;
if (IsCreated (currentType, true, out nested))
continue;
string computedName = clas.computedName;
clas.computedName = baseName;
replaceArgs = templated.Types;
clas.atom = new Class (clas.computedName) {
StaticCppLibrary = string.Format ("{0}.Libs.{1}", Namespace, Library),
OriginalType = currentType
};
int i = 0;
foreach (var t in templated.Types)
clas.Class.TemplateArguments.Add (genericTypeArgs[i++]);
clas.Class.GenericName = String.Format ("{0}<{1}>", baseName, string.Join (",", clas.Class.TemplateArguments.ToArray ()));
Console.Error.WriteLine ("Warning: Creating generic type {0}<{1}> from the instantiated template {2} (very buggy!!!)",
baseName,
string.Join (",", clas.Class.TemplateArguments.ToArray ()), computedName);
} else {
clas.atom = new Class (clas.computedName) {
StaticCppLibrary = string.Format ("{0}.Libs.{1}", Namespace, Library),
OriginalType = currentType
};
}
string [] ras = new string[replaceArgs.Length];
string [] letters = new string[replaceArgs.Length];
for (int i = 0; i < replaceArgs.Length; i++) {
letters[i] = genericTypeArgs[i];
ras[i] = string.Format ("{0} with {1}", replaceArgs[i].ToString (), letters[i]);
}
Console.Error.WriteLine ("Warning: Creating generic type {0}<{1}> from the instantiated template {2} by replacing {3} (very buggy!!!)", baseName, string.Join (",", letters), clas.computedName, string.Join (", ", ras));
// FIXME: Handle when base class name is fully qualified
foreach (Entry bs in clas.children.Where (o => o.type == "Base")) {
clas.Class.Bases.Add (new Class.BaseClass { Name = bs.Base.name, Access = bs.CheckValue ("access", "public") ? Access.Public : bs.CheckValue ("access", "protected") ? Access.Protected : Access.Private, IsVirtual = bs.IsTrue ("virtual") });
}
clas.computedName = baseName;
} else if (IsCreated (currentType, true, out nested))
IEnumerable<CodeAtom> nested = null;
if (IsCreated (clas.Class.OriginalType, true, out nested))
continue;
clas.atom = new Class (clas.computedName) { StaticCppLibrary = string.Format ("{0}.Libs.{1}", Namespace, Library) };
GetContainer (clas, Tree).Atoms.AddLast (clas.atom);
if (nested != null) {
foreach (var orphan in nested)
clas.Class.Atoms.AddLast (orphan);
}
}
// add template type args
if (replaceArgs != null) {
for (int i = 0; i < replaceArgs.Length; i++)
clas.Class.TemplateArguments.Add (genericTypeArgs[i]);
}
return removed;
}
// FIXME: Handle when base class name is fully qualified
foreach (Entry bs in clas.children.Where (o => o.type == "Base")) {
clas.Class.Bases.Add (new Class.BaseClass { Name = bs.Base.name, Access = bs.CheckValue ("access", "public") ? Access.Public : bs.CheckValue ("access", "protected") ? Access.Protected : Access.Private, IsVirtual = bs.IsTrue ("virtual") });
}
void ProcessClasses (List<Entry> entries, List<Entry> removed)
{
foreach (Entry clas in entries.Where (o => o.type == "Class" || o.type == "Struct")) {
var templated = clas.Class.OriginalType.Modifiers.OfType<CppModifiers.TemplateModifier> ().SingleOrDefault ();
Dictionary<MethodSignature, string> methods = new Dictionary<MethodSignature, string> ();
foreach (Entry member in clas.Members) {
@ -304,7 +304,7 @@ namespace Mono.VisualC.Tools.Generator { @@ -304,7 +304,7 @@ namespace Mono.VisualC.Tools.Generator {
case "Method":
break;
case "Field":
CppType fieldType = findType (member.Base);
CppType fieldType = findType (clas.Class, member.Base, removed);
string fieldName = "field" + fieldCount++;
if (member.name != "")
fieldName = member.name;
@ -321,11 +321,11 @@ namespace Mono.VisualC.Tools.Generator { @@ -321,11 +321,11 @@ namespace Mono.VisualC.Tools.Generator {
string mname = member.name;
CppType retType = member.HasValue ("returns") ? findType (clas.Class, Entry.idlist[member["returns"]], removed) : CppTypes.Void;
CppType retType = member.HasValue ("returns") ? findType (Entry.idlist[member["returns"]]) : CppTypes.Void;
if (replaceArgs != null) {
for (int i = 0; i < replaceArgs.Length; i++)
retType = replaceType (retType, replaceArgs[i], genericTypeArgs[i]);
if (templated != null) {
for (int i = 0; i < templated.Types.Length; i++)
retType = replaceType (retType, templated.Types[i], genericTypeArgs[i]);
}
var methodAtom = new Method (dtor ? "Destruct" : mname) { RetType = retType, IsVirtual = member.IsTrue ("virtual"), IsStatic = member.IsTrue ("static"), IsConst = member.IsTrue ("const"), IsConstructor = ctor, IsDestructor = dtor };
@ -343,11 +343,11 @@ namespace Mono.VisualC.Tools.Generator { @@ -343,11 +343,11 @@ namespace Mono.VisualC.Tools.Generator {
else
argname = arg.name;
CppType argtype = findType (arg.Base);
CppType argtype = findType (clas.Class, arg.Base, removed);
var templat = argtype.Modifiers.OfType<CppModifiers.TemplateModifier> ().SingleOrDefault ();
if (replaceArgs != null) {
for (int i = 0; i < replaceArgs.Length; i++)
argtype = replaceType (argtype, replaceArgs[i], genericTypeArgs[i]);
if (templated != null) {
for (int i = 0; i < templated.Types.Length; i++)
argtype = replaceType (argtype, templated.Types[i], genericTypeArgs[i]);
}
methodAtom.Parameters.Add (new NameTypePair<CppType> { Name = argname, Type = argtype });
@ -409,7 +409,7 @@ namespace Mono.VisualC.Tools.Generator { @@ -409,7 +409,7 @@ namespace Mono.VisualC.Tools.Generator {
doIt = propertyAtom.Getter != null && propertyAtom.Getter.RetType.Equals (methodAtom.Parameters[0].Type);
} else {
Entry getter = clas.Members.Where (o => o.name == getterName).FirstOrDefault ();
doIt = (getter != null && findType (Entry.idlist[getter.attributes["returns"]]).Equals (methodAtom.Parameters[0].Type));
doIt = (getter != null && findType (clas.Class, Entry.idlist[getter.attributes["returns"]], removed).Equals (methodAtom.Parameters[0].Type));
}
if (doIt) {
if (propertyAtom != null) {
@ -915,7 +915,7 @@ namespace Mono.VisualC.Tools.Generator { @@ -915,7 +915,7 @@ namespace Mono.VisualC.Tools.Generator {
// return enumType;
//}
CppType ProcessUnion (Entry entry)
CppType ProcessUnion (Class clas, Entry entry, List<Entry> removed)
{
string fullName = entry.name;
if (entry.name == "") {
@ -932,7 +932,7 @@ namespace Mono.VisualC.Tools.Generator { @@ -932,7 +932,7 @@ namespace Mono.VisualC.Tools.Generator {
Union unionAtom = new Union (fullName);
foreach (Entry m in entry.Members.Where (o => o.type == "Field")) {
Field field = new Field (m.name, findType (m.Base));
Field field = new Field (m.name, findType (clas, m.Base, removed));
unionAtom.Atoms.AddLast (field);
}
@ -1053,10 +1053,12 @@ namespace Mono.VisualC.Tools.Generator { @@ -1053,10 +1053,12 @@ namespace Mono.VisualC.Tools.Generator {
int i = 0;
foreach (var param in type.Modifiers.OfType<CppModifiers.TemplateModifier> ()) {
if (param.Types != null) {
foreach (var t in param.Types)
foreach (var t in param.Types) {
atom.TemplateArguments.Add (genericTypeArgs[i++]);
} else
}
} else {
atom.TemplateArguments.Add (genericTypeArgs[i++]);
}
}
if (orphans != null) {
@ -1201,14 +1203,14 @@ namespace Mono.VisualC.Tools.Generator { @@ -1201,14 +1203,14 @@ namespace Mono.VisualC.Tools.Generator {
// return root.SelectSingleNode (string.Format ("/GCC_XML/Method[({0}) and ({1})]", predicate, isMember));
//}
CppType findType (Entry entry)
CppType findType (Class clas, Entry entry, List<Entry> removed)
{
if (entry == null)
return CppTypes.Unknown;
return findType (entry, new CppType ());
return findType (clas, entry, removed, new CppType ());
}
CppType findType (Entry entry, CppType modifiers)
CppType findType (Class clas, Entry entry, List<Entry> removed, CppType modifiers)
{
if (entry == null)
return CppTypes.Unknown;
@ -1216,28 +1218,49 @@ namespace Mono.VisualC.Tools.Generator { @@ -1216,28 +1218,49 @@ namespace Mono.VisualC.Tools.Generator {
switch (entry.type) {
case "ArrayType":
return findType (entry.Base, modifiers.Modify (CppModifiers.Array));
return findType (clas, entry.Base, removed, modifiers.Modify (CppModifiers.Array));
case "PointerType":
return findType (entry.Base, modifiers.Modify (CppModifiers.Pointer));
return findType (clas, entry.Base, removed, modifiers.Modify (CppModifiers.Pointer));
case "ReferenceType":
return findType (entry.Base, modifiers.Modify (CppModifiers.Reference));
return findType (clas, entry.Base, removed, modifiers.Modify (CppModifiers.Reference));
case "CvQualifiedType":
return findType (entry.Base, modifiers.Modify ((from c in entry.attributes
return findType (clas, entry.Base, removed, modifiers.Modify ((from c in entry.attributes
where c.Key == "const" && c.Value == "1"
select CppModifiers.Const).DefaultIfEmpty (CppModifiers.Volatile).First ()));
case "Typedef":
return findType (entry.Base, modifiers);
return findType (clas, entry.Base, removed, modifiers);
case "FundamentalType":
return modifiers.CopyTypeFrom (new CppType (name));
case "Class":
return modifiers.CopyTypeFrom (new CppType (CppTypes.Class, name));
if (removed.Contains (entry))
return modifiers.CopyTypeFrom (CppTypes.Unknown);
if (entry.Class != null && entry.Class.GenericName != null) {
if (clas == entry.Class) {
Console.WriteLine ("Replacing {0} with {1}", name, entry.Class.GenericName);
return modifiers.CopyTypeFrom (new CppType (CppTypes.Class, entry.Class.GenericName));
} else {
Console.WriteLine ("Replacing {0} with Unknown", name);
// return modifiers.CopyTypeFrom (new CppType (CppTypes.Class, name));
return modifiers.CopyTypeFrom (CppTypes.Unknown);
}
} else
return modifiers.CopyTypeFrom (new CppType (CppTypes.Class, name));
case "Struct":
if (removed.Contains (entry))
return modifiers.CopyTypeFrom (CppTypes.Unknown);
Console.WriteLine ("Return struct {0}", name);
return modifiers.CopyTypeFrom (new CppType (CppTypes.Struct, name));
case "Union":
return modifiers.CopyTypeFrom (ProcessUnion (entry));
if (removed.Contains (entry))
return modifiers.CopyTypeFrom (CppTypes.Unknown);
Console.WriteLine ("Return union {0}", entry.name);
return modifiers.CopyTypeFrom (ProcessUnion (clas, entry, removed));
case "Enumeration":
if (removed.Contains (entry))
return modifiers.CopyTypeFrom (CppTypes.Unknown);
Console.WriteLine ("Return enumeration {0}", entry.name);
return modifiers.CopyTypeFrom (ProcessEnum (entry));
// FIXME: support function pointers betters

2
src/generator/generator.csproj

@ -40,7 +40,7 @@ @@ -40,7 +40,7 @@
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Commandlineparameters>-f=/Users/Alex/OpenSource/cppinterop/tests/QObject.xml -o=output</Commandlineparameters>
<Commandlineparameters>-f=QObject.xml -o=output</Commandlineparameters>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">

Loading…
Cancel
Save