Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Common / EntitySql / TypeResolver.cs / 3 / 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
- ActivityDesignerAccessibleObject.cs
- DataGridViewCellStyle.cs
- TemplateEditingService.cs
- WebPartEditorApplyVerb.cs
- XmlSerializerSection.cs
- EngineSiteSapi.cs
- TypeBrowserDialog.cs
- CollectionViewProxy.cs
- InternalControlCollection.cs
- DbDataReader.cs
- MediaScriptCommandRoutedEventArgs.cs
- WindowProviderWrapper.cs
- ToolStripSettings.cs
- NameSpaceEvent.cs
- XmlILAnnotation.cs
- XamlSerializationHelper.cs
- XsdBuildProvider.cs
- AppDomainManager.cs
- XPathItem.cs
- FlowLayoutPanel.cs
- State.cs
- FormatSettings.cs
- Debug.cs
- LineGeometry.cs
- BaseParaClient.cs
- PeerCollaborationPermission.cs
- SafeRightsManagementQueryHandle.cs
- Thickness.cs
- ConfigurationPropertyCollection.cs
- PeerEndPoint.cs
- GroupItemAutomationPeer.cs
- AddressAlreadyInUseException.cs
- SingleConverter.cs
- WebPartZoneBase.cs
- ResourceWriter.cs
- SqlDataSourceCommandEventArgs.cs
- XmlElementAttributes.cs
- ToolStripItemDataObject.cs
- EditingCoordinator.cs
- MimeTypeMapper.cs
- ProxyHelper.cs
- EpmCustomContentSerializer.cs
- ComAdminInterfaces.cs
- MenuRenderer.cs
- ThreadStartException.cs
- GenericUI.cs
- Rijndael.cs
- Timer.cs
- OdbcErrorCollection.cs
- LineSegment.cs
- URL.cs
- PageThemeCodeDomTreeGenerator.cs
- MultiDataTrigger.cs
- DialogResultConverter.cs
- _NetRes.cs
- ISessionStateStore.cs
- PackageProperties.cs
- UnmanagedMarshal.cs
- ManifestSignedXml.cs
- PreservationFileWriter.cs
- _OSSOCK.cs
- RtfToXamlLexer.cs
- Int64AnimationUsingKeyFrames.cs
- ChangeInterceptorAttribute.cs
- CodeIdentifiers.cs
- JpegBitmapEncoder.cs
- SessionEndedEventArgs.cs
- BuilderPropertyEntry.cs
- DataGridViewCheckBoxColumn.cs
- ResumeStoryboard.cs
- KeyedCollection.cs
- MissingSatelliteAssemblyException.cs
- ClientSection.cs
- TileBrush.cs
- CollectionChangeEventArgs.cs
- RetriableClipboard.cs
- MenuAdapter.cs
- PageCodeDomTreeGenerator.cs
- shaperfactory.cs
- XmlSchemaExternal.cs
- ExpressionCopier.cs
- WCFModelStrings.Designer.cs
- ListBindingConverter.cs
- HostedHttpContext.cs
- HyperLinkStyle.cs
- AppDomain.cs
- DefaultObjectMappingItemCollection.cs
- MemberInfoSerializationHolder.cs
- BackgroundFormatInfo.cs
- ResizeBehavior.cs
- DrawingContextDrawingContextWalker.cs
- WebPartCloseVerb.cs
- TextBox.cs
- DataGridCaption.cs
- SplitterDesigner.cs
- PagePropertiesChangingEventArgs.cs
- CopyOnWriteList.cs
- ClientSettings.cs
- TextSelectionHelper.cs
- XPathEmptyIterator.cs