isOK() public method

public isOK ( ) : bool
return bool
Beispiel #1
0
 public static bool isANYLOCAL_OK(this EXPR expr)
 {
     return(expr.isANYLOCAL() && expr.isOK());
 }
Beispiel #2
0
 public static bool isCONSTANT_OK(this EXPR expr)
 {
     return((expr == null) ? false : (expr.kind == ExpressionKind.EK_CONSTANT && expr.isOK()));
 }
Beispiel #3
0
        ////////////////////////////////////////////////////////////////////////////////

        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;
        }
Beispiel #4
0
        ////////////////////////////////////////////////////////////////////////////////

        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;
        }
Beispiel #5
0
        internal EXPR BindArrayIndexCore(BindingFlag bindFlags, EXPR pOp1, EXPR pOp2)
        {
            EXPR pExpr;
            bool bIsError = false;
            if (!pOp1.isOK() || !pOp2.isOK())
            {
                bIsError = true;
            }

            CType pIntType = GetReqPDT(PredefinedType.PT_INT);

            // Array indexing must occur on an array type.
            if (!pOp1.type.IsArrayType())
            {
                Debug.Assert(!pOp1.type.IsPointerType());
                pExpr = bindIndexer(pOp1, pOp2, bindFlags);
                if (bIsError)
                {
                    pExpr.SetError();
                }
                return pExpr;
            }
            ArrayType pArrayType = pOp1.type.AsArrayType();
            checkUnsafe(pArrayType.GetElementType()); // added to the binder so we don't bind to pointer ops
            // Check the rank of the array against the number of indices provided, and
            // convert the indexes to ints

            CType pDestType = chooseArrayIndexType(pOp2);

            if (null == pDestType)
            {
                // using int as the type will allow us to give a better error...
                pDestType = pIntType;
            }

            int rank = pArrayType.rank;
            int cIndices = 0;

            EXPR transformedIndices = pOp2.Map(GetExprFactory(),
                (EXPR x) =>
                {
                    cIndices++;
                    EXPR pTemp = mustConvert(x, pDestType);
                    if (pDestType == pIntType)
                        return pTemp;
#if CSEE
                    EXPRFLAG flag = 0;
#else
                    EXPRFLAG flag = EXPRFLAG.EXF_INDEXEXPR;
#endif
                    EXPRCLASS exprType = GetExprFactory().MakeClass(pDestType);
                    return GetExprFactory().CreateCast(flag, exprType, pTemp);
                });

            if (cIndices != rank)
            {
                ErrorContext.Error(ErrorCode.ERR_BadIndexCount, rank);
                pExpr = GetExprFactory().CreateArrayIndex(pOp1, transformedIndices);
                pExpr.SetError();
                return pExpr;
            }

            // Allocate a new expression, the type is the element type of the array.
            // Array index operations are always lvalues.
            pExpr = GetExprFactory().CreateArrayIndex(pOp1, transformedIndices);
            pExpr.flags |= EXPRFLAG.EXF_LVALUE | EXPRFLAG.EXF_ASSGOP;

            if (bIsError)
            {
                pExpr.SetError();
            }

            return pExpr;
        }
Beispiel #6
0
        ////////////////////////////////////////////////////////////////////////////////
        // Bind the simple assignment operator =.

        public EXPR bindAssignment(EXPR op1, EXPR op2, bool allowExplicit)
        {
            bool fOp2NotAddrOp = false;
            bool fOp2WasCast = false;

            if (!op1.isANYLOCAL_OK())
            {
                if (!checkLvalue(op1, CheckLvalueKind.Assignment))
                {
                    EXPR rval = GetExprFactory().CreateAssignment(op1, op2);
                    rval.SetError();
                    return rval;
                }
            }
            else
            {
                if (op2.type.IsArrayType())
                {
                    return BindPtrToArray(op1.asANYLOCAL(), op2);
                }
                if (op2.type == GetReqPDT(PredefinedType.PT_STRING))
                {
                    op2 = bindPtrToString(op2);
                }
                else if (op2.kind == ExpressionKind.EK_ADDR)
                {
                    op2.flags |= EXPRFLAG.EXF_ADDRNOCONV;
                }
                else if (op2.isOK())
                {
                    fOp2NotAddrOp = true;
                    fOp2WasCast = (op2.isCAST());
                }
            }

            op2 = GenerateAssignmentConversion(op1, op2, allowExplicit);
            if (op2.isOK() && fOp2NotAddrOp)
            {
                // Only report these errors if the convert succeeded
                if (fOp2WasCast)
                {
                    ErrorContext.Error(ErrorCode.ERR_BadCastInFixed);
                }
                else
                {
                    ErrorContext.Error(ErrorCode.ERR_FixedNotNeeded);
                }
            }
            return GenerateOptimizedAssignment(op1, op2);
        }
Beispiel #7
0
        ////////////////////////////////////////////////////////////////////////////////
        // A false return means not to process the expr any further - it's totally out
        // of place. For example - a method group or an anonymous method.
        internal bool checkLvalue(EXPR expr, CheckLvalueKind kind)
        {
            if (!expr.isOK())
                return false;
            if (expr.isLvalue())
            {
                if (expr.isPROP())
                {
                    CheckLvalueProp(expr.asPROP());
                }
                markFieldAssigned(expr);
                return true;
            }

            switch (expr.kind)
            {
                case ExpressionKind.EK_PROP:
                    if (kind == CheckLvalueKind.OutParameter)
                    {
                        // passing a property as ref or out
                        ErrorContext.Error(ErrorCode.ERR_RefProperty);
                        return true;
                    }
                    if (!expr.asPROP().mwtSet)
                    {
                        // Assigning to a property without a setter.
                        // If we have
                        // bool? b = true; (bool)b = false;
                        // then this is realized immediately as 
                        // b.Value = false; 
                        // and no ExpressionKind.EK_CAST is generated. We'd rather not give a "you're writing
                        // to a read-only property" error in the case where the property access
                        // is not explicit in the source code.  Fortunately in this case the
                        // cast is still hanging around in the parse tree, so we can look for it.

                        // POSSIBLE ERROR: It would be nice to also give this error for other situations
                        // POSSIBLE ERROR: in which the user is attempting to assign to a value, such as
                        // POSSIBLE ERROR: an explicit (bool)b.Value = false;
                        // POSSIBLE ERROR: Unfortunately we cannot use this trick in that situation because
                        // POSSIBLE ERROR: we've already discarded the OperatorKind.OP_CAST node.  (This is an SyntaxKind.Dot).

                        // SPEC VIOLATION: More generally:
                        // SPEC VIOLATION: The spec states that the result of any cast is a value, not a
                        // SPEC VIOLATION: variable. Unfortunately we do not correctly implement this
                        // SPEC VIOLATION: and we probably should not start implementing it because this
                        // SPEC VIOLATION: would be a breaking change.  We currently discard "no op" casts
                        // SPEC VIOLATION: very aggressively rather than generating an ExpressionKind.EK_CAST node.

                        ErrorContext.Error(ErrorCode.ERR_AssgReadonlyProp, expr.asPROP().pwtSlot);
                        return true;
                    }
                    break;

                case ExpressionKind.EK_ARRAYLENGTH:
                    if (kind == CheckLvalueKind.OutParameter)
                    {
                        // passing a property as ref or out
                        ErrorContext.Error(ErrorCode.ERR_RefProperty);
                    }
                    else
                    {
                        // Special case, the length property of an array
                        ErrorContext.Error(ErrorCode.ERR_AssgReadonlyProp, GetSymbolLoader().getPredefinedMembers().GetProperty(PREDEFPROP.PP_ARRAY_LENGTH));
                    }
                    return true;

                case ExpressionKind.EK_BOUNDLAMBDA:
                case ExpressionKind.EK_UNBOUNDLAMBDA:
                case ExpressionKind.EK_CONSTANT:
                    ErrorContext.Error(GetStandardLvalueError(kind));
                    return false;
                case ExpressionKind.EK_MEMGRP:
                    {
                        ErrorCode err = (kind == CheckLvalueKind.OutParameter) ? ErrorCode.ERR_RefReadonlyLocalCause : ErrorCode.ERR_AssgReadonlyLocalCause;
                        ErrorContext.Error(err, expr.asMEMGRP().name, new ErrArgIds(MessageID.MethodGroup));
                        return false;
                    }
                default:
                    break;
            }

            return !TryReportLvalueFailure(expr, kind);
        }