Code:
/ 4.0 / 4.0 / 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 internal abstract string MetadataMemberClassName { get; } internal static IEqualityComparerfor error messages. /// 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 ICollectionNamespaceImports { get { return _namespaces; } } /// /// Returns internal TypeUsage StringType { get { return _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.String); } } ///for . /// /// Returns internal TypeUsage BooleanType { get { return _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Boolean); } } ///for . /// /// Returns internal TypeUsage Int64Type { get { return _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Int64); } } ///for . /// /// 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"); Listoverloads; 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) { IListfunctionMetadata; 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) { ListinlineFunctionMetadata; 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. //---------------------------------------------------------------------- //. /// // 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 internal abstract string MetadataMemberClassName { get; } internal static IEqualityComparerfor error messages. /// 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 ICollectionNamespaceImports { get { return _namespaces; } } /// /// Returns internal TypeUsage StringType { get { return _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.String); } } ///for . /// /// Returns internal TypeUsage BooleanType { get { return _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Boolean); } } ///for . /// /// Returns internal TypeUsage Int64Type { get { return _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Int64); } } ///for . /// /// 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"); Listoverloads; 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) { IListfunctionMetadata; 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) { ListinlineFunctionMetadata; 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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RoleServiceManager.cs
- DocumentPageHost.cs
- ListSortDescription.cs
- DocumentSequenceHighlightLayer.cs
- Solver.cs
- TypeValidationEventArgs.cs
- EventBuilder.cs
- Number.cs
- ConfigXmlAttribute.cs
- ToolStripContentPanel.cs
- SiteMapDataSourceView.cs
- RichTextBoxContextMenu.cs
- XmlRawWriterWrapper.cs
- XmlTypeMapping.cs
- Random.cs
- UnmanagedMemoryAccessor.cs
- storepermission.cs
- Metadata.cs
- UICuesEvent.cs
- XmlNodeComparer.cs
- CompositeKey.cs
- GenericUriParser.cs
- ProviderCollection.cs
- InvalidWMPVersionException.cs
- StrokeNodeData.cs
- SqlDataSourceCommandParser.cs
- ContractNamespaceAttribute.cs
- CompressStream.cs
- InputLanguageCollection.cs
- JumpItem.cs
- EmptyEnumerator.cs
- ArraySet.cs
- ButtonFlatAdapter.cs
- DataBindingHandlerAttribute.cs
- Package.cs
- ListBindingHelper.cs
- PagedDataSource.cs
- ValidationRuleCollection.cs
- StoreAnnotationsMap.cs
- ScrollChrome.cs
- Activator.cs
- InstallHelper.cs
- RelationshipConverter.cs
- WindowClosedEventArgs.cs
- SyncMethodInvoker.cs
- DataGridViewColumnEventArgs.cs
- SettingsPropertyValue.cs
- Calendar.cs
- PageStatePersister.cs
- DataBinder.cs
- RegexParser.cs
- TextSimpleMarkerProperties.cs
- ProxyManager.cs
- SelectionChangedEventArgs.cs
- VariableBinder.cs
- PageFunction.cs
- SettingsSection.cs
- ServiceHttpHandlerFactory.cs
- HttpConfigurationSystem.cs
- IsolatedStorageException.cs
- PropertyMappingExceptionEventArgs.cs
- CompilerWrapper.cs
- WebSysDescriptionAttribute.cs
- StorageEndPropertyMapping.cs
- EqualityComparer.cs
- PowerEase.cs
- FlowDocumentPageViewerAutomationPeer.cs
- FileNotFoundException.cs
- DataSourceView.cs
- SmiEventSink_Default.cs
- ArgumentOutOfRangeException.cs
- EmptyElement.cs
- ContextItemManager.cs
- Delay.cs
- QilTypeChecker.cs
- Stream.cs
- Solver.cs
- MessageTraceRecord.cs
- Util.cs
- XamlReaderHelper.cs
- TextEffect.cs
- SqlFormatter.cs
- TaskFileService.cs
- IntSecurity.cs
- XmlChoiceIdentifierAttribute.cs
- Binding.cs
- StylusPointProperty.cs
- Boolean.cs
- DocumentViewer.cs
- XmlIlGenerator.cs
- MonitoringDescriptionAttribute.cs
- DataGridTextBoxColumn.cs
- XmlDataLoader.cs
- LayoutTable.cs
- SecurityPermission.cs
- TextTrailingWordEllipsis.cs
- Part.cs
- StateBag.cs
- SQLMoney.cs
- Publisher.cs