示例#1
0
        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 ();
 }