예제 #1
0
        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);
        }
예제 #2
0
            public override void AppendName(StringBuilder sb, GenericParameterDesc type)
            {
                string prefix = type.Kind == GenericParameterKind.Type ? "!" : "!!";

                sb.Append(prefix);
                sb.Append(type.Name);
            }
예제 #3
0
        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));
            }
예제 #5
0
 public bool RequiresGenericArgumentDataFlowAnalysis(GenericParameterDesc genericParameter)
 {
     try
     {
         return(GetGenericParameterAnnotation(genericParameter) != DynamicallyAccessedMemberTypes.None);
     }
     catch (TypeSystemException)
     {
         return(false);
     }
 }
예제 #6
0
        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);
예제 #7
0
            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));
            }
예제 #8
0
        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);
        }
예제 #9
0
            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);
            }
예제 #10
0
        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));
        }
예제 #11
0
        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;
            }
        }
예제 #12
0
 public override void AppendName(StringBuilder sb, GenericParameterDesc type)
 {
     sb.Append(type.Name);
 }
예제 #13
0
        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);
                        }
                    }
예제 #14
0
파일: Origin.cs 프로젝트: z77ma/runtime
 public GenericParameterOrigin(GenericParameterDesc genericParam)
 {
     GenericParameter = genericParam;
 }
예제 #15
0
파일: TypeDecl.cs 프로젝트: Ashod/Phalanger
		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;
		}
예제 #16
0
 public GenericParameterProxy(GenericParameterDesc genericParameter) => GenericParameter = genericParameter;