public EXPRTHISPOINTER CreateThis(LocalVariableSymbol pLocal, bool fImplicit) { Debug.Assert(pLocal == null || pLocal.isThis); CType type = null; if (pLocal != null) { type = pLocal.GetType(); } EXPRFLAG flags = EXPRFLAG.EXF_CANTBENULL; if (fImplicit) { flags |= EXPRFLAG.EXF_IMPLICITTHIS; } if (type != null && type.isStructType()) { flags |= EXPRFLAG.EXF_LVALUE; } EXPRTHISPOINTER rval = new EXPRTHISPOINTER(); rval.kind = ExpressionKind.EK_THISPOINTER; rval.type = type; rval.flags = flags; rval.local = pLocal; Debug.Assert(rval != null); return(rval); }
//////////////////////////////////////////////////////////////////////////////// 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 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 AggregateType GetUserDefinedBinopArgumentType(CType type) { for (; ;) { switch (type.GetTypeKind()) { case TypeKind.TK_NullableType: type = type.StripNubs(); break; case TypeKind.TK_TypeParameterType: type = type.AsTypeParameterType().GetEffectiveBaseClass(); break; case TypeKind.TK_AggregateType: if ((type.isClassType() || type.isStructType()) && !type.AsAggregateType().getAggregate().IsSkipUDOps()) { return type.AsAggregateType(); } return null; default: return null; } } }