/// <summary> /// Gets whether reading/writing an element of accessType from the pointer /// is equivalent to reading/writing an element of the memoryType. /// </summary> /// <remarks> /// The access semantics may sligthly differ on read accesses of small integer types, /// due to zero extension vs. sign extension when the signs differ. /// </remarks> public static bool IsCompatibleTypeForMemoryAccess(IType memoryType, IType accessType) { memoryType = memoryType.AcceptVisitor(NormalizeTypeVisitor.TypeErasure); accessType = accessType.AcceptVisitor(NormalizeTypeVisitor.TypeErasure); if (memoryType.Equals(accessType)) { return(true); } // If the types are not equal, the access still might produce equal results in some cases: // 1) Both types are reference types if (memoryType.IsReferenceType == true && accessType.IsReferenceType == true) { return(true); } // 2) Both types are integer types of equal size StackType memoryStackType = memoryType.GetStackType(); StackType accessStackType = accessType.GetStackType(); if (memoryStackType == accessStackType && memoryStackType.IsIntegerType() && GetSize(memoryType) == GetSize(accessType)) { return(true); } // 3) Any of the types is unknown: we assume they are compatible. return(memoryType.Kind == TypeKind.Unknown || accessType.Kind == TypeKind.Unknown); }
public static bool Equals(IType a, IType b) { IType aType = a.AcceptVisitor(normalizationVisitor); IType bType = b.AcceptVisitor(normalizationVisitor); return(aType.Equals(bType)); }
static bool CompareTypes(IType a, IType b) { IType type1 = a.AcceptVisitor(normalizeTypeVisitor); IType type2 = b.AcceptVisitor(normalizeTypeVisitor); return(type1.Equals(type2)); }
public override IType VisitChildren(TypeVisitor visitor) { IType[] newElementTypes = null; for (int i = 0; i < ElementTypes.Length; i++) { IType type = ElementTypes[i]; var newType = type.AcceptVisitor(visitor); if (newType != type) { if (newElementTypes == null) { newElementTypes = ElementTypes.ToArray(); } newElementTypes[i] = newType; } } if (newElementTypes != null) { return(new TupleType(this.Compilation, newElementTypes.ToImmutableArray(), this.ElementNames, this.GetDefinition()?.ParentModule)); } else { return(this); } }
static object MapToNewContext(object val, ITypeResolveContext context) { IType type = val as IType; if (type != null) { return(type.AcceptVisitor(new MapTypeIntoNewContext(context))); } object[] arr = val as object[]; if (arr != null) { object[] newArr = new object[arr.Length]; bool modified = false; for (int i = 0; i < arr.Length; i++) { newArr[i] = MapToNewContext(arr[i], context); modified |= arr[i] != newArr[i]; } if (modified) { return(newArr); } } return(val); }
/// <summary> /// Converts a type definition, reference or specification into a string. This method is used by tree nodes and search results. /// </summary> public virtual string TypeToString(IType type, bool includeNamespace) { var visitor = new TypeToStringVisitor(includeNamespace); type.AcceptVisitor(visitor); return(visitor.ToString()); }
public static bool ContainsAnonymousType(this IType type) { var visitor = new ContainsAnonTypeVisitor(); type.AcceptVisitor(visitor); return(visitor.ContainsAnonType); }
static IType CreateInstantiatedGenericTypeInternal(IType type, IList <IReturnType> genericArguments, GenericTypeInstanceResolver parent) { // This method is now internal. The public one has been moved to ProjectDom, which take cares of caching // instantiated generic types. if (type is InstantiatedType) { return(type); } string name = GetInstantiatedTypeName(type.Name, genericArguments); GenericTypeInstanceResolver resolver = new GenericTypeInstanceResolver(type.SourceProjectDom); resolver.Parent = parent; if (genericArguments != null) { int j = genericArguments.Count - 1; IType curType = type; while (curType != null) { string fullTypeName = curType.DecoratedFullName; for (int i = curType.TypeParameters.Count - 1; i >= 0 && j >= 0; i--, j--) { resolver.Add(fullTypeName + "." + curType.TypeParameters [i].Name, genericArguments [j]); } curType = curType.DeclaringType; } } AddInnerTypes(resolver, type.DecoratedFullName, type, genericArguments); InstantiatedType result = (InstantiatedType)type.AcceptVisitor(resolver, type); if (result.typeParameters != null) { result.typeParameters.Clear(); } result.Name = name; result.SourceProjectDom = type.SourceProjectDom; result.Resolved = (type is DomType) ? ((DomType)type).Resolved : false; result.GenericParameters = genericArguments; result.UninstantiatedType = type; result.DeclaringType = type.DeclaringType; CreateInstantiatedSubtypes(result, type, genericArguments, resolver); Dictionary <string, IType> typeTable = new Dictionary <string, IType> (); Stack <IType> typeStack = new Stack <IType> (); typeStack.Push(result); while (typeStack.Count > 0) { IType cur = typeStack.Pop(); foreach (var inner in cur.InnerTypes) { typeStack.Push(inner); } var returnType = new DomReturnType(cur); typeTable [returnType.ToInvariantString()] = cur; } result.AcceptVisitor(new SeedVisitor(), typeTable); return(result); }
/// <summary> /// Gets the entity that owns the type parameters occurring in the specified type. /// If both class and method type parameters are present, the method is returned. /// Returns null if the specified type is closed. /// </summary> /// <seealso cref="IsOpen"/> static IEntity GetTypeParameterOwner(IType type) { if (type == null) throw new ArgumentNullException("type"); TypeClassificationVisitor v = new TypeClassificationVisitor(); type.AcceptVisitor(v); return v.typeParameterOwner; }
/// <summary> /// Gets whether the type is an open type (contains type parameters). /// </summary> /// <example> /// <code> /// class X<T> { /// List<T> open; /// X<X<T[]>> open; /// X<string> closed; /// int closed; /// } /// </code> /// </example> public static bool IsOpen(this IType type) { if (type == null) throw new ArgumentNullException("type"); TypeClassificationVisitor v = new TypeClassificationVisitor(); type.AcceptVisitor(v); return v.isOpen; }
/// <summary> /// Gets whether the type is an open type (contains type parameters). /// </summary> /// <example> /// <code> /// class X<T> { /// List<T> open; /// X<X<T[]>> open; /// X<string> closed; /// int closed; /// } /// </code> /// </example> public static bool IsOpen(this IType type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } TypeClassificationVisitor v = new TypeClassificationVisitor(); type.AcceptVisitor(v); return(v.isOpen); }
/// <summary> /// Gets the entity that owns the type parameters occurring in the specified type. /// If both class and method type parameters are present, the method is returned. /// Returns null if the specified type is closed. /// </summary> /// <seealso cref="IsOpen"/> static IEntity GetTypeParameterOwner(IType type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } TypeClassificationVisitor v = new TypeClassificationVisitor(); type.AcceptVisitor(v); return(v.typeParameterOwner); }
public override IType VisitChildren(TypeVisitor visitor) { var newElementType = elementType.AcceptVisitor(visitor); var newModifier = modifier.AcceptVisitor(visitor); if (newModifier != modifier || newElementType != elementType) { return(new ModifiedType(newModifier, newElementType, kind == TypeKind.ModReq)); } return(this); }
internal static IType Substitute(IType type, TypeVisitor substitution) { if (substitution == null) { return(type); } else { return(type.AcceptVisitor(substitution)); } }
internal static bool ValidateConstraints(ITypeParameter typeParameter, IType typeArgument, TypeVisitor substitution, CSharpConversions conversions) { switch (typeArgument.Kind) // void, null, and pointers cannot be used as type arguments { case TypeKind.Void: case TypeKind.Null: case TypeKind.Pointer: return(false); } if (typeParameter.HasReferenceTypeConstraint) { if (typeArgument.IsReferenceType != true) { return(false); } } if (typeParameter.HasValueTypeConstraint) { if (!NullableType.IsNonNullableValueType(typeArgument)) { return(false); } } if (typeParameter.HasDefaultConstructorConstraint) { ITypeDefinition def = typeArgument.GetDefinition(); if (def != null && def.IsAbstract) { return(false); } var ctors = typeArgument.GetConstructors( m => m.Parameters.Count == 0 && m.Accessibility == Accessibility.Public, GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions ); if (!ctors.Any()) { return(false); } } foreach (IType constraintType in typeParameter.DirectBaseTypes) { IType c = constraintType; if (substitution != null) { c = c.AcceptVisitor(substitution); } if (!conversions.IsConstraintConvertible(typeArgument, c)) { return(false); } } return(true); }
/// <summary> /// Imports a type into the debugger's type system, and into the current generic context. /// </summary> IType Import(IType type) { IType importedType = debuggerTypeSystem.Import(type); if (importedType != null) { return(importedType.AcceptVisitor(context.MethodInfo.Substitution)); } else { return(null); } }
public static ITypeReference Create(ITypeReference baseTypeReference, TypeVisitor substitution) { IType baseType = baseTypeReference as IType; if (baseType != null && substitution != null) { return(baseType.AcceptVisitor(substitution)); } else { return(new SubstitutionTypeReference(baseTypeReference, substitution)); } }
public IType GetValueType(ITypeResolveContext context) { CSharpResolver resolver = CreateResolver(context); IType type = expression.Resolve(resolver).Type; if (resolver.Context != context) { // Retrieve the equivalent type in the new resolve context. // E.g. if the constant is defined in a .NET 2.0 project, type might be Int32 from mscorlib 2.0. // However, the calling project might be a .NET 4.0 project, so we need to return Int32 from mscorlib 4.0. return(type.AcceptVisitor(new MapTypeIntoNewContext(context))); } return(type); }
public static IType CreateInstantiatedGenericTypeInternal(IType type, IList <IReturnType> genericArguments) { // This method is now internal. The public one has been moved to ProjectDom, which take cares of caching // instantiated generic types. if (type is InstantiatedType) { return(type); } string name = GetInstantiatedTypeName(type.Name, genericArguments); GenericTypeInstanceResolver resolver = new GenericTypeInstanceResolver(); if (genericArguments != null) { int j = genericArguments.Count - 1; IType curType = type; while (curType != null) { string fullTypeName = curType.DecoratedFullName; for (int i = curType.TypeParameters.Count - 1; i >= 0 && j >= 0; i--, j--) { resolver.Add(fullTypeName + "." + curType.TypeParameters[i].Name, genericArguments[j]); } curType = curType.DeclaringType; } } InstantiatedType result = (InstantiatedType)type.AcceptVisitor(resolver, type); if (result.typeParameters != null) { result.typeParameters.Clear(); } result.Name = name; result.SourceProjectDom = type.SourceProjectDom; result.Resolved = (type is DomType) ? ((DomType)type).Resolved : false; result.GenericParameters = genericArguments; result.UninstantiatedType = type; result.DeclaringType = type.DeclaringType; CreateInstantiatedSubtypes(result, type, genericArguments); return(result); }
public override IType VisitChildren(TypeVisitor visitor) { IType r = ReturnType.AcceptVisitor(visitor); // Keep ta == null as long as no elements changed, allocate the array only if necessary. IType[] pt = (r != ReturnType) ? new IType[ParameterTypes.Length] : null; for (int i = 0; i < ParameterTypes.Length; i++) { IType p = ParameterTypes[i].AcceptVisitor(visitor); if (p == null) { throw new NullReferenceException("TypeVisitor.Visit-method returned null"); } if (pt == null && p != ParameterTypes[i]) { // we found a difference, so we need to allocate the array pt = new IType[ParameterTypes.Length]; for (int j = 0; j < i; j++) { pt[j] = ParameterTypes[j]; } } if (pt != null) { pt[i] = p; } } if (pt == null) { return(this); } else { return(new FunctionPointerType( module, CallingConvention, r, ReturnIsRefReadOnly, pt != null ? pt.ToImmutableArray() : ParameterTypes, ParameterReferenceKinds)); } }
public static MethodBuilder Compile(IType functorType, string variableName, TypeBuilder utilityClass, string[] genericParameters, IRuntimeContainer runtimeContainer) { var genericParameterNames = new[] { Constants.FMapMethodInputParameterName, Constants.FMapMethodOutputParameterName }.Concat(genericParameters).ToArray(); var fmap = utilityClass.DefineMethod(Constants.FMapMethodName, MethodAttributes.Public | MethodAttributes.Static); var fmapParameters = fmap.DefineGenericParameters(genericParameterNames); fmap.SetReturnType(typeof(IFunction<,>).MakeGenericType(fmapParameters.Take(2).Select(t => FunctorTypeMapper.Map(functorType, variableName, t, fmapParameters, runtimeContainer)).ToArray())); fmap.SetParameters(typeof(IFunction<,>).MakeGenericType(fmapParameters.Take(2).ToArray())); var fmapBody = fmap.GetILGenerator(); functorType.AcceptVisitor(new FmapCompiler(fmapBody, variableName, fmapParameters, runtimeContainer)); fmapBody.Emit(OpCodes.Ret); return fmap; }
public IType VisitChildren(TypeVisitor visitor) { IType g = genericType.AcceptVisitor(visitor); // Keep ta == null as long as no elements changed, allocate the array only if necessary. IType[] ta = (g != genericType) ? new IType[typeArguments.Length] : null; for (int i = 0; i < typeArguments.Length; i++) { IType r = typeArguments[i].AcceptVisitor(visitor); if (r == null) { throw new NullReferenceException("TypeVisitor.Visit-method returned null"); } if (ta == null && r != typeArguments[i]) { // we found a difference, so we need to allocate the array ta = new IType[typeArguments.Length]; for (int j = 0; j < i; j++) { ta[j] = typeArguments[j]; } } if (ta != null) { ta[i] = r; } } if (ta == null) { return(this); } else { return(new ParameterizedType(g, ta ?? typeArguments)); } }
/// <summary> /// Replaces all occurrences of method type parameters in the given type /// by normalized type parameters. This allows comparing parameter types from different /// generic methods. /// </summary> public IType NormalizeMethodTypeParameters(IType type) { return(type.AcceptVisitor(normalization)); }
void MakeOutputTypeInference(ResolveResult e, IType t) { Log.WriteLine(" MakeOutputTypeInference from " + e + " to " + t); // If E is an anonymous function with inferred return type U (§7.5.2.12) and T is a delegate type or expression // tree type with return type Tb, then a lower-bound inference (§7.5.2.9) is made from U to Tb. LambdaResolveResult lrr = e as LambdaResolveResult; if (lrr != null) { IMethod m = GetDelegateOrExpressionTreeSignature(t); if (m != null) { IType inferredReturnType; if (lrr.IsImplicitlyTyped) { if (m.Parameters.Count != lrr.Parameters.Count) { return; // cannot infer due to mismatched parameter lists } TypeParameterSubstitution substitution = GetSubstitutionForFixedTPs(); IType[] inferredParameterTypes = new IType[m.Parameters.Count]; for (int i = 0; i < inferredParameterTypes.Length; i++) { IType parameterType = m.Parameters[i].Type; inferredParameterTypes[i] = parameterType.AcceptVisitor(substitution); } inferredReturnType = lrr.GetInferredReturnType(inferredParameterTypes); } else { inferredReturnType = lrr.GetInferredReturnType(null); } MakeLowerBoundInference(inferredReturnType, m.ReturnType); return; } } // Otherwise, if E is a method group and T is a delegate type or expression tree type // with parameter types T1…Tk and return type Tb, and overload resolution // of E with the types T1…Tk yields a single method with return type U, then a lower-bound // inference is made from U to Tb. MethodGroupResolveResult mgrr = e as MethodGroupResolveResult; if (mgrr != null) { IMethod m = GetDelegateOrExpressionTreeSignature(t); if (m != null) { ResolveResult[] args = new ResolveResult[m.Parameters.Count]; TypeParameterSubstitution substitution = GetSubstitutionForFixedTPs(); for (int i = 0; i < args.Length; i++) { IParameter param = m.Parameters[i]; IType parameterType = param.Type.AcceptVisitor(substitution); if ((param.IsRef || param.IsOut) && parameterType.Kind == TypeKind.ByReference) { parameterType = ((ByReferenceType)parameterType).ElementType; args[i] = new ByReferenceResolveResult(parameterType, param.IsOut); } else { args[i] = new ResolveResult(parameterType); } } var or = mgrr.PerformOverloadResolution(compilation, args, allowExpandingParams: false, allowOptionalParameters: false); if (or.FoundApplicableCandidate && or.BestCandidateAmbiguousWith == null) { IType returnType = or.GetBestCandidateWithSubstitutedTypeArguments().ReturnType; MakeLowerBoundInference(returnType, m.ReturnType); } } return; } // Otherwise, if E is an expression with type U, then a lower-bound inference is made from U to T. if (IsValidType(e.Type)) { MakeLowerBoundInference(e.Type, t); } }
/// <summary> /// Gets whether there is an identity conversion from <paramref name="fromType"/> to <paramref name="toType"/> /// </summary> public bool IdentityConversion(IType fromType, IType toType) { // C# 4.0 spec: §6.1.1 return(fromType.AcceptVisitor(dynamicErasure).Equals(toType.AcceptVisitor(dynamicErasure))); }
internal static IType Substitute(IType type, TypeVisitor substitution) { if (substitution == null) return type; else return type.AcceptVisitor(substitution); }
/// <summary> /// Replaces all occurrences of method type parameters in the given type /// by normalized type parameters. This allows comparing parameter types from different /// generic methods. /// </summary> public static IType NormalizeMethodTypeParameters(IType type) { return type.AcceptVisitor(normalizeMethodTypeParameters); }
void AddRelationshipsForType(NodeBase node, IType type) { type.AcceptVisitor(new AnalysisTypeVisitor(this, node)); }
/// <summary> /// Substitutes the class type parameters in the <paramref name="type"/> with the /// type arguments of this parameterized type. /// </summary> public IType SubstituteInType(IType type) { return type.AcceptVisitor(new Substitution(typeArguments)); }
/// <summary> /// Substitutes the class type parameters in the <paramref name="type"/> with the /// type arguments of this parameterized type. /// </summary> public IType SubstituteInType(IType type) { return(type.AcceptVisitor(new TypeParameterSubstitution(typeArguments, null))); }
/// <summary> /// Substitutes the class type parameters in the <paramref name="type"/> with the /// type arguments of this parameterized type. /// </summary> public IType SubstituteInType(IType type) { return(type.AcceptVisitor(new Substitution(typeArguments))); }
/// <summary> /// Replaces all occurrences of class and method type parameters in the given type /// by normalized type parameters. This allows comparing parameter types from different /// generic methods. /// </summary> public static IType NormalizeAllTypeParameters(IType type) { return(type.AcceptVisitor(normalizeClassTypeParameters).AcceptVisitor(normalizeMethodTypeParameters)); }
public bool EquivalentTypes(IType a, IType b) { a = a.AcceptVisitor(this); b = b.AcceptVisitor(this); return(a.Equals(b)); }
public static IType ApplyAttributesToType( IType inputType, ICompilation compilation, SRM.CustomAttributeHandleCollection?attributes, SRM.MetadataReader metadata, TypeSystemOptions options, bool typeChildrenOnly = false) { bool useDynamicType = (options & TypeSystemOptions.Dynamic) != 0; bool useTupleTypes = (options & TypeSystemOptions.Tuple) != 0; bool hasDynamicAttribute = false; bool[] dynamicAttributeData = null; string[] tupleElementNames = null; if (attributes != null && (useDynamicType || useTupleTypes)) { foreach (var attrHandle in attributes.Value) { var attr = metadata.GetCustomAttribute(attrHandle); var attrType = attr.GetAttributeType(metadata); if (useDynamicType && attrType.IsKnownType(metadata, KnownAttribute.Dynamic)) { hasDynamicAttribute = true; var ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider); if (ctor.FixedArguments.Length == 1) { var arg = ctor.FixedArguments[0]; if (arg.Value is ImmutableArray <SRM.CustomAttributeTypedArgument <IType> > values && values.All(v => v.Value is bool)) { dynamicAttributeData = values.SelectArray(v => (bool)v.Value); } } } else if (useTupleTypes && attrType.IsKnownType(metadata, KnownAttribute.TupleElementNames)) { var ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider); if (ctor.FixedArguments.Length == 1) { var arg = ctor.FixedArguments[0]; if (arg.Value is ImmutableArray <SRM.CustomAttributeTypedArgument <IType> > values && values.All(v => v.Value is string || v.Value == null)) { tupleElementNames = values.SelectArray(v => (string)v.Value); } } } } } if (hasDynamicAttribute || (options & (TypeSystemOptions.Tuple | TypeSystemOptions.KeepModifiers)) != TypeSystemOptions.KeepModifiers) { var visitor = new ApplyAttributeTypeVisitor( compilation, hasDynamicAttribute, dynamicAttributeData, options, tupleElementNames ); if (typeChildrenOnly) { return(inputType.VisitChildren(visitor)); } else { return(inputType.AcceptVisitor(visitor)); } } else { return(inputType); } }
/// <summary> /// Substitutes the class type parameters in the <paramref name="type"/> with the /// type arguments of this parameterized type. /// </summary> public IType SubstituteInType(IType type) { return type.AcceptVisitor(new TypeParameterSubstitution(typeArguments, null)); }
public override IType VisitOtherType(IType type) { return NullableType.Create(compilation, type.AcceptVisitor(typeParameterSubstitution)); }
/// <summary> /// Gets whether there is an identity conversion from <paramref name="fromType"/> to <paramref name="toType"/> /// </summary> public bool IdentityConversion(IType fromType, IType toType) { // C# 4.0 spec: §6.1.1 return fromType.AcceptVisitor(dynamicErasure).Equals(toType.AcceptVisitor(dynamicErasure)); }