public DynamicallyAccessedMemberTypes GetGenericParameterAnnotation(GenericParameterDesc genericParameter) { if (genericParameter is not EcmaGenericParameter ecmaGenericParameter) { return(DynamicallyAccessedMemberTypes.None); } GenericParameter paramDef = ecmaGenericParameter.MetadataReader.GetGenericParameter(ecmaGenericParameter.Handle); if (ecmaGenericParameter.Kind == GenericParameterKind.Type) { TypeDesc parent = ecmaGenericParameter.Module.GetType(paramDef.Parent); if (GetAnnotations(parent).TryGetAnnotation(ecmaGenericParameter, out var annotation)) { return(annotation); } } else { Debug.Assert(ecmaGenericParameter.Kind == GenericParameterKind.Method); MethodDesc parent = ecmaGenericParameter.Module.GetMethod(paramDef.Parent); if (GetAnnotations(parent.OwningType).TryGetAnnotation(parent, out var methodAnnotation) && methodAnnotation.TryGetAnnotation(genericParameter, out var annotation)) { return(annotation); } } return(DynamicallyAccessedMemberTypes.None); }
public override void AppendName(StringBuilder sb, GenericParameterDesc type) { string prefix = type.Kind == GenericParameterKind.Type ? "!" : "!!"; sb.Append(prefix); sb.Append(type.Name); }
private bool ComputeInstantiationVersionsWithCode(Instantiation inst, TypeSystemEntity entityWithInstantiation) { for (int iInstantiation = 0; iInstantiation < inst.Length; iInstantiation++) { TypeDesc instType = inst[iInstantiation]; if (!ComputeInstantiationTypeVersionsWithCode(this, instType)) { if (instType.IsPrimitive || instType.IsObject || instType.IsString) { // Primitive type instantiations are only instantiated in the module of the generic defining type // if the generic does not apply interface constraints to that type parameter, or if System.Private.CoreLib is part of the version bubble Instantiation entityDefinitionInstantiation; if (entityWithInstantiation is TypeDesc type) { entityDefinitionInstantiation = type.GetTypeDefinition().Instantiation; } else { entityDefinitionInstantiation = ((MethodDesc)entityWithInstantiation).GetTypicalMethodDefinition().Instantiation; } GenericParameterDesc genericParam = (GenericParameterDesc)entityDefinitionInstantiation[iInstantiation]; if (instType.IsPrimitive) { if (genericParam.HasReferenceTypeConstraint) { return(false); } } else { Debug.Assert(instType.IsString || instType.IsObject); if (genericParam.HasNotNullableValueTypeConstraint) { return(false); } if (instType.IsString && genericParam.HasDefaultConstructorConstraint) { return(false); } } // This checks to see if the type constraints list is empty if (genericParam.TypeConstraints.GetEnumerator().MoveNext()) { return(false); } } else { // Non-primitive which doesn't version with type implies instantiation doesn't version with type return(false); } } } return(true);
internal NativeLayoutTypeSignatureVertexNode TypeSignatureVertex(TypeDesc type) { if (type.IsRuntimeDeterminedType) { GenericParameterDesc genericParameter = ((RuntimeDeterminedType)type).RuntimeDeterminedDetailsType; type = _factory.TypeSystemContext.GetSignatureVariable(genericParameter.Index, method: (genericParameter.Kind == GenericParameterKind.Method)); } return(_typeSignatures.GetOrAdd(type)); }
public bool RequiresGenericArgumentDataFlowAnalysis(GenericParameterDesc genericParameter) { try { return(GetGenericParameterAnnotation(genericParameter) != DynamicallyAccessedMemberTypes.None); } catch (TypeSystemException) { return(false); } }
private static Instantiation GetInstantiationThatMeetsConstraints(Instantiation definition) { TypeDesc[] args = new TypeDesc[definition.Length]; for (int i = 0; i < definition.Length; i++) { GenericParameterDesc genericParameter = (GenericParameterDesc)definition[i]; // If the parameter is not constrained to be a valuetype, we can instantiate over __Canon if (genericParameter.HasNotNullableValueTypeConstraint) { return(default);
internal NativeLayoutTypeSignatureVertexNode TypeSignatureVertex(TypeDesc type) { if (type.IsRuntimeDeterminedType) { GenericParameterDesc genericParameter = ((RuntimeDeterminedType)type).RuntimeDeterminedDetailsType; type = _factory.TypeSystemContext.GetSignatureVariable(genericParameter.Index, method: (genericParameter.Kind == GenericParameterKind.Method)); } if (type.Category == TypeFlags.FunctionPointer) { // Pretend for now it's an IntPtr, may need to be revisited depending on https://github.com/dotnet/runtime/issues/11354 type = _factory.TypeSystemContext.GetWellKnownType(WellKnownType.IntPtr); } return(_typeSignatures.GetOrAdd(type)); }
private static TypeDesc GetTypeThatMeetsConstraints(GenericParameterDesc genericParam) { TypeSystemContext context = genericParam.Context; // Universal canon is the best option if it's supported if (context.SupportsUniversalCanon) { return(context.UniversalCanonType); } // Try normal canon next if (!context.SupportsCanon) { return(null); } // Not nullable type is the only thing where reference canon doesn't make sense. GenericConstraints constraints = genericParam.Constraints; if ((constraints & GenericConstraints.NotNullableValueTypeConstraint) != 0) { return(null); } foreach (var c in genericParam.TypeConstraints) { // Could be e.g. "where T : U" // We could try to dig into the U and solve it, but that just opens us up to // recursion and it's just not worth it. if (c.IsSignatureVariable) { return(null); } if (!c.IsGCPointer) { return(null); } } return(genericParam.Context.CanonType); }
public override void AppendName(StringBuilder builder, GenericParameterDesc genericParameter) { // Is this a type parameter on a type? if (genericParameter.Kind == GenericParameterKind.Method) { builder.Append("``"); } else { Debug.Assert(genericParameter.Kind == GenericParameterKind.Type); // If the containing type is nested within other types. // e.g. A<T>.B<U>.M<V>(T t, U u, V v) should be M(`0, `1, ``0). // Roslyn needs to add generic arities of parents, but the innermost type redeclares // all generic parameters so we don't need to add them. builder.Append('`'); } builder.Append(genericParameter.Index); }
private static TypeDesc GetTypeThatMeetsConstraints(GenericParameterDesc genericParam, bool allowCanon) { TypeSystemContext context = genericParam.Context; // Universal canon is the best option if it's supported if (allowCanon && context.SupportsUniversalCanon) { return(context.UniversalCanonType); } // Not nullable type is the only thing where we can't substitute reference types GenericConstraints constraints = genericParam.Constraints; if ((constraints & GenericConstraints.NotNullableValueTypeConstraint) != 0) { return(null); } // If canon is allowed, we can use that if (allowCanon && context.SupportsCanon) { foreach (var c in genericParam.TypeConstraints) { // Could be e.g. "where T : U" // We could try to dig into the U and solve it, but that just opens us up to // recursion and it's just not worth it. if (c.IsSignatureVariable) { return(null); } if (!c.IsGCPointer) { return(null); } } return(genericParam.Context.CanonType); } // If canon is not allowed, we're limited in our choices. TypeDesc constrainedType = null; foreach (var c in genericParam.TypeConstraints) { // Can't do multiple constraints if (constrainedType != null) { return(null); } // Could be e.g. "where T : IFoo<U>" or "where T : U" if (c.ContainsSignatureVariables()) { return(null); } constrainedType = c; } return(constrainedType ?? genericParam.Context.GetWellKnownType(WellKnownType.Object)); }
private static void ReportErrorMakingInstantiation(DTypeDesc.MakeGenericArgumentsResult/*!*/ error, DTypeDesc/*!*/ genericType, DTypeDesc argument, GenericParameterDesc/*!*/ parameter) { switch (error) { case DTypeDesc.MakeGenericArgumentsResult.IncompatibleConstraint: PhpException.Throw(PhpError.Error, CoreResources.GetString("incompatible_type_parameter_constraints_type", argument.MakeFullName(), parameter.RealType.GenericParameterPosition, parameter.RealType.Name)); break; case DTypeDesc.MakeGenericArgumentsResult.MissingArgument: PhpException.Throw(PhpError.Error, CoreResources.GetString("missing_type_argument_in_type_use", genericType.MakeFullName(), parameter.RealType.GenericParameterPosition, parameter.RealType.Name)); break; case DTypeDesc.MakeGenericArgumentsResult.TooManyArguments: PhpException.Throw(PhpError.Warning, CoreResources.GetString("too_many_type_arguments_in_type_use", genericType.MakeFullName(), genericType.GenericParameters.Length)); break; } }
public override void AppendName(StringBuilder sb, GenericParameterDesc type) { sb.Append(type.Name); }
private static TypeDesc GetTypeThatMeetsConstraints(GenericParameterDesc genericParam, bool allowCanon) { TypeSystemContext context = genericParam.Context; // Universal canon is the best option if it's supported if (allowCanon && context.SupportsUniversalCanon) { return(context.UniversalCanonType); } // Not nullable type is the only thing where we can't substitute reference types GenericConstraints constraints = genericParam.Constraints; if ((constraints & GenericConstraints.NotNullableValueTypeConstraint) != 0) { return(null); } // If canon is allowed, we can use that if (allowCanon && context.SupportsCanon) { foreach (var c in genericParam.TypeConstraints) { // Could be e.g. "where T : U" // We could try to dig into the U and solve it, but that just opens us up to // recursion and it's just not worth it. if (c.IsSignatureVariable) { return(null); } if (!c.IsGCPointer) { return(null); } } return(genericParam.Context.CanonType); } // If canon is not allowed, we're limited in our choices. TypeDesc constrainedType = null; foreach (var c in genericParam.TypeConstraints) { // Can't do multiple constraints if (constrainedType != null) { return(null); } // Could be e.g. "where T : IFoo<U>" or "where T : U" if (c.ContainsSignatureVariables()) { return(null); } // If there's unimplemented static abstract methods, this is not a suitable instantiation. // We shortcut to look for any static virtuals. It matches what Roslyn does for error CS8920. // Once TypeSystemConstraintsHelpers is updated to check constraints around static virtuals, // we could dispatch there instead. if (c.IsInterface) { if (HasStaticVirtualMethods(c)) { return(null); } foreach (DefType intface in c.RuntimeInterfaces) { if (HasStaticVirtualMethods(intface)) { return(null); } }
public GenericParameterOrigin(GenericParameterDesc genericParam) { GenericParameter = genericParam; }
private GenericParameterDesc[]/*!!*/ ToGenericParameters(DMember/*!*/ declaringMember, out int mandatoryCount) { Debug.Assert(declaringMember != null); if (typeParams.Count == 0) { mandatoryCount = 0; return GenericParameterDesc.EmptyArray; } GenericParameterDesc[] result = new GenericParameterDesc[typeParams.Count]; mandatoryCount = 0; for (int i = 0; i < typeParams.Count; i++) { result[i] = new GenericParameter(typeParams[i].Name, i, declaringMember).GenericParameterDesc; if (typeParams[i].DefaultType == null) mandatoryCount++; } return result; }
public GenericParameterProxy(GenericParameterDesc genericParameter) => GenericParameter = genericParameter;