public TypeConversion(float quality, bool isNatural, MemberDescription implicitConversion = null, MemberDescription explicitConversion = null) { this.Quality = quality; this.IsNatural = isNatural; this.Implicit = implicitConversion; this.Explicit = explicitConversion; }
public TypeConversion Expand(MemberDescription implicitConversion, MemberDescription explicitConversion) { implicitConversion = implicitConversion ?? this.Implicit; explicitConversion = explicitConversion ?? this.Explicit; if (implicitConversion == this.Implicit && explicitConversion == this.Explicit) { return(this); } var newQuality = Math.Max(this.Quality, this.Implicit != null ? QUALITY_IMPLICIT_CONVERSION : QUALITY_EXPLICIT_CONVERSION); return(new TypeConversion(newQuality, this.IsNatural, implicitConversion, explicitConversion)); }
private MemberDescription[] GetOperators(List <MethodInfo> methods, MemberDescription[] methodsDescriptions, string operatorName, int?compareParameterIndex = null) { if (methods == null) { throw new ArgumentNullException("methods"); } if (methodsDescriptions == null) { throw new ArgumentNullException("methodsDescriptions"); } if (operatorName == null) { throw new ArgumentNullException("operatorName"); } var operators = default(List <MemberDescription>); for (var i = 0; i < methods.Count; i++) { var method = methods[i]; if (method.Name != operatorName) { continue; } if (methodsDescriptions[i] == null) { methodsDescriptions[i] = new MemberDescription(this, method); } var methodDescription = methodsDescriptions[i]; if (compareParameterIndex.HasValue && methodDescription.GetParameterType(compareParameterIndex.Value) != this.type) { continue; } if (operators == null) { operators = new List <MemberDescription>(); } operators.Add(new MemberDescription(this, method)); } return(operators != null?operators.ToArray() : EmptyMembers); }
private static bool TryMakeGenericMethod(ref MemberDescription methodDescription, Type[] typeArguments) { if (methodDescription == null) { throw new ArgumentNullException("methodDescription"); } try { if (typeArguments != null) { methodDescription = methodDescription.MakeGenericMethod(typeArguments); } Debug.Assert(methodDescription != null, "methodDescription != null"); return(true); } catch { return(false); } }
public bool TryResolveMember(object memberName, out MemberDescription member) { member = null; if (memberName is SyntaxTreeNode == false) { return(false); } var memberNode = (SyntaxTreeNode)memberName; var typeName = memberNode.GetTypeName(throwOnError: false); var type = default(Type); if (typeName == null || this.TryResolveType(typeName, out type) == false) { return(false); } var name = memberNode.GetName(throwOnError: false); var nameRef = default(TypeReference); if (name == null || TryGetTypeReference(name, out nameRef) == false) { return(false); } var genericArguments = default(Type[]); if (nameRef.IsGenericType) { genericArguments = new Type[nameRef.TypeArguments.Count]; for (var i = 0; i < genericArguments.Length; i++) { var typeArgument = nameRef.TypeArguments[i]; if (this.TryResolveType(typeArgument, out genericArguments[i]) == false) { return(false); } } } var typeDescription = TypeDescription.GetTypeDescription(type); var argumentNames = memberNode.GetArgumentNames(throwOnError: false); var members = nameRef.Name == ".ctor" ? typeDescription.Constructors : typeDescription.GetMembers(nameRef.Name); foreach (var declaredMember in members) { if ((declaredMember.IsMethod || declaredMember.IsConstructor) && argumentNames != null) { var paramsCount = declaredMember.GetParametersCount(); if (paramsCount != argumentNames.Count) { continue; } else if (paramsCount > 0) { for (var i = 0; i < paramsCount; i++) { var parameter = declaredMember.GetParameter(i); var parameterIndex = Constants.GetIndexAsString(parameter.Position); var argumentName = default(string); if (argumentNames.TryGetValue(parameterIndex, out argumentName) == false) { break; } if (string.Equals(argumentName, parameter.Name, StringComparison.OrdinalIgnoreCase) == false && string.Equals(argumentName, parameterIndex, StringComparison.OrdinalIgnoreCase) == false) { break; } if (i == paramsCount - 1) { member = declaredMember; return(TryMakeGenericMethod(ref member, genericArguments)); } } } else { member = declaredMember; return(TryMakeGenericMethod(ref member, genericArguments)); } } else if (nameRef.TypeArguments.Count == declaredMember.GenericArgumentsCount) { member = declaredMember; return(TryMakeGenericMethod(ref member, genericArguments)); } } return(false); }
public TypeDescription(Type type, TypeCache cache) { if (type == null) { throw new ArgumentNullException("type"); } if (cache == null) { throw new ArgumentNullException("cache"); } this.type = type; this.hashCode = type.GetHashCode(); this.Name = NameUtils.RemoveGenericSuffix(NameUtils.WriteName(type)).ToString(); cache.Add(type, this); var typeInfo = type.GetTypeInfo(); var underlyingType = default(Type); if (typeInfo.IsEnum) { underlyingType = Enum.GetUnderlyingType(type); } else if (typeInfo.IsValueType) { underlyingType = Nullable.GetUnderlyingType(type); } else if (typeInfo.IsArray) { underlyingType = typeInfo.GetElementType(); } this.BaseType = typeInfo.BaseType != null?cache.GetOrCreateTypeDescription(typeInfo.BaseType) : null; this.UnderlyingType = underlyingType != null?cache.GetOrCreateTypeDescription(underlyingType) : null; this.BaseTypes = GetBaseTypes(this, 0); this.Interfaces = typeInfo.GetImplementedInterfaces().Select(cache.GetOrCreateTypeDescription).ToArray(); this.GenericArguments = typeInfo.IsGenericType ? ArrayUtils.ConvertAll(typeInfo.GetGenericArguments(), cache.GetOrCreateTypeDescription) : EmptyTypes; this.IsInterface = typeInfo.IsInterface; this.IsValueType = typeInfo.IsValueType; this.IsNullable = Nullable.GetUnderlyingType(type) != null; this.IsNumber = NumberUtils.IsNumber(type); this.CanBeNull = this.IsNullable || typeInfo.IsValueType == false; this.IsEnum = typeInfo.IsEnum; this.IsVoid = type == typeof(void); this.IsDelegate = typeof(Delegate).GetTypeInfo().IsAssignableFrom(typeInfo) && type != typeof(Delegate) && type != typeof(MulticastDelegate); this.HasGenericParameters = typeInfo.ContainsGenericParameters; if (this.IsVoid) { this.DefaultExpression = Expression.Constant(null, typeof(object)); } else { this.DefaultExpression = Expression.Constant(typeInfo.IsValueType && this.IsNullable == false ? Activator.CreateInstance(type) : null, type); } this.TypeCode = ReflectionUtils.GetTypeCode(type); this.MembersByName = this.GetMembersByName(ref this.Indexers); var methods = typeInfo.GetAllMethods().Where(m => m.IsPublic && m.IsStatic).ToList(); var methodsDescriptions = new MemberDescription[methods.Count]; // ReSharper disable LocalizableElement this.ImplicitConvertTo = this.GetOperators(methods, methodsDescriptions, "op_Implicit", 0); this.ImplicitConvertFrom = this.GetOperators(methods, methodsDescriptions, "op_Implicit", -1); this.ExplicitConvertTo = this.GetOperators(methods, methodsDescriptions, "op_Explicit", 0); this.ExplicitConvertFrom = this.GetOperators(methods, methodsDescriptions, "op_Explicit", -1); this.Addition = this.GetOperators(methods, methodsDescriptions, "op_Addition"); this.Division = this.GetOperators(methods, methodsDescriptions, "op_Division"); this.Equality = this.GetOperators(methods, methodsDescriptions, "op_Equality"); this.GreaterThan = this.GetOperators(methods, methodsDescriptions, "op_GreaterThan"); this.GreaterThanOrEqual = this.GetOperators(methods, methodsDescriptions, "op_GreaterThanOrEqual"); this.Inequality = this.GetOperators(methods, methodsDescriptions, "op_Inequality"); this.LessThan = this.GetOperators(methods, methodsDescriptions, "op_LessThan"); this.LessThanOrEqual = this.GetOperators(methods, methodsDescriptions, "op_LessThanOrEqual"); this.Modulus = this.GetOperators(methods, methodsDescriptions, "op_Modulus"); this.Multiply = this.GetOperators(methods, methodsDescriptions, "op_Multiply"); this.Subtraction = this.GetOperators(methods, methodsDescriptions, "op_Subtraction"); this.UnaryNegation = this.GetOperators(methods, methodsDescriptions, "op_UnaryNegation"); this.UnaryPlus = this.GetOperators(methods, methodsDescriptions, "op_UnaryPlus"); this.BitwiseAnd = this.GetOperators(methods, methodsDescriptions, "op_BitwiseAnd"); this.BitwiseOr = this.GetOperators(methods, methodsDescriptions, "op_BitwiseOr"); // ReSharper restore LocalizableElement this.Conversions = Combine(this.ImplicitConvertTo, this.ImplicitConvertFrom, this.ExplicitConvertTo, this.ExplicitConvertFrom); this.Constructors = type.GetTypeInfo().GetPublicInstanceConstructors().Select(ctr => new MemberDescription(this, ctr)).ToArray(); Array.Sort(this.Conversions); Array.Sort(this.Constructors); if (this.IsNullable && this.UnderlyingType != null) { this.UnderlyingType.nullableType = this; } }
private Dictionary <string, MemberDescription[]> GetMembersByName(ref MemberDescription[] indexers) { var declaredMembers = GetDeclaredMembers(this.type); var memberSetsByName = new Dictionary <string, HashSet <MemberDescription> >((this.BaseType != null ? this.BaseType.MembersByName.Count : 0) + declaredMembers.Count); foreach (var member in declaredMembers) { var memberDescription = default(MemberDescription); var method = member as MethodInfo; var field = member as FieldInfo; var property = member as PropertyInfo; if (property != null) { memberDescription = new MemberDescription(this, property); if (memberDescription.GetParametersCount() != 0) { Add(ref indexers, memberDescription); } } else if (field != null) { memberDescription = new MemberDescription(this, field); } else if (method != null && method.IsSpecialName == false) { memberDescription = new MemberDescription(this, method); } if (memberDescription == null) { continue; } var members = default(HashSet <MemberDescription>); if (memberSetsByName.TryGetValue(memberDescription.Name, out members) == false) { memberSetsByName[memberDescription.Name] = members = new HashSet <MemberDescription>(); } members.Add(memberDescription); } if (this.BaseType != null) { foreach (var kv in this.BaseType.MembersByName) { var memberName = kv.Key; var memberList = kv.Value; var members = default(HashSet <MemberDescription>); if (memberSetsByName.TryGetValue(memberName, out members) == false) { memberSetsByName[memberName] = members = new HashSet <MemberDescription>(); } foreach (var member in memberList) { members.Add(member); } } } var membersByName = new Dictionary <string, MemberDescription[]>(memberSetsByName.Count, StringComparer.Ordinal); foreach (var kv in memberSetsByName) { var membersArray = kv.Value.ToArray(); Array.Sort(membersArray); membersByName.Add(kv.Key, membersArray); } return(membersByName); }