CNullable
using Microsoft.CSharp.RuntimeBinder.Errors;
namespace Microsoft.CSharp.RuntimeBinder.Semantics
{
internal sealed class CNullable
{
private readonly SymbolLoader _pSymbolLoader;
private readonly ExprFactory _exprFactory;
private readonly ErrorHandling _pErrorContext;
private SymbolLoader GetSymbolLoader()
{
return _pSymbolLoader;
}
private ExprFactory GetExprFactory()
{
return _exprFactory;
}
private ErrorHandling GetErrorContext()
{
return _pErrorContext;
}
private static bool IsNullableConstructor(Expr expr, out ExprCall call)
{
ExprCall exprCall;
if ((exprCall = (expr as ExprCall)) != null && exprCall.MemberGroup.OptionalObject == null) {
MethodSymbol methodSymbol = exprCall.MethWithInst.Meth();
if (methodSymbol != null && methodSymbol.IsNullableConstructor()) {
call = exprCall;
return true;
}
}
call = null;
return false;
}
public static Expr StripNullableConstructor(Expr pExpr)
{
ExprCall call;
while (IsNullableConstructor(pExpr, out call)) {
pExpr = call.OptionalArguments;
}
return pExpr;
}
public Expr BindValue(Expr exprSrc)
{
if (IsNullableConstructor(exprSrc, out ExprCall call))
return call.OptionalArguments;
CType underlyingType = exprSrc.Type.AsNullableType().GetUnderlyingType();
AggregateType ats = exprSrc.Type.AsNullableType().GetAts(GetErrorContext());
if (ats == null) {
ExprProperty exprProperty = GetExprFactory().CreateProperty(underlyingType, exprSrc);
exprProperty.SetError();
return exprProperty;
}
PropertySymbol propertySymbol = GetSymbolLoader().getBSymmgr().propNubValue;
if (propertySymbol == null) {
propertySymbol = GetSymbolLoader().getPredefinedMembers().GetProperty(PREDEFPROP.PP_G_OPTIONAL_VALUE);
GetSymbolLoader().getBSymmgr().propNubValue = propertySymbol;
}
PropWithType pwtSlot = new PropWithType(propertySymbol, ats);
MethWithType mwtGet = new MethWithType(propertySymbol?.methGet, ats);
MethPropWithInst mwi = new MethPropWithInst(propertySymbol, ats);
ExprMemberGroup pMemberGroup = GetExprFactory().CreateMemGroup(exprSrc, mwi);
ExprProperty exprProperty2 = GetExprFactory().CreateProperty(underlyingType, null, null, pMemberGroup, pwtSlot, mwtGet, null);
if (propertySymbol == null)
exprProperty2.SetError();
return exprProperty2;
}
public ExprCall BindNew(Expr pExprSrc)
{
NullableType nullable = GetSymbolLoader().GetTypeManager().GetNullable(pExprSrc.Type);
AggregateType ats = nullable.GetAts(GetErrorContext());
if (ats == null) {
MethWithInst mwi = new MethWithInst(null, null);
ExprMemberGroup pMemberGroup = GetExprFactory().CreateMemGroup(pExprSrc, mwi);
ExprCall exprCall = GetExprFactory().CreateCall((EXPRFLAG)0, nullable, null, pMemberGroup, null);
exprCall.SetError();
return exprCall;
}
MethodSymbol methodSymbol = GetSymbolLoader().getBSymmgr().methNubCtor;
if (methodSymbol == null) {
methodSymbol = GetSymbolLoader().getPredefinedMembers().GetMethod(PREDEFMETH.PM_G_OPTIONAL_CTOR);
GetSymbolLoader().getBSymmgr().methNubCtor = methodSymbol;
}
MethWithInst methWithInst = new MethWithInst(methodSymbol, ats, BSYMMGR.EmptyTypeArray());
ExprMemberGroup pMemberGroup2 = GetExprFactory().CreateMemGroup(null, methWithInst);
ExprCall exprCall2 = GetExprFactory().CreateCall(EXPRFLAG.EXF_LITERALCONST | EXPRFLAG.EXF_CANTBENULL, nullable, pExprSrc, pMemberGroup2, methWithInst);
if (methodSymbol == null)
exprCall2.SetError();
return exprCall2;
}
public CNullable(SymbolLoader symbolLoader, ErrorHandling errorContext, ExprFactory exprFactory)
{
_pSymbolLoader = symbolLoader;
_pErrorContext = errorContext;
_exprFactory = exprFactory;
}
}
}