public MutableSymbol AddChild(MutableSymbol child) { if (_database == null) throw new InvalidOperationException("Can't add a child of a MutableSymbol if the parent hasn't been added to a database yet."); // Add the name int nameIdentifier = _database.StringStore.FindOrAddString(child.Name); // Build the details SymbolDetails newDetails = new SymbolDetails(); newDetails.Type = child.Type; newDetails.Modifiers = child.Modifiers; newDetails.ParametersIdentifier = _database.StringStore.FindOrAddString(child.Parameters); // If the parent has exactly the same item already, just return that one for (int i = _database.DeclaredMembers.GetFirstChild(_index); i > 0; i = _database.DeclaredMembers.GetNextSibling(i)) { if (nameIdentifier == _database.DeclaredMembers.GetNameIdentifier(i)) { SymbolDetails iDetails = _database.DeclaredMemberDetails[i]; if (newDetails.Equals(iDetails)) { child._database = _database; child._index = i; return child; } } } // Add the symbol itself to the DefinedSymbolTree int newSymbolIndex = _database.DeclaredMembers.Add(_index, nameIdentifier); // Index this name with this ID _database.Index.AddItem(nameIdentifier, newSymbolIndex); // Add parallel SymbolDetails if (_database.DeclaredMemberDetails.Count != newSymbolIndex) throw new InvalidOperationException(String.Format(Resources.DatabaseArraysOutOfSync, "DeclaredMemberDetails")); _database.DeclaredMemberDetails.Add(newDetails); // Add parallel location details if (String.Equals(this.FilePath, child.FilePath)) { _database.DeclaredMemberLocations.Add(new SymbolLocation(_database.DeclaredMemberLocations[_index].FileIndex, child.Line, child.CharInLine)); } else { ((IMemberDatabase)_database).SetLocation(newSymbolIndex, child.FilePath, child.Line, child.CharInLine); } // Bind the child to the database child._database = _database; child._index = newSymbolIndex; return child; }
public void AddTree(Symbol root) { MutableSymbol newRoot = AddChild(new MutableSymbol(root)); Symbol child = root.FirstChild(); while (child.IsValid) { newRoot.AddTree(child); child = child.NextSibling(); } }