예제 #1
0
파일: Clang.cs 프로젝트: thfabian/Bifrost
 private void Visit(IReadOnlyList <Cursor> decls, TraversalData traversalData)
 {
     foreach (var decl in decls)
     {
         Visit(decl, traversalData);
     }
 }
예제 #2
0
파일: Clang.cs 프로젝트: thfabian/Bifrost
            /// <summary>
            /// Visit a function declaration
            /// </summary>
            private void VisitFunctionDecl(FunctionDecl funDecl, TraversalData traversalData)
            {
                var desc = MatchHook(traversalData.GetQualifiedType(funDecl));

                if (desc != null)
                {
                    m_bir.Hooks.Add(CreateHook(funDecl, desc, traversalData));
                }
            }
예제 #3
0
파일: Clang.cs 프로젝트: thfabian/Bifrost
            /// <summary>
            /// Visit a namespace declaration
            /// </summary>
            private void VisitTypeDecl(TypeDecl typeDecl, TraversalData traversalData)
            {
                if (typeDecl.Kind == CXCursorKind.CXCursor_ClassDecl || typeDecl.Kind == CXCursorKind.CXCursor_StructDecl)
                {
                    traversalData.AddClass(typeDecl.Name);
                }

                Visit(typeDecl.CursorChildren, traversalData);

                if (typeDecl.Kind == CXCursorKind.CXCursor_ClassDecl || typeDecl.Kind == CXCursorKind.CXCursor_StructDecl)
                {
                    traversalData.RemoveClass();
                }
            }
예제 #4
0
파일: Clang.cs 프로젝트: thfabian/Bifrost
            /// <summary>
            /// Main dispatch method
            /// </summary>
            private void Visit(Cursor cursor, TraversalData traversalData)
            {
                if (m_visitedCursors.Contains(cursor))
                {
                    // The AST can by cyclic
                    return;
                }
                m_visitedCursors.Add(cursor);

                if (cursor is Decl decl)
                {
                    VisitDecl(decl, traversalData);
                }
            }
예제 #5
0
        public static PgnFormatterVariationTestCase GetLongVariation()
        {
            var testCase = new PgnFormatterVariationTestCase(BoardConstants.FenStartingPosition,
                                                             PGN.PgnFormatterAllAccoutrements,
                                                             TraversalData.longGameMainLine, "Game with comments, multiple variations on variations, annotations, tags filled");

            TraversalData.SetupLongGame(testCase);
            testCase.Game.Tags.Event        = "The Mediocre of Chess";
            testCase.Game.Tags.White        = "GoodPlayer, One";
            testCase.Game.Tags.Black        = "DecentPlayer, A.";
            testCase.Game.Tags.Site         = "New York City, NY USA";
            testCase.Game.Tags.Date         = "2021.08.18";
            testCase.Game.Tags.Round        = "2";
            testCase.Game.Tags["EventDate"] = "2021.08.16";
            testCase.Game.GameResult        = GameResult.WhiteWins;
            testCase.Game.Tags["ECO"]       = "D51";

            return(testCase);
        }
예제 #6
0
파일: Clang.cs 프로젝트: thfabian/Bifrost
 /// <summary>
 /// Declaration dispatch
 /// </summary>
 private void VisitDecl(Decl decl, TraversalData traversalData)
 {
     if (decl.Kind == CXCursorKind.CXCursor_FirstDecl || decl.Kind == CXCursorKind.CXCursor_UnexposedDecl)
     {
         Visit(decl.CursorChildren, traversalData);
     }
     else if (decl is NamespaceDecl namespaceDecl)
     {
         VisitNamespaceDecl(namespaceDecl, traversalData);
     }
     else if (decl is FunctionDecl funDecl)
     {
         VisitFunctionDecl(funDecl, traversalData);
     }
     else if (decl is TypeDecl typeDecl)
     {
         VisitTypeDecl(typeDecl, traversalData);
     }
 }
예제 #7
0
파일: Clang.cs 프로젝트: thfabian/Bifrost
            /// <summary>
            /// Register a hook
            /// </summary>
            private BIR.BIR.Hook CreateHook(FunctionDecl decl, HookDesc hookDesc, TraversalData traversalData)
            {
                BIR.BIR.Hook hook = new BIR.BIR.Hook();

                var desc = hookDesc.Desc;

                hook.Identifier = IO.MakeValidIdentifier(string.IsNullOrEmpty(desc.Identifier) ? traversalData.GetQualifiedType(decl).Replace("::", "_") : desc.Identifier);
                hook.ReturnType = decl.ReturnType.ToString();
                hook.Module     = desc.Module;
                hook.Inputs     = desc.Input;

                if (decl.Handle.Kind == CXCursorKind.CXCursor_CXXMethod)
                {
                    var cxxMethodDecl = (CXXMethodDecl)decl;
                    hook.VTableThisType = traversalData.GetClasses();
                    hook.HookType       = cxxMethodDecl.IsVirtual ? BIR.BIR.HookTypeEnum.VTable : BIR.BIR.HookTypeEnum.CFunction;
                }
                else
                {
                    hook.HookType      = BIR.BIR.HookTypeEnum.CFunction;
                    hook.CFunctionName = traversalData.GetQualifiedType(decl);
                    if (string.IsNullOrEmpty(hook.Module))
                    {
                        throw new Exception($"'hook.descriptions.[{hookDesc.Key}].module' is required to load function \"{desc.Name}\"");
                    }
                }

                // Extract parameter
                foreach (var param in decl.Parameters)
                {
                    hook.Parameters.Add(new BIR.BIR.Hook.Parameter()
                    {
                        Name = param.Name,
                        Type = param.Type.ToString(),
                    });
                }

                return(hook);
            }
예제 #8
0
        /// <summary>
        /// Save persiston to database
        /// </summary>
        /// <param name="pristineDaton">null or the version before the diff was applied</param>
        /// <param name="modifiedDaton">the validated final version</param>
        /// <param name="diff">the difference between pristine and modified, which is what this method inspects to make the changes</param>
        public virtual async Task Save(IDbConnection db, IUser user, Persiston pristineDaton, Persiston modifiedDaton, PersistonDiff diff)
        {
            //called for each row in traversal; return true to recurse over children
            async Task <(object, bool)> rowCallback(RowChangingData cdata)
            {
                if (cdata.DiffRow.Kind == DiffKind.DeletedRow)
                {
                    await DeleteRowWithCascade(db, cdata.TableDef, cdata.PristineRow);

                    return(null, false);  //don't recur to children of deleted row
                }
                object newpk = await InsertUpdateRow(db, cdata);

                return(newpk, true);
            }

            var tdata = new TraversalData
            {
                ParentKey    = null,
                TableDef     = diff.DatonDef.MainTableDef,
                DiffRowList  = diff.MainTable,
                PristineList = null,
                ModifiedList = null,
                ProcessRowF  = rowCallback
            };

            if (diff.DatonDef.MultipleMainRows)
            {
                var mainListField = diff.DatonDef.Type.GetField(tdata.TableDef.Name);
                tdata.PristineList = mainListField.GetValue(pristineDaton) as IList;
                tdata.ModifiedList = mainListField.GetValue(modifiedDaton) as IList;
                await TraverseDiffList(tdata, null, null);
            }
            else
            {
                await TraverseDiffList(tdata, pristineDaton, modifiedDaton);
            }
        }
예제 #9
0
        /// <summary>
        /// Call ProcessRowF on all rows in the diff list, and recurse to all child tables.
        /// </summary>
        /// <param name="singleMainPristineRow">only set for top level call if there is a single main row</param>
        /// <param name="singleMainModifiedRow">only set for top level call if there is a single main row</param>
        protected async Task TraverseDiffList(TraversalData tdata, Row singleMainPristineRow, Row singleMainModifiedRow)
        {
            var pkField = tdata.TableDef.RowType.GetField(tdata.TableDef.PrimaryKeyColName);

            foreach (var row in tdata.DiffRowList)
            {
                if (!row.Columns.TryGetValue(tdata.TableDef.PrimaryKeyColName, out object rowKey))
                {
                    throw new Exception($"Diff row is missing primary key {tdata.TableDef.PrimaryKeyColName}");
                }

                //find pristine row
                Row pristineRow = singleMainPristineRow;
                if (tdata.PristineList != null && row.Kind != DiffKind.NewRow)
                {
                    int rowIdx = Utils.IndexOfPrimaryKeyMatch(tdata.PristineList, pkField, rowKey);
                    if (rowIdx >= 0)
                    {
                        pristineRow = tdata.PristineList[rowIdx] as Row;
                    }
                }

                //find modified row
                Row modifiedRow = singleMainModifiedRow;
                if (tdata.ModifiedList != null)
                {
                    int rowIdx = Utils.IndexOfPrimaryKeyMatch(tdata.ModifiedList, pkField, rowKey);
                    if (rowIdx >= 0)
                    {
                        modifiedRow = tdata.ModifiedList[rowIdx] as Row;
                    }
                }

                //callback to process row
                var cdata = new RowChangingData
                {
                    ParentKey   = tdata.ParentKey,
                    DiffRow     = row,
                    DiffRowList = tdata.DiffRowList,
                    TableDef    = tdata.TableDef,
                    PristineRow = pristineRow,
                    ModifiedRow = modifiedRow
                };
                (object newPK, bool doTraverseChildren) = await tdata.ProcessRowF?.Invoke(cdata);

                if (newPK != null)
                {
                    rowKey = newPK;
                }

                //skip child tables?
                if (!doTraverseChildren)
                {
                    continue;
                }

                //loop child tables of this row
                if (row.ChildTables != null)
                {
                    foreach (var child in row.ChildTables)
                    {
                        var childTableDef = child.Key;
                        var childRows     = child.Value;
                        var listField     = tdata.TableDef.RowType.GetField(childTableDef.Name);

                        //get pristine list
                        IList childPristineList = null;
                        if (pristineRow != null)
                        {
                            childPristineList = listField.GetValue(pristineRow) as IList;
                        }

                        //get modified list
                        IList childModifiedList = null;
                        if (modifiedRow != null)
                        {
                            childModifiedList = listField.GetValue(modifiedRow) as IList;
                        }

                        var childTdata = new TraversalData
                        {
                            ParentKey    = rowKey,
                            TableDef     = childTableDef,
                            DiffRowList  = childRows,
                            PristineList = childPristineList,
                            ModifiedList = childModifiedList,
                            ProcessRowF  = tdata.ProcessRowF
                        };
                        await TraverseDiffList(childTdata, null, null);
                    }
                }
            }
        }
예제 #10
0
파일: Clang.cs 프로젝트: thfabian/Bifrost
 /// <summary>
 /// Visit a namespace declaration
 /// </summary>
 private void VisitNamespaceDecl(NamespaceDecl namespaceDecl, TraversalData traversalData)
 {
     traversalData.AddNamespace(namespaceDecl.ToString());
     Visit(namespaceDecl.Decls, traversalData);
     traversalData.RemoveNamespace();
 }
예제 #11
0
 /// <summary>
 /// basic init
 /// </summary>
 public Tile()
 {
     Traversals  = new TraversalData(this);
     Cover       = new CoverData();
     TileObjects = new TileObjectData(this);
 }