Browse Source

New C++ type abstraction, CppType. Will parse C++ type declaration strings,

map managed -> C++ type, and canonicalize different declarations that equate
to the same type. Reworked ItaniumAbi to use new CppType for name mangling.

git-svn-id: https://mono-soc-2010.googlecode.com/svn/trunk/cppinterop@68 a470b8cb-0e6f-1642-1b45-71e107334c4b
pull/1/head
alexander.corrado 15 years ago
parent
commit
5d599a4494
  1. 11
      CPPInterop.sln
  2. 4
      Mono.VisualC.Interop/ABI/CppAbi.cs
  3. 113
      Mono.VisualC.Interop/ABI/Impl/ItaniumAbi.cs
  4. 2
      Mono.VisualC.Interop/ABI/VTableManaged.cs
  5. 57
      Mono.VisualC.Interop/Attributes.cs
  6. 257
      Mono.VisualC.Interop/CppType.cs
  7. 495
      Mono.VisualC.Interop/IEnumerableTransform.cs
  8. 2
      Mono.VisualC.Interop/Mono.VisualC.Interop.csproj
  9. 9
      Mono.VisualC.Interop/Util.cs
  10. 6
      QtBindings/Core/QCoreApplication.cs
  11. 6
      QtBindings/Core/QString.cs
  12. 6
      QtBindings/Gui/QApplication.cs
  13. 3
      QtBindings/Gui/QPushButton.cs
  14. 2
      QtBindings/Gui/QWidget.cs
  15. 11
      QtBindings/Libs.cs

11
CPPInterop.sln

@ -42,16 +42,23 @@ Global @@ -42,16 +42,23 @@ Global
StartupItem = Mono.VisualC.Interop\Mono.VisualC.Interop.csproj
Policies = $0
$0.TextStylePolicy = $1
$1.TabWidth = 8
$1.NoTabsAfterNonTabs = True
$1.RemoveTrailingWhitespace = True
$1.inheritsSet = VisualStudio
$1.inheritsSet = Mono
$1.inheritsScope = text/plain
$1.scope = text/x-csharp
$0.CSharpFormattingPolicy = $2
$2.NamespaceBraceStyle = EndOfLine
$2.ClassBraceStyle = EndOfLine
$2.InterfaceBraceStyle = EndOfLine
$2.StructBraceStyle = EndOfLine
$2.EnumBraceStyle = EndOfLine
$2.inheritsSet = Mono
$2.inheritsScope = text/x-csharp
$2.scope = text/x-csharp
$0.StandardHeader = $3
$3.Text =
$3.inheritsSet = Apache2License
name = CPPInterop
EndGlobalSection
EndGlobal

4
Mono.VisualC.Interop/ABI/CppAbi.cs

@ -454,8 +454,8 @@ namespace Mono.VisualC.Interop.ABI { @@ -454,8 +454,8 @@ namespace Mono.VisualC.Interop.ABI {
Label bail = il.DefineLabel ();
il.Emit (OpCodes.Ldloca_S, cppInstancePtr);
//il.Emit (OpCodes.Dup);
//il.Emit (OpCodes.Brfalse_S, bail);
il.Emit (OpCodes.Brfalse_S, bail);
il.Emit (OpCodes.Ldloca_S, cppInstancePtr);
il.Emit (OpCodes.Call, typeof (CppInstancePtr).GetProperty ("IsManagedAlloc").GetGetMethod ());
il.Emit (OpCodes.Brfalse_S, bail);

113
Mono.VisualC.Interop/ABI/Impl/ItaniumAbi.cs

@ -8,8 +8,10 @@ @@ -8,8 +8,10 @@
//
using System;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Mono.VisualC.Interop.ABI {
@ -20,92 +22,83 @@ namespace Mono.VisualC.Interop.ABI { @@ -20,92 +22,83 @@ namespace Mono.VisualC.Interop.ABI {
}
public override CallingConvention DefaultCallingConvention {
get {
return CallingConvention.Cdecl;
}
get { return CallingConvention.Cdecl; }
}
public override string GetMangledMethodName (MethodInfo methodInfo)
{
string methodName = methodInfo.Name;
MethodType methodType = GetMethodType (methodInfo);
ParameterInfo[] parameters = methodInfo.GetParameters ();
ParameterInfo [] parameters = methodInfo.GetParameters ();
StringBuilder nm = new StringBuilder ("_ZN", 30);
nm.Append (class_name.Length).Append (class_name);
switch (methodType) {
case MethodType.NativeCtor:
nm.Append ("C1");
break;
case MethodType.NativeCtor:
nm.Append ("C1");
break;
case MethodType.NativeDtor:
nm.Append ("D1");
break;
default:
nm.Append (methodName.Length).Append (methodName);
break;
case MethodType.NativeDtor:
nm.Append ("D1");
break;
default:
nm.Append (methodName.Length).Append (methodName);
break;
}
nm.Append ("E");
int argStart = (Modifiers.IsStatic (methodInfo)? 0 : 1);
if (parameters.Length == argStart) { // no args (other than C++ "this" object)
if (parameters.Length == argStart) // no args (other than C++ "this" object)
nm.Append ("v");
} else for (int i = argStart; i < parameters.Length; i++) {
nm.Append (GetTypeCode (Modifiers.GetMangleInfo (parameters[i])));
}
else
for (int i = argStart; i < parameters.Length; i++)
nm.Append (GetTypeCode (Modifiers.GetMangleType (parameters[i])));
return nm.ToString ();
}
protected virtual string GetTypeCode(MangleAsAttribute mangleInfo) {
Type type = mangleInfo.MangleType;
Type element = type;
bool cppObj = typeof (ICppObject).IsAssignableFrom (element);
StringBuilder code = new StringBuilder ();
if (type.IsArray)
{
code.Append ("P");
element = type.GetElementType ();
}
if (type.IsByRef)
{
code.Append ("R");
element = type.GetElementType ();
}
else
if (mangleInfo.Modifiers == CppModifiers.PointerToConst)
code.Append ("PK");
else
if (cppObj || mangleInfo.Modifiers == CppModifiers.Pointer || mangleInfo.Modifiers == CppModifiers.ConstPointer)
code.Append ("P");
if (element.Equals (typeof (string)))
code.Append ("P");
if (mangleInfo.Modifiers == CppModifiers.Const)
code.Append ("K");
if (element.Equals (typeof (int))) code.Append ("i");
else if (element.Equals (typeof (ushort))) code.Append ("t");
else if (element.Equals (typeof (string))) code.Append ("c"); // char
else if (cppObj || element.StructLayoutAttribute.Value != LayoutKind.Auto) {
code.Append(element.Name.Length);
code.Append(element.Name);
}
else throw new NotSupportedException ("Unsupported parameter type: " + type.ToString ());
public virtual string GetTypeCode (CppType mangleType)
{
CppTypes element = mangleType.ElementType;
IEnumerable<CppModifiers> modifiers = mangleType.Modifiers;
StringBuilder code = new StringBuilder ();
var modifierCode = modifiers.Reverse ().Transform (
For.AnyInputIn (CppModifiers.Pointer, CppModifiers.Array).Emit ("P"),
For.AnyInputIn (CppModifiers.Reference).Emit ("R"),
Choose.TopOne (
For.AnyInputIn (CppModifiers.Pointer, CppModifiers.Reference).FollowedBy ().AllInputsIn (CppModifiers.Volatile, CppModifiers.Const).InAnyOrder ().Emit ("VK"),
For.AnyInputIn (CppModifiers.Pointer, CppModifiers.Reference).FollowedBy ().AnyInputIn(CppModifiers.Volatile).Emit ("V"),
For.AnyInputIn (CppModifiers.Pointer, CppModifiers.Reference).FollowedBy ().AnyInputIn(CppModifiers.Const).Emit ("K")
)
);
code.Append (string.Join(string.Empty, modifierCode.ToArray ()));
switch (element) {
case CppTypes.Int:
code.Append (modifiers.Transform (
For.AllInputsIn (CppModifiers.Unsigned, CppModifiers.Short).InAnyOrder ().Emit ('t')
).DefaultIfEmpty ('i').ToArray ());
break;
case CppTypes.Char:
code.Append ('c');
break;
case CppTypes.Class:
code.Append(mangleType.ElementTypeName.Length);
code.Append(mangleType.ElementTypeName);
break;
}
return code.ToString ();
}
}
}

2
Mono.VisualC.Interop/ABI/VTableManaged.cs

@ -56,7 +56,7 @@ namespace Mono.VisualC.Interop.ABI { @@ -56,7 +56,7 @@ namespace Mono.VisualC.Interop.ABI {
callsite.Emit (OpCodes.Throw);
callsite.MarkLabel (notNull);
return delegateType.GetMethod ("Invoke");
return Util.GetMethodInfoForDelegate (delegateType);
}

57
Mono.VisualC.Interop/Attributes.cs

@ -18,48 +18,28 @@ namespace Mono.VisualC.Interop { @@ -18,48 +18,28 @@ namespace Mono.VisualC.Interop {
[AttributeUsage (AttributeTargets.Method)]
public class StaticAttribute : Attribute {}
[AttributeUsage (AttributeTargets.Parameter)]
public class ConstAttribute : Attribute {}
[AttributeUsage (AttributeTargets.Method)]
public class OverrideNativeAttribute : Attribute {}
[AttributeUsage (AttributeTargets.Parameter)]
[AttributeUsage (AttributeTargets.Parameter | AttributeTargets.ReturnValue)]
public class MangleAsAttribute : Attribute {
public CppModifiers Modifiers { get; set; }
public Type MangleType { get; private set; }
public CppType MangleType { get; private set; }
public bool ByRef {
get { return MangleType.IsByRef; }
set {
if (!MangleType.IsByRef && value)
MangleType = MangleType.MakeByRefType ();
else if (MangleType.IsByRef && !value)
MangleType = MangleType.GetElementType ();
}
}
public MangleAsAttribute (Type mangleType)
public MangleAsAttribute (CppType mangleType)
{
this.Modifiers = CppModifiers.None;
this.MangleType = mangleType;
}
public MangleAsAttribute (string mangleTypeStr)
{
this.Modifiers = CppModifiers.None;
this.MangleType = Type.GetType (mangleTypeStr);
this.MangleType = new CppType (mangleTypeStr);
}
public MangleAsAttribute (params object[] cppTypeSpec)
{
this.MangleType = new CppType (cppTypeSpec);
}
}
public enum CppModifiers {
None,
Const,
Pointer,
PointerToConst,
ConstPointer,
ConstPointerToConst
}
public static class Modifiers {
public static class Modifiers {
public static bool IsVirtual (MethodInfo method)
{
@ -71,17 +51,22 @@ namespace Mono.VisualC.Interop { @@ -71,17 +51,22 @@ namespace Mono.VisualC.Interop {
return method.IsDefined (typeof (StaticAttribute), false);
}
public static MangleAsAttribute GetMangleInfo (ParameterInfo param)
public static CppType GetMangleType (ParameterInfo param)
{
CppType mangleType = new CppType ();
MangleAsAttribute maa = (MangleAsAttribute)param.GetCustomAttributes (typeof (MangleAsAttribute), false).FirstOrDefault ();
bool isConst = param.IsDefined (typeof (ConstAttribute), false);
if (maa == null)
maa = new MangleAsAttribute (param.ParameterType);
if (maa != null)
mangleType = maa.MangleType;
if (isConst)
maa.Modifiers = CppModifiers.Const;
// this means that only CppModifiers were applied .. apply CppType from managed parameter type
if (mangleType.ElementType == CppTypes.Unknown && mangleType.ElementTypeName == null)
mangleType.Apply (CppType.ForManagedType (param.ParameterType));
else if (mangleType.ElementType == CppTypes.Unknown)
// FIXME: otherwise, we just assume it's CppTypes.Class for now.
mangleType.ElementType = CppTypes.Class;
return maa;
return mangleType;
}
}
}

257
Mono.VisualC.Interop/CppType.cs

@ -0,0 +1,257 @@ @@ -0,0 +1,257 @@
//
// Mono.VisualC.Interop.CppType.cs: Abstracts a C++ type declaration
//
// Author:
// Alexander Corrado (alexander.corrado@gmail.com)
//
// Copyright (C) 2010 Alexander Corrado
//
using System;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Reflection;
using System.Collections.Generic;
namespace Mono.VisualC.Interop {
public enum CppModifiers {
Const,
Pointer,
Array,
Reference,
Volatile,
// ---
Signed,
Unsigned,
Short,
Long
}
public enum CppTypes {
Unknown,
Class,
Struct,
Enum,
Union,
Void,
Bool,
Char,
Int,
Float,
Double
}
public struct CppType {
public static Dictionary<string,CppModifiers> Tokenize = new Dictionary<string, CppModifiers> () {
{ "\\*", CppModifiers.Pointer },
{ "\\[\\s*\\]", CppModifiers.Array },
{ "\\&", CppModifiers.Reference }
};
/*
public static Dictionary<CppModifiers,string> Stringify = new Dictionary<CppModifiers, string> () {
{ CppModifiers.Pointer, "*" },
{ CppModifiers.Array, "[]" },
{ CppModifiers.Reference, "&" }
};
*/
// FIXME: Passing these as delegates allows for the flexibility of doing processing on the
// type (i.e. to correctly mangle the function pointer arguments if the managed type is a delegate),
// however this does not make it very easy to override the default mappings at runtime.
public static List<Func<Type,CppType>> ManagedTypeMap = new List<Func<Type,CppType>> () {
(t) => { return typeof (void).Equals (t) ? CppTypes.Void : CppTypes.Unknown; },
(t) => { return typeof (bool).Equals (t) ? CppTypes.Bool : CppTypes.Unknown; },
(t) => { return typeof (char).Equals (t) ? CppTypes.Char : CppTypes.Unknown; },
(t) => { return typeof (int).Equals (t) ? CppTypes.Int : CppTypes.Unknown; },
(t) => { return typeof (float).Equals (t) ? CppTypes.Float : CppTypes.Unknown; },
(t) => { return typeof (double).Equals (t)? CppTypes.Double : CppTypes.Unknown; },
(t) => { return typeof (short).Equals (t) ? new CppType (CppModifiers.Short, CppTypes.Int) : CppTypes.Unknown; },
(t) => { return typeof (long).Equals (t) ? new CppType (CppModifiers.Long, CppTypes.Int) : CppTypes.Unknown; },
// strings mangle as "const char*" by default
(t) => { return typeof (string).Equals (t)? new CppType (CppModifiers.Const, CppTypes.Char, CppModifiers.Pointer) : CppTypes.Unknown; },
// StringBuilder gets "char*"
(t) => { return typeof (StringBuilder).Equals (t)? new CppType (CppTypes.Char, CppModifiers.Pointer) : CppTypes.Unknown; },
// delegate types get special treatment
(t) => { return typeof (Delegate).IsAssignableFrom (t)? CppType.ForDelegate (t) : CppTypes.Unknown; },
// ... and of course ICppObjects do too!
// FIXME: We assume c++ class not struct. There should probably be an attribute
// we can apply to managed wrappers to indicate if the underlying C++ type is actually declared struct
(t) => { return typeof (ICppObject).IsAssignableFrom (t)? new CppType (CppTypes.Class, t.Name, CppModifiers.Pointer) : CppTypes.Unknown; },
// convert managed type modifiers to C++ type modifiers like so:
// ref types to C++ references
// pointer types to C++ pointers
// array types to C++ arrays
(t) => {
if (t.GetElementType () == null) return CppTypes.Unknown;
CppType cppType = CppType.ForManagedType (t.GetElementType ());
if (t.IsByRef) cppType.Modifiers.Add (CppModifiers.Reference);
if (t.IsPointer) cppType.Modifiers.Add (CppModifiers.Pointer);
if (t.IsArray) cppType.Modifiers.Add (CppModifiers.Array);
return cppType;
}
};
public CppTypes ElementType { get; set; }
// if the ElementType is Union, Struct, Class, or Enum
// this will contain the name of said type
public string ElementTypeName { get; set; }
public List<CppModifiers> Modifiers { get; private set; }
// here, you can pass in things like "const char*" or "const Foo * const"
// DISCLAIMER: this is really just for convenience for now, and is not meant to be able
// to parse even moderately complex C++ type declarations.
public CppType (string type) : this (Regex.Split (type, "\\s+(?!\\])"))
{
}
public CppType (params object[] cppTypeSpec)
{
ElementType = CppTypes.Unknown;
ElementTypeName = null;
Modifiers = new List<CppModifiers> ();
Parse (cppTypeSpec);
}
private void Parse (object [] modifiers)
{
for (int i = 0; i < modifiers.Length; i++) {
if (modifiers [i] is CppModifiers) {
Modifiers.Add ((CppModifiers)modifiers [i]);
continue;
}
string strModifier = modifiers [i] as string;
if (strModifier != null) {
// FIXME: Use Enum.TryParse here if we decide to make this NET_4_0 only
try {
Modifiers.Add ((CppModifiers)Enum.Parse (typeof (CppModifiers), strModifier, true));
continue;
} catch { }
}
// must be a type name
ParseType (modifiers [i]);
}
}
private void ParseType (object type)
{
if (type is CppTypes) {
ElementType = (CppTypes)type;
ElementTypeName = null;
return;
}
string strType = type as string;
if (strType != null) {
// strip tokens off type name
foreach (var token in Tokenize) {
foreach (var match in Regex.Matches (strType, token.Key))
Modifiers.Add (token.Value);
strType = Regex.Replace (strType, token.Key, string.Empty);
}
// FIXME: Use Enum.TryParse here if we decide to make this NET_4_0 only
try {
CppTypes parsed = (CppTypes)Enum.Parse (typeof (CppTypes), strType, true);
ElementType = parsed;
ElementTypeName = null;
return;
} catch { }
// it's the element type name
strType = strType.Trim ();
if (!strType.Equals (string.Empty))
ElementTypeName = strType;
return;
}
Type managedType = type as Type;
if (managedType != null) {
CppType mapped = CppType.ForManagedType (managedType);
Apply (mapped);
return;
}
}
// Applies the element type of the passed instance
// and combines its modifiers into this instance.
// Use when THIS instance may have attributes you want,
// but want the element type of the passed instance.
public void Apply (CppType type)
{
ElementType = type.ElementType;
ElementTypeName = type.ElementTypeName;
if (Modifiers == null) Modifiers = new List<CppModifiers> ();
List<CppModifiers> oldModifiers = Modifiers;
Modifiers = type.Modifiers;
Modifiers.AddRange (oldModifiers);
}
/*
public override string ToString ()
{
StringBuilder cppTypeString = new StringBuilder ();
cppTypeString.Append (Enum.GetName (typeof (CppTypes), ElementType).ToLower ());
if (ElementTypeName != null)
cppTypeString.Append (" ").Append (ElementTypeName);
foreach (var modifier in Modifiers) {
string stringified;
if (!Stringify.TryGetValue (modifier, out stringified))
stringified = Enum.GetName (typeof (CppModifiers), modifier).ToLower ();
cppTypeString.Append (" ").Append (stringified);
}
return cppTypeString.ToString ();
}
*/
public static CppType ForManagedType (Type type)
{
var mappedType = (from checkType in ManagedTypeMap
where checkType (type).ElementType != CppTypes.Unknown
select checkType (type)).FirstOrDefault ();
if (mappedType.Modifiers == null)
mappedType.Modifiers = new List<CppModifiers> ();
return mappedType;
}
public static CppType ForDelegate (Type delType)
{
if (!typeof (Delegate).IsAssignableFrom (delType))
throw new ArgumentException ("Argument must be a delegate type");
throw new NotImplementedException ();
}
public static implicit operator CppType (CppTypes type) {
return new CppType (type);
}
}
}

495
Mono.VisualC.Interop/IEnumerableTransform.cs

@ -0,0 +1,495 @@ @@ -0,0 +1,495 @@
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
namespace Mono.VisualC.Interop {
public delegate bool EmitterFunc<TIn, TOut> (InputData<TIn> input, out TOut output);
public struct InputData<TIn> {
public IEnumerable<TIn> AllValues;
public LookaheadEnumerator<TIn> Enumerator;
public List<IRule<TIn>> MatchedRules;
public InputData (IEnumerable<TIn> input, LookaheadEnumerator<TIn> enumerator)
{
this.AllValues = input;
this.Enumerator = enumerator;
this.MatchedRules = new List<IRule<TIn>> ();
}
public TIn Value {
get { return Enumerator.Current; }
}
}
#region Rules
public interface IRule<TIn> {
bool SatisfiedBy (InputData<TIn> input);
}
// yields all inputs indescriminately
public class AnyRule<TIn> : IRule<TIn> {
public AnyRule ()
{
}
public bool SatisfiedBy (InputData<TIn> input)
{
return true;
}
}
// yields all inputs that haven't satisfied
// any other rule
public class UnmatchedRule<TIn> : IRule<TIn> {
public UnmatchedRule ()
{
}
public bool SatisfiedBy (InputData<TIn> input)
{
return !input.MatchedRules.Any ();
}
}
// yields input if it hasn't been satisfied before
public class FirstRule<TIn> : IRule<TIn> {
protected bool triggered = false;
public FirstRule ()
{
}
public bool SatisfiedBy (InputData<TIn> input)
{
if (!triggered) {
triggered = true;
return true;
}
return false;
}
}
// yields input if it is the last that would satisfy
// all its matched rules
public class LastRule<TIn> : IRule<TIn> {
public LastRule ()
{
}
public bool SatisfiedBy (InputData<TIn> input)
{
IEnumerator<TIn> item = input.Enumerator;
while (item.MoveNext ()) {
foreach (var prevRule in input.MatchedRules) {
if (prevRule.SatisfiedBy (input))
return false;
}
}
return true;
}
}
// yields all inputs found in the specified set
public class InSetRule<TIn> : IRule<TIn> {
protected IEnumerable<TIn> conditions;
public InSetRule (params TIn [] conditions)
{
this.conditions = conditions;
}
public InSetRule (IEnumerable<TIn> conditions)
{
this.conditions = conditions;
}
public bool SatisfiedBy (InputData<TIn> input)
{
return conditions.Contains (input.Value);
}
}
// is satisfied by any of the specified items as long the
// item appears adjacent with all the other items
public class AnyOrderRule<TIn> : IRule<TIn> {
protected IEnumerable<TIn> conditions;
protected Queue<TIn> verifiedItems = new Queue<TIn> ();
protected bool verified = false;
public AnyOrderRule (params TIn [] conditions)
{
this.conditions = conditions;
}
public AnyOrderRule (IEnumerable<TIn> conditions)
{
this.conditions = conditions;
}
public bool SatisfiedBy (InputData<TIn> inputData)
{
if (verified && verifiedItems.Count > 0) {
verifiedItems.Dequeue ();
return false;
} else
verified = false;
IEnumerator<TIn> input = inputData.Enumerator;
while (conditions.Contains (input.Current) && !verifiedItems.Contains (input.Current)) {
verifiedItems.Enqueue (input.Current);
if (!input.MoveNext ()) break;
}
if (verifiedItems.Count == conditions.Count ()) {
verified = true;
verifiedItems.Dequeue ();
return true;
} else
verifiedItems.Clear ();
return false;
}
}
public class InOrderRule<TIn> : IRule<TIn> {
protected IEnumerable<IRule<TIn>> conditions;
protected bool verified = false;
protected int verifiedCount = 0;
public InOrderRule (params IRule<TIn> [] conditions)
{
this.conditions = conditions;
}
public InOrderRule (IEnumerable<IRule<TIn>> conditions)
{
this.conditions = conditions;
}
public bool SatisfiedBy (InputData<TIn> inputData)
{
if (verified && verifiedCount > 0) {
verifiedCount--;
return false;
} else
verified = false;
IEnumerator<IRule<TIn>> condition = conditions.GetEnumerator ();
IEnumerator<TIn> input = inputData.Enumerator;
while (condition.MoveNext () && condition.Current.SatisfiedBy (inputData)) {
verifiedCount++;
if (!input.MoveNext ()) break;
}
if (verifiedCount == conditions.Count ()) {
verified = true;
verifiedCount--;
return true;
} else
verifiedCount = 0;
return false;
}
}
// yields all inputs that match all specified rules
public class AndRule<TIn> : IRule<TIn> {
protected IEnumerable<IRule<TIn>> rules;
public AndRule (IEnumerable<IRule<TIn>> rules)
{
this.rules = rules;
}
public AndRule (params IRule<TIn>[] rules)
{
this.rules = rules;
}
public bool SatisfiedBy (InputData<TIn> input)
{
foreach (var rule in rules) {
if (!rule.SatisfiedBy (input))
return false;
input.MatchedRules.Add (rule);
}
return true;
}
}
// yields all inputs that match any specified rules
public class OrRule<TIn> : IRule<TIn> {
protected IEnumerable<IRule<TIn>> rules;
public OrRule (IEnumerable<IRule<TIn>> rules)
{
this.rules = rules;
}
public OrRule (params IRule<TIn>[] rules)
{
this.rules = rules;
}
public bool SatisfiedBy (InputData<TIn> input)
{
bool satisfied = false;
foreach (var rule in rules) {
if (!rule.SatisfiedBy (input))
continue;
satisfied = true;
input.MatchedRules.Add (rule);
}
return satisfied;
}
}
#endregion
// the base point for building up rules
// All rules start For...
public static class For {
public static IRule<TIn> AnyInputIn<TIn> (params TIn [] input)
{
return new InSetRule<TIn> (input);
}
public static IRule<TIn> AnyInputIn<TIn> (IEnumerable<TIn> input)
{
return new InSetRule<TIn> (input);
}
public static SequenceQualifier<TIn> AllInputsIn<TIn> (params TIn [] input)
{
return new SequenceQualifier<TIn> (input, null);
}
public static SequenceQualifier<TIn> AllInputsIn<TIn> (IEnumerable<TIn> input)
{
return new SequenceQualifier<TIn> (input, null);
}
public static RuleCompound<TIn> First<TIn> ()
{
return new RuleCompound<TIn> ((subsequentRules) => {
return new AndRule<TIn> (subsequentRules, new FirstRule<TIn> ());
});
}
public static RuleCompound<TIn> Last<TIn> ()
{
return new RuleCompound<TIn> ((subsequentRules) => {
return new AndRule<TIn> (subsequentRules, new LastRule<TIn> ());
});
}
public static IRule<TIn> AnyInput<TIn> ()
{
return new AnyRule<TIn> ();
}
public static IRule<TIn> UnmatchedInput<TIn> ()
{
return new UnmatchedRule<TIn> ();
}
}
public class RuleCompound<TIn> {
protected Func<IRule<TIn>,IRule<TIn>> additionalRuleCallback;
public RuleCompound (Func<IRule<TIn>,IRule<TIn>> additionalRuleCallback)
{
this.additionalRuleCallback = additionalRuleCallback;
}
public SequenceQualifier<TIn> AllInputsIn (params TIn [] input)
{
return new SequenceQualifier<TIn> (input, additionalRuleCallback);
}
public SequenceQualifier<TIn> AllInputsIn (IEnumerable<TIn> input)
{
return new SequenceQualifier<TIn> (input, additionalRuleCallback);
}
public IRule<TIn> AnyInputIn (params TIn[] input)
{
return additionalRuleCallback(new InSetRule<TIn> (input));
}
public IRule<TIn> AnyInputIn (IEnumerable<TIn> input)
{
return additionalRuleCallback(new InSetRule<TIn> (input));
}
public IRule<TIn> AnyInput ()
{
return additionalRuleCallback(new AnyRule<TIn> ());
}
}
public class SequenceQualifier<TIn> {
protected IEnumerable<TIn> sequence;
protected Func<IRule<TIn>, IRule<TIn>> additionalRuleCallback;
public SequenceQualifier (IEnumerable<TIn> sequence, Func<IRule<TIn>, IRule<TIn>> additionalRuleCallback)
{
this.sequence = sequence;
this.additionalRuleCallback = additionalRuleCallback ?? (rul => rul);
}
public IRule<TIn> InThatOrder ()
{
return additionalRuleCallback (new InOrderRule<TIn> (sequence.Select (tin => (IRule<TIn>)new InSetRule<TIn> (tin))));
}
public IRule<TIn> InAnyOrder ()
{
return additionalRuleCallback (new AnyOrderRule<TIn> (sequence));
}
}
public static class Choose {
public static EmitterFunc<TIn, TOut> TopOne<TIn, TOut> (params EmitterFunc<TIn, TOut> [] rules)
{
return delegate (InputData<TIn> input, out TOut output) {
output = default (TOut);
foreach (var rule in rules) {
if (rule (input, out output))
return true;
input.Enumerator.Validate ();
}
return false;
};
}
}
public class LookaheadEnumerator<T> : IEnumerator<T> {
private IEnumerable<T> wrappedEnumerable;
private IEnumerator<T> wrappedEnumerator;
private int position;
private bool invalidated;
public LookaheadEnumerator (IEnumerable<T> enumerable, int position)
{
this.wrappedEnumerable = enumerable;
this.position = position;
this.invalidated = true;
Validate ();
}
public void Reset ()
{
invalidated = true;
wrappedEnumerator.Reset ();
}
public void Validate ()
{
if (!invalidated) return;
wrappedEnumerator = wrappedEnumerable.GetEnumerator ();
for (int i = 0; i < position; i++)
wrappedEnumerator.MoveNext ();
invalidated = false;
}
public bool ValidMoveNext ()
{
Validate ();
position++;
return wrappedEnumerator.MoveNext ();
}
public bool MoveNext ()
{
invalidated = true;
return wrappedEnumerator.MoveNext ();
}
public bool Invalidated {
get { return invalidated; }
}
public T Current {
get { return wrappedEnumerator.Current; }
}
object IEnumerator.Current {
get { return this.Current; }
}
public void Dispose ()
{
}
}
public static class EnumerableSequenceExtensions {
// Transforms an IEnumerable into another by specific rules.
public static IEnumerable<TOut> Transform<TIn, TOut> (this IEnumerable<TIn> input, params EmitterFunc<TIn, TOut> [] rules)
{
LookaheadEnumerator<TIn> enumerator = new LookaheadEnumerator<TIn> (input, 0);
while (enumerator.ValidMoveNext ()) {
InputData<TIn> inputData = new InputData<TIn> (input, enumerator);
foreach (var rule in rules) {
TOut output;
if (rule (inputData, out output))
yield return output;
enumerator.Validate ();
}
}
}
public static IRule<TIn> And<TIn> (this IRule<TIn> previousRules, IRule<TIn> parentheticalRules)
{
return new AndRule<TIn> (previousRules, parentheticalRules);
}
public static RuleCompound<TIn> And<TIn> (this IRule<TIn> previousRules)
{
return new RuleCompound<TIn> ((subsequentRules) => {
return And<TIn> (previousRules, subsequentRules);
});
}
public static IRule<TIn> Or<TIn> (this IRule<TIn> previousRules, IRule<TIn> parentheticalRules)
{
return new OrRule<TIn> (previousRules, parentheticalRules);
}
public static RuleCompound<TIn> Or<TIn> (this IRule<TIn> previousRules)
{
return new RuleCompound<TIn> ((subsequentRules) => {
return Or<TIn> (previousRules, subsequentRules);
});
}
public static IRule<TIn> FollowedBy<TIn> (this IRule<TIn> previousRules, IRule<TIn> parentheticalRules)
{
return new InOrderRule<TIn> (previousRules, parentheticalRules);
}
public static RuleCompound<TIn> FollowedBy<TIn> (this IRule<TIn> previousRules)
{
return new RuleCompound<TIn> ((subsequentRules) => {
return FollowedBy<TIn> (previousRules, subsequentRules);
});
}
public static EmitterFunc<TIn, TOut> Emit<TIn, TOut> (this IRule<TIn> rule, Func<TIn, TOut> result)
{
return delegate (InputData<TIn> input, out TOut output) {
output = default (TOut);
TIn value = input.Value;
if (rule.SatisfiedBy (input)) {
input.MatchedRules.Add (rule);
output = result (value);
return true;
}
return false;
};
}
public static EmitterFunc<TIn, TOut> Emit<TIn, TOut> (this IRule<TIn> rule, TOut result)
{
return Emit (rule, (input) => result);
}
}
}

2
Mono.VisualC.Interop/Mono.VisualC.Interop.csproj

@ -50,6 +50,8 @@ @@ -50,6 +50,8 @@
<Compile Include="ABI\Impl\VirtualOnlyAbi.cs" />
<Compile Include="ABI\Impl\MsvcAbi.cs" />
<Compile Include="CppObjectMarshaler.cs" />
<Compile Include="CppType.cs" />
<Compile Include="IEnumerableTransform.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>

9
Mono.VisualC.Interop/Util.cs

@ -1,11 +1,12 @@ @@ -1,11 +1,12 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.VisualC.Interop {
public static class Util {
internal static class Util {
public static MethodInfo GetMethodInfoForDelegate (Type delType)
{
@ -37,12 +38,6 @@ namespace Mono.VisualC.Interop { @@ -37,12 +38,6 @@ namespace Mono.VisualC.Interop {
return del.CreateType ();
}
public static Delegate GetDelegateForMethodInfo (ModuleBuilder mod, MethodInfo targetMethod)
{
Type delType = GetDelegateTypeForMethodInfo (mod, targetMethod);
return Delegate.CreateDelegate (delType, targetMethod);
}
public static Type[] GetDelegateParameterTypes (Type delType)
{
MethodInfo invoke = GetMethodInfoForDelegate (delType);

6
QtBindings/Core/QCoreApplication.cs

@ -6,10 +6,10 @@ namespace Qt.Core { @@ -6,10 +6,10 @@ namespace Qt.Core {
public class QCoreApplication : QObject {
#region Sync with qcoreapplication.h
// C++ interface
protected interface IQCoreApplication : ICppClassOverridable<QCoreApplication>, Base<QObject.IQObject> {
public interface IQCoreApplication : ICppClassOverridable<QCoreApplication>, Base<QObject.IQObject> {
// ...
void QCoreApplication (CppInstancePtr @this, [MangleAs ("System.Int32&")] IntPtr argc,
[MangleAs (typeof (string[]))] IntPtr argv);
void QCoreApplication (CppInstancePtr @this, [MangleAs ("int&")] IntPtr argc,
[MangleAs ("char**")] IntPtr argv);
// ...
[Static] int exec ();
// ...

6
QtBindings/Core/QString.cs

@ -9,12 +9,8 @@ namespace Qt.Core { @@ -9,12 +9,8 @@ namespace Qt.Core {
public unsafe struct QString {
#region Sync with qstring.h
public interface IQString : ICppClass {
void QString(ref QString @this,
[MangleAs (typeof (QChar), Modifiers=CppModifiers.PointerToConst)]
IntPtr unicode, int size);
void QString(ref QString @this, [MangleAs ("const QChar*")] IntPtr unicode, int size);
}
[StructLayout (LayoutKind.Sequential)]
private struct QChar {}
[StructLayout (LayoutKind.Sequential)]
public struct Data {

6
QtBindings/Gui/QApplication.cs

@ -8,10 +8,10 @@ namespace Qt.Gui { @@ -8,10 +8,10 @@ namespace Qt.Gui {
public class QApplication : QCoreApplication {
#region Sync with qapplication.h
// C++ interface
protected interface IQApplication : ICppClassOverridable<QApplication>, Base<QCoreApplication.IQCoreApplication> {
public interface IQApplication : ICppClassOverridable<QApplication>, Base<QCoreApplication.IQCoreApplication> {
// ...
void QApplication (CppInstancePtr @this, [MangleAs ("System.Int32&")] IntPtr argc,
[MangleAs (typeof (string[]))] IntPtr argv, int version);
void QApplication (CppInstancePtr @this, [MangleAs ("int&")] IntPtr argc,
[MangleAs ("char**")] IntPtr argv, int version);
// ...
[Virtual] bool macEventFilter(CppInstancePtr @this, IntPtr eventHandlerCallRef, IntPtr eventRef);
// ...

3
QtBindings/Gui/QPushButton.cs

@ -8,8 +8,7 @@ namespace Qt.Gui { @@ -8,8 +8,7 @@ namespace Qt.Gui {
// C++ interface
public interface IQPushButton : ICppClassOverridable<QPushButton>, Base<QAbstractButton.IQAbstractButton> {
// ...
void QPushButton (CppInstancePtr @this, [Const] ref QString text,
QWidget parent);
void QPushButton (CppInstancePtr @this, [MangleAs ("const QString &")] ref QString text, QWidget parent);
// ...
}
// C++ fields

2
QtBindings/Gui/QWidget.cs

@ -14,7 +14,7 @@ namespace Qt.Gui { @@ -14,7 +14,7 @@ namespace Qt.Gui {
// ...
[Virtual] void setVisible (CppInstancePtr @this, bool visible);
// ...
void resize (CppInstancePtr @this, [MangleAs (typeof (QSize), ByRef=true, Modifiers=CppModifiers.Const)] ref QSize size);
void resize (CppInstancePtr @this, [MangleAs ("const QSize &")] ref QSize size);
// ...
[Virtual] /*QSize*/ int sizeHint (CppInstancePtr @this);
[Virtual] /*QSize*/ int minimumSizeHint (CppInstancePtr @this);

11
QtBindings/Libs.cs

@ -10,15 +10,20 @@ namespace Qt { @@ -10,15 +10,20 @@ namespace Qt {
static Libs ()
{
string lib;
CppAbi abi;
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{ // for Windows...
lib = "{0}4.dll";
abi = new MsvcAbi ();
else
} else { // for Mac...
lib = "/Library/Frameworks/{0}.framework/Versions/Current/{0}";
abi = new ItaniumAbi ();
}
QtCore = new CppLibrary ("/Library/Frameworks/QtCore.framework/Versions/Current/QtCore", abi);
QtGui = new CppLibrary ("/Library/Frameworks/QtGui.framework/Versions/Current/QtGui", abi);
QtCore = new CppLibrary (string.Format(lib, "QtCore"), abi);
QtGui = new CppLibrary (string.Format(lib, "QtGui"), abi);
}
}
}

Loading…
Cancel
Save