IsArray() public method

Gets value indicating whether given type mask represents an array.
public IsArray ( TypeRefMask mask ) : bool
mask TypeRefMask
return bool
Ejemplo n.º 1
0
        ///// <summary>
        ///// Gets value determining whether <paramref name="totype"/> type can be assigned from <paramref name="fromtype"/>.
        ///// </summary>
        ///// <param name="totype">Type mask which we check whether is assignable from <paramref name="fromtype"/>.</param>
        ///// <param name="fromtype">Type mask we check whether is equal or is a subclass of <paramref name="totype"/>.</param>
        ///// <param name="ctx">Type context for resolving class names from type mask.</param>
        ///// <param name="model">Helper object which caches class inheritance.</param>
        ///// <remarks>
        ///// Gets <c>true</c>, if <paramref name="totype"/> is equal to or is a base type of <paramref name="fromtype"/>.
        ///// Gets <c>False</c> for <c>void</c> type masks.
        ///// </remarks>
        //public static bool IsAssignableFrom(this TypeRefMask totype, TypeRefMask fromtype, TypeRefContext/*!*/ctx, ISemanticModel/*!*/model)
        //{
        //    Debug.Assert(ctx != null);
        //    Debug.Assert(model != null);

        //    if ((totype & fromtype & ~(ulong)TypeRefMask.FlagsMask) != 0)
        //        return true;    // types are equal (or at least one of them is Any Type)

        //    // object <-> unspecified object instance
        //    if ((ctx.IsObject(totype) && ctx.IsObject(fromtype)) &&
        //        (ctx.IsAnObject(totype) || ctx.IsAnObject(fromtype)))
        //        return true;

        //    if (IsImplicitConversion(fromtype, totype, ctx, model))
        //        return true;

        //    // cut off object types (primitive types do not have subclasses)
        //    var selfObjs = ctx.GetObjectTypes(totype);
        //    if (selfObjs.Count == 0)
        //        return false;  // self mask does not represent a class

        //    var typeObjs = ctx.GetObjectTypes(fromtype);
        //    if (typeObjs.Count == 0)
        //        return false;  // type mask does not represent a class

        //    // build inheritance graph and check whether any type from self is a base of anything in type
        //    if (selfObjs.Count == 1 && typeObjs.Count == 1)
        //        return model.IsAssignableFrom(selfObjs[0].QualifiedName, typeObjs[0].QualifiedName);

        //    //
        //    return model.IsAssignableFrom(selfObjs.Select(t => t.QualifiedName), typeObjs.Select(t => t.QualifiedName));
        //}

        ///// <summary>
        ///// Determines whether there is an implicit conversion from one type to another.
        ///// </summary>
        //private static bool IsImplicitConversion(TypeRefMask fromtype, TypeRefMask totype, TypeRefContext/*!*/ctx, ISemanticModel/*!*/model)
        //{
        //    // TODO: optimize bit operations

        //    //
        //    if (ctx.IsArray(totype) && ctx.IsArray(fromtype))
        //    {
        //        // both types are arrays, type may be more specific (int[]) and self just ([])

        //        // TODO: check whether their element types are assignable,
        //        // avoid infinite recursion!

        //        return true;
        //    }

        //    // any callable -> "callable"
        //    if (ctx.IsLambda(totype) && IsCallable(fromtype, ctx, model))
        //        return true;

        //    //// allowed conversions

        //    // int <-> bool
        //    //if (ctx.IsInteger(totype) && ctx.IsBoolean(fromtype))   // int -> bool
        //    //    return true;

        //    // int <-> double
        //    if (ctx.IsNumber(fromtype) && ctx.IsNumber(totype)) // TODO: maybe settings for strict number type check
        //        return true;

        //    if (ctx.IsString(totype) && IsConversionToString(fromtype, ctx, model))
        //        return true;

        //    //
        //    if (ctx.IsNull(fromtype) && ctx.IsNullable(totype))
        //        return true;    // NULL can be assigned to any nullable

        //    //
        //    return false;
        //}

        ///// <summary>
        ///// Determines whether given type can be converted to string without warning.
        ///// </summary>
        //internal static bool IsConversionToString(TypeRefMask fromtype, TypeRefContext/*!*/ctx, ISemanticModel/*!*/model)
        //{
        //    // primitive -> string
        //    if (ctx.IsPrimitiveType(fromtype))
        //        return true;

        //    // object with __toString() -> string
        //    if (ctx.IsObject(fromtype) && ctx.GetObjectTypes(fromtype).Any(tref => model.GetClass(tref.QualifiedName).HasMethod(NameUtils.SpecialNames.__toString, model)))
        //        return true;

        //    //
        //    return false;
        //}

        /// <summary>
        /// Checks whether given type may be callable.
        /// </summary>
        internal static bool IsCallable(TypeRefContext /*!*/ ctx, TypeRefMask type)
        {
            if (type.IsAnyType || type.IsRef ||
                ctx.IsLambda(type) || ctx.IsAString(type) || ctx.IsArray(type) || ctx.IsObject(type))
            {
                return(true);
            }

            //// type has "__invoke" method
            //if (type.IsSingleType)  // just optimization
            //{
            //    var tref = ctx.GetObjectTypes(type).FirstOrDefault();
            //    if (tref != null)
            //    {
            //        var node = model.GetClass(tref.QualifiedName);
            //        // type has __invoke method or is assignable from Closure
            //        if (node.HasMethod(NameUtils.SpecialNames.__invoke, model) || model.IsAssignableFrom(NameUtils.SpecialNames.Closure, node))
            //            return true;
            //    }
            //}

            return(false);
        }
Ejemplo n.º 2
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);
        }