public static string GetTextFromCompoundStmt(CXCursor cursor) { var stmts = cursor.GetChildren (); CXSourceLocation start = clang.getCursorLocation (stmts.First ()); CXSourceLocation end = clang.getRangeEnd (clang.getCursorExtent (stmts.Last ())); CXFile file; uint line1, line2; uint column1, column2; uint offset1, offset2; clang.getFileLocation (start, out file, out line1, out column1, out offset1); clang.getFileLocation (end, out file, out line2, out column2, out offset2); string filePath = clang.getFileName (file).ToString (); // We have to read bytes first and then convert them to utf8 string // because .net string is utf16 char array, but clang handles utf8 src text only. // clang's offset means byte offset (not utf16 char offset) uint count = offset2 - offset1 + 1; byte[] text = new byte[count]; using(FileStream fs = File.OpenRead(filePath)) { fs.Seek (offset1, SeekOrigin.Begin); fs.Read (text, 0, (int)count); } return Encoding.UTF8.GetString (text); }
static void Dump(CXCursor cursor, StringBuilder sb, int level, int mask) { for (int i = 1; i <= level; i++) { if (IsSet (mask, level - i)) { if (i == level) sb.Append ("|-"); else sb.Append ("| "); } else { if (i == level) sb.Append ("`-"); else sb.Append (" "); } } sb.AppendFormat ("{0} {1}\n", cursor.kind, cursor.ToString ()); CXCursor[] children = cursor.GetChildren ().ToArray(); for (int i = 0; i < children.Length; i++) Dump (children[i], sb, level + 1, (mask << 1) | (i == children.Length - 1 ? 0 : 1)); }
BaseMethodDeclarationSyntax PortMethod(CXCursor cursor) { var objcMethod = new ObjCMethod (cursor); IEnumerable<ParameterSyntax> mParams = FetchParamInfos (cursor); MethodDefinition mDef; MethodDeclarationSyntax mDecl = null; ConstructorDeclarationSyntax ctorDecl = null; var mb = new MethodBuilder (); var isBound = bindingLocator.TryFindMethod (ImplContext.SuperClassName, objcMethod.Selector, out mDef); if (isBound) { if (mDef.IsConstructor) ctorDecl = mb.BuildCtor (mDef, ImplContext.ClassName, mParams); else mDecl = mb.BuildDeclaration (mDef, mParams); } else { if (objcMethod.IsInitializer) ctorDecl = mb.BuildCtor (ImplContext.ClassName, mParams); else mDecl = BuildDefaultDeclaration (objcMethod, mParams); } IEnumerable<CXCursor> children = cursor.GetChildren (); var compoundStmt = children.First (c => c.kind == CXCursorKind.CXCursor_CompoundStmt); if (ctorDecl != null) return AddBody (compoundStmt, ctorDecl); else return AddBody (compoundStmt, mDecl); }
ClassDeclarationSyntax PortClass(CXCursor cursor) { if (cursor.kind != CXCursorKind.CXCursor_ObjCImplementationDecl) throw new ArgumentException (); ImplContext = new ObjCImplementationDeclContext (cursor); TypePorter = new ObjCTypePorter (ImplContext.ClassName); ClassDeclarationSyntax classDecl = SF.ClassDeclaration (ImplContext.ClassName); classDecl = classDecl.AddModifiers (SF.Token (SyntaxKind.PublicKeyword)); classDecl = classDecl.AddBaseListTypes (SF.SimpleBaseType (SF.ParseTypeName(ImplContext.SuperClassName))); var propDecls = ImplContext.DeclCursor.GetChildren ().Where (c => c.kind == CXCursorKind.CXCursor_ObjCPropertyDecl); foreach (var pDecl in propDecls) classDecl = classDecl.AddMembers (CreatePropertyFromPropertyDecl (pDecl)); var unrecognized = new List<CXCursor> (); IEnumerable<CXCursor> children = cursor.GetChildren (); foreach (var m in children) { if (m.kind == CXCursorKind.CXCursor_ObjCInstanceMethodDecl || m.kind == CXCursorKind.CXCursor_ObjCClassMethodDecl) classDecl = classDecl.AddMembers(PortMethod (m)); else unrecognized.Add (m); } // TODO: warn about unrecognized cursors return classDecl; }
MethodDeclarationSyntax PortCategoryMethod(CXCursor cursor) { var objcMethod = new ObjCMethod (cursor); IEnumerable<ParameterSyntax> mParams = FetchParamInfos (cursor); ParameterSyntax thisParam = SF.Parameter (SF.Identifier ("self")) .WithType (SF.ParseTypeName (CategoryImplContext.ExtendedClassName)); mParams = (new ParameterSyntax[] { thisParam }).Concat (mParams); TypeSyntax retType = TypePorter.PortType (objcMethod.ReturnType); string methodName = MethodHelper.ConvertToMehtodName (objcMethod.Selector); var mb = new MethodBuilder (); MethodDeclarationSyntax mDecl = mb.BuildExtensionMethod (retType, methodName, mParams); IEnumerable<CXCursor> children = cursor.GetChildren (); var compoundStmt = children.First (c => c.kind == CXCursorKind.CXCursor_CompoundStmt); return AddBody (compoundStmt, mDecl); }
ClassDeclarationSyntax PortCategory(CXCursor cursor) { if (cursor.kind != CXCursorKind.CXCursor_ObjCCategoryImplDecl) throw new ArgumentException (); CategoryImplContext = new ObjCCategoryImplDeclContext (cursor); TypePorter = new ObjCTypePorter (CategoryImplContext.ExtendedClassName); string className = string.Format ("{0}{1}Extensions", CategoryImplContext.ExtendedClassName, CategoryImplContext.CategoryName); ClassDeclarationSyntax classDecl = SF.ClassDeclaration (className); classDecl = classDecl.AddModifiers (SF.Token (SyntaxKind.PublicKeyword), SF.Token (SyntaxKind.StaticKeyword)); var unrecognized = new List<CXCursor> (); IEnumerable<CXCursor> children = cursor.GetChildren (); foreach (var m in children) { if (m.kind == CXCursorKind.CXCursor_ObjCInstanceMethodDecl || m.kind == CXCursorKind.CXCursor_ObjCClassMethodDecl) classDecl = classDecl.AddMembers(PortCategoryMethod (m)); else unrecognized.Add (m); } // TODO: warn about unrecognized cursors return classDecl; }
IEnumerable<ParameterSyntax> FetchParamInfos(CXCursor methodCursor) { return methodCursor.GetChildren () .Where (c => c.kind == CXCursorKind.CXCursor_ParmDecl) .Select (TypePorter.PortParameter); }
static CXCursor GetSuperClass(CXCursor interfaceDecl) { return interfaceDecl.GetChildren ().Where (c => c.kind == CXCursorKind.CXCursor_ObjCSuperClassRef).Single (); }
static CXCursor GetExtendedClass(CXCursor cursor) { return cursor.GetChildren ().Where (c => c.kind == CXCursorKind.CXCursor_ObjCClassRef).Single (); }