GetOwningAggregate() public méthode

public GetOwningAggregate ( ) : AggregateSymbol
Résultat AggregateSymbol
Exemple #1
0
        public virtual bool CheckTypeAccess(CType type, Symbol symWhere)
        {
            Debug.Assert(type != null);

            // Array, Ptr, Nub, etc don't matter.
            type = type.GetNakedType(true);

            if (!type.IsAggregateType())
            {
                Debug.Assert(type.IsVoidType() || type.IsErrorType() || type.IsTypeParameterType());
                return(true);
            }

            for (AggregateType ats = type.AsAggregateType(); ats != null; ats = ats.outerType)
            {
                if (ACCESSERROR.ACCESSERROR_NOERROR != CheckAccessCore(ats.GetOwningAggregate(), ats.outerType, symWhere, null))
                {
                    return(false);
                }
            }

            TypeArray typeArgs = type.AsAggregateType().GetTypeArgsAll();

            for (int i = 0; i < typeArgs.size; i++)
            {
                if (!CheckTypeAccess(typeArgs.Item(i), symWhere))
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #2
0
        private static Type CalculateAssociatedSystemTypeForAggregate(AggregateType aggtype)
        {
            AggregateSymbol agg      = aggtype.GetOwningAggregate();
            TypeArray       typeArgs = aggtype.GetTypeArgsAll();

            List <Type> list = new List <Type>();

            // Get each type arg.
            for (int i = 0; i < typeArgs.Count; i++)
            {
                // Unnamed type parameter types are just placeholders.
                if (typeArgs[i] is TypeParameterType typeParamArg && typeParamArg.GetTypeParameterSymbol().name == null)
                {
                    return(null);
                }
                list.Add(typeArgs[i].AssociatedSystemType);
            }

            Type[] systemTypeArgs     = list.ToArray();
            Type   uninstantiatedType = agg.AssociatedSystemType;

            if (uninstantiatedType.IsGenericType)
            {
                try
                {
                    return(uninstantiatedType.MakeGenericType(systemTypeArgs));
                }
                catch (ArgumentException)
                {
                    // If the constraints don't work, just return the type without substituting it.
                    return(uninstantiatedType);
                }
            }
            return(uninstantiatedType);
        }
        ////////////////////////////////////////////////////////////////////////////////

        private void UpperBoundTypeArgumentInference(
            AggregateType pSource, AggregateType pDest)
        {
            // SPEC: The choice of inference for the i-th CType argument is made
            // SPEC: based on the declaration of the i-th CType parameter of C, as
            // SPEC: follows:
            // SPEC:  if Ui is known to be of reference CType and the i-th CType parameter
            // SPEC:   was declared as covariant then an upper-bound inference is made.
            // SPEC:  if Ui is known to be of reference CType and the i-th CType parameter
            // SPEC:   was declared as contravariant then a lower-bound inference is made.
            // SPEC:  otherwise, an exact inference is made.

            Debug.Assert(pSource != null);
            Debug.Assert(pDest != null);
            Debug.Assert(pSource.GetOwningAggregate() == pDest.GetOwningAggregate());

            TypeArray pTypeParams = pSource.GetOwningAggregate().GetTypeVarsAll();
            TypeArray pSourceArgs = pSource.GetTypeArgsAll();
            TypeArray pDestArgs = pDest.GetTypeArgsAll();

            Debug.Assert(pTypeParams != null);
            Debug.Assert(pSourceArgs != null);
            Debug.Assert(pDestArgs != null);

            Debug.Assert(pTypeParams.size == pSourceArgs.size);
            Debug.Assert(pTypeParams.size == pDestArgs.size);

            for (int arg = 0; arg < pSourceArgs.size; ++arg)
            {
                TypeParameterType pTypeParam = pTypeParams.ItemAsTypeParameterType(arg);
                CType pSourceArg = pSourceArgs.Item(arg);
                CType pDestArg = pDestArgs.Item(arg);

                if (pSourceArg.IsRefType() && pTypeParam.Covariant)
                {
                    UpperBoundInference(pSourceArg, pDestArg);
                }
                else if (pSourceArg.IsRefType() && pTypeParam.Contravariant)
                {
                    LowerBoundInference(pSourceArgs.Item(arg), pDestArgs.Item(arg));
                }
                else
                {
                    ExactInference(pSourceArgs.Item(arg), pDestArgs.Item(arg));
                }
            }
        }
        ////////////////////////////////////////////////////////////////////////////////

        private bool UpperBoundInterfaceInference(AggregateType pSource, CType pDest)
        {
            if (!pSource.isInterfaceType())
            {
                return false;
            }

            // SPEC:  Otherwise, if U is an interface CType C<U1...Uk> and V is a class CType
            // SPEC:   or struct CType and there is a unique set V1...Vk such that V directly 
            // SPEC:   or indirectly implements C<V1...Vk> then an exact ...
            // SPEC:  ... and U is an interface CType ...

            if (!pDest.isStructType() && !pDest.isClassType() &&
                !pDest.isInterfaceType())
            {
                return false;
            }

            var interfaces = pDest.AllPossibleInterfaces();
            AggregateType pInterface = null;
            foreach (AggregateType pCurrent in interfaces)
            {
                if (pCurrent.GetOwningAggregate() == pSource.GetOwningAggregate())
                {
                    if (pInterface == null)
                    {
                        pInterface = pCurrent;
                    }
                    else if (pInterface != pCurrent)
                    {
                        // Not unique. Bail out.
                        return false;
                    }
                }
            }
            if (pInterface == null)
            {
                return false;
            }
            UpperBoundTypeArgumentInference(pInterface, pDest.AsAggregateType());
            return true;
        }
        ////////////////////////////////////////////////////////////////////////////////

        private bool UpperBoundClassInference(AggregateType pSource, CType pDest)
        {
            if (!pSource.isClassType() || !pDest.isClassType())
            {
                return false;
            }

            // SPEC:  Otherwise, if U is a class CType C<U1...Uk> and V is a class CType which
            // SPEC:   inherits directly or indirectly from C<V1...Vk> then an exact 
            // SPEC:   inference is made from each Ui to the corresponding Vi.

            AggregateType pDestBase = pDest.AsAggregateType().GetBaseClass();

            while (pDestBase != null)
            {
                if (pDestBase.GetOwningAggregate() == pSource.GetOwningAggregate())
                {
                    ExactTypeArgumentInference(pSource, pDestBase);
                    return true;
                }
                pDestBase = pDestBase.GetBaseClass();
            }
            return false;
        }
        ////////////////////////////////////////////////////////////////////////////////

        private bool LowerBoundInterfaceInference(CType pSource, AggregateType pDest)
        {
            if (!pDest.isInterfaceType())
            {
                return false;
            }

            // SPEC:  Otherwise, if V is an interface CType C<V1...Vk> and U is a class CType
            // SPEC:   or struct CType and there is a unique set U1...Uk such that U directly 
            // SPEC:   or indirectly implements C<U1...Uk> then an
            // SPEC:   exact, upper-bound, or lower-bound inference ...
            // SPEC:  ... and U is an interface CType ...
            // SPEC:  ... and U is a CType parameter ...

            //TypeArray pInterfaces = null;

            if (!pSource.isStructType() && !pSource.isClassType() &&
                !pSource.isInterfaceType() && !pSource.IsTypeParameterType())
            {
                return false;
            }

            var interfaces = pSource.AllPossibleInterfaces();
            AggregateType pInterface = null;
            foreach (AggregateType pCurrent in interfaces)
            {
                if (pCurrent.GetOwningAggregate() == pDest.GetOwningAggregate())
                {
                    if (pInterface == null)
                    {
                        pInterface = pCurrent;
                    }
                    else if (pInterface != pCurrent)
                    {
                        // Not unique. Bail out.
                        return false;
                    }
                }
            }
            if (pInterface == null)
            {
                return false;
            }
            LowerBoundTypeArgumentInference(pInterface, pDest);
            return true;
        }
        ////////////////////////////////////////////////////////////////////////////////

        private bool LowerBoundClassInference(CType pSource, AggregateType pDest)
        {
            if (!pDest.isClassType())
            {
                return false;
            }

            // SPEC:  Otherwise, if V is a class CType C<V1...Vk> and U is a class CType which
            // SPEC:   inherits directly or indirectly from C<U1...Uk> 
            // SPEC:   then an exact inference is made from each Ui to the corresponding Vi.
            // SPEC:  Otherwise, if V is a class CType C<V1...Vk> and U is a CType parameter
            // SPEC:   with effective base class C<U1...Uk> 
            // SPEC:   then an exact inference is made from each Ui to the corresponding Vi.
            // SPEC:  Otherwise, if V is a class CType C<V1...Vk> and U is a CType parameter
            // SPEC:   with an effective base class which inherits directly or indirectly from
            // SPEC:   C<U1...Uk> then an exact inference is made
            // SPEC:   from each Ui to the corresponding Vi.

            AggregateType pSourceBase = null;

            if (pSource.isClassType())
            {
                pSourceBase = pSource.AsAggregateType().GetBaseClass();
            }
            else if (pSource.IsTypeParameterType())
            {
                pSourceBase = pSource.AsTypeParameterType().GetEffectiveBaseClass();
            }

            while (pSourceBase != null)
            {
                if (pSourceBase.GetOwningAggregate() == pDest.GetOwningAggregate())
                {
                    ExactTypeArgumentInference(pSourceBase, pDest);
                    return true;
                }
                pSourceBase = pSourceBase.GetBaseClass();
            }
            return false;
        }
        ////////////////////////////////////////////////////////////////////////////////

        private void ExactTypeArgumentInference(
            AggregateType pSource, AggregateType pDest)

        {
            Debug.Assert(pSource != null);
            Debug.Assert(pDest != null);
            Debug.Assert(pSource.GetOwningAggregate() == pDest.GetOwningAggregate());

            TypeArray pSourceArgs = pSource.GetTypeArgsAll();
            TypeArray pDestArgs = pDest.GetTypeArgsAll();

            Debug.Assert(pSourceArgs != null);
            Debug.Assert(pDestArgs != null);
            Debug.Assert(pSourceArgs.size == pDestArgs.size);

            for (int arg = 0; arg < pSourceArgs.size; ++arg)
            {
                ExactInference(pSourceArgs.Item(arg), pDestArgs.Item(arg));
            }
        }
Exemple #9
0
        private static Type CalculateAssociatedSystemTypeForAggregate(AggregateType aggtype)
        {
            AggregateSymbol agg = aggtype.GetOwningAggregate();
            TypeArray typeArgs = aggtype.GetTypeArgsAll();

            List<Type> list = new List<Type>();

            // Get each type arg.
            for (int i = 0; i < typeArgs.size; i++)
            {
                // Unnamed type parameter types are just placeholders.
                if (typeArgs.Item(i).IsTypeParameterType() && typeArgs.Item(i).AsTypeParameterType().GetTypeParameterSymbol().name == null)
                {
                    return null;
                }
                list.Add(typeArgs.Item(i).AssociatedSystemType);
            }

            Type[] systemTypeArgs = list.ToArray();
            Type uninstantiatedType = agg.AssociatedSystemType;

            if (uninstantiatedType.GetTypeInfo().IsGenericType)
            {
                try
                {
                    return uninstantiatedType.MakeGenericType(systemTypeArgs);
                }
                catch (ArgumentException)
                {
                    // If the constraints don't work, just return the type without substituting it.
                    return uninstantiatedType;
                }
            }
            return uninstantiatedType;
        }
Exemple #10
0
        private bool TryVarianceAdjustmentToGetAccessibleType(CSemanticChecker semanticChecker, BindingContext bindingContext, AggregateType typeSrc, out CType typeDst)
        {
            Debug.Assert(typeSrc != null);
            Debug.Assert(typeSrc.isInterfaceType() || typeSrc.isDelegateType());

            typeDst = null;

            AggregateSymbol aggSym      = typeSrc.GetOwningAggregate();
            AggregateType   aggOpenType = aggSym.getThisType();

            if (!semanticChecker.CheckTypeAccess(aggOpenType, bindingContext.ContextForMemberLookup))
            {
                // if the aggregate symbol itself is not accessible, then forget it, there is no
                // variance that will help us arrive at an accessible type.
                return(false);
            }

            TypeArray typeArgs   = typeSrc.GetTypeArgsThis();
            TypeArray typeParams = aggOpenType.GetTypeArgsThis();

            CType[] newTypeArgsTemp = new CType[typeArgs.Count];

            for (int i = 0; i < typeArgs.Count; i++)
            {
                if (semanticChecker.CheckTypeAccess(typeArgs[i], bindingContext.ContextForMemberLookup))
                {
                    // we have an accessible argument, this position is not a problem.
                    newTypeArgsTemp[i] = typeArgs[i];
                    continue;
                }

                if (!typeArgs[i].IsRefType() || !((TypeParameterType)typeParams[i]).Covariant)
                {
                    // This guy is inaccessible, and we are not going to be able to vary him, so we need to fail.
                    return(false);
                }

                CType intermediateTypeArg;
                if (GetBestAccessibleType(semanticChecker, bindingContext, typeArgs[i], out intermediateTypeArg))
                {
                    // now we either have a value type (which must be accessible due to the above
                    // check, OR we have an inaccessible type (which must be a ref type). In either
                    // case, the recursion worked out and we are OK to vary this argument.
                    newTypeArgsTemp[i] = intermediateTypeArg;
                    continue;
                }
                else
                {
                    Debug.Assert(false, "GetBestAccessibleType unexpectedly failed on a type that was used as a type parameter");
                    return(false);
                }
            }

            TypeArray newTypeArgs      = semanticChecker.getBSymmgr().AllocParams(typeArgs.Count, newTypeArgsTemp);
            CType     intermediateType = this.GetAggregate(aggSym, typeSrc.outerType, newTypeArgs);

            // All type arguments were varied successfully, which means now we must be accessible. But we could
            // have violated constraints. Let's check that out.

            if (!TypeBind.CheckConstraints(semanticChecker, null /*ErrorHandling*/, intermediateType, CheckConstraintsFlags.NoErrors))
            {
                return(false);
            }

            typeDst = intermediateType;
            Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, bindingContext.ContextForMemberLookup));
            return(true);
        }
Exemple #11
0
        private bool TryVarianceAdjustmentToGetAccessibleType(CSemanticChecker semanticChecker, BindingContext bindingContext, AggregateType typeSrc, out CType typeDst)
        {
            Debug.Assert(typeSrc != null);
            Debug.Assert(typeSrc.isInterfaceType() || typeSrc.isDelegateType());

            typeDst = null;

            AggregateSymbol aggSym = typeSrc.GetOwningAggregate();
            AggregateType aggOpenType = aggSym.getThisType();

            if (!semanticChecker.CheckTypeAccess(aggOpenType, bindingContext.ContextForMemberLookup()))
            {
                // if the aggregate symbol itself is not accessible, then forget it, there is no
                // variance that will help us arrive at an accessible type.
                return false;
            }

            TypeArray typeArgs = typeSrc.GetTypeArgsThis();
            TypeArray typeParams = aggOpenType.GetTypeArgsThis();
            CType[] newTypeArgsTemp = new CType[typeArgs.size];

            for (int i = 0; i < typeArgs.size; i++)
            {
                if (semanticChecker.CheckTypeAccess(typeArgs.Item(i), bindingContext.ContextForMemberLookup()))
                {
                    // we have an accessible argument, this position is not a problem.
                    newTypeArgsTemp[i] = typeArgs.Item(i);
                    continue;
                }

                if (!typeArgs.Item(i).IsRefType() || !typeParams.Item(i).AsTypeParameterType().Covariant)
                {
                    // This guy is inaccessible, and we are not going to be able to vary him, so we need to fail.
                    return false;
                }

                CType intermediateTypeArg;
                if (GetBestAccessibleType(semanticChecker, bindingContext, typeArgs.Item(i), out intermediateTypeArg))
                {
                    // now we either have a value type (which must be accessible due to the above
                    // check, OR we have an inaccessible type (which must be a ref type). In either
                    // case, the recursion worked out and we are OK to vary this argument.
                    newTypeArgsTemp[i] = intermediateTypeArg;
                    continue;
                }
                else
                {
                    Debug.Assert(false, "GetBestAccessibleType unexpectedly failed on a type that was used as a type parameter");
                    return false;
                }
            }

            TypeArray newTypeArgs = semanticChecker.getBSymmgr().AllocParams(typeArgs.size, newTypeArgsTemp);
            CType intermediateType = this.GetAggregate(aggSym, typeSrc.outerType, newTypeArgs);

            // All type arguments were varied successfully, which means now we must be accessible. But we could
            // have violated constraints. Let's check that out.

            if (!TypeBind.CheckConstraints(semanticChecker, null/*ErrorHandling*/, intermediateType, CheckConstraintsFlags.NoErrors))
            {
                return false;
            }

            typeDst = intermediateType;
            Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, bindingContext.ContextForMemberLookup()));
            return true;
        }