ExprFactory
using Microsoft.CSharp.RuntimeBinder.Syntax;
using System;
namespace Microsoft.CSharp.RuntimeBinder.Semantics
{
internal sealed class ExprFactory
{
private readonly GlobalSymbolContext _globalSymbolContext;
public ExprFactory(GlobalSymbolContext globalSymbolContext)
{
_globalSymbolContext = globalSymbolContext;
}
private TypeManager GetTypes()
{
return _globalSymbolContext.GetTypes();
}
private BSYMMGR GetGlobalSymbols()
{
return _globalSymbolContext.GetGlobalSymbols();
}
public ExprCall CreateCall(EXPRFLAG nFlags, CType pType, Expr pOptionalArguments, ExprMemberGroup pMemberGroup, MethWithInst MWI)
{
ExprCall exprCall = new ExprCall(pType);
exprCall.Flags = nFlags;
exprCall.OptionalArguments = pOptionalArguments;
exprCall.MemberGroup = pMemberGroup;
exprCall.NullableCallLiftKind = NullableCallLiftKind.NotLifted;
exprCall.MethWithInst = MWI;
return exprCall;
}
public ExprField CreateField(EXPRFLAG nFlags, CType pType, Expr pOptionalObject, FieldWithType FWT)
{
ExprField exprField = new ExprField(pType);
exprField.Flags = nFlags;
exprField.OptionalObject = pOptionalObject;
exprField.FieldWithType = FWT;
return exprField;
}
public ExprFuncPtr CreateFunctionPointer(EXPRFLAG nFlags, CType pType, Expr pObject, MethWithInst MWI)
{
ExprFuncPtr exprFuncPtr = new ExprFuncPtr(pType);
exprFuncPtr.Flags = nFlags;
exprFuncPtr.OptionalObject = pObject;
exprFuncPtr.MethWithInst = new MethWithInst(MWI);
return exprFuncPtr;
}
public ExprArrayInit CreateArrayInit(EXPRFLAG nFlags, CType pType, Expr pOptionalArguments, Expr pOptionalArgumentDimensions, int[] pDimSizes)
{
ExprArrayInit exprArrayInit = new ExprArrayInit(pType);
exprArrayInit.OptionalArguments = pOptionalArguments;
exprArrayInit.OptionalArgumentDimensions = pOptionalArgumentDimensions;
exprArrayInit.DimensionSizes = pDimSizes;
exprArrayInit.DimensionSize = ((pDimSizes != null) ? pDimSizes.Length : 0);
return exprArrayInit;
}
public ExprProperty CreateProperty(CType pType, Expr pOptionalObject)
{
MethPropWithInst mwi = new MethPropWithInst();
ExprMemberGroup pMemberGroup = CreateMemGroup(pOptionalObject, mwi);
return CreateProperty(pType, null, null, pMemberGroup, null, null, null);
}
public ExprProperty CreateProperty(CType pType, Expr pOptionalObjectThrough, Expr pOptionalArguments, ExprMemberGroup pMemberGroup, PropWithType pwtSlot, MethWithType mwtGet, MethWithType mwtSet)
{
ExprProperty exprProperty = new ExprProperty(pType);
exprProperty.OptionalObjectThrough = pOptionalObjectThrough;
exprProperty.OptionalArguments = pOptionalArguments;
exprProperty.MemberGroup = pMemberGroup;
if ((SymWithType)pwtSlot != (SymWithType)null)
exprProperty.PropWithTypeSlot = pwtSlot;
if ((SymWithType)mwtSet != (SymWithType)null)
exprProperty.MethWithTypeSet = mwtSet;
return exprProperty;
}
public ExprEvent CreateEvent(CType pType, Expr pOptionalObject, EventWithType EWT)
{
ExprEvent exprEvent = new ExprEvent(pType);
exprEvent.OptionalObject = pOptionalObject;
exprEvent.EventWithType = EWT;
return exprEvent;
}
public ExprMemberGroup CreateMemGroup(EXPRFLAG nFlags, Name pName, TypeArray pTypeArgs, SYMKIND symKind, CType pTypePar, MethodOrPropertySymbol pMPS, Expr pObject, CMemberLookupResults memberLookupResults)
{
ExprMemberGroup exprMemberGroup = new ExprMemberGroup(GetTypes().GetMethGrpType());
exprMemberGroup.Flags = nFlags;
exprMemberGroup.Name = pName;
exprMemberGroup.TypeArgs = (pTypeArgs ?? BSYMMGR.EmptyTypeArray());
exprMemberGroup.SymKind = symKind;
exprMemberGroup.ParentType = pTypePar;
exprMemberGroup.OptionalObject = pObject;
exprMemberGroup.MemberLookupResults = memberLookupResults;
return exprMemberGroup;
}
public ExprMemberGroup CreateMemGroup(Expr pObject, MethPropWithInst mwi)
{
Name name = mwi.Sym?.name;
MethodOrPropertySymbol methodOrPropertySymbol = mwi.MethProp();
CType cType = (CType)(((object)mwi.GetType()) ?? ((object)GetTypes().GetErrorSym()));
return CreateMemGroup((EXPRFLAG)0, name, mwi.TypeArgs, methodOrPropertySymbol?.getKind() ?? SYMKIND.SK_MethodSymbol, mwi.GetType(), methodOrPropertySymbol, pObject, new CMemberLookupResults(GetGlobalSymbols().AllocParams(1, new CType[1] {
cType
}), name));
}
public ExprUserDefinedConversion CreateUserDefinedConversion(Expr arg, Expr call, MethWithInst mwi)
{
ExprUserDefinedConversion exprUserDefinedConversion = new ExprUserDefinedConversion();
exprUserDefinedConversion.Argument = arg;
exprUserDefinedConversion.UserDefinedCall = call;
exprUserDefinedConversion.UserDefinedCallMethod = mwi;
if (call.HasError)
exprUserDefinedConversion.SetError();
return exprUserDefinedConversion;
}
public ExprCast CreateCast(EXPRFLAG nFlags, CType pType, Expr pArg)
{
return CreateCast(nFlags, CreateClass(pType, null), pArg);
}
public ExprCast CreateCast(EXPRFLAG nFlags, ExprClass pType, Expr pArg)
{
ExprCast exprCast = new ExprCast();
exprCast.Argument = pArg;
exprCast.Flags = nFlags;
exprCast.DestinationType = pType;
return exprCast;
}
public ExprReturn CreateReturn(EXPRFLAG nFlags, Scope pCurrentScope, Expr pOptionalObject)
{
ExprReturn exprReturn = new ExprReturn();
exprReturn.Flags = nFlags;
exprReturn.OptionalObject = pOptionalObject;
return exprReturn;
}
public ExprLocal CreateLocal(EXPRFLAG nFlags, LocalVariableSymbol pLocal)
{
ExprLocal exprLocal = new ExprLocal();
exprLocal.Flags = nFlags;
exprLocal.Local = pLocal;
return exprLocal;
}
public ExprBoundLambda CreateAnonymousMethod(AggregateType delegateType)
{
return new ExprBoundLambda(delegateType);
}
public ExprUnboundLambda CreateLambda()
{
return new ExprUnboundLambda(GetTypes().GetAnonMethType());
}
public ExprHoistedLocalExpr CreateHoistedLocalInExpression(ExprLocal localToHoist)
{
return new ExprHoistedLocalExpr(GetTypes().GetOptPredefAgg(PredefinedType.PT_EXPRESSION).getThisType());
}
public ExprMethodInfo CreateMethodInfo(MethPropWithInst mwi)
{
return CreateMethodInfo(mwi.Meth(), mwi.GetType(), mwi.TypeArgs);
}
public ExprMethodInfo CreateMethodInfo(MethodSymbol method, AggregateType methodType, TypeArray methodParameters)
{
ExprMethodInfo exprMethodInfo = new ExprMethodInfo(GetTypes().GetOptPredefAgg(method.IsConstructor() ? PredefinedType.PT_CONSTRUCTORINFO : PredefinedType.PT_METHODINFO).getThisType());
exprMethodInfo.Method = new MethWithInst(method, methodType, methodParameters);
return exprMethodInfo;
}
public ExprPropertyInfo CreatePropertyInfo(PropertySymbol prop, AggregateType propertyType)
{
ExprPropertyInfo exprPropertyInfo = new ExprPropertyInfo(GetTypes().GetOptPredefAgg(PredefinedType.PT_PROPERTYINFO).getThisType());
exprPropertyInfo.Property = new PropWithType(prop, propertyType);
return exprPropertyInfo;
}
public ExprFieldInfo CreateFieldInfo(FieldSymbol field, AggregateType fieldType)
{
return new ExprFieldInfo(field, fieldType, GetTypes().GetOptPredefAgg(PredefinedType.PT_FIELDINFO).getThisType());
}
private ExprTypeOf CreateTypeOf(ExprClass pSourceType)
{
ExprTypeOf exprTypeOf = new ExprTypeOf(GetTypes().GetReqPredefAgg(PredefinedType.PT_TYPE).getThisType());
exprTypeOf.Flags = EXPRFLAG.EXF_CANTBENULL;
exprTypeOf.SourceType = pSourceType;
return exprTypeOf;
}
public ExprTypeOf CreateTypeOf(CType pSourceType)
{
return CreateTypeOf(MakeClass(pSourceType));
}
public ExprUserLogicalOp CreateUserLogOp(CType pType, Expr pCallTF, ExprCall pCallOp)
{
ExprUserLogicalOp exprUserLogicalOp = new ExprUserLogicalOp(pType);
Expr expr = ((ExprList)pCallOp.OptionalArguments).OptionalElement;
ExprWrap exprWrap;
if ((exprWrap = (expr as ExprWrap)) != null)
expr = exprWrap.OptionalExpression;
exprUserLogicalOp.Flags = EXPRFLAG.EXF_ASSGOP;
exprUserLogicalOp.TrueFalseCall = pCallTF;
exprUserLogicalOp.OperatorCall = pCallOp;
exprUserLogicalOp.FirstOperandToExamine = expr;
return exprUserLogicalOp;
}
public ExprUserLogicalOp CreateUserLogOpError(CType pType, Expr pCallTF, ExprCall pCallOp)
{
ExprUserLogicalOp exprUserLogicalOp = CreateUserLogOp(pType, pCallTF, pCallOp);
exprUserLogicalOp.SetError();
return exprUserLogicalOp;
}
public ExprConcat CreateConcat(Expr op1, Expr op2)
{
CType type = op1.Type;
if (!type.isPredefType(PredefinedType.PT_STRING))
type = op2.Type;
ExprConcat exprConcat = new ExprConcat(type);
exprConcat.FirstArgument = op1;
exprConcat.SecondArgument = op2;
return exprConcat;
}
public ExprConstant CreateStringConstant(string str)
{
return CreateConstant(GetTypes().GetReqPredefAgg(PredefinedType.PT_STRING).getThisType(), ConstVal.Get(str));
}
public ExprMultiGet CreateMultiGet(EXPRFLAG nFlags, CType pType, ExprMulti pOptionalMulti)
{
ExprMultiGet exprMultiGet = new ExprMultiGet(pType);
exprMultiGet.Flags = nFlags;
exprMultiGet.OptionalMulti = pOptionalMulti;
return exprMultiGet;
}
public ExprMulti CreateMulti(EXPRFLAG nFlags, CType pType, Expr pLeft, Expr pOp)
{
ExprMulti exprMulti = new ExprMulti(pType);
exprMulti.Flags = nFlags;
exprMulti.Left = pLeft;
exprMulti.Operator = pOp;
return exprMulti;
}
public Expr CreateZeroInit(CType pType)
{
ExprClass pTypeExpr = MakeClass(pType);
return CreateZeroInit(pTypeExpr);
}
private Expr CreateZeroInit(ExprClass pTypeExpr)
{
return CreateZeroInit(pTypeExpr, null, false);
}
private Expr CreateZeroInit(ExprClass pTypeExpr, Expr pOptionalOriginalConstructorCall, bool isConstructor)
{
CType type = pTypeExpr.Type;
bool flag = false;
if (type.isEnumType())
return CreateConstant(type, ConstVal.Get(Activator.CreateInstance(type.AssociatedSystemType)));
switch (type.fundType()) {
default:
flag = true;
break;
case FUNDTYPE.FT_PTR: {
CType nullType = GetTypes().GetNullType();
if (nullType.fundType() == type.fundType())
return CreateConstant(type, ConstVal.GetDefaultValue(ConstValKind.IntPtr));
return CreateCast((EXPRFLAG)0, pTypeExpr, CreateNull());
}
case FUNDTYPE.FT_I1:
case FUNDTYPE.FT_I2:
case FUNDTYPE.FT_I4:
case FUNDTYPE.FT_U1:
case FUNDTYPE.FT_U2:
case FUNDTYPE.FT_U4:
case FUNDTYPE.FT_I8:
case FUNDTYPE.FT_U8:
case FUNDTYPE.FT_R4:
case FUNDTYPE.FT_R8:
case FUNDTYPE.FT_REF: {
ExprConstant result2 = CreateConstant(type, ConstVal.GetDefaultValue(type.constValKind()));
ExprConstant exprConstant2 = CreateConstant(type, ConstVal.GetDefaultValue(type.constValKind()));
exprConstant2.OptionalConstructorCall = pOptionalOriginalConstructorCall;
return result2;
}
case FUNDTYPE.FT_STRUCT:
if (type.isPredefType(PredefinedType.PT_DECIMAL)) {
ExprConstant result = CreateConstant(type, ConstVal.GetDefaultValue(type.constValKind()));
ExprConstant exprConstant = CreateConstant(type, ConstVal.GetDefaultValue(type.constValKind()));
exprConstant.OptionalConstructorCall = pOptionalOriginalConstructorCall;
return result;
}
break;
case FUNDTYPE.FT_VAR:
break;
}
ExprZeroInit exprZeroInit = new ExprZeroInit(type);
exprZeroInit.OptionalConstructorCall = pOptionalOriginalConstructorCall;
exprZeroInit.IsConstructor = isConstructor;
if (flag)
exprZeroInit.SetError();
return exprZeroInit;
}
public ExprConstant CreateConstant(CType pType, ConstVal constVal)
{
ExprConstant exprConstant = CreateConstant(pType);
exprConstant.Val = constVal;
return exprConstant;
}
private ExprConstant CreateConstant(CType pType)
{
return new ExprConstant(pType);
}
public ExprConstant CreateIntegerConstant(int x)
{
return CreateConstant(GetTypes().GetReqPredefAgg(PredefinedType.PT_INT).getThisType(), ConstVal.Get(x));
}
public ExprConstant CreateBoolConstant(bool b)
{
return CreateConstant(GetTypes().GetReqPredefAgg(PredefinedType.PT_BOOL).getThisType(), ConstVal.Get(b));
}
public ExprBlock CreateBlock(ExprStatement pOptionalStatements, Scope pOptionalScope)
{
ExprBlock exprBlock = new ExprBlock();
exprBlock.OptionalStatements = pOptionalStatements;
exprBlock.OptionalScopeSymbol = pOptionalScope;
return exprBlock;
}
public ExprArrayIndex CreateArrayIndex(Expr pArray, Expr pIndex)
{
CType cType = pArray.Type;
if (cType != null && cType.IsArrayType())
cType = cType.AsArrayType().GetElementType();
else if (cType == null) {
cType = GetTypes().GetReqPredefAgg(PredefinedType.PT_INT).getThisType();
}
ExprArrayIndex exprArrayIndex = new ExprArrayIndex(cType);
exprArrayIndex.Array = pArray;
exprArrayIndex.Index = pIndex;
return exprArrayIndex;
}
public ExprBinOp CreateBinop(ExpressionKind exprKind, CType pType, Expr p1, Expr p2)
{
ExprBinOp exprBinOp = new ExprBinOp(exprKind, pType);
exprBinOp.Flags = EXPRFLAG.EXF_BINOP;
exprBinOp.OptionalLeftChild = p1;
exprBinOp.OptionalRightChild = p2;
return exprBinOp;
}
public ExprUnaryOp CreateUnaryOp(ExpressionKind exprKind, CType pType, Expr pOperand)
{
ExprUnaryOp exprUnaryOp = new ExprUnaryOp(exprKind, pType);
exprUnaryOp.Child = pOperand;
return exprUnaryOp;
}
public ExprOperator CreateOperator(ExpressionKind exprKind, CType pType, Expr pArg1, Expr pOptionalArg2)
{
if (!exprKind.IsUnaryOperator())
return CreateBinop(exprKind, pType, pArg1, pOptionalArg2);
return CreateUnaryOp(exprKind, pType, pArg1);
}
public ExprBinOp CreateUserDefinedBinop(ExpressionKind exprKind, CType pType, Expr p1, Expr p2, Expr call, MethPropWithInst pmpwi)
{
ExprBinOp exprBinOp = new ExprBinOp(exprKind, pType);
exprBinOp.Flags = EXPRFLAG.EXF_BINOP;
exprBinOp.OptionalLeftChild = p1;
exprBinOp.OptionalRightChild = p2;
exprBinOp.OptionalUserDefinedCall = call;
exprBinOp.UserDefinedCallMethod = pmpwi;
if (call.HasError)
exprBinOp.SetError();
return exprBinOp;
}
public ExprUnaryOp CreateUserDefinedUnaryOperator(ExpressionKind exprKind, CType pType, Expr pOperand, ExprCall call, MethPropWithInst pmpwi)
{
ExprUnaryOp exprUnaryOp = new ExprUnaryOp(exprKind, pType);
exprUnaryOp.Child = pOperand;
exprUnaryOp.OptionalUserDefinedCall = call;
exprUnaryOp.UserDefinedCallMethod = pmpwi;
if (call.HasError)
exprUnaryOp.SetError();
return exprUnaryOp;
}
public ExprUnaryOp CreateNeg(EXPRFLAG nFlags, Expr pOperand)
{
ExprUnaryOp exprUnaryOp = CreateUnaryOp(ExpressionKind.Negate, pOperand.Type, pOperand);
exprUnaryOp.Flags |= nFlags;
return exprUnaryOp;
}
public ExprBinOp CreateSequence(Expr p1, Expr p2)
{
return CreateBinop(ExpressionKind.Sequence, p2.Type, p1, p2);
}
public ExprBinOp CreateReverseSequence(Expr p1, Expr p2)
{
return CreateBinop(ExpressionKind.SequenceReverse, p1.Type, p1, p2);
}
public ExprAssignment CreateAssignment(Expr pLHS, Expr pRHS)
{
ExprAssignment exprAssignment = new ExprAssignment();
exprAssignment.Flags = EXPRFLAG.EXF_ASSGOP;
exprAssignment.LHS = pLHS;
exprAssignment.RHS = pRHS;
return exprAssignment;
}
public ExprNamedArgumentSpecification CreateNamedArgumentSpecification(Name pName, Expr pValue)
{
ExprNamedArgumentSpecification exprNamedArgumentSpecification = new ExprNamedArgumentSpecification();
exprNamedArgumentSpecification.Value = pValue;
exprNamedArgumentSpecification.Name = pName;
return exprNamedArgumentSpecification;
}
public ExprWrap CreateWrap(Scope pCurrentScope, Expr pOptionalExpression)
{
ExprWrap exprWrap = new ExprWrap();
exprWrap.OptionalExpression = pOptionalExpression;
exprWrap.Flags = EXPRFLAG.EXF_LVALUE;
return exprWrap;
}
public ExprWrap CreateWrapNoAutoFree(Scope pCurrentScope, Expr pOptionalWrap)
{
return CreateWrap(pCurrentScope, pOptionalWrap);
}
public ExprBinOp CreateSave(ExprWrap wrap)
{
ExprBinOp exprBinOp = CreateBinop(ExpressionKind.Save, wrap.Type, wrap.OptionalExpression, wrap);
exprBinOp.SetAssignment();
return exprBinOp;
}
public ExprConstant CreateNull()
{
return CreateConstant(GetTypes().GetNullType(), default(ConstVal));
}
public void AppendItemToList(Expr newItem, ref Expr first, ref Expr last)
{
if (newItem != null) {
if (first == null) {
first = newItem;
last = newItem;
} else if (first.Kind != ExpressionKind.List) {
first = CreateList(first, newItem);
last = first;
} else {
ExprList exprList = (ExprList)last;
exprList.OptionalNextListNode = CreateList(exprList.OptionalNextListNode, newItem);
last = exprList.OptionalNextListNode;
}
}
}
public ExprList CreateList(Expr op1, Expr op2)
{
ExprList exprList = new ExprList();
exprList.OptionalElement = op1;
exprList.OptionalNextListNode = op2;
return exprList;
}
public ExprList CreateList(Expr op1, Expr op2, Expr op3)
{
return CreateList(op1, CreateList(op2, op3));
}
public ExprList CreateList(Expr op1, Expr op2, Expr op3, Expr op4)
{
return CreateList(op1, CreateList(op2, CreateList(op3, op4)));
}
public ExprTypeArguments CreateTypeArguments(TypeArray pTypeArray, Expr pOptionalElements)
{
ExprTypeArguments exprTypeArguments = new ExprTypeArguments();
exprTypeArguments.OptionalElements = pOptionalElements;
return exprTypeArguments;
}
public ExprClass CreateClass(CType pType, ExprTypeArguments pOptionalTypeArguments)
{
return new ExprClass(pType);
}
public ExprClass MakeClass(CType pType)
{
return CreateClass(pType, null);
}
}
}