public ClassDefinition(string name, HeaderDefinition header) { Name = name; Header = header; Classes = new List <ClassDefinition>(); Methods = new List <MethodDefinition>(); Properties = new List <PropertyDefinition>(); Fields = new List <FieldDefinition>(); }
public ClassDefinition(string name, HeaderDefinition header) { Name = name; Header = header; Classes = new List<ClassDefinition>(); Methods = new List<MethodDefinition>(); Properties = new List<PropertyDefinition>(); Fields = new List<FieldDefinition>(); }
string GetManagedHeaderName(HeaderDefinition header) { string mapping = Project.HeaderNameMapping?.Map(header.Name); if (mapping != null) { return(mapping); } return(header.Name); }
private ManagedHeader GetManagedHeader(HeaderDefinition header) { ManagedHeader managedHeader; if (!Headers.TryGetValue(header.Filename, out managedHeader)) { managedHeader = new ManagedHeader(header, GetManagedHeaderName(header)); Headers[header.Filename] = managedHeader; } return(managedHeader); }
// Return condition unless type is already used under the same condition. string GetTypeConditional(TypeRefDefinition type, HeaderDefinition header) { string typeConditional = GetTypeConditional(type); if (typeConditional != null && headerConditional.ContainsKey(header.ManagedName)) { if (headerConditional[header.ManagedName].Equals(typeConditional)) { return(null); } } return(typeConditional); }
public ClassDefinition(string name, HeaderDefinition header = null, ClassDefinition parent = null) { Name = name; Header = header; Parent = parent; NamespaceName = ""; Classes = new List <ClassDefinition>(); Methods = new List <MethodDefinition>(); Properties = new List <PropertyDefinition>(); Fields = new List <FieldDefinition>(); CachedProperties = new Dictionary <string, CachedProperty>(); }
Cursor.ChildVisitResult HeaderVisitor(Cursor cursor, Cursor parent) { string filename = cursor.Extent.Start.File.Name.Replace('\\', '/'); // Do not visit any included header if (!filename.Equals(_context.HeaderFilename)) { return(Cursor.ChildVisitResult.Continue); } headerQueue.Remove(filename); // Have we visited this header already? HeaderDefinition header; if (!project.HeaderDefinitions.TryGetValue(filename, out header)) { // No, define a new one header = new HeaderDefinition(filename); project.HeaderDefinitions[filename] = header; } _context.Header = header; if (cursor.IsDefinition) { switch (cursor.Kind) { case CursorKind.ClassDecl: case CursorKind.ClassTemplate: case CursorKind.EnumDecl: case CursorKind.StructDecl: ParseClassCursor(cursor); break; case CursorKind.TypedefDecl: ParseTypedefCursor(cursor); break; case CursorKind.Namespace: _context.Namespace = cursor.Spelling; cursor.VisitChildren(HeaderVisitor); _context.Namespace = ""; break; } } return(Cursor.ChildVisitResult.Continue); }
Cursor.ChildVisitResult HeaderVisitor(Cursor cursor, Cursor parent) { string filename = cursor.Extent.Start.File.Name.Replace('\\', '/'); if (!filename.StartsWith(src, StringComparison.OrdinalIgnoreCase)) { return(Cursor.ChildVisitResult.Continue); } // Have we visited this header already? if (HeaderDefinitions.ContainsKey(filename)) { currentHeader = HeaderDefinitions[filename]; } else { // No, define a new one string relativeFilename = filename.Substring(src.Length); currentHeader = new HeaderDefinition(relativeFilename); HeaderDefinitions.Add(filename, currentHeader); headerQueue.Remove(filename); } if ((cursor.Kind == CursorKind.ClassDecl || cursor.Kind == CursorKind.StructDecl || cursor.Kind == CursorKind.ClassTemplate || cursor.Kind == CursorKind.TypedefDecl) && cursor.IsDefinition) { ParseClassCursor(cursor); } else if (cursor.Kind == CursorKind.EnumDecl) { if (!currentHeader.Enums.Any(x => x.Name.Equals(cursor.Spelling))) { currentEnum = new EnumDefinition(cursor.Spelling, cursor.Spelling); currentHeader.Enums.Add(currentEnum); cursor.VisitChildren(EnumVisitor); currentEnum = null; } } else if (cursor.Kind == CursorKind.Namespace) { return(Cursor.ChildVisitResult.Recurse); } return(Cursor.ChildVisitResult.Continue); }
private void ResolveInclude(TypeRefDefinition type, HeaderDefinition parentHeader) { switch (type.Kind) { case TypeKind.Pointer: case TypeKind.LValueReference: case TypeKind.ConstantArray: ResolveInclude(type.Referenced, parentHeader); return; } if (type.TemplateParams != null) { type.TemplateParams.ForEach(p => ResolveInclude(p, parentHeader)); } else if (type.IsIncomplete && type.Target != null) { if (type.Target.MarshalAsStruct) { return; } parentHeader.Includes.Add(type.Target.Header); } }
Cursor.ChildVisitResult HeaderVisitor(Cursor cursor, Cursor parent) { string filename = cursor.Extent.Start.File.Name.Replace('\\', '/'); // Do not visit any included header if (!filename.Equals(_context.HeaderFilename)) return Cursor.ChildVisitResult.Continue; headerQueue.Remove(filename); // Have we visited this header already? HeaderDefinition header; if (!project.HeaderDefinitions.TryGetValue(filename, out header)) { // No, define a new one header = new HeaderDefinition(filename); project.HeaderDefinitions[filename] = header; } _context.Header = header; if (cursor.IsDefinition) { switch (cursor.Kind) { case CursorKind.ClassDecl: case CursorKind.ClassTemplate: case CursorKind.EnumDecl: case CursorKind.StructDecl: ParseClassCursor(cursor); break; case CursorKind.TypedefDecl: ParseTypedefCursor(cursor); break; case CursorKind.Namespace: _context.Namespace = cursor.Spelling; cursor.VisitChildren(HeaderVisitor); _context.Namespace = ""; break; } } return Cursor.ChildVisitResult.Continue; }
private static bool RequiresConversionHeader(HeaderDefinition header) { return header.Classes.Any(RequiresConversionHeader); }
private static bool RequiresInterop(HeaderDefinition header) { return header.Classes.Any(RequiresInterop); }
private static bool RequiresMathNamespace(HeaderDefinition header) { return(header.Classes.Any(RequiresMathNamespace)); }
public EnumDefinition(string name, HeaderDefinition header = null, ClassDefinition parent = null) : base(name, header, parent) { }
public ManagedHeader GetManaged(HeaderDefinition header) { return Headers[header.Filename]; }
// Return condition unless type is already used under the same condition. string GetTypeConditional(TypeRefDefinition type, HeaderDefinition header) { string typeConditional = GetTypeConditional(type); if (typeConditional != null && headerConditionals.ContainsKey(header.ManagedName)) { if (headerConditionals[header.ManagedName].Equals(typeConditional)) { return null; } } return typeConditional; }
private void ResolveInclude(TypeRefDefinition type, HeaderDefinition parentHeader) { switch (type.Kind) { case TypeKind.Pointer: case TypeKind.LValueReference: case TypeKind.ConstantArray: ResolveInclude(type.Referenced, parentHeader); return; } if (type.TemplateParams != null) { type.TemplateParams.ForEach(p => ResolveInclude(p, parentHeader)); } else if (type.IsIncomplete && type.Target != null) { if (type.Target.MarshalAsStruct) return; parentHeader.Includes.Add(type.Target.Header); } }
public ClassDefinition(string name, HeaderDefinition header = null, ClassDefinition parent = null) { Name = name; Header = header; Parent = parent; }
void ResolveInclude(TypeRefDefinition typeRef, HeaderDefinition parentHeader) { if (typeRef.IsPointer || typeRef.IsReference || typeRef.IsConstantArray) { ResolveInclude(typeRef.Referenced, parentHeader); } else if (typeRef.SpecializedTemplateType != null) { ResolveInclude(typeRef.SpecializedTemplateType, parentHeader); } else if (typeRef.IsIncomplete && typeRef.Target != null) { parentHeader.Includes.Add(typeRef.Target.Header); } }
private static bool RequiresConversionHeader(HeaderDefinition header) { return(header.Classes.Any(RequiresConversionHeader)); }
void WriteHeader(HeaderDefinition header, string sourceRootFolder) { // Entirely skip headers that have no classes // TODO: parse C++ methods outside of classes if (header.AllClasses.All(@class => @class.IsExcluded)) { return; } // Some headers only need a C# wrapper class, skip C part bool hasCWrapper = header.AllClasses.Any(@class => [email protected] && @class.Methods.Any(m => !m.IsExcluded) && !(@class is ClassTemplateDefinition)); if (!hasCWrapper) { return; } // C++ header file string headerPath = header.Name + "_wrap.h"; string headerFullPath = Path.Combine(Project.CProjectPathFull, headerPath); OpenFile(headerFullPath, WriteTo.Header); WriteLine("#include \"main.h\""); WriteLine(); // C++ source file string sourcePath = header.Name + "_wrap.cpp"; string sourceFullPath = Path.Combine(Project.CProjectPathFull, sourcePath); OpenFile(sourceFullPath, WriteTo.Source); // C++ #includes var includes = new List <string>(); foreach (var includeHeader in header.Includes.Concat(new[] { header })) { // No need to include the base class header, // it will already be included by the header of this class. if (includeHeader != header && header.AllClasses.Any(c => c.BaseClass != null && c.BaseClass.Header == includeHeader)) { continue; } string includePath = WrapperProject.MakeRelativePath(sourceRootFolder, includeHeader.Filename).Replace('\\', '/'); includes.Add(includePath); } includes.Sort(); foreach (var include in includes) { WriteLine($"#include <{include}>"); } WriteLine(); if (RequiresConversionHeader(header)) { WriteLine("#include \"conversion.h\""); } WriteLine($"#include \"{headerPath}\""); // Write wrapper class headers To = WriteTo.Header; _hasCppClassSeparatingWhitespace = true; var wrappedClasses = header.AllClasses .Where(x => _wrapperHeaderGuards.ContainsKey(x.Name)) .OrderBy(GetFullNameC).ToList(); if (wrappedClasses.Count != 0) { WriteLine($"#ifndef {_wrapperHeaderGuards[wrappedClasses[0].Name]}"); foreach (var @class in wrappedClasses) { foreach (var method in @class.Methods.Where(m => m.IsVirtual)) { WriteLine($"#define p_{GetFullNameC(@class)}_{method.Name} void*"); } } foreach (var @class in wrappedClasses) { WriteLine($"#define {GetFullNameC(@class)}Wrapper void"); } WriteLine("#else"); foreach (var @class in wrappedClasses) { WriteWrapperClass(@class); } WriteLine("#endif"); WriteLine(); } // Write classes WriteLine("extern \"C\""); WriteLine("{"); _hasCppClassSeparatingWhitespace = true; foreach (var @class in header.Classes .Where(c => !IsExcludedClass(c))) { WriteClass(@class, 1); } WriteLine('}', WriteTo.Header); CloseFile(WriteTo.Header); CloseFile(WriteTo.Source); }
void AddForwardReference(List <ManagedClass> forwardRefs, TypeRefDefinition type, HeaderDefinition header) { if (type.IsBasic) { return; } switch (type.Kind) { case TypeKind.Pointer: case TypeKind.LValueReference: AddForwardReference(forwardRefs, type.Referenced, header); return; } var target = type.Target; if (target == null) { return; } if (target.IsExcluded || target.MarshalAsStruct || target.Header == header) { return; } var targetManaged = DotNetParser.GetManaged(target); if (!forwardRefs.Contains(targetManaged)) { forwardRefs.Add(targetManaged); } }
public ManagedHeader(HeaderDefinition nativeHeader, string managedName) { Native = nativeHeader; Name = managedName; }
void AddForwardReference(List<ClassDefinition> forwardRefs, TypeRefDefinition type, HeaderDefinition header) { if (type.IsBasic) { return; } if (type.IsPointer || type.IsReference) { AddForwardReference(forwardRefs, type.Referenced, header); return; } if (type.Target == null) { return; } if (type.Target.IsExcluded || forwardRefs.Contains(type.Target) || PrecompiledHeaderReferences.Contains(type.Target.ManagedName)) { return; } // Forward ref to class in another header if (type.Target.Header != header) { forwardRefs.Add(type.Target); } }
void WriteHeader(HeaderDefinition header, string sourceRootFolder) { // Entirely skip headers that have no classes // TODO: parse C++ methods outside of classes if (header.AllClasses.All(@class => { if (@class.IsExcluded || @class.IsTypedef) return true; return false; })) { return; } // Some headers only need a C# wrapper class, skip C++ part bool hasCppWrapper = header.AllClasses. Any(@class => @class.AllSubClasses.Any() || @class.Methods.Count != 0); FileStream headerFile = null; FileStream sourceFile = null; if (hasCppWrapper) { // C++ header file string headerPath = header.Name + "_wrap.h"; string headerFullPath = Path.Combine(project.CProjectPathFull, headerPath); headerFile = new FileStream(headerFullPath, FileMode.Create, FileAccess.Write); headerWriter = new StreamWriter(headerFile); headerWriter.WriteLine("#include \"main.h\""); headerWriter.WriteLine(); // C++ source file string sourcePath = header.Name + "_wrap.cpp"; string sourceFullPath = Path.Combine(project.CProjectPathFull, sourcePath); sourceFile = new FileStream(sourceFullPath, FileMode.Create, FileAccess.Write); sourceWriter = new StreamWriter(sourceFile); // C++ #includes var includes = new List<string>(); foreach (var includeHeader in header.Includes.Concat(new[] {header})) { // No need to include the base class header, // it will already be included by the header of this class. if (includeHeader != header && header.AllClasses.Any(c => c.BaseClass != null && c.BaseClass.Header == includeHeader)) { continue; } string includePath = WrapperProject.MakeRelativePath(sourceRootFolder, includeHeader.Filename).Replace('\\', '/'); includes.Add(includePath); } includes.Sort(); foreach (var include in includes) { sourceWriter.WriteLine("#include <{0}>", include); } sourceWriter.WriteLine(); if (RequiresConversionHeader(header)) { sourceWriter.WriteLine("#include \"conversion.h\""); } sourceWriter.WriteLine("#include \"{0}\"", headerPath); } // C# source file string csPath = header.ManagedName + ".cs"; string csFullPath = Path.Combine(project.CsProjectPathFull, csPath); var csFile = new FileStream(csFullPath, FileMode.Create, FileAccess.Write); csWriter = new StreamWriter(csFile); csWriter.WriteLine("using System;"); if (RequiresInterop(header)) { csWriter.WriteLine("using System.Runtime.InteropServices;"); csWriter.WriteLine("using System.Security;"); } if (RequiresMathNamespace(header)) { csWriter.WriteLine("using BulletSharp.Math;"); } csWriter.WriteLine(); if (hasCppWrapper) { // Write wrapper class headers hasCppClassSeparatingWhitespace = true; var wrappedClasses = header.AllClasses.Where(x => wrapperHeaderGuards.ContainsKey(x.Name)) .OrderBy(x => x.FullNameC) .ToList(); if (wrappedClasses.Count != 0) { string headerGuard = wrapperHeaderGuards[wrappedClasses[0].Name]; WriteLine("#ifndef " + headerGuard, WriteTo.Header); foreach (var @class in wrappedClasses) { WriteClassWrapperMethodPointers(@class); } foreach (var @class in wrappedClasses) { WriteLine($"#define {@class.FullNameC}Wrapper void", WriteTo.Header); } WriteLine("#else", WriteTo.Header); foreach (var @class in wrappedClasses) { WriteClassWrapperMethodDeclarations(@class); WriteClassWrapperDefinition(@class); } WriteLine("#endif", WriteTo.Header); WriteLine(WriteTo.Header); } } // Write classes if (hasCppWrapper) { headerWriter.WriteLine("extern \"C\""); headerWriter.WriteLine("{"); hasCppClassSeparatingWhitespace = true; } csWriter.WriteLine("namespace {0}", NamespaceName); csWriter.WriteLine("{"); hasCSWhiteSpace = true; var enums = GetEnums(header.Classes).OrderBy(e => e.ManagedName).ToList(); foreach (var @enum in enums) { WriteEnumClass(@enum, 1); } foreach (var @class in header.Classes) { WriteClass(@class, 1); } if (hasCppWrapper) { headerWriter.WriteLine('}'); headerWriter.Dispose(); headerFile.Dispose(); sourceWriter.Dispose(); sourceFile.Dispose(); } csWriter.WriteLine('}'); csWriter.Dispose(); csFile.Dispose(); }
Cursor.ChildVisitResult HeaderVisitor(Cursor cursor, Cursor parent) { string filename = cursor.Extent.Start.File.Name.Replace('\\', '/'); if (!filename.StartsWith(src, StringComparison.OrdinalIgnoreCase)) { return Cursor.ChildVisitResult.Continue; } // Have we visited this header already? if (HeaderDefinitions.ContainsKey(filename)) { currentHeader = HeaderDefinitions[filename]; } else { // No, define a new one string relativeFilename = filename.Substring(src.Length); currentHeader = new HeaderDefinition(relativeFilename); HeaderDefinitions.Add(filename, currentHeader); headerQueue.Remove(filename); } if ((cursor.Kind == CursorKind.ClassDecl || cursor.Kind == CursorKind.StructDecl || cursor.Kind == CursorKind.ClassTemplate || cursor.Kind == CursorKind.TypedefDecl) && cursor.IsDefinition) { ParseClassCursor(cursor); } else if (cursor.Kind == CursorKind.EnumDecl) { if (!currentHeader.Enums.Any(x => x.Name.Equals(cursor.Spelling))) { currentEnum = new EnumDefinition(cursor.Spelling, cursor.Spelling); currentHeader.Enums.Add(currentEnum); cursor.VisitChildren(EnumVisitor); currentEnum = null; } } else if (cursor.Kind == CursorKind.Namespace) { return Cursor.ChildVisitResult.Recurse; } return Cursor.ChildVisitResult.Continue; }
void WriteHeader(HeaderDefinition header, string sourceRootFolder) { // Entirely skip headers that have no classes // TODO: parse C++ methods outside of classes if (header.AllClasses.All(@class => @class.IsExcluded)) return; // Some headers only need a C# wrapper class, skip C part bool hasCWrapper = header.AllClasses.Any(@class => [email protected] && @class.Methods.Any(m => !m.IsExcluded) && !(@class is ClassTemplateDefinition)); if (!hasCWrapper) return; // C++ header file string headerPath = header.Name + "_wrap.h"; string headerFullPath = Path.Combine(Project.CProjectPathFull, headerPath); OpenFile(headerFullPath, WriteTo.Header); WriteLine("#include \"main.h\""); WriteLine(); // C++ source file string sourcePath = header.Name + "_wrap.cpp"; string sourceFullPath = Path.Combine(Project.CProjectPathFull, sourcePath); OpenFile(sourceFullPath, WriteTo.Source); // C++ #includes var includes = new List<string>(); foreach (var includeHeader in header.Includes.Concat(new[] { header })) { // No need to include the base class header, // it will already be included by the header of this class. if (includeHeader != header && header.AllClasses.Any(c => c.BaseClass != null && c.BaseClass.Header == includeHeader)) { continue; } string includePath = WrapperProject.MakeRelativePath(sourceRootFolder, includeHeader.Filename).Replace('\\', '/'); includes.Add(includePath); } includes.Sort(); foreach (var include in includes) { WriteLine($"#include <{include}>"); } WriteLine(); if (RequiresConversionHeader(header)) { WriteLine("#include \"conversion.h\""); } WriteLine($"#include \"{headerPath}\""); // Write wrapper class headers To = WriteTo.Header; _hasCppClassSeparatingWhitespace = true; var wrappedClasses = header.AllClasses .Where(x => _wrapperHeaderGuards.ContainsKey(x.Name)) .OrderBy(GetFullNameC).ToList(); if (wrappedClasses.Count != 0) { WriteLine($"#ifndef {_wrapperHeaderGuards[wrappedClasses[0].Name]}"); foreach (var @class in wrappedClasses) { foreach (var method in @class.Methods.Where(m => m.IsVirtual)) { WriteLine($"#define p_{GetFullNameC(@class)}_{method.Name} void*"); } } foreach (var @class in wrappedClasses) { WriteLine($"#define {GetFullNameC(@class)}Wrapper void"); } WriteLine("#else"); foreach (var @class in wrappedClasses) { WriteWrapperClass(@class); } WriteLine("#endif"); WriteLine(); } // Write classes WriteLine("extern \"C\""); WriteLine("{"); _hasCppClassSeparatingWhitespace = true; foreach (var @class in header.Classes .Where(c => !IsExcludedClass(c))) { WriteClass(@class, 1); } WriteLine('}', WriteTo.Header); CloseFile(WriteTo.Header); CloseFile(WriteTo.Source); }
public ManagedHeader GetManaged(HeaderDefinition header) { return(Headers[header.Filename]); }
private ManagedHeader GetManagedHeader(HeaderDefinition header) { ManagedHeader managedHeader; if (!Headers.TryGetValue(header.Filename, out managedHeader)) { managedHeader = new ManagedHeader(header, GetManagedHeaderName(header)); Headers[header.Filename] = managedHeader; } return managedHeader; }
private static bool RequiresInterop(HeaderDefinition header) { return(header.Classes.Any(RequiresInterop)); }
public EnumDefinition(string name, HeaderDefinition header = null, ClassDefinition parent = null) : base(name, header, parent) { EnumConstants = new List<string>(); EnumConstantValues = new List<string>(); }
void AddForwardReference(List<ManagedClass> forwardRefs, TypeRefDefinition type, HeaderDefinition header) { if (type.IsBasic) return; switch (type.Kind) { case TypeKind.Pointer: case TypeKind.LValueReference: AddForwardReference(forwardRefs, type.Referenced, header); return; } var target = type.Target; if (target == null) return; if (target.IsExcluded || target.MarshalAsStruct || target.Header == header) return; var targetManaged = DotNetParser.GetManaged(target); if (!forwardRefs.Contains(targetManaged)) { forwardRefs.Add(targetManaged); } }
public ClassTemplateDefinition(string name, HeaderDefinition header = null, ClassDefinition parent = null) : base(name, header, parent) { }
void AddForwardReference(List <ClassDefinition> forwardRefs, TypeRefDefinition type, HeaderDefinition header) { if (type.IsBasic) { return; } if (type.IsPointer || type.IsReference) { AddForwardReference(forwardRefs, type.Referenced, header); return; } if (type.Target == null) { return; } if (type.Target.IsExcluded || forwardRefs.Contains(type.Target) || PrecompiledHeaderReferences.Contains(type.Target.ManagedName)) { return; } // Forward ref to class in another header if (type.Target.Header != header) { forwardRefs.Add(type.Target); } }
private static bool RequiresMathNamespace(HeaderDefinition header) { return header.Classes.Any(RequiresMathNamespace); }
string GetManagedHeaderName(HeaderDefinition header) { string mapping = Project.HeaderNameMapping?.Map(header.Name); if (mapping != null) return mapping; return header.Name; }
public EnumDefinition(string name, HeaderDefinition header = null, ClassDefinition parent = null) : base(name, header, parent) { EnumConstants = new List <string>(); EnumConstantValues = new List <string>(); }