Esempio n. 1
0
        /// <summary>
        /// Sets type of local variable in current state.
        /// </summary>
        protected virtual TypeRefMask SetVar(string name, TypeRefMask typemask)
        {
            AssertState();

            _state.SetVar(name, typemask);
            return(typemask);
        }
Esempio n. 2
0
        /// <summary>
        /// Creates new type context, flow context and flow state for the routine.
        /// </summary>
        public static FlowState CreateInitialState(SourceRoutineSymbol /*!*/ routine)
        {
            Contract.ThrowIfNull(routine);

            // create typeCtx
            var typeCtx = routine.TypeRefContext;

            // create FlowContext
            var flowCtx = new FlowContext(typeCtx, routine);

            // create FlowState
            var state = new FlowState(flowCtx);

            // handle input parameters type
            var parameters = routine.Parameters.OfType <SourceParameterSymbol>().ToImmutableArray();

            foreach (var p in parameters)
            {
                state.SetVar(p.Name, p.GetResultType(typeCtx));

                if (p.Syntax.PassedByRef)
                {
                    state.SetVarRef(p.Name);
                }
            }

            // $this
            if (routine.HasThis)
            {
                InitThisVar(flowCtx, state);
            }

            //
            return(state);
        }
Esempio n. 3
0
 /// <summary>
 /// Sets the initial routine return type.
 /// </summary>
 /// <param name="ctx"></param>
 /// <param name="initialState"></param>
 /// <param name="phpdoc"></param>
 static void InitReturn(FlowContext /*!*/ ctx, FlowState /*!*/ initialState, PHPDocBlock phpdoc)
 {
     Debug.Assert(ctx.ReturnVarIndex >= 0);
     if (phpdoc != null)
     {
         var returnTag = phpdoc.Returns;
         if (returnTag != null && returnTag.TypeNamesArray.Length != 0)
         {
             initialState.SetVar(ctx.ReturnVarIndex, PHPDoc.GetTypeMask(ctx.TypeRefContext, returnTag.TypeNamesArray));
         }
     }
 }
Esempio n. 4
0
        /// <summary>
        /// Initializes <c>$this</c> variable, its type and initialized state.
        /// </summary>
        private static void InitThisVar(FlowContext /*!*/ ctx, FlowState /*!*/ initialState, int varIndex)
        {
            var thisVarType = ctx.TypeRefContext.GetThisTypeMask();

            if (thisVarType.IsUninitialized)
            {
                thisVarType = TypeRefMask.AnyType;
            }

            //
            initialState.SetVarUsed(varIndex);
            initialState.SetVar(varIndex, thisVarType);
        }
Esempio n. 5
0
        /// <summary>
        /// Initializes <c>$this</c> variable, its type and initialized state.
        /// </summary>
        private static void InitThisVar(FlowContext /*!*/ ctx, FlowState /*!*/ initialState)
        {
            var thisVarType = ctx.TypeRefContext.GetThisTypeMask();

            if (thisVarType.IsUninitialized)
            {
                thisVarType = TypeRefMask.AnyType;
            }

            //
            var thisIdx = ctx.GetVarIndex(VariableName.ThisVariableName);

            initialState.SetVarUsed(thisIdx);
            initialState.SetVar(thisIdx, thisVarType);
        }
Esempio n. 6
0
        /// <summary>
        /// Creates new type context, flow context and flow state for the routine.
        /// </summary>
        public static FlowState CreateInitialState(SourceRoutineSymbol routine)
        {
            Contract.ThrowIfNull(routine);

            var containingType = routine.ContainingType as SourceNamedTypeSymbol;

            // collect locals
            var locals    = LocalsBinder.BindLocals(routine);
            var returnIdx = locals.IndexOf(x => x.VariableKind == VariableKind.ReturnVariable);

            // create typeCtx
            var typeCtx = routine.TypeRefContext;

            // create FlowContext
            var flowCtx = new FlowContext(typeCtx, locals, returnIdx);

            // create FlowState
            var state = new FlowState(flowCtx, routine);

            // handle parameters passed by reference
            var parameters = routine.Parameters.OfType <SourceParameterSymbol>().ToImmutableArray();

            foreach (var p in parameters)
            {
                if (p.Syntax.PassedByRef)
                {
                    state.SetVarRef(p.Name);
                }
            }

            // mark $this as initialized
            // mark global variables as ByRef, used
            // mark function parameters as used, initialized, typed
            // construct initial state for variables

            int paramIdx = 0;

            for (int i = 0; i < locals.Length; i++)
            {
                switch (locals[i].VariableKind)
                {
                case VariableKind.GlobalVariable:
                    state.SetVarRef(i);     // => used, byref, initialized
                    break;

                case VariableKind.Parameter:
                    //state.SetVarUsed(i);
                    var paramtag = PHPDoc.GetParamTag(routine.PHPDocBlock, paramIdx, locals[i].Name);
                    state.SetVar(i, GetParamType(typeCtx, paramtag, parameters[paramIdx].Syntax, default(CallInfo), paramIdx));
                    paramIdx++;
                    break;

                //case VariableKind.UseParameter:
                //    state.SetVar(i, TypeRefMask.AnyType);
                //    break;
                case VariableKind.ThisParameter:
                    InitThisVar(flowCtx, state, i);
                    break;

                case VariableKind.StaticVariable:
                    state.SetVarInitialized(i);
                    break;

                case VariableKind.ReturnVariable:
                    InitReturn(flowCtx, state, routine.PHPDocBlock);
                    break;
                }
            }
            //
            return(state);
        }