//---------------------------------------------------------------------
// <copyright file="SymbolTable.cs" company="Microsoft">
// Portions of this file copyright (c) Microsoft Corporation
// and are released under the Microsoft Pulic License. See
// http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx
// or License.txt for details.
// All rights reserved.
// </copyright>
//---------------------------------------------------------------------
#if USE_ENTITY_FRAMEWORK_6
namespace System.Data.SQLite.EF6
#else
namespace System.Data.SQLite.Linq
#endif
{
using System;
using System.Collections.Generic;
#if USE_ENTITY_FRAMEWORK_6
using System.Data.Entity.Core.Common.CommandTrees;
#else
using System.Data.Common.CommandTrees;
#endif
/// <summary>
/// The symbol table is quite primitive - it is a stack with a new entry for
/// each scope. Lookups search from the top of the stack to the bottom, until
/// an entry is found.
///
/// The symbols are of the following kinds
/// <list type="bullet">
/// <item><see cref="Symbol"/> represents tables (extents/nested selects/unnests)</item>
/// <item><see cref="JoinSymbol"/> represents Join nodes</item>
/// <item><see cref="Symbol"/> columns.</item>
/// </list>
///
/// Symbols represent names <see cref="SqlGenerator.Visit(DbVariableReferenceExpression)"/> to be resolved,
/// or things to be renamed.
/// </summary>
internal sealed class SymbolTable
{
private List<Dictionary<string, Symbol>> symbols = new List<Dictionary<string, Symbol>>();
internal void EnterScope()
{
symbols.Add(new Dictionary<string, Symbol>(StringComparer.OrdinalIgnoreCase));
}
internal void ExitScope()
{
symbols.RemoveAt(symbols.Count - 1);
}
internal void Add(string name, Symbol value)
{
symbols[symbols.Count - 1][name] = value;
}
internal Symbol Lookup(string name)
{
for (int i = symbols.Count - 1; i >= 0; --i)
{
if (symbols[i].ContainsKey(name))
{
return symbols[i][name];
}
}
return null;
}
}
}