/// <summary> /// Copies the value of all fields from one <see cref="object"/> to another. /// </summary> internal static void CopyTo <T>(this T from, T to) where T : class { // Find base type of both compilations TypeInfo fromType = from.GetType().GetTypeInfo(); TypeInfo toType = to.GetType().GetTypeInfo(); Type baseType; if (fromType.IsAssignableFrom(toType)) { // ToCompilation inherits FromCompilation baseType = fromType.AsType(); } else if (toType.IsAssignableFrom(fromType)) { // FromCompilation inherits ToCompilation baseType = toType.AsType(); } else { // No common type: find first common type baseType = FindCommonType(fromType.AsType(), toType.AsType()); } // Copy fields from one compilation to the other foreach (FieldInfo field in baseType.GetAllFields()) { if (field.IsStatic) { continue; } field.SetValue(to, field.GetValue(from)); } }
public IEnumerable<TypeInfo> FindTypes(IEnumerable<Assembly> targetAssmblies, TypeInfo targetTypeInfo) { var types = targetAssmblies .SelectMany(GetLoadableTypes) .Where(t => t.IsClass && !t.IsAbstract && !t.ContainsGenericParameters && targetTypeInfo.IsAssignableFrom(t)); return types; }
private static ImmutableDictionary <SyntaxKind, IDeclarationHandler> InitializeHandlerLookup() { System.Reflection.TypeInfo handlerTypeInfo = typeof(IDeclarationHandler).GetTypeInfo(); System.Reflection.TypeInfo containerTypeInfo = typeof(DeclarationHandlers).GetTypeInfo(); System.Reflection.TypeInfo[] handlerTypes = containerTypeInfo.DeclaredNestedTypes .Where(t => handlerTypeInfo.IsAssignableFrom(t)) .ToArray(); return(handlerTypes .Select(t => Activator.CreateInstance(t.AsType()) as IDeclarationHandler) .ToImmutableDictionary(handler => handler.Kind)); }
private bool ArePropertyValuesEqual([NotNull] PropertyInfo property, [NotNull] object left, [NotNull] object right) { object leftValue = property.GetMethod.Invoke(left, Array.Empty <object>()); object rightValue = property.GetMethod.Invoke(right, Array.Empty <object>()); if (EnumerableInterface.IsAssignableFrom(property.PropertyType.GetTypeInfo())) { Type elementType = property.PropertyType.GetSequenceElementType(); return(AreOptionalSequenceValuesEqual(elementType, (IEnumerable)leftValue, (IEnumerable)rightValue)); } return(AreValuesEqual(property.PropertyType, leftValue, rightValue)); }
private bool AreValuesEqual([NotNull] Type type, [CanBeNull] object leftValue, [CanBeNull] object rightValue) { if (SymbolInterface.IsAssignableFrom(type.GetTypeInfo())) { var leftSymbol = (ISymbol)leftValue; var rightSymbol = (ISymbol)rightValue; return(leftSymbol.IsEqualTo(rightSymbol)); } if (OperationInterface.IsAssignableFrom(type.GetTypeInfo())) { return(Equals((IOperation)leftValue, (IOperation)rightValue)); } return(EqualityComparer <object> .Default.Equals(leftValue, rightValue)); }
/// <summary> /// Clears the change list for certain objects /// </summary> public void ClearChanges(GameObject targetObj, TypeInfo cmpType, PropertyInfo prop) { if (this.changes == null || this.changes.Count == 0) return; IEnumerable<int> indexPath = targetObj != null ? this.obj.IndexPathOfChild(targetObj) : null; for (int i = this.changes.Count - 1; i >= 0; i--) { if (indexPath != null && !this.changes[i].childIndex.SequenceEqual(indexPath)) continue; if (cmpType != null && !cmpType.IsAssignableFrom(this.changes[i].componentType.GetTypeInfo())) continue; if (prop != null && prop != this.changes[i].prop) continue; this.changes.RemoveAt(i); } }
/// <summary> /// Tries to get the part builder. /// </summary> /// <param name="serviceContractMetadata">The service contract metadata.</param> /// <param name="serviceContract">The service contract.</param> /// <param name="conventions">The conventions.</param> /// <param name="typeInfos">The type infos.</param> /// <returns> /// The part builder or <c>null</c>. /// </returns> private IPartConventionsBuilder TryGetPartBuilder( AppServiceContractAttribute serviceContractMetadata, TypeInfo serviceContract, IConventionsBuilder conventions, IEnumerable<TypeInfo> typeInfos) { var serviceContractType = serviceContract.AsType(); if (serviceContract.IsGenericTypeDefinition) { // if there is non-generic service contract with the same full name // then add just the conventions for the derived types. return conventions.ForTypesMatching(t => this.MatchOpenGenericContractType(t, serviceContractType)); } if (serviceContractMetadata.AllowMultiple) { // if the service contract metadata allows multiple service registrations // then add just the conventions for the derived types. return conventions.ForTypesDerivedFrom(serviceContractType); } var parts = typeInfos.Where( ti => serviceContract.IsAssignableFrom(ti) && ti.IsClass && !ti.IsAbstract && ti.GetCustomAttribute<ExcludeFromCompositionAttribute>() == null).ToList(); if (parts.Count == 1) { return conventions.ForType(parts[0].AsType()); } if (parts.Count > 1) { var overrideChain = parts.ToDictionary( ti => ti, ti => ti.GetCustomAttribute<OverridePriorityAttribute>() ?? new OverridePriorityAttribute(Priority.Normal)) .OrderBy(item => item.Value.Value) .ToList(); var selectedPart = overrideChain[0].Key; if (overrideChain[0].Value.Value == overrideChain[1].Value.Value) { throw new InvalidOperationException( string.Format( Strings.AmbiguousOverrideForAppServiceContract, serviceContract, selectedPart, string.Join(", ", overrideChain.Select(item => item.Key.ToString() + ":" + item.Value.Value)))); } return conventions.ForType(selectedPart.AsType()); } return null; }
/// <summary> /// Determines whether an instance of the current Type can be assigned from an instance of the specified Type. /// </summary> /// <param name="type">Type on which to perform lookup</param> /// <param name="c">The type to compare with the current type. </param> /// <returns>true if c and the current Type represent the same type, or if the current Type is in the inheritance hierarchy of c, or if the current Type is an interface that c implements, or if c is a generic type parameter and the current Type represents one of the constraints of c, or if c represents a value type and the current Type represents Nullable<c> (Nullable(Of c) in Visual Basic). false if none of these conditions are true, or if c is null.</returns> public static bool IsAssignableFrom(this Type type, Type c) { TypeInfo typeInfo = GetTypeInfoOrThrow(type); return(c != null && typeInfo.IsAssignableFrom(GetTypeInfoOrThrow(c, "c"))); }
private void VisitSymbol(ISymbol symbol) { // Only check methods if (!(symbol is IMethodSymbol method)) { return; } // Find Invoke attribute var attr = method.GetAttributes().FirstOrDefault(x => x.AttributeClass.Name == nameof(InvokeAttribute)); if (attr == null) { // No attribute found, return return; } // We have the attribute, find its matching method var info = method.GetCorrespondingMethod() as MethodInfo; if (info == null) { ReportWarning("Cannot invoke given method", symbol.Locations[0]); return; } // Check method if (!method.IsStatic) { throw new DiagnosticException("A compile-time function must be static.", symbol.Locations[0]); } if (method.IsAbstract) { throw new DiagnosticException("A compile-time function cannot be abstract.", symbol.Locations[0]); } if (method.ReturnType.MetadataName != "Void") { ReportWarning("A compile-time function should return void.", symbol.Locations[0]); } // Populate args ParameterInfo[] parameters = info.GetParameters(); object[] arguments = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { ParameterInfo parameter = parameters[i]; TypeInfo parameterType = parameter.ParameterType.GetTypeInfo(); if (parameterType.IsAssignableFrom(typeof(IMethodSymbol).GetTypeInfo())) { arguments[i] = method; } else if (parameterType.IsAssignableFrom(typeof(MethodInfo).GetTypeInfo())) { arguments[i] = info; } else if (parameter.ParameterType.IsAssignableFrom(typeof(ITypeSymbol))) { arguments[i] = symbol.ContainingType; } else if (parameter.ParameterType == typeof(TypeInfo)) { arguments[i] = info.DeclaringType.GetTypeInfo(); } else if (parameter.ParameterType == typeof(Type)) { arguments[i] = info.DeclaringType; } } // Invoke and return try { info.Invoke(null, arguments); } catch (Exception e) { ReportError(e.Message, symbol.Locations[0]); } }
private static void Convert(ILGenerator il, Type source, Type target, bool isAddress) { Debug.Assert(!target.IsByRef); if (target == source) { return; } TypeInfo sourceTypeInfo = source.GetTypeInfo(); TypeInfo targetTypeInfo = target.GetTypeInfo(); if (source.IsByRef) { Debug.Assert(!isAddress); Type argType = source.GetElementType(); Ldind(il, argType); Convert(il, argType, target, isAddress); return; } if (targetTypeInfo.IsValueType) { if (sourceTypeInfo.IsValueType) { OpCode opCode = s_convOpCodes[GetTypeCode(target)]; Debug.Assert(!opCode.Equals(OpCodes.Nop)); il.Emit(opCode); } else { Debug.Assert(sourceTypeInfo.IsAssignableFrom(targetTypeInfo)); il.Emit(OpCodes.Unbox, target); if (!isAddress) { Ldind(il, target); } } } else if (targetTypeInfo.IsAssignableFrom(sourceTypeInfo)) { if (sourceTypeInfo.IsValueType) { if (isAddress) { Ldind(il, source); } il.Emit(OpCodes.Box, source); } } else { Debug.Assert(sourceTypeInfo.IsAssignableFrom(targetTypeInfo) || targetTypeInfo.IsInterface || sourceTypeInfo.IsInterface); if (target.IsGenericParameter) { // T GetProperty<T>() where T : class; Debug.Assert(targetTypeInfo.GenericParameterAttributes == GenericParameterAttributes.ReferenceTypeConstraint); il.Emit(OpCodes.Unbox_Any, target); } else { il.Emit(OpCodes.Castclass, target); } } }
private static void CheckInstanceExportCompatibility(TypeInfo partType, TypeInfo contractType) { if (partType.IsGenericTypeDefinition) { CheckGenericContractCompatibility(partType, partType, contractType); } else if (!contractType.IsAssignableFrom(partType)) { var message = string.Format(Properties.Resources.TypeInspector_ContractNotAssignable, contractType.Name, partType.Name); throw new CompositionFailedException(message); } }
/// <summary> /// Checks whether the part type matches the type of the open generic contract. /// </summary> /// <param name="partTypeInfo">Type of the part.</param> /// <param name="serviceContract">Type of the service contract.</param> /// <returns><c>true</c> if the part type matches the type of the generic contract, otherwise <c>false</c>.</returns> private bool MatchDerivedFromContractType(TypeInfo partTypeInfo, TypeInfo serviceContract) { if (!this.IsEligiblePart(partTypeInfo) || partTypeInfo.IsGenericTypeDefinition) { return false; } return serviceContract.IsAssignableFrom(partTypeInfo); }
private static IDictionary<Type, Type> MatchTypesByGenerics(Type[] types, TypeInfo genericTypeDefinition, TypeInfo baseTypeDefinition) { return types .Where(t => t.GetTypeInfo().IsClass && baseTypeDefinition.IsAssignableFrom(t.GetTypeInfo())).ToArray() .ToDictionary(x => genericTypeDefinition.MakeGenericType(x), x => { var genericTypeBase = genericTypeDefinition.MakeGenericType(x); var result = types.Where(t => genericTypeBase.GetTypeInfo().IsAssignableFrom(t.GetTypeInfo())).ToArray(); if (result.Length > 1) throw new AmbiguousMatchException($"Ambiguous match found for {x.FullName}: {String.Join(", ", result.Select(t => t.FullName))}"); return result.FirstOrDefault(); }); }
private static IDictionary<Type, Type> MatchTypes(Type[] types, TypeInfo baseTypeDefinition) { return types .Where(t => t.GetTypeInfo().IsInterface && baseTypeDefinition.IsAssignableFrom(t.GetTypeInfo())).ToArray() .ToDictionary(x => x, x => { var result = types.Where(t => (t != x) && x.GetTypeInfo().IsAssignableFrom(t.GetTypeInfo())).ToArray(); if (result.Length > 1) throw new AmbiguousMatchException($"Ambiguous match found for {x.FullName}: {String.Join(", ", result.Select(t => t.FullName))}"); return result.FirstOrDefault(); }); }