Exemple #1
0
        BoundExpression BindSimpleVarUse(AST.SimpleVarUse expr, BoundAccess access)
        {
            var dexpr = expr as AST.DirectVarUse;
            var iexpr = expr as AST.IndirectVarUse;

            Debug.Assert(dexpr != null || iexpr != null);

            var varname = (dexpr != null)
                ? new BoundVariableName(dexpr.VarName)
                : new BoundVariableName(BindExpression(iexpr.VarNameEx));

            if (expr.IsMemberOf == null)
            {
                return(new BoundVariableRef(varname));
            }
            else
            {
                var instanceAccess = BoundAccess.Read;

                if (access.IsWrite || access.EnsureObject || access.EnsureArray)
                {
                    instanceAccess = instanceAccess.WithEnsureObject();
                }

                if (access.IsQuiet)
                {
                    instanceAccess = instanceAccess.WithQuiet();
                }

                return(BoundFieldRef.CreateInstanceField(BindExpression(expr.IsMemberOf, instanceAccess), varname).WithAccess(access));
            }
        }
Exemple #2
0
        BoundExpression BindConstUse(AST.ConstantUse x)
        {
            if (x is AST.GlobalConstUse)
            {
                return(BindGlobalConstUse((AST.GlobalConstUse)x));
            }

            if (x is AST.ClassConstUse)
            {
                var cx      = (AST.ClassConstUse)x;
                var typeref = BindTypeRef(cx.TargetType);

                if (cx.Name.Equals("class"))   // pseudo class constant
                {
                    return(new BoundPseudoClassConst(typeref, AST.PseudoClassConstUse.Types.Class));
                }

                return(BoundFieldRef.CreateClassConst(typeref, new BoundVariableName(cx.Name)));
            }

            throw ExceptionUtilities.UnexpectedValue(x);
        }
Exemple #3
0
        BoundExpression BindConstUse(AST.ConstantUse x)
        {
            if (x is AST.GlobalConstUse)
            {
                return(BindGlobalConstUse((AST.GlobalConstUse)x));
            }

            if (x is AST.ClassConstUse)
            {
                var cx    = (AST.ClassConstUse)x;
                var dtype = cx.TypeRef as AST.DirectTypeRef;
                if (dtype != null && cx.Name.Equals("class"))   // Type::class ~ "Type"
                {
                    return(new BoundLiteral(dtype.ClassName.ToString()));
                }

                var typeref = BindTypeRef(cx.TypeRef);

                return(BoundFieldRef.CreateClassConst(typeref, new BoundVariableName(cx.Name)));
            }

            throw ExceptionUtilities.UnexpectedValue(x);
        }
Exemple #4
0
        BoundExpression BindFieldUse(AST.StaticFieldUse x, BoundAccess access)
        {
            var typeref = BindTypeRef(x.TypeRef);
            BoundVariableName varname;

            if (x is AST.DirectStFldUse)
            {
                var dx = (AST.DirectStFldUse)x;
                varname = new BoundVariableName(dx.PropertyName);
            }
            else if (x is AST.IndirectStFldUse)
            {
                var ix            = (AST.IndirectStFldUse)x;
                var fieldNameExpr = BindExpression(ix.FieldNameExpr, BoundAccess.Read);

                varname = new BoundVariableName(fieldNameExpr);
            }
            else
            {
                throw ExceptionUtilities.UnexpectedValue(x);
            }

            return(BoundFieldRef.CreateStaticField(typeref, varname));
        }
Exemple #5
0
 public virtual void VisitFieldRef(BoundFieldRef x)
 {
     VisitTypeRef(x.ParentType);
     Accept(x.Instance);
     Accept(x.FieldName.NameExpression);
 }
 public virtual TResult VisitFieldRef(BoundFieldRef x) => DefaultVisitOperation(x);
Exemple #7
0
 public BoundIndirectStFieldPlace(BoundTypeRef typeref, BoundVariableName fldname, BoundFieldRef boundref)
 {
     _type = typeref;
     _name = fldname;
     _boundref = boundref;
 }
        public virtual void VisitFieldRef(BoundFieldRef x)
        {

        }
        public override void VisitFieldRef(BoundFieldRef x)
        {
            Accept(x.Instance);
            VisitTypeRef(x.ParentType);
            Accept(x.FieldName.NameExpression);

            if (x.IsInstanceField)  // {Instance}->FieldName
            {
                Debug.Assert(x.Instance != null);
                Debug.Assert(x.Instance.Access.IsRead);

                // resolve field if possible
                var typerefs = TypeCtx.GetTypes(x.Instance.TypeRefMask);
                if (typerefs.Count == 1 && typerefs[0].IsObject)
                {
                    // TODO: x.Instance.ResultType instead of following

                    var t = (NamedTypeSymbol)_model.GetType(typerefs[0].QualifiedName);
                    if (t != null)
                    {
                        if (x.FieldName.IsDirect)
                        {
                            // TODO: visibility and resolution (model)

                            var field = t.LookupMember<FieldSymbol>(x.FieldName.NameValue.Value);
                            if (field != null)
                            {
                                x.BoundReference = new BoundFieldPlace(x.Instance, field, x);
                                x.TypeRefMask = field.GetResultType(TypeCtx);
                                return;
                            }
                            else
                            {
                                var prop = t.LookupMember<PropertySymbol>(x.FieldName.NameValue.Value);
                                if (prop != null)
                                {
                                    x.BoundReference = new BoundPropertyPlace(x.Instance, prop);
                                    x.TypeRefMask = TypeRefFactory.CreateMask(TypeCtx, prop.Type);
                                    return;
                                }
                                else
                                {
                                    // TODO: use runtime fields directly, __get, __set, etc.,
                                    // do not fallback to BoundIndirectFieldPlace
                                }
                            }
                        }
                    }

                }

                // dynamic behavior
                // indirect field access ...

                x.BoundReference = new BoundIndirectFieldPlace(x.Instance, x.FieldName, x.Access);
                x.TypeRefMask = TypeRefMask.AnyType;
                return;
            }

            // static fields or constants
            if (x.IsStaticField || x.IsClassConstant)    // {ClassName}::${StaticFieldName}, {ClassName}::{ConstantName}
            {
                var ParentType = (NamedTypeSymbol)x.ParentType.ResolvedType;

                if (x.IsClassConstant)
                {
                    Debug.Assert(x.Access.IsRead);
                    Debug.Assert(!x.Access.IsEnsure && !x.Access.IsWrite && !x.Access.IsReadRef);
                }

                if (ParentType != null && x.FieldName.IsDirect)
                {
                    var fldname = x.FieldName.NameValue.Value;
                    var field = x.IsStaticField ? ParentType.ResolveStaticField(fldname) : ParentType.ResolveClassConstant(fldname);
                    if (field != null)
                    {
                        // TODO: visibility -> ErrCode

                        Debug.Assert(
                            field.IsConst ||    // .NET constant
                            field.IsStatic ||   // .NET static
                            field.ContainingType.TryGetStatics().LookupMember<FieldSymbol>(x.FieldName.NameValue.Value) != null); // or PHP context static

                        if (BindConstantValue(x, field))
                        {
                            Debug.Assert(x.Access.IsRead && !x.Access.IsWrite && !x.Access.IsEnsure);
                            x.BoundReference = null; // not reachable
                        }
                        else
                        {
                            x.BoundReference = field.IsStatic
                                ? new BoundFieldPlace(null, field, x)        // the field is real .NET static member (CLR static fields)
                                : new BoundPhpStaticFieldPlace(field, x);    // the field is contained in special __statics container (fields & constants)
                        }

                        x.TypeRefMask = field.GetResultType(TypeCtx);
                        return;
                    }
                    else if (x.IsStaticField)
                    {
                        // TODO: visibility
                        var prop = ParentType.LookupMember<PropertySymbol>(fldname);
                        if (prop != null && prop.IsStatic)
                        {
                            x.BoundReference = new BoundPropertyPlace(null, prop);
                            x.TypeRefMask = TypeRefFactory.CreateMask(TypeCtx, prop.Type);
                            return;
                        }
                    }

                    // TODO: __getStatic, __setStatic
                }

                // indirect field access:
                // indirect field access with known class name:
                x.BoundReference = new BoundIndirectStFieldPlace(x.ParentType, x.FieldName, x);
                x.TypeRefMask = TypeRefMask.AnyType;
                return;
            }
        }
Exemple #10
0
 public virtual void VisitFieldRef(BoundFieldRef x)
 {
 }