public ExprPropertyInfo(CType type, PropertySymbol propertySymbol, AggregateType propertyType) : base(ExpressionKind.PropertyInfo, type) { Debug.Assert(propertySymbol != null); Debug.Assert(propertyType != null); Property = new PropWithType(propertySymbol, propertyType); }
// Value public Expr BindValue(Expr exprSrc) { Debug.Assert(exprSrc != null && exprSrc.Type is NullableType); // For new T?(x), the answer is x. if (IsNullableConstructor(exprSrc, out ExprCall call)) { var args = call.OptionalArguments; Debug.Assert(args != null && !(args is ExprList)); return(args); } NullableType nubSrc = (NullableType)exprSrc.Type; CType typeBase = nubSrc.GetUnderlyingType(); AggregateType ats = nubSrc.GetAts(); PropertySymbol prop = GetSymbolLoader().getBSymmgr().propNubValue; if (prop == null) { prop = GetSymbolLoader().getPredefinedMembers().GetProperty(PREDEFPROP.PP_G_OPTIONAL_VALUE); Debug.Assert(prop != null); GetSymbolLoader().getBSymmgr().propNubValue = prop; } PropWithType pwt = new PropWithType(prop, ats); MethPropWithInst mpwi = new MethPropWithInst(prop, ats); ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(exprSrc, mpwi); return(GetExprFactory().CreateProperty(typeBase, null, null, pMemGroup, pwt, null)); }
// Value public EXPR BindValue(EXPR exprSrc) { Debug.Assert(exprSrc != null && exprSrc.type.IsNullableType()); // For new T?(x), the answer is x. if (CNullable.IsNullableConstructor(exprSrc)) { Debug.Assert(exprSrc.asCALL().GetOptionalArguments() != null && !exprSrc.asCALL().GetOptionalArguments().isLIST()); return(exprSrc.asCALL().GetOptionalArguments()); } CType typeBase = exprSrc.type.AsNullableType().GetUnderlyingType(); AggregateType ats = exprSrc.type.AsNullableType().GetAts(GetErrorContext()); if (ats == null) { EXPRPROP rval = GetExprFactory().CreateProperty(typeBase, exprSrc); rval.SetError(); return(rval); } // UNDONE: move this to transform pass ... PropertySymbol prop = GetSymbolLoader().getBSymmgr().propNubValue; if (prop == null) { prop = GetSymbolLoader().getPredefinedMembers().GetProperty(PREDEFPROP.PP_G_OPTIONAL_VALUE); GetSymbolLoader().getBSymmgr().propNubValue = prop; } PropWithType pwt = new PropWithType(prop, ats); MethWithType mwt = new MethWithType(prop != null ? prop.methGet : null, ats); MethPropWithInst mpwi = new MethPropWithInst(prop, ats); EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(exprSrc, mpwi); EXPRPROP exprRes = GetExprFactory().CreateProperty(typeBase, null, null, pMemGroup, pwt, mwt, null); if (prop == null) { exprRes.SetError(); } return(exprRes); }
// Value public Expr BindValue(Expr exprSrc) { Debug.Assert(exprSrc != null && exprSrc.Type.IsNullableType()); // For new T?(x), the answer is x. if (IsNullableConstructor(exprSrc, out ExprCall call)) { var args = call.OptionalArguments; Debug.Assert(args != null && !(args is ExprList)); return(args); } CType typeBase = exprSrc.Type.AsNullableType().GetUnderlyingType(); AggregateType ats = exprSrc.Type.AsNullableType().GetAts(GetErrorContext()); if (ats == null) { ExprProperty rval = GetExprFactory().CreateProperty(typeBase, exprSrc); rval.SetError(); return(rval); } PropertySymbol prop = GetSymbolLoader().getBSymmgr().propNubValue; if (prop == null) { prop = GetSymbolLoader().getPredefinedMembers().GetProperty(PREDEFPROP.PP_G_OPTIONAL_VALUE); GetSymbolLoader().getBSymmgr().propNubValue = prop; } PropWithType pwt = new PropWithType(prop, ats); MethWithType mwt = new MethWithType(prop?.methGet, ats); MethPropWithInst mpwi = new MethPropWithInst(prop, ats); ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(exprSrc, mpwi); ExprProperty exprRes = GetExprFactory().CreateProperty(typeBase, null, null, pMemGroup, pwt, mwt, null); if (prop == null) { exprRes.SetError(); } return(exprRes); }
// If we have this.prop = 123, but the implementation of the property is in the // base class, then the object is of the base class type. Note that to get // the object, we must go through the MEMGRP. // // "throughObject" is // of the type we are actually calling through. (We need to know the // "through" type to ensure that protected semantics are correctly enforced.) public ExprProperty(CType type, Expr pOptionalObjectThrough, Expr pOptionalArguments, ExprMemberGroup pMemberGroup, PropWithType pwtSlot, MethWithType mwtSet) : base(ExpressionKind.Property, type) { OptionalObjectThrough = pOptionalObjectThrough; OptionalArguments = pOptionalArguments; MemberGroup = pMemberGroup; if (pwtSlot != null) { PropWithTypeSlot = pwtSlot; } if (mwtSet != null) { MethWithTypeSet = mwtSet; if (!HasIsExternalInitModifier(mwtSet)) { Flags = EXPRFLAG.EXF_LVALUE; } } }
public static ExprProperty CreateProperty(CType type, Expr optionalObjectThrough, Expr arguments, ExprMemberGroup memberGroup, PropWithType property, MethWithType setMethod) => new ExprProperty(type, optionalObjectThrough, arguments, memberGroup, property, setMethod);
public EXPRPROP CreateProperty(CType pType, EXPR pOptionalObjectThrough, EXPR pOptionalArguments, EXPRMEMGRP pMemberGroup, PropWithType pwtSlot, MethWithType mwtGet, MethWithType mwtSet) { EXPRPROP rval = new EXPRPROP(); rval.kind = ExpressionKind.EK_PROP; rval.type = pType; rval.flags = 0; rval.SetOptionalObjectThrough(pOptionalObjectThrough); rval.SetOptionalArguments(pOptionalArguments); rval.SetMemberGroup(pMemberGroup); if (pwtSlot != null) { rval.pwtSlot = pwtSlot; } if (mwtSet != null) { rval.mwtSet = mwtSet; } Debug.Assert(rval != null); return(rval); }
public ExprProperty CreateProperty(CType pType, Expr pOptionalObjectThrough, Expr pOptionalArguments, ExprMemberGroup pMemberGroup, PropWithType pwtSlot, MethWithType mwtGet, MethWithType mwtSet) { ExprProperty rval = new ExprProperty(); rval.Kind = ExpressionKind.EK_PROP; rval.Type = pType; rval.Flags = 0; rval.OptionalObjectThrough = pOptionalObjectThrough; rval.OptionalArguments = pOptionalArguments; rval.MemberGroup = pMemberGroup; if (pwtSlot != null) { rval.PropWithTypeSlot = pwtSlot; } if (mwtSet != null) { rval.MethWithTypeSet = mwtSet; } Debug.Assert(rval != null); return(rval); }
///////////////////////////////////////////////////////////////////////////////// private EXPR CreateProperty( SymWithType swt, EXPR callingObject, BindingFlag flags) { // For a property, we simply create the EXPRPROP for the thing, call the // expression tree rewriter, rewrite it, and send it on its way. PropertySymbol property = swt.Prop(); AggregateType propertyType = swt.GetType(); PropWithType pwt = new PropWithType(property, propertyType); EXPRMEMGRP pMemGroup = CreateMemberGroupEXPR(property.name.Text, null, callingObject, SYMKIND.SK_PropertySymbol); return _binder.BindToProperty(// For a static property instance, don't set the object. callingObject.isCLASS() ? null : callingObject, pwt, flags, null, null, pMemGroup); }
//////////////////////////////////////////////////////////////////////////////// internal EXPR BindToProperty(EXPR pObject, PropWithType pwt, BindingFlag bindFlags, EXPR args, AggregateType pOtherType, EXPRMEMGRP pMemGroup) { Debug.Assert(pwt.Sym != null && pwt.Sym.IsPropertySymbol() && pwt.GetType() != null && pwt.Prop().getClass() == pwt.GetType().getAggregate()); Debug.Assert(pwt.Prop().Params.size == 0 || pwt.Prop().isIndexer()); Debug.Assert(pOtherType == null || !pwt.Prop().isIndexer() && pOtherType.getAggregate() == pwt.Prop().RetType.getAggregate()); bool fConstrained; MethWithType mwtGet; MethWithType mwtSet; EXPR pObjectThrough = null; // We keep track of the type of the pObject which we're doing the call through so that we can report // protection access errors later, either below when binding the get, or later when checking that // the setter is actually an lvalue. If we're actually doing a base.prop call then we do not // need to ensure that the left side of the dot is an instance of the derived class, otherwise // we save it away for later. if (0 == (bindFlags & BindingFlag.BIND_BASECALL)) { pObjectThrough = pObject; } bool bIsMatchingStatic; PostBindProperty((bindFlags & BindingFlag.BIND_BASECALL) != 0, pwt, pObject, out mwtGet, out mwtSet); if (mwtGet && (!mwtSet || mwtSet.GetType() == mwtGet.GetType() || GetSymbolLoader().HasBaseConversion(mwtGet.GetType(), mwtSet.GetType()) ) ) { pObject = AdjustMemberObject(mwtGet, pObject, out fConstrained, out bIsMatchingStatic); } else if (mwtSet) { pObject = AdjustMemberObject(mwtSet, pObject, out fConstrained, out bIsMatchingStatic); } else { pObject = AdjustMemberObject(pwt, pObject, out fConstrained, out bIsMatchingStatic); } pMemGroup.SetOptionalObject(pObject); CType pReturnType = GetTypes().SubstType(pwt.Prop().RetType, pwt.GetType()); Debug.Assert(pOtherType == pReturnType || pOtherType == null); if (pObject != null && !pObject.isOK()) { EXPRPROP pResult = GetExprFactory().CreateProperty(pReturnType, pObjectThrough, args, pMemGroup, pwt, null, null); if (!bIsMatchingStatic) { pResult.SetMismatchedStaticBit(); } pResult.SetError(); return pResult; } // if we are doing a get on this thing, and there is no get, and // most importantly, we are not leaving the arguments to be bound by the array index // then error... if ((bindFlags & BindingFlag.BIND_RVALUEREQUIRED) != 0) { if (!mwtGet) { if (pOtherType != null) { return GetExprFactory().MakeClass(pOtherType); } ErrorContext.ErrorRef(ErrorCode.ERR_PropertyLacksGet, pwt); } else if (((bindFlags & BindingFlag.BIND_BASECALL) != 0) && mwtGet.Meth().isAbstract) { // if the get exists, but is abstract, forbid the call as well... if (pOtherType != null) { return GetExprFactory().MakeClass(pOtherType); } ErrorContext.Error(ErrorCode.ERR_AbstractBaseCall, pwt); } else { CType type = null; if (pObjectThrough != null) { type = pObjectThrough.type; } ACCESSERROR error = SemanticChecker.CheckAccess2(mwtGet.Meth(), mwtGet.GetType(), ContextForMemberLookup(), type); if (error != ACCESSERROR.ACCESSERROR_NOERROR) { // if the get exists, but is not accessible, give an error. if (pOtherType != null) { return GetExprFactory().MakeClass(pOtherType); } if (error == ACCESSERROR.ACCESSERROR_NOACCESSTHRU) { ErrorContext.Error(ErrorCode.ERR_BadProtectedAccess, pwt, type, ContextForMemberLookup()); } else { ErrorContext.ErrorRef(ErrorCode.ERR_InaccessibleGetter, pwt); } } } } EXPRPROP result = GetExprFactory().CreateProperty(pReturnType, pObjectThrough, args, pMemGroup, pwt, mwtGet, mwtSet); if (!bIsMatchingStatic) { result.SetMismatchedStaticBit(); } Debug.Assert(EXPRFLAG.EXF_BASECALL == (EXPRFLAG)BindingFlag.BIND_BASECALL); if ((EXPRFLAG.EXF_BASECALL & (EXPRFLAG)bindFlags) != 0) { result.flags |= EXPRFLAG.EXF_BASECALL; } else if (fConstrained && pObject != null) { // Use the constrained prefix. result.flags |= EXPRFLAG.EXF_CONSTRAINED; } if (result.GetOptionalArguments() != null) { verifyMethodArgs(result, pObjectThrough != null ? pObjectThrough.type : null); } if (mwtSet && objectIsLvalue(result.GetMemberGroup().GetOptionalObject())) { result.flags |= EXPRFLAG.EXF_LVALUE; } if (pOtherType != null) { result.flags |= EXPRFLAG.EXF_SAMENAMETYPE; } return result; }
//////////////////////////////////////////////////////////////////////////////// internal EXPR BindToField(EXPR pOptionalObject, FieldWithType fwt, BindingFlag bindFlags, EXPR pOptionalLHS) { Debug.Assert(fwt.GetType() != null && fwt.Field().getClass() == fwt.GetType().getAggregate()); CType pFieldType = GetTypes().SubstType(fwt.Field().GetType(), fwt.GetType()); if (pOptionalObject != null && !pOptionalObject.isOK()) { EXPRFIELD pField = GetExprFactory().CreateField(0, pFieldType, pOptionalObject, 0, fwt, pOptionalLHS); pField.SetError(); return pField; } EXPR pOriginalObject = pOptionalObject; bool bIsMatchingStatic; bool pfConstrained; pOptionalObject = AdjustMemberObject(fwt, pOptionalObject, out pfConstrained, out bIsMatchingStatic); checkUnsafe(pFieldType); // added to the binder so we don't bind to pointer ops EXPRFIELD pResult; { bool isLValue = false; if ((pOptionalObject != null && pOptionalObject.type.IsPointerType()) || objectIsLvalue(pOptionalObject)) { isLValue = true; } // Exception: a readonly field is not an lvalue unless we're in the constructor/static constructor appropriate // for the field. if (RespectReadonly() && fwt.Field().isReadOnly) { if (ContainingAgg() == null || !InMethod() || !InConstructor() || fwt.Field().getClass() != ContainingAgg() || InStaticMethod() != fwt.Field().isStatic || (pOptionalObject != null && !isThisPointer(pOptionalObject)) || InAnonymousMethod()) { isLValue = false; } } pResult = GetExprFactory().CreateField(isLValue ? EXPRFLAG.EXF_LVALUE : 0, pFieldType, pOptionalObject, 0, fwt, pOptionalLHS); if (!bIsMatchingStatic) { pResult.SetMismatchedStaticBit(); } if (pFieldType.IsErrorType()) { pResult.SetError(); } Debug.Assert(BindingFlag.BIND_MEMBERSET == (BindingFlag)EXPRFLAG.EXF_MEMBERSET); pResult.flags |= (EXPRFLAG)(bindFlags & BindingFlag.BIND_MEMBERSET); } // If this field is the backing field of a WindowsRuntime event then we need to bind to its // invocationlist property which is a delegate containing all the handlers. if (pResult.isFIELD() && fwt.Field().isEvent && fwt.Field().getEvent(GetSymbolLoader()) != null && fwt.Field().getEvent(GetSymbolLoader()).IsWindowsRuntimeEvent) { CType fieldType = fwt.Field().GetType(); if (fieldType.IsAggregateType()) { // Access event backing field (EventRegistrationTokenTable<T>) using // EventRegistrationTokenTable<T>.GetOrCreateEventRegistrationTokenTable() // to ensure non-null pResult.setType(GetTypes().GetParameterModifier(pResult.type, false)); Name getOrCreateMethodName = GetSymbolLoader().GetNameManager().GetPredefName(PredefinedName.PN_GETORCREATEEVENTREGISTRATIONTOKENTABLE); GetSymbolLoader().RuntimeBinderSymbolTable.PopulateSymbolTableWithName(getOrCreateMethodName.Text, null, fieldType.AssociatedSystemType); MethodSymbol getOrCreateMethod = GetSymbolLoader().LookupAggMember(getOrCreateMethodName, fieldType.getAggregate(), symbmask_t.MASK_MethodSymbol).AsMethodSymbol(); MethPropWithInst getOrCreatempwi = new MethPropWithInst(getOrCreateMethod, fieldType.AsAggregateType()); EXPRMEMGRP getOrCreateGrp = GetExprFactory().CreateMemGroup(null, getOrCreatempwi); EXPR getOrCreateCall = BindToMethod(new MethWithInst(getOrCreatempwi), pResult, getOrCreateGrp, (MemLookFlags)MemLookFlags.None); AggregateSymbol fieldTypeSymbol = fieldType.AsAggregateType().GetOwningAggregate(); Name invocationListName = GetSymbolLoader().GetNameManager().GetPredefName(PredefinedName.PN_INVOCATIONLIST); // InvocationList might not be populated in the symbol table as no one would have called it. GetSymbolLoader().RuntimeBinderSymbolTable.PopulateSymbolTableWithName(invocationListName.Text, null, fieldType.AssociatedSystemType); PropertySymbol invocationList = GetSymbolLoader().LookupAggMember( invocationListName, fieldTypeSymbol, symbmask_t.MASK_PropertySymbol).AsPropertySymbol(); MethPropWithInst mpwi = new MethPropWithInst(invocationList, fieldType.AsAggregateType()); EXPRMEMGRP memGroup = GetExprFactory().CreateMemGroup(getOrCreateCall, mpwi); PropWithType pwt = new PropWithType(invocationList, fieldType.AsAggregateType()); EXPR propertyExpr = BindToProperty(getOrCreateCall, pwt, bindFlags, null, null, memGroup); return propertyExpr; } } return pResult; }
protected void PostBindProperty(bool fBaseCall, PropWithType pwt, EXPR pObject, out MethWithType pmwtGet, out MethWithType pmwtSet) { pmwtGet = new MethWithType(); pmwtSet = new MethWithType(); // Get the accessors. if (pwt.Prop().methGet != null) { pmwtGet.Set(pwt.Prop().methGet, pwt.GetType()); } else { pmwtGet.Clear(); } if (pwt.Prop().methSet != null) { pmwtSet.Set(pwt.Prop().methSet, pwt.GetType()); } else { pmwtSet.Clear(); } // If it is virtual, find a remap of the method to something more specific. This // may alter where the accessors are found. if (fBaseCall && pObject != null) { if (pmwtGet) { RemapToOverride(GetSymbolLoader(), pmwtGet, pObject.type); } if (pmwtSet) { RemapToOverride(GetSymbolLoader(), pmwtSet, pObject.type); } } if (pwt.Prop().RetType != null) { checkUnsafe(pwt.Prop().RetType); } }
protected bool CheckPropertyAccess(MethWithType mwt, PropWithType pwtSlot, CType type) { ACCESSERROR error = SemanticChecker.CheckAccess2(mwt.Meth(), mwt.GetType(), ContextForMemberLookup(), type); if (error == ACCESSERROR.ACCESSERROR_NOACCESSTHRU) { ErrorContext.Error(ErrorCode.ERR_BadProtectedAccess, pwtSlot, type, ContextForMemberLookup()); return false; } else if (error == ACCESSERROR.ACCESSERROR_NOACCESS) { ErrorContext.Error(mwt.Meth().isSetAccessor() ? ErrorCode.ERR_InaccessibleSetter : ErrorCode.ERR_InaccessibleGetter, pwtSlot); return false; } return true; }
// Value public EXPR BindValue(EXPR exprSrc) { Debug.Assert(exprSrc != null && exprSrc.type.IsNullableType()); // For new T?(x), the answer is x. if (CNullable.IsNullableConstructor(exprSrc)) { Debug.Assert(exprSrc.asCALL().GetOptionalArguments() != null && !exprSrc.asCALL().GetOptionalArguments().isLIST()); return exprSrc.asCALL().GetOptionalArguments(); } CType typeBase = exprSrc.type.AsNullableType().GetUnderlyingType(); AggregateType ats = exprSrc.type.AsNullableType().GetAts(GetErrorContext()); if (ats == null) { EXPRPROP rval = GetExprFactory().CreateProperty(typeBase, exprSrc); rval.SetError(); return rval; } PropertySymbol prop = GetSymbolLoader().getBSymmgr().propNubValue; if (prop == null) { prop = GetSymbolLoader().getPredefinedMembers().GetProperty(PREDEFPROP.PP_G_OPTIONAL_VALUE); GetSymbolLoader().getBSymmgr().propNubValue = prop; } PropWithType pwt = new PropWithType(prop, ats); MethWithType mwt = new MethWithType(prop != null ? prop.methGet : null, ats); MethPropWithInst mpwi = new MethPropWithInst(prop, ats); EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(exprSrc, mpwi); EXPRPROP exprRes = GetExprFactory().CreateProperty(typeBase, null, null, pMemGroup, pwt, mwt, null); if (prop == null) { exprRes.SetError(); } return exprRes; }
public ExprProperty CreateProperty(CType pType, Expr pOptionalObjectThrough, Expr pOptionalArguments, ExprMemberGroup pMemberGroup, PropWithType pwtSlot, MethWithType mwtGet, MethWithType mwtSet) { ExprProperty rval = new ExprProperty(pType); rval.OptionalObjectThrough = pOptionalObjectThrough; rval.OptionalArguments = pOptionalArguments; rval.MemberGroup = pMemberGroup; if (pwtSlot != null) { rval.PropWithTypeSlot = pwtSlot; } if (mwtSet != null) { rval.MethWithTypeSet = mwtSet; } return(rval); }
public EXPRPROP CreateProperty(CType pType, EXPR pOptionalObjectThrough, EXPR pOptionalArguments, EXPRMEMGRP pMemberGroup, PropWithType pwtSlot, MethWithType mwtGet, MethWithType mwtSet) { EXPRPROP rval = new EXPRPROP(); rval.kind = ExpressionKind.EK_PROP; rval.type = pType; rval.flags = 0; rval.SetOptionalObjectThrough(pOptionalObjectThrough); rval.SetOptionalArguments(pOptionalArguments); rval.SetMemberGroup(pMemberGroup); if (pwtSlot != null) { rval.pwtSlot = pwtSlot; } if (mwtSet != null) { rval.mwtSet = mwtSet; } Debug.Assert(rval != null); return (rval); }