Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Common / EntitySql / TypeResolver.cs / 2 / TypeResolver.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backup [....]
//---------------------------------------------------------------------
namespace System.Data.Common.EntitySql
{
using System;
using System.Globalization;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Data.Common;
using System.Data.Metadata.Edm;
using System.Data.Entity;
///
/// Represents Type Resolver Helper in the context of a typespace
///
internal sealed class TypeResolver
{
private TypeUsage _cachedStringType;
private TypeUsage _cachedBooleanType;
private TypeUsage _cachedInt64Type;
private Perspective _perspective;
private Dictionary _aliasedNamespaces;
private HashSet _namespaces;
///
/// Initializes TypeResolver instance
///
///
///
internal TypeResolver( Perspective perspective, StringComparer stringComparer )
{
EntityUtil.CheckArgumentNull(perspective, "perspective");
_perspective = perspective;
_aliasedNamespaces = new Dictionary(stringComparer);
_namespaces = new HashSet(stringComparer);
}
///
/// returns perspective instance
///
internal Perspective Perspective
{
get { return _perspective; }
}
///
/// Add aliased namespace declaration
///
///
///
internal bool TryAddAliasedNamespace( string alias, string namespaceName )
{
if (_aliasedNamespaces.ContainsKey(alias))
{
return false;
}
_aliasedNamespaces.Add(alias, namespaceName);
return true;
}
///
/// Add namespaces declaration
///
///
internal bool TryAddNamespace( string namespaceName )
{
if (_namespaces.Contains(namespaceName))
{
return false;
}
_namespaces.Add(namespaceName);
return true;
}
///
/// returns true if key type is valid for collation
///
///
///
internal static bool IsKeyValidForCollation( TypeUsage type )
{
return (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String) /* && isSearchable */ );
}
///
/// returns if a given type is allowed to have method calls
///
///
///
internal static bool IsValidTypeForMethodCall( TypeUsage type )
{
return (type.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType);
}
///
/// returns true if type is string type
///
///
///
internal static bool IsStringType( TypeUsage type )
{
return TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String);
}
///
/// Checks if a type is boolean
///
///
///
internal static bool IsBooleanType( TypeUsage type )
{
return TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Boolean);
}
///
/// Checks if two types are sub/super type inclusive
///
///
///
///
internal static bool IsSubOrSuperType( TypeUsage type1, TypeUsage type2 )
{
return TypeSemantics.IsEquivalent(type1, type2) || type1.IsSubtypeOf(type2) || type2.IsSubtypeOf(type1);
}
///
/// returns target space Edm.String type
///
internal TypeUsage StringType
{
get
{
if (null == _cachedStringType)
{
_cachedStringType = _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.String);
}
return _cachedStringType;
}
}
///
/// returns target space Edm.Booelan type
///
internal TypeUsage BooleanType
{
get
{
if (null == _cachedBooleanType)
{
_cachedBooleanType = _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Boolean);
}
return _cachedBooleanType;
}
}
///
/// returns target space Edm.Int64 type
///
internal TypeUsage Int64Type
{
get
{
if (null == _cachedInt64Type)
{
_cachedInt64Type = _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Int64);
}
return _cachedInt64Type;
}
}
///
/// resolves a name as type
///
///
///
///
/// TypeUsage
internal TypeUsage ResolveNameAsType( string[] names, int countNames, out int matchCount )
{
TypeUsage TypeUsage = null;
matchCount = 0;
//
// lookup type in aliased namespaces if aliased
//
if (names.Length > 1 && (countNames > (names.Length - 1)))
{
string namespaceName = null;
if (_aliasedNamespaces.TryGetValue(names[0], out namespaceName))
{
if (TryGetTypeFromMetadata(namespaceName + "." + ConcatStringsWithSeparator(names, '.', 1, countNames - 1), out TypeUsage))
{
matchCount = 1;
return TypeUsage;
}
}
}
string typeName = ConcatStringsWithSeparator(names, '.', 0, countNames);
//
// Try Full type name
//
if (TryGetTypeFromMetadata(typeName, out TypeUsage))
{
matchCount = 1;
return TypeUsage;
}
//
// lookup type in namespaces
//
TypeUsage matchType;
foreach (string ns in _namespaces)
{
if (TryGetTypeFromMetadata(ns + "." + typeName, out matchType))
{
matchCount++;
TypeUsage = matchType;
}
}
return TypeUsage;
}
///
/// Resolves a Name as Function
///
///
///
///
///
///
internal IList ResolveNameAsFunction( string[] names, bool ignoreCase, out int matchCount,
out List foundNamespaces)
{
IList functionList = null;
foundNamespaces = new List();
string namespaceName = null;
string functionName = names[names.Length - 1];
matchCount = 0;
//
// lookup type in aliased namespaces if aliased
//
if (names.Length > 1)
{
if (_aliasedNamespaces.TryGetValue(names[0], out namespaceName))
{
if (TryGetFunctionFromMetadata(functionName, namespaceName, ignoreCase, out functionList))
{
matchCount = 1;
foundNamespaces.Add(namespaceName);
return functionList;
}
}
//
// Try function full name
//
namespaceName = ConcatStringsWithSeparator(names, '.', 0, names.Length - 1);
if (TryGetFunctionFromMetadata(functionName, namespaceName, ignoreCase, out functionList))
{
matchCount = 1;
foundNamespaces.Add(namespaceName);
}
return functionList;
}
//
// lookup type in namespaces
//
IList tmpFunctionList;
foreach (string ns in _namespaces)
{
if (TryGetFunctionFromMetadata(functionName, ns, ignoreCase, out tmpFunctionList))
{
matchCount++;
functionList = tmpFunctionList;
foundNamespaces.Add(ns);
}
}
return functionList;
}
///
/// find name base type
///
///
///
///
///
internal TypeUsage ResolveBaseType( string[] names, out int suffixIndex, out int matchCount )
{
TypeUsage TypeUsage = null;
suffixIndex = 0;
matchCount = 0;
Debug.Assert(names.Length > 0, "names.Length > 0");
//
// lookup in aliased namespaces
//
if (!TryGetBaseTypeInAliasedNamespaces(names, out TypeUsage, out suffixIndex))
{
//
// Try Resolve id base type
//
int idMatchCount = 0;
int idSuffix = 0;
TypeUsage idTypeUsage;
if (TryGetIdentifierBaseType(names, out idTypeUsage, out idSuffix))
{
idMatchCount++;
}
//
// lookup in known namespaces
//
if (TryGetBaseTypeInNamespaces(names, out TypeUsage, out suffixIndex, out matchCount))
{
matchCount += idMatchCount;
}
if (null == TypeUsage)
{
TypeUsage = idTypeUsage;
suffixIndex = idSuffix;
matchCount = idMatchCount;
}
}
return TypeUsage;
}
///
/// given an identifier try to get its base type
///
///
///
///
///
internal bool TryGetIdentifierBaseType( string[] names, out TypeUsage TypeUsage, out int suffixIndex )
{
TypeUsage = null;
suffixIndex = 0;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for(int i=0; i < names.Length; i++)
{
sb.Append(names[i]);
if (TryGetTypeFromMetadata(sb.ToString(), out TypeUsage))
{
suffixIndex = i;
return true;
}
sb.Append('.');
}
return false;
}
///
/// try resolve base type in aliased namespaces
///
///
///
///
///
internal bool TryGetBaseTypeInAliasedNamespaces( string[] names, out TypeUsage TypeUsage, out int suffixIndex )
{
TypeUsage = null;
suffixIndex = 0;
if (names.Length > 1)
{
string namespaceName = null;
if (_aliasedNamespaces.TryGetValue(names[0], out namespaceName))
{
if (TryGetBaseTypeFromMetadata(namespaceName, TrimNamesPrefix(names, 1), out TypeUsage, out suffixIndex))
{
suffixIndex++;
return true;
}
}
}
return false;
}
///
/// try resolve Base type in declared non-aliased namespaces
///
///
///
///
///
///
internal bool TryGetBaseTypeInNamespaces( string[] names, out TypeUsage TypeUsage, out int suffixIndex, out int matchCount )
{
TypeUsage = null;
suffixIndex = 0;
matchCount = 0;
TypeUsage matchType = null;
foreach (string nsPrefix in _namespaces)
{
if (TryGetTypeFromMetadata(nsPrefix + "." + names[0], out TypeUsage))
{
matchType = TypeUsage;
suffixIndex = 1;
matchCount++;
}
}
TypeUsage = matchType;
return (matchCount > 0);
}
///
/// try get base type from metadata
///
///
///
///
///
///
internal bool TryGetBaseTypeFromMetadata( string namespaceName, string[] names, out TypeUsage TypeUsage, out int suffixIndex )
{
TypeUsage = null;
suffixIndex = 0;
if (TryGetTypeFromMetadata(namespaceName + "." + names[0], out TypeUsage))
{
suffixIndex = 1;
}
return (null != TypeUsage);
}
///
/// Lookup metadata for a function given its fqn
///
///
///
///
///
///
internal bool TryGetFunctionFromMetadata(string name, string namespaceName, bool ignoreCase,
out IList functionMetadata)
{
System.Collections.ObjectModel.ReadOnlyCollection functions =
_perspective.GetFunctions(name, namespaceName, ignoreCase);
functionMetadata = functions;
if (functionMetadata.Count > 0)
{
return true;
}
return false;
}
///
/// Get global function metadata
///
///
///
///
///
/// Funciton metadata
internal static EdmFunction ResolveFunctionOverloads( IList functionsMetadata,
IList argTypes,
bool isGroupAggregateFunction,
out bool isAmbiguous )
{
EdmFunction closestFunctionMatch = null;
uint maxRank = 0;
isAmbiguous = false;
Debug.Assert(functionsMetadata.Count > 0, "functionsMetadata.Count must be greater than zero");
for (int i = 0 ; i < functionsMetadata.Count ; i++)
{
uint rank = RankFunctionParameters(argTypes,
functionsMetadata[i].Parameters,
isGroupAggregateFunction);
if (0 == rank)
{
continue;
}
if (rank == maxRank)
{
isAmbiguous = true;
}
if (rank > maxRank)
{
isAmbiguous = false;
maxRank = rank;
closestFunctionMatch = functionsMetadata[i];
}
}
return closestFunctionMatch;
}
///
/// Ranks a list of candidate parameter types against the function formal signature especification
///
/// list of candidate parameter types
/// function formal signature parameter metadata
///
///
/// assumes no overload will have more than 10^12 equivalent parameters
static internal uint RankFunctionParameters( IList candidateParams,
IList signatureParams,
bool isGroupAggregateFunction )
{
if (candidateParams.Count != signatureParams.Count)
{
return 0;
}
if (0 == candidateParams.Count && 0 == signatureParams.Count)
{
return 0X40000000;
}
int equivalenceCount = 0;
int promotionCount = 0;
for (int i = 0 ; i < candidateParams.Count ; i++)
{
TypeUsage candidateParamType = candidateParams[i];
TypeUsage formalParamType = signatureParams[i].TypeUsage;
//
// if function being ranked is a group aggregate, consider the element type
//
if (isGroupAggregateFunction)
{
if (!TypeSemantics.IsCollectionType(formalParamType))
{
//
// even though it is the job of metadata to ensure that the provider manifest is consistent
// ensure that if a function is marked as aggregate, then the argument type must be of collection{GivenType}
//
throw EntityUtil.EntitySqlError(Strings.InvalidArgumentTypeForAggregateFunction);
}
formalParamType = TypeHelpers.GetElementTypeUsage(formalParamType);
}
if (signatureParams[i].Mode != ParameterMode.In && signatureParams[i].Mode != ParameterMode.InOut)
{
return 0;
}
if (TypeSemantics.IsEquivalent(candidateParamType, formalParamType) ||
(TypeSemantics.IsNullType(candidateParamType) && !TypeSemantics.IsCollectionType(formalParamType)))
{
equivalenceCount++;
}
else if (TypeSemantics.IsPromotableTo(candidateParamType, formalParamType))
{
promotionCount += GetPromotionRank(candidateParamType, formalParamType);
}
else
{
return 0;
}
}
if (equivalenceCount >= 0x8000 || promotionCount >= 0x8000)
{
throw EntityUtil.EntitySqlError(Strings.TooManyFunctionArguments);
}
return (uint)((equivalenceCount << 15) | promotionCount);
}
///
/// Assume that candidateType *IS PROMOTABLE* to formalType
///
///
///
///
static private int GetPromotionRank( TypeUsage candidateType, TypeUsage formalType )
{
int promotionRank = 1;
Debug.Assert(TypeSemantics.IsPromotableTo(candidateType, formalType));
if (TypeSemantics.IsCollectionType(candidateType) && TypeSemantics.IsCollectionType(formalType))
{
return GetPromotionRank(TypeHelpers.GetElementTypeUsage(candidateType), TypeHelpers.GetElementTypeUsage(formalType));
}
PrimitiveType primitiveCandidateType = candidateType.EdmType as PrimitiveType;
PrimitiveType primitiveFormalType = formalType.EdmType as PrimitiveType;
if (null != primitiveCandidateType && null != primitiveFormalType)
{
IList promotionTypes = EdmProviderManifest.Instance.GetPromotionTypes(primitiveCandidateType);
if (primitiveCandidateType == primitiveFormalType)
{
// we don't put the same type in the manifest, so we need to check
// if it is the same type.
promotionRank = promotionTypes.Count + 1; // +1 because we want to be 1 above the rank of any other possibility
}
else
{
Debug.Assert(promotionTypes.Count > 0);
Debug.Assert(Helper.IsPromotableTo(promotionTypes, primitiveFormalType) != -1);
promotionRank = promotionTypes.Count - Helper.IsPromotableTo(promotionTypes, primitiveFormalType);
}
}
Debug.Assert(promotionRank >= 0, "promotionRank >=0");
return promotionRank;
}
///
/// Try get fqtn from current metadata typespace
///
///
///
///
internal bool TryGetTypeFromMetadata( string typeFullName, out TypeUsage typeUsage )
{
return _perspective.TryGetTypeByName(typeFullName, true /* ignore case */, out typeUsage);
}
///
/// Returns the proper TypeUsage for a given literal expression
///
///
///
internal TypeUsage GetLiteralTypeUsage( Literal literal )
{
PrimitiveType primitiveType = null;
if (!ClrProviderManifest.Instance.TryGetPrimitiveType(literal.Type, out primitiveType))
{
throw EntityUtil.EntitySqlError(literal.ErrCtx, System.Data.Entity.Strings.LiteralTypeNotFoundInMetadata(literal.OriginalValue));
}
TypeUsage literalTypeUsage = TypeHelpers.GetLiteralTypeUsage(primitiveType.PrimitiveTypeKind, literal.IsUnicodeString);
return literalTypeUsage;
}
///
/// Trims prefix from fqn in array form
///
///
///
///
internal static string[] TrimNamesPrefix( string[] names, int startIndex )
{
string[] s = new string[names.Length - 1];
for (int i = startIndex ; i < names.Length ; s[i - 1] = names[i], i++) ;
return s;
}
///
/// returns full string
///
///
///
static internal string GetFullName( string[] names )
{
return ConcatStringsWithSeparator(names, '.', 0 /*startIndex*/, names.Length);
}
static private string ConcatStringsWithSeparator( string[] names, char separator, int startIndex, int endIndex )
{
Debug.Assert(names.Length > 0, "names.Length > 0");
Debug.Assert(startIndex <= endIndex, "startIndex <= endIndex");
Debug.Assert(startIndex >= 0, "startIndex >= 0");
Debug.Assert(startIndex < names.Length, "startIndex < names.Length");
if (startIndex == endIndex)
{
return names[startIndex];
}
StringBuilder sb = new StringBuilder();
sb.Append(names[startIndex]);
for (int i = startIndex + 1 ; i < endIndex ; i++)
{
sb.Append(separator).Append(names[i]);
}
return sb.ToString();
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backup [....]
//---------------------------------------------------------------------
namespace System.Data.Common.EntitySql
{
using System;
using System.Globalization;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Data.Common;
using System.Data.Metadata.Edm;
using System.Data.Entity;
///
/// Represents Type Resolver Helper in the context of a typespace
///
internal sealed class TypeResolver
{
private TypeUsage _cachedStringType;
private TypeUsage _cachedBooleanType;
private TypeUsage _cachedInt64Type;
private Perspective _perspective;
private Dictionary _aliasedNamespaces;
private HashSet _namespaces;
///
/// Initializes TypeResolver instance
///
///
///
internal TypeResolver( Perspective perspective, StringComparer stringComparer )
{
EntityUtil.CheckArgumentNull(perspective, "perspective");
_perspective = perspective;
_aliasedNamespaces = new Dictionary(stringComparer);
_namespaces = new HashSet(stringComparer);
}
///
/// returns perspective instance
///
internal Perspective Perspective
{
get { return _perspective; }
}
///
/// Add aliased namespace declaration
///
///
///
internal bool TryAddAliasedNamespace( string alias, string namespaceName )
{
if (_aliasedNamespaces.ContainsKey(alias))
{
return false;
}
_aliasedNamespaces.Add(alias, namespaceName);
return true;
}
///
/// Add namespaces declaration
///
///
internal bool TryAddNamespace( string namespaceName )
{
if (_namespaces.Contains(namespaceName))
{
return false;
}
_namespaces.Add(namespaceName);
return true;
}
///
/// returns true if key type is valid for collation
///
///
///
internal static bool IsKeyValidForCollation( TypeUsage type )
{
return (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String) /* && isSearchable */ );
}
///
/// returns if a given type is allowed to have method calls
///
///
///
internal static bool IsValidTypeForMethodCall( TypeUsage type )
{
return (type.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType);
}
///
/// returns true if type is string type
///
///
///
internal static bool IsStringType( TypeUsage type )
{
return TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String);
}
///
/// Checks if a type is boolean
///
///
///
internal static bool IsBooleanType( TypeUsage type )
{
return TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Boolean);
}
///
/// Checks if two types are sub/super type inclusive
///
///
///
///
internal static bool IsSubOrSuperType( TypeUsage type1, TypeUsage type2 )
{
return TypeSemantics.IsEquivalent(type1, type2) || type1.IsSubtypeOf(type2) || type2.IsSubtypeOf(type1);
}
///
/// returns target space Edm.String type
///
internal TypeUsage StringType
{
get
{
if (null == _cachedStringType)
{
_cachedStringType = _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.String);
}
return _cachedStringType;
}
}
///
/// returns target space Edm.Booelan type
///
internal TypeUsage BooleanType
{
get
{
if (null == _cachedBooleanType)
{
_cachedBooleanType = _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Boolean);
}
return _cachedBooleanType;
}
}
///
/// returns target space Edm.Int64 type
///
internal TypeUsage Int64Type
{
get
{
if (null == _cachedInt64Type)
{
_cachedInt64Type = _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Int64);
}
return _cachedInt64Type;
}
}
///
/// resolves a name as type
///
///
///
///
/// TypeUsage
internal TypeUsage ResolveNameAsType( string[] names, int countNames, out int matchCount )
{
TypeUsage TypeUsage = null;
matchCount = 0;
//
// lookup type in aliased namespaces if aliased
//
if (names.Length > 1 && (countNames > (names.Length - 1)))
{
string namespaceName = null;
if (_aliasedNamespaces.TryGetValue(names[0], out namespaceName))
{
if (TryGetTypeFromMetadata(namespaceName + "." + ConcatStringsWithSeparator(names, '.', 1, countNames - 1), out TypeUsage))
{
matchCount = 1;
return TypeUsage;
}
}
}
string typeName = ConcatStringsWithSeparator(names, '.', 0, countNames);
//
// Try Full type name
//
if (TryGetTypeFromMetadata(typeName, out TypeUsage))
{
matchCount = 1;
return TypeUsage;
}
//
// lookup type in namespaces
//
TypeUsage matchType;
foreach (string ns in _namespaces)
{
if (TryGetTypeFromMetadata(ns + "." + typeName, out matchType))
{
matchCount++;
TypeUsage = matchType;
}
}
return TypeUsage;
}
///
/// Resolves a Name as Function
///
///
///
///
///
///
internal IList ResolveNameAsFunction( string[] names, bool ignoreCase, out int matchCount,
out List foundNamespaces)
{
IList functionList = null;
foundNamespaces = new List();
string namespaceName = null;
string functionName = names[names.Length - 1];
matchCount = 0;
//
// lookup type in aliased namespaces if aliased
//
if (names.Length > 1)
{
if (_aliasedNamespaces.TryGetValue(names[0], out namespaceName))
{
if (TryGetFunctionFromMetadata(functionName, namespaceName, ignoreCase, out functionList))
{
matchCount = 1;
foundNamespaces.Add(namespaceName);
return functionList;
}
}
//
// Try function full name
//
namespaceName = ConcatStringsWithSeparator(names, '.', 0, names.Length - 1);
if (TryGetFunctionFromMetadata(functionName, namespaceName, ignoreCase, out functionList))
{
matchCount = 1;
foundNamespaces.Add(namespaceName);
}
return functionList;
}
//
// lookup type in namespaces
//
IList tmpFunctionList;
foreach (string ns in _namespaces)
{
if (TryGetFunctionFromMetadata(functionName, ns, ignoreCase, out tmpFunctionList))
{
matchCount++;
functionList = tmpFunctionList;
foundNamespaces.Add(ns);
}
}
return functionList;
}
///
/// find name base type
///
///
///
///
///
internal TypeUsage ResolveBaseType( string[] names, out int suffixIndex, out int matchCount )
{
TypeUsage TypeUsage = null;
suffixIndex = 0;
matchCount = 0;
Debug.Assert(names.Length > 0, "names.Length > 0");
//
// lookup in aliased namespaces
//
if (!TryGetBaseTypeInAliasedNamespaces(names, out TypeUsage, out suffixIndex))
{
//
// Try Resolve id base type
//
int idMatchCount = 0;
int idSuffix = 0;
TypeUsage idTypeUsage;
if (TryGetIdentifierBaseType(names, out idTypeUsage, out idSuffix))
{
idMatchCount++;
}
//
// lookup in known namespaces
//
if (TryGetBaseTypeInNamespaces(names, out TypeUsage, out suffixIndex, out matchCount))
{
matchCount += idMatchCount;
}
if (null == TypeUsage)
{
TypeUsage = idTypeUsage;
suffixIndex = idSuffix;
matchCount = idMatchCount;
}
}
return TypeUsage;
}
///
/// given an identifier try to get its base type
///
///
///
///
///
internal bool TryGetIdentifierBaseType( string[] names, out TypeUsage TypeUsage, out int suffixIndex )
{
TypeUsage = null;
suffixIndex = 0;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for(int i=0; i < names.Length; i++)
{
sb.Append(names[i]);
if (TryGetTypeFromMetadata(sb.ToString(), out TypeUsage))
{
suffixIndex = i;
return true;
}
sb.Append('.');
}
return false;
}
///
/// try resolve base type in aliased namespaces
///
///
///
///
///
internal bool TryGetBaseTypeInAliasedNamespaces( string[] names, out TypeUsage TypeUsage, out int suffixIndex )
{
TypeUsage = null;
suffixIndex = 0;
if (names.Length > 1)
{
string namespaceName = null;
if (_aliasedNamespaces.TryGetValue(names[0], out namespaceName))
{
if (TryGetBaseTypeFromMetadata(namespaceName, TrimNamesPrefix(names, 1), out TypeUsage, out suffixIndex))
{
suffixIndex++;
return true;
}
}
}
return false;
}
///
/// try resolve Base type in declared non-aliased namespaces
///
///
///
///
///
///
internal bool TryGetBaseTypeInNamespaces( string[] names, out TypeUsage TypeUsage, out int suffixIndex, out int matchCount )
{
TypeUsage = null;
suffixIndex = 0;
matchCount = 0;
TypeUsage matchType = null;
foreach (string nsPrefix in _namespaces)
{
if (TryGetTypeFromMetadata(nsPrefix + "." + names[0], out TypeUsage))
{
matchType = TypeUsage;
suffixIndex = 1;
matchCount++;
}
}
TypeUsage = matchType;
return (matchCount > 0);
}
///
/// try get base type from metadata
///
///
///
///
///
///
internal bool TryGetBaseTypeFromMetadata( string namespaceName, string[] names, out TypeUsage TypeUsage, out int suffixIndex )
{
TypeUsage = null;
suffixIndex = 0;
if (TryGetTypeFromMetadata(namespaceName + "." + names[0], out TypeUsage))
{
suffixIndex = 1;
}
return (null != TypeUsage);
}
///
/// Lookup metadata for a function given its fqn
///
///
///
///
///
///
internal bool TryGetFunctionFromMetadata(string name, string namespaceName, bool ignoreCase,
out IList functionMetadata)
{
System.Collections.ObjectModel.ReadOnlyCollection functions =
_perspective.GetFunctions(name, namespaceName, ignoreCase);
functionMetadata = functions;
if (functionMetadata.Count > 0)
{
return true;
}
return false;
}
///
/// Get global function metadata
///
///
///
///
///
/// Funciton metadata
internal static EdmFunction ResolveFunctionOverloads( IList functionsMetadata,
IList argTypes,
bool isGroupAggregateFunction,
out bool isAmbiguous )
{
EdmFunction closestFunctionMatch = null;
uint maxRank = 0;
isAmbiguous = false;
Debug.Assert(functionsMetadata.Count > 0, "functionsMetadata.Count must be greater than zero");
for (int i = 0 ; i < functionsMetadata.Count ; i++)
{
uint rank = RankFunctionParameters(argTypes,
functionsMetadata[i].Parameters,
isGroupAggregateFunction);
if (0 == rank)
{
continue;
}
if (rank == maxRank)
{
isAmbiguous = true;
}
if (rank > maxRank)
{
isAmbiguous = false;
maxRank = rank;
closestFunctionMatch = functionsMetadata[i];
}
}
return closestFunctionMatch;
}
///
/// Ranks a list of candidate parameter types against the function formal signature especification
///
/// list of candidate parameter types
/// function formal signature parameter metadata
///
///
/// assumes no overload will have more than 10^12 equivalent parameters
static internal uint RankFunctionParameters( IList candidateParams,
IList signatureParams,
bool isGroupAggregateFunction )
{
if (candidateParams.Count != signatureParams.Count)
{
return 0;
}
if (0 == candidateParams.Count && 0 == signatureParams.Count)
{
return 0X40000000;
}
int equivalenceCount = 0;
int promotionCount = 0;
for (int i = 0 ; i < candidateParams.Count ; i++)
{
TypeUsage candidateParamType = candidateParams[i];
TypeUsage formalParamType = signatureParams[i].TypeUsage;
//
// if function being ranked is a group aggregate, consider the element type
//
if (isGroupAggregateFunction)
{
if (!TypeSemantics.IsCollectionType(formalParamType))
{
//
// even though it is the job of metadata to ensure that the provider manifest is consistent
// ensure that if a function is marked as aggregate, then the argument type must be of collection{GivenType}
//
throw EntityUtil.EntitySqlError(Strings.InvalidArgumentTypeForAggregateFunction);
}
formalParamType = TypeHelpers.GetElementTypeUsage(formalParamType);
}
if (signatureParams[i].Mode != ParameterMode.In && signatureParams[i].Mode != ParameterMode.InOut)
{
return 0;
}
if (TypeSemantics.IsEquivalent(candidateParamType, formalParamType) ||
(TypeSemantics.IsNullType(candidateParamType) && !TypeSemantics.IsCollectionType(formalParamType)))
{
equivalenceCount++;
}
else if (TypeSemantics.IsPromotableTo(candidateParamType, formalParamType))
{
promotionCount += GetPromotionRank(candidateParamType, formalParamType);
}
else
{
return 0;
}
}
if (equivalenceCount >= 0x8000 || promotionCount >= 0x8000)
{
throw EntityUtil.EntitySqlError(Strings.TooManyFunctionArguments);
}
return (uint)((equivalenceCount << 15) | promotionCount);
}
///
/// Assume that candidateType *IS PROMOTABLE* to formalType
///
///
///
///
static private int GetPromotionRank( TypeUsage candidateType, TypeUsage formalType )
{
int promotionRank = 1;
Debug.Assert(TypeSemantics.IsPromotableTo(candidateType, formalType));
if (TypeSemantics.IsCollectionType(candidateType) && TypeSemantics.IsCollectionType(formalType))
{
return GetPromotionRank(TypeHelpers.GetElementTypeUsage(candidateType), TypeHelpers.GetElementTypeUsage(formalType));
}
PrimitiveType primitiveCandidateType = candidateType.EdmType as PrimitiveType;
PrimitiveType primitiveFormalType = formalType.EdmType as PrimitiveType;
if (null != primitiveCandidateType && null != primitiveFormalType)
{
IList promotionTypes = EdmProviderManifest.Instance.GetPromotionTypes(primitiveCandidateType);
if (primitiveCandidateType == primitiveFormalType)
{
// we don't put the same type in the manifest, so we need to check
// if it is the same type.
promotionRank = promotionTypes.Count + 1; // +1 because we want to be 1 above the rank of any other possibility
}
else
{
Debug.Assert(promotionTypes.Count > 0);
Debug.Assert(Helper.IsPromotableTo(promotionTypes, primitiveFormalType) != -1);
promotionRank = promotionTypes.Count - Helper.IsPromotableTo(promotionTypes, primitiveFormalType);
}
}
Debug.Assert(promotionRank >= 0, "promotionRank >=0");
return promotionRank;
}
///
/// Try get fqtn from current metadata typespace
///
///
///
///
internal bool TryGetTypeFromMetadata( string typeFullName, out TypeUsage typeUsage )
{
return _perspective.TryGetTypeByName(typeFullName, true /* ignore case */, out typeUsage);
}
///
/// Returns the proper TypeUsage for a given literal expression
///
///
///
internal TypeUsage GetLiteralTypeUsage( Literal literal )
{
PrimitiveType primitiveType = null;
if (!ClrProviderManifest.Instance.TryGetPrimitiveType(literal.Type, out primitiveType))
{
throw EntityUtil.EntitySqlError(literal.ErrCtx, System.Data.Entity.Strings.LiteralTypeNotFoundInMetadata(literal.OriginalValue));
}
TypeUsage literalTypeUsage = TypeHelpers.GetLiteralTypeUsage(primitiveType.PrimitiveTypeKind, literal.IsUnicodeString);
return literalTypeUsage;
}
///
/// Trims prefix from fqn in array form
///
///
///
///
internal static string[] TrimNamesPrefix( string[] names, int startIndex )
{
string[] s = new string[names.Length - 1];
for (int i = startIndex ; i < names.Length ; s[i - 1] = names[i], i++) ;
return s;
}
///
/// returns full string
///
///
///
static internal string GetFullName( string[] names )
{
return ConcatStringsWithSeparator(names, '.', 0 /*startIndex*/, names.Length);
}
static private string ConcatStringsWithSeparator( string[] names, char separator, int startIndex, int endIndex )
{
Debug.Assert(names.Length > 0, "names.Length > 0");
Debug.Assert(startIndex <= endIndex, "startIndex <= endIndex");
Debug.Assert(startIndex >= 0, "startIndex >= 0");
Debug.Assert(startIndex < names.Length, "startIndex < names.Length");
if (startIndex == endIndex)
{
return names[startIndex];
}
StringBuilder sb = new StringBuilder();
sb.Append(names[startIndex]);
for (int i = startIndex + 1 ; i < endIndex ; i++)
{
sb.Append(separator).Append(names[i]);
}
return sb.ToString();
}
}
}
// 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
- CircleHotSpot.cs
- FileSystemInfo.cs
- FixedSOMLineRanges.cs
- CommonXSendMessage.cs
- ScrollPattern.cs
- exports.cs
- SetIterators.cs
- MarginsConverter.cs
- CompoundFileDeflateTransform.cs
- CurrentChangedEventManager.cs
- ToolStripSeparatorRenderEventArgs.cs
- HttpValueCollection.cs
- ImageSource.cs
- PageBuildProvider.cs
- Event.cs
- ValidationErrorEventArgs.cs
- ProgressBar.cs
- Keywords.cs
- FtpWebResponse.cs
- DiscardableAttribute.cs
- ActiveXSite.cs
- TraceUtils.cs
- PingOptions.cs
- List.cs
- SortedDictionary.cs
- IDReferencePropertyAttribute.cs
- PeerIPHelper.cs
- XmlAnyElementAttribute.cs
- CacheVirtualItemsEvent.cs
- ImmutableCollection.cs
- XXXInfos.cs
- SkinIDTypeConverter.cs
- WebPermission.cs
- TreeIterators.cs
- ZoneButton.cs
- Configuration.cs
- TimelineGroup.cs
- JsonFormatGeneratorStatics.cs
- DataRelation.cs
- FileClassifier.cs
- XmlDocumentViewSchema.cs
- ConnectionProviderAttribute.cs
- WebPartVerbCollection.cs
- MetadataItemEmitter.cs
- CapabilitiesAssignment.cs
- DbTransaction.cs
- TreeNode.cs
- templategroup.cs
- PeerEndPoint.cs
- DataServiceCollectionOfT.cs
- hebrewshape.cs
- ExpressionVisitor.cs
- DrawingContextWalker.cs
- FileDialogPermission.cs
- DataGridViewSortCompareEventArgs.cs
- BrowserDefinitionCollection.cs
- SqlCacheDependencySection.cs
- IISUnsafeMethods.cs
- TypeReference.cs
- XXXInfos.cs
- RootBrowserWindowProxy.cs
- FormatterConverter.cs
- PropertyGeneratedEventArgs.cs
- WebServiceErrorEvent.cs
- SingleKeyFrameCollection.cs
- GridItemProviderWrapper.cs
- ModelPropertyImpl.cs
- XpsS0ValidatingLoader.cs
- Configuration.cs
- PopupRootAutomationPeer.cs
- TextEditorLists.cs
- ItemList.cs
- MediaCommands.cs
- ContentPresenter.cs
- CollectionTypeElement.cs
- XPathMessageFilter.cs
- ItemType.cs
- SqlDataSourceTableQuery.cs
- ByteKeyFrameCollection.cs
- MenuItemStyleCollection.cs
- EditingScopeUndoUnit.cs
- RadioButtonRenderer.cs
- MsmqInputChannelListener.cs
- DBNull.cs
- AttributedMetaModel.cs
- EventMappingSettingsCollection.cs
- QilName.cs
- ActivityCodeDomReferenceService.cs
- Dynamic.cs
- ApplicationServicesHostFactory.cs
- ErrorProvider.cs
- FileDialog.cs
- TypeLibConverter.cs
- HasCopySemanticsAttribute.cs
- WebBrowserNavigatedEventHandler.cs
- String.cs
- IsolatedStorageFile.cs
- TimerEventSubscriptionCollection.cs
- VisualTreeUtils.cs
- DataGridViewMethods.cs