// Generates an error for static classes public RuntimeBinderException ReportStaticClassError(Symbol symCtx, CType CType, ErrorCode err) => ErrorContext.Error(err, symCtx != null ? new [] { CType, new ErrArg(symCtx) } : new ErrArg[] { CType });
private void TryReportLvalueFailure(Expr expr, CheckLvalueKind kind) { Debug.Assert(expr != null); // We have a lvalue failure. Was the reason because this field // was marked readonly? Give special messages for this case. bool isNested = false; // Did we recurse on a field or property to give a better error? while (true) { Debug.Assert(expr != null); if (expr is ExprLocal local && local.IsOK) { throw ReportLocalError(local.Local, kind, isNested); } Expr pObject = null; if (expr is ExprProperty prop) { // We've already reported read-only-property errors. Debug.Assert(prop.MethWithTypeSet != null); pObject = prop.MemberGroup.OptionalObject; } else if (expr is ExprField field) { if (field.FieldWithType.Field().isReadOnly) { throw ReportReadOnlyError(field, kind, isNested); } if (!field.FieldWithType.Field().isStatic) { pObject = field.OptionalObject; } } if (pObject != null && pObject.Type.isStructOrEnum()) { if (pObject is IExprWithArgs withArgs) { // assigning to RHS of method or property getter returning a value-type on the stack or // passing RHS of method or property getter returning a value-type on the stack, as ref or out throw ErrorContext.Error(ErrorCode.ERR_ReturnNotLValue, withArgs.GetSymWithType()); } if (pObject is ExprCast) { // An unboxing conversion. // // In the static compiler, we give the following error here: // ErrorContext.Error(pObject.GetTree(), ErrorCode.ERR_UnboxNotLValue); // // But in the runtime, we allow this - mark that we're doing an // unbox here, so that we gen the correct expression tree for it. pObject.Flags |= EXPRFLAG.EXF_UNBOXRUNTIME; return; } } // everything else if (pObject != null && !pObject.isLvalue() && (expr is ExprField || !isNested)) { Debug.Assert(pObject.Type.isStructOrEnum()); expr = pObject; } else { throw ErrorContext.Error(GetStandardLvalueError(kind)); } isNested = true; } }
// Return true if we actually report a failure. private bool TryReportLvalueFailure(EXPR expr, CheckLvalueKind kind) { Debug.Assert(expr != null); // We have a lvalue failure. Was the reason because this field // was marked readonly? Give special messages for this case. bool isNested = false; // Did we recurse on a field or property to give a better error? EXPR walk = expr; while (true) { Debug.Assert(walk != null); if (walk.isANYLOCAL_OK()) { ReportLocalError(walk.asANYLOCAL().local, kind, isNested); return(true); } EXPR pObject = null; if (walk.isPROP()) { // We've already reported read-only-property errors. Debug.Assert(walk.asPROP().mwtSet != null); pObject = walk.asPROP().GetMemberGroup().GetOptionalObject(); } else if (walk.isFIELD()) { EXPRFIELD field = walk.asFIELD(); if (field.fwt.Field().isReadOnly) { ReportReadOnlyError(field, kind, isNested); return(true); } if (!field.fwt.Field().isStatic) { pObject = field.GetOptionalObject(); } } if (pObject != null && pObject.type.isStructOrEnum()) { if (pObject.isCALL() || pObject.isPROP()) { // assigning to RHS of method or property getter returning a value-type on the stack or // passing RHS of method or property getter returning a value-type on the stack, as ref or out ErrorContext.Error(ErrorCode.ERR_ReturnNotLValue, pObject.GetSymWithType()); return(true); } if (pObject.isCAST()) { // An unboxing conversion. // // In the static compiler, we give the following error here: // ErrorContext.Error(pObject.GetTree(), ErrorCode.ERR_UnboxNotLValue); // // But in the runtime, we allow this - mark that we're doing an // unbox here, so that we gen the correct expression tree for it. pObject.flags |= EXPRFLAG.EXF_UNBOXRUNTIME; return(false); } } // everything else if (pObject != null && !pObject.isLvalue() && (walk.isFIELD() || (!isNested && walk.isPROP()))) { Debug.Assert(pObject.type.isStructOrEnum()); walk = pObject; } else { ErrorContext.Error(GetStandardLvalueError(kind)); return(true); } isNested = true; } }