IsLambda() public method

Gets value indicating whether given type mask represents a lambda function or callable primitive type.
public IsLambda ( TypeRefMask mask ) : bool
mask TypeRefMask
return bool
コード例 #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);
        }