Ejemplo n.º 1
0
        /// <summary>
        /// Helper method getting parameter type.
        /// </summary>
        /// <param name="typeCtx">Routine type context.</param>
        /// <param name="paramTag">PHPDoc param tag if available.</param>
        /// <param name="signature">Call signature.</param>
        /// <param name="call">Call information if called specifically with given context.</param>
        /// <param name="paramIndex">Parameter index.</param>
        /// <returns>Expected type of parameter. Cannot be uninitialized.</returns>
        private static TypeRefMask GetParamType(TypeRefContext /*!*/ typeCtx, PHPDocBlock.ParamTag paramTag, FormalParam syntax, CallInfo call, int paramIndex)
        {
            Contract.ThrowIfNull(typeCtx);
            Debug.Assert(paramIndex >= 0);

            TypeRefMask result     = 0;
            bool        isvariadic = false;
            bool        isalias    = false;

            // lookup actual type hint
            if (syntax != null)
            {
                isvariadic = syntax.IsVariadic;
                isalias    = syntax.PassedByRef || syntax.IsOut;

                var hint = syntax.TypeHint;
                if (hint != null)
                {
                    result = typeCtx.GetTypeMaskFromTypeHint(syntax.TypeHint);

                    if (isvariadic) // PHP 5.6 variadic parameter (...) // TypeHint -> TypeHint[]
                    {
                        result = typeCtx.GetArrayTypeMask(result);
                    }
                }
            }

            if (result.IsUninitialized)
            {
                // lookup callInfo
                result = call.GetParamType(typeCtx, paramIndex);
                if (result.IsUninitialized)
                {
                    // lookup PHPDoc
                    if (paramTag != null && paramTag.TypeNamesArray.Length != 0)
                    {
                        result = PHPDoc.GetTypeMask(typeCtx, paramTag.TypeNamesArray);
                    }

                    if (result.IsUninitialized)
                    {
                        // NOTE: if still unknown, we can use type of the FormalParam.InitValue as Hint
                        result = TypeRefMask.AnyType;
                    }
                }

                // PHP 5.6, variadic parameter (...) is always of type array,
                // if specified else, user meant type of its elements
                if (isvariadic && !typeCtx.IsArray(result))
                {
                    result = typeCtx.GetArrayTypeMask(result);  // hint -> hint[]
                }
            }

            //
            result.IsRef = isalias;

            //
            Debug.Assert(!result.IsUninitialized);
            return(result);
        }