TypeResolver.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Common / EntitySql / TypeResolver.cs / 1305376 / TypeResolver.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

namespace System.Data.Common.EntitySql 
{
    using System;
    using System.Globalization;
    using System.Collections.Generic; 
    using System.Diagnostics;
    using System.Data.Common; 
    using System.Data.Metadata.Edm; 
    using System.Data.Entity;
    using System.Linq; 

    /// 
    /// Represents eSQL metadata member expression class.
    ///  
    internal enum MetadataMemberClass
    { 
        Type, 
        FunctionGroup,
        InlineFunctionGroup, 
        Namespace
    }

    ///  
    /// Abstract class representing an eSQL expression classified as .
    ///  
    internal abstract class MetadataMember : ExpressionResolution 
    {
        protected MetadataMember(MetadataMemberClass @class, string name) 
            : base(ExpressionResolutionClass.MetadataMember)
        {
            Debug.Assert(!String.IsNullOrEmpty(name), "name must not be empty");
 
            MetadataMemberClass = @class;
            Name = name; 
        } 

        internal override string ExpressionClassName { get { return MetadataMemberExpressionClassName; } } 
        internal static string MetadataMemberExpressionClassName { get { return Strings.LocalizedMetadataMemberExpression; } }

        internal readonly MetadataMemberClass MetadataMemberClass;
        internal readonly string Name; 
        /// 
        /// Return the name of the  for error messages. 
        ///  
        internal abstract string MetadataMemberClassName { get; }
 
        internal static IEqualityComparer CreateMetadataMemberNameEqualityComparer(StringComparer stringComparer)
        {
            return new MetadataMemberNameEqualityComparer(stringComparer);
        } 

        private sealed class MetadataMemberNameEqualityComparer : IEqualityComparer 
        { 
            private readonly StringComparer _stringComparer;
 
            internal MetadataMemberNameEqualityComparer(StringComparer stringComparer)
            {
                _stringComparer = stringComparer;
            } 

            bool IEqualityComparer.Equals(MetadataMember x, MetadataMember y) 
            { 
                Debug.Assert(x != null && y != null, "metadata members must not be null");
                return _stringComparer.Equals(x.Name, y.Name); 
            }

            int IEqualityComparer.GetHashCode(MetadataMember obj)
            { 
                Debug.Assert(obj != null, "metadata member must not be null");
                return _stringComparer.GetHashCode(obj.Name); 
            } 
        }
    } 

    /// 
    /// Represents an eSQL metadata member expression classified as .
    ///  
    internal sealed class MetadataNamespace : MetadataMember
    { 
        internal MetadataNamespace(string name) : base(MetadataMemberClass.Namespace, name) { } 

        internal override string MetadataMemberClassName { get { return NamespaceClassName; } } 
        internal static string NamespaceClassName { get { return Strings.LocalizedNamespace; } }
    }

    ///  
    /// Represents an eSQL metadata member expression classified as .
    ///  
    internal sealed class MetadataType : MetadataMember 
    {
        internal MetadataType(string name, TypeUsage typeUsage) 
            : base(MetadataMemberClass.Type, name)
        {
            Debug.Assert(typeUsage != null, "typeUsage must not be null");
            TypeUsage = typeUsage; 
        }
 
        internal override string MetadataMemberClassName { get { return TypeClassName; } } 
        internal static string TypeClassName { get { return Strings.LocalizedType; } }
 
        internal readonly TypeUsage TypeUsage;
    }

    ///  
    /// Represents an eSQL metadata member expression classified as .
    ///  
    internal sealed class MetadataFunctionGroup : MetadataMember 
    {
        internal MetadataFunctionGroup(string name, IList functionMetadata) 
            : base(MetadataMemberClass.FunctionGroup, name)
        {
            Debug.Assert(functionMetadata != null && functionMetadata.Count > 0, "FunctionMetadata must not be null or empty");
            FunctionMetadata = functionMetadata; 
        }
 
        internal override string MetadataMemberClassName { get { return FunctionGroupClassName; } } 
        internal static string FunctionGroupClassName { get { return Strings.LocalizedFunction; } }
 
        internal readonly IList FunctionMetadata;
    }

    ///  
    /// Represents an eSQL metadata member expression classified as .
    ///  
    internal sealed class InlineFunctionGroup : MetadataMember 
    {
        internal InlineFunctionGroup(string name, IList functionMetadata) 
            : base(MetadataMemberClass.InlineFunctionGroup, name)
        {
            Debug.Assert(functionMetadata != null && functionMetadata.Count > 0, "FunctionMetadata must not be null or empty");
            FunctionMetadata = functionMetadata; 
        }
 
        internal override string MetadataMemberClassName { get { return InlineFunctionGroupClassName; } } 
        internal static string InlineFunctionGroupClassName { get { return Strings.LocalizedInlineFunction; } }
 
        internal readonly IList FunctionMetadata;
    }

    ///  
    /// Represents eSQL type and namespace name resolver.
    ///  
    internal sealed class TypeResolver 
    {
        private readonly Perspective _perspective; 
        private readonly Dictionary _aliasedNamespaces;
        private readonly HashSet _namespaces;
        /// 
        /// name -> list(overload) 
        /// 
        private readonly Dictionary> _functionDefinitions; 
        private bool _includeInlineFunctions; 
        private bool _resolveLeftMostUnqualifiedNameAsNamespaceOnly;
 
        /// 
        /// Initializes TypeResolver instance
        /// 
        internal TypeResolver(Perspective perspective, StringComparer stringComparer) 
        {
            EntityUtil.CheckArgumentNull(perspective, "perspective"); 
 
            _perspective = perspective;
            _aliasedNamespaces = new Dictionary(stringComparer); 
            _namespaces = new HashSet(MetadataMember.CreateMetadataMemberNameEqualityComparer(stringComparer));
            _functionDefinitions = new Dictionary>(stringComparer);
            _includeInlineFunctions = true;
            _resolveLeftMostUnqualifiedNameAsNamespaceOnly = false; 
        }
 
        ///  
        /// Returns perspective.
        ///  
        internal Perspective Perspective
        {
            get { return _perspective; }
        } 

        ///  
        /// Returns namespace imports. 
        /// 
        internal ICollection NamespaceImports 
        {
            get { return _namespaces; }
        }
 
        /// 
        /// Returns  for . 
        ///  
        internal TypeUsage StringType
        { 
            get { return _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.String); }
        }

        ///  
        /// Returns  for .
        ///  
        internal TypeUsage BooleanType 
        {
            get { return _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Boolean); } 
        }

        /// 
        /// Returns  for . 
        /// 
        internal TypeUsage Int64Type 
        { 
            get { return _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Int64); }
        } 

        /// 
        /// Adds an aliased namespace import.
        ///  
        internal void AddAliasedNamespaceImport(string alias, MetadataNamespace @namespace, ErrorContext errCtx)
        { 
            if (_aliasedNamespaces.ContainsKey(alias)) 
            {
                throw EntityUtil.EntitySqlError(errCtx, Strings.NamespaceAliasAlreadyUsed(alias)); 
            }

            _aliasedNamespaces.Add(alias, @namespace);
        } 

        ///  
        /// Adds a non-aliased namespace import. 
        /// 
        internal void AddNamespaceImport(MetadataNamespace @namespace, ErrorContext errCtx) 
        {
            if (_namespaces.Contains(@namespace))
            {
                throw EntityUtil.EntitySqlError(errCtx, Strings.NamespaceAlreadyImported(@namespace.Name)); 
            }
 
            _namespaces.Add(@namespace); 
        }
 
        #region Inline function declarations
        /// 
        /// Declares inline function in the query local metadata.
        ///  
        internal void DeclareInlineFunction(string name, InlineFunctionInfo functionInfo)
        { 
            Debug.Assert(!String.IsNullOrEmpty(name), "name must not be null or empty"); 
            Debug.Assert(functionInfo != null, "functionInfo != null");
 
            List overloads;
            if (!_functionDefinitions.TryGetValue(name, out overloads))
            {
                overloads = new List(); 
                _functionDefinitions.Add(name, overloads);
            } 
 
            //
            // Check overload uniqueness. 
            //
            if (overloads.Exists(overload =>
                overload.Parameters.Select(p => p.ResultType).SequenceEqual(functionInfo.Parameters.Select(p => p.ResultType), TypeUsageStructuralComparer.Instance)))
            { 
                throw EntityUtil.EntitySqlError(functionInfo.FunctionDefAst.ErrCtx, Strings.DuplicatedInlineFunctionOverload(name));
            } 
 
            overloads.Add(functionInfo);
        } 

        private sealed class TypeUsageStructuralComparer : IEqualityComparer
        {
            internal static readonly TypeUsageStructuralComparer Instance = new TypeUsageStructuralComparer(); 

            private TypeUsageStructuralComparer() { } 
 
            public bool Equals(TypeUsage x, TypeUsage y)
            { 
                return TypeSemantics.IsStructurallyEqual(x, y);
            }

            public int GetHashCode(TypeUsage obj) 
            {
                Debug.Fail("Not implemented"); 
                return 0; 
            }
        } 
        #endregion

        internal IDisposable EnterFunctionNameResolution(bool includeInlineFunctions)
        { 
            bool savedIncludeInlineFunctions = _includeInlineFunctions;
            _includeInlineFunctions = includeInlineFunctions; 
            return new Disposer(delegate { this._includeInlineFunctions = savedIncludeInlineFunctions; }); 
        }
 
        internal IDisposable EnterBackwardCompatibilityResolution()
        {
            Debug.Assert(!_resolveLeftMostUnqualifiedNameAsNamespaceOnly, "EnterBackwardCompatibilityResolution() is not reentrant.");
            _resolveLeftMostUnqualifiedNameAsNamespaceOnly = true; 
            return new Disposer(delegate
            { 
                Debug.Assert(this._resolveLeftMostUnqualifiedNameAsNamespaceOnly, "_resolveLeftMostUnqualifiedNameAsNamespaceOnly must be true."); 
                this._resolveLeftMostUnqualifiedNameAsNamespaceOnly = false;
            }); 
        }

        internal MetadataMember ResolveMetadataMemberName(string[] name, ErrorContext errCtx)
        { 
            Debug.Assert(name != null && name.Length > 0, "name must not be empty");
 
            MetadataMember metadataMember; 
            if (name.Length == 1)
            { 
                metadataMember = ResolveUnqualifiedName(name[0], false /* partOfQualifiedName */, errCtx);
            }
            else
            { 
                metadataMember = ResolveFullyQualifiedName(name, name.Length, errCtx);
            } 
            Debug.Assert(metadataMember != null, "metadata member name resolution must not return null"); 

            return metadataMember; 
        }

        internal MetadataMember ResolveMetadataMemberAccess(MetadataMember qualifier, string name, ErrorContext errCtx)
        { 
            string fullName = GetFullName(qualifier.Name, name);
            if (qualifier.MetadataMemberClass == MetadataMemberClass.Namespace) 
            { 
                //
                // Try resolving as a type. 
                //
                MetadataType type;
                if (TryGetTypeFromMetadata(fullName, out type))
                { 
                    return type;
                } 
 
                //
                // Try resolving as a function. 
                //
                MetadataFunctionGroup function;
                if (TryGetFunctionFromMetadata(fullName, out function))
                { 
                    return function;
                } 
 
                //
                // Otherwise, resolve as a namespace. 
                //
                return new MetadataNamespace(fullName);
            }
            else 
            {
                throw EntityUtil.EntitySqlError(errCtx, Strings.InvalidMetadataMemberClassResolution( 
                    qualifier.Name, qualifier.MetadataMemberClassName, MetadataNamespace.NamespaceClassName)); 
            }
        } 

        internal MetadataMember ResolveUnqualifiedName(string name, bool partOfQualifiedName, ErrorContext errCtx)
        {
            Debug.Assert(!String.IsNullOrEmpty(name), "name must not be empty"); 

            // 
            // In the case of Name1.Name2...NameN and if backward compatibility mode is on, then resolve Name1 as namespace only, ignore any other possible resolutions. 
            //
            bool resolveAsNamespaceOnly = partOfQualifiedName && _resolveLeftMostUnqualifiedNameAsNamespaceOnly; 

            //
            // In the case of Name1.Name2...NameN, ignore functions while resolving Name1: functions don't have members.
            // 
            bool includeFunctions = !partOfQualifiedName;
 
            // 
            // Try resolving as an inline function.
            // 
            InlineFunctionGroup inlineFunctionGroup;
            if (!resolveAsNamespaceOnly &&
                includeFunctions && TryGetInlineFunction(name, out inlineFunctionGroup))
            { 
                return inlineFunctionGroup;
            } 
 
            //
            // Try resolving as a namespace alias. 
            //
            MetadataNamespace aliasedNamespaceImport;
            if (_aliasedNamespaces.TryGetValue(name, out aliasedNamespaceImport))
            { 
                return aliasedNamespaceImport;
            } 
 
            if (!resolveAsNamespaceOnly)
            { 
                //
                // Try resolving as a type or functionGroup in the global namespace or as an imported member.
                // Throw if ambiguous.
                // 
                MetadataType type = null;
                MetadataFunctionGroup functionGroup = null; 
 
                //
                // Try resolving in the global namespace. 
                //
                if (!TryGetTypeFromMetadata(name, out type))
                {
                    if (includeFunctions) 
                    {
                        TryGetFunctionFromMetadata(name, out functionGroup); 
                    } 
                }
 
                //
                // Try resolving as an imported member.
                //
                MetadataNamespace importedMemberNamespace = null; 
                foreach (MetadataNamespace namespaceImport in _namespaces)
                { 
                    string fullName = GetFullName(namespaceImport.Name, name); 

                    MetadataType importedType; 
                    if (TryGetTypeFromMetadata(fullName, out importedType))
                    {
                        if (type == null && functionGroup == null)
                        { 
                            type = importedType;
                            importedMemberNamespace = namespaceImport; 
                        } 
                        else
                        { 
                            throw AmbiguousMetadataMemberName(errCtx, name, namespaceImport, importedMemberNamespace);
                        }
                    }
 
                    MetadataFunctionGroup importedFunctionGroup;
                    if (includeFunctions && TryGetFunctionFromMetadata(fullName, out importedFunctionGroup)) 
                    { 
                        if (type == null && functionGroup == null)
                        { 
                            functionGroup = importedFunctionGroup;
                            importedMemberNamespace = namespaceImport;
                        }
                        else 
                        {
                            throw AmbiguousMetadataMemberName(errCtx, name, namespaceImport, importedMemberNamespace); 
                        } 
                    }
                } 
                if (type != null)
                {
                    return type;
                } 
                if (functionGroup != null)
                { 
                    return functionGroup; 
                }
            } 

            //
            // Otherwise, resolve as a namespace.
            // 
            return new MetadataNamespace(name);
        } 
 
        private MetadataMember ResolveFullyQualifiedName(string[] name, int length, ErrorContext errCtx)
        { 
            Debug.Assert(name != null && length > 1 && length <= name.Length, "name must not be empty");

            //
            // Resolve N in N.R 
            //
            MetadataMember left; 
            if (length == 2) 
            {
                // 
                // If N is a single name, ignore functions: functions don't have members.
                //
                left = ResolveUnqualifiedName(name[0], true /* partOfQualifiedName */, errCtx);
            } 
            else
            { 
                left = ResolveFullyQualifiedName(name, length - 1, errCtx); 
            }
 
            //
            // Get R in N.R
            //
            string rightName = name[length - 1]; 
            Debug.Assert(!String.IsNullOrEmpty(rightName), "rightName must not be empty");
 
            // 
            // Resolve R in the context of N
            // 
            return ResolveMetadataMemberAccess(left, rightName, errCtx);
        }

        private static Exception AmbiguousMetadataMemberName(ErrorContext errCtx, string name, MetadataNamespace ns1, MetadataNamespace ns2) 
        {
            throw EntityUtil.EntitySqlError(errCtx, Strings.AmbiguousMetadataMemberName(name, ns1.Name, ns2 != null ? ns2.Name : null)); 
        } 

        ///  
        /// Try get type from the model using the fully qualified name.
        /// 
        private bool TryGetTypeFromMetadata(string typeFullName, out MetadataType type)
        { 
            TypeUsage typeUsage;
            if (_perspective.TryGetTypeByName(typeFullName, true /* ignore case */, out typeUsage)) 
            { 
                type = new MetadataType(typeFullName, typeUsage);
                return true; 
            }
            else
            {
                type = null; 
                return false;
            } 
        } 

        ///  
        /// Try get function from the model using the fully qualified name.
        /// 
        internal bool TryGetFunctionFromMetadata(string functionFullName, out MetadataFunctionGroup functionGroup)
        { 
            IList functionMetadata;
            if (_perspective.TryGetFunctionByName(functionFullName, true /* ignore case */, out functionMetadata)) 
            { 
                functionGroup = new MetadataFunctionGroup(functionFullName, functionMetadata);
                return true; 
            }
            else
            {
                functionGroup = null; 
                return false;
            } 
        } 

        ///  
        /// Try get function from the local metadata using the fully qualified name.
        /// 
        private bool TryGetInlineFunction(string functionName, out InlineFunctionGroup inlineFunctionGroup)
        { 
            List inlineFunctionMetadata;
            if (_includeInlineFunctions && _functionDefinitions.TryGetValue(functionName, out inlineFunctionMetadata)) 
            { 
                inlineFunctionGroup = new InlineFunctionGroup(functionName, inlineFunctionMetadata);
                return true; 
            }
            else
            {
                inlineFunctionGroup = null; 
                return false;
            } 
        } 

        ///  
        /// Builds a dot-separated multipart identifier off the provided .
        /// 
        internal static string GetFullName(params string[] names)
        { 
            Debug.Assert(names != null && names.Length > 0, "names must not be null or empty");
            return String.Join(".", names); 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK