GetArrayTypeMask() public method

Gets type mask of generic array with element of any type.
public GetArrayTypeMask ( ) : TypeRefMask
return TypeRefMask
示例#1
0
        /// <summary>
        /// Gets type mask representing given type name.
        /// </summary>
        public static TypeRefMask GetTypeMask(TypeRefContext /*!*/ typeCtx, string tname, NamingContext naming, bool fullyQualified = false)
        {
            if (!string.IsNullOrEmpty(tname))
            {
                // handle various array conventions
                if (tname.LastCharacter() == ']')
                {
                    // "TName[]"
                    if (tname.EndsWith("[]", StringComparison.Ordinal))
                    {
                        var elementType = GetTypeMask(typeCtx, tname.Remove(tname.Length - 2), naming, fullyQualified);
                        return(typeCtx.GetArrayTypeMask(elementType));
                    }

                    // "array[TName]"
                    var arrayTypeName = QualifiedName.Array.Name.Value;
                    if (tname.Length > arrayTypeName.Length && tname[arrayTypeName.Length] == '[' &&
                        tname.StartsWith(arrayTypeName, StringComparison.OrdinalIgnoreCase))
                    {
                        var elementTypeName = tname.Substring(arrayTypeName.Length + 1, tname.Length - arrayTypeName.Length - 2);
                        var elementType     = GetTypeMask(typeCtx, elementTypeName, naming, fullyQualified);
                        return(typeCtx.GetArrayTypeMask(elementType));
                    }

                    // unknown something // ...
                }
                else if (tname[0] == '&')
                {
                    return(GetTypeMask(typeCtx, tname.Substring(1), naming, fullyQualified).WithRefFlag);
                }
                else
                {
                    var result = GetKnownTypeMask(typeCtx, tname);
                    if (result.IsUninitialized)
                    {
                        var qname = NameUtils.MakeQualifiedName(tname, false);
                        if (!fullyQualified && naming != null && !qname.IsReservedClassName)
                        {
                            qname = QualifiedName.TranslateAlias(qname, AliasKind.Type, naming.Aliases, naming.CurrentNamespace);
                        }

                        if (qname.IsPrimitiveTypeName)
                        {
                            result = GetKnownTypeMask(typeCtx, qname.Name.Value);
                            if (!result.IsUninitialized)
                            {
                                return(result);
                            }
                        }

                        result = BoundTypeRefFactory.Create(qname, typeCtx.SelfType as SourceTypeSymbol).GetTypeRefMask(typeCtx);
                    }

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

            return(0);
        }
示例#2
0
        /// <summary>
        /// Gets type mask representing given type name.
        /// </summary>
        public static TypeRefMask GetTypeMask(TypeRefContext/*!*/typeCtx, string tname, NamingContext naming, bool fullyQualified = false)
        {
            if (!string.IsNullOrEmpty(tname))
            {
                // handle various array conventions
                if (tname.LastCharacter() == ']')
                {
                    // "TName[]"
                    if (tname.EndsWith("[]", StringComparison.Ordinal))
                    {
                        var elementType = GetTypeMask(typeCtx, tname.Remove(tname.Length - 2), naming, fullyQualified);
                        return typeCtx.GetArrayTypeMask(elementType);
                    }

                    // "array[TName]"
                    var arrayTypeName = QualifiedName.Array.Name.Value;
                    if (tname.Length > arrayTypeName.Length && tname[arrayTypeName.Length] == '[' &&
                        tname.StartsWith(arrayTypeName, StringComparison.OrdinalIgnoreCase))
                    {
                        var elementTypeName = tname.Substring(arrayTypeName.Length + 1, tname.Length - arrayTypeName.Length - 2);
                        var elementType = GetTypeMask(typeCtx, elementTypeName, naming, fullyQualified);
                        return typeCtx.GetArrayTypeMask(elementType);
                    }

                    // unknown something // ...                    
                }
                else
                {
                    var result = GetKnownTypeMask(typeCtx, tname);
                    if (result.IsUninitialized)
                    {
                        var qname = NameUtils.MakeQualifiedName(tname, false);
                        if (!fullyQualified && naming != null && !qname.IsReservedClassName)
                            qname = QualifiedName.TranslateAlias(qname, AliasKind.Type, naming.Aliases, naming.CurrentNamespace);

                        if (qname.IsPrimitiveTypeName)
                        {
                            result = GetKnownTypeMask(typeCtx, qname.Name.Value);
                            if (!result.IsUninitialized)
                                return result;
                        }

                        result = typeCtx.GetTypeMask(qname, true);
                    }

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

            return 0;
        }
示例#3
0
        public static TypeRefMask CreateMask(TypeRefContext ctx, TypeSymbol t)
        {
            Contract.ThrowIfNull(t);

            switch (t.SpecialType)
            {
                case SpecialType.System_Void: return 0;
                case SpecialType.System_Int64: return ctx.GetLongTypeMask();
                case SpecialType.System_String: return ctx.GetStringTypeMask();
                case SpecialType.System_Double: return ctx.GetDoubleTypeMask();
                case SpecialType.System_Boolean: return ctx.GetBooleanTypeMask();
                case SpecialType.None:
                    var containing = t.ContainingAssembly;
                    if (containing != null && containing.IsPchpCorLibrary)
                    {
                        if (t.Name == "PhpValue") return TypeRefMask.AnyType;
                        if (t.Name == "PhpAlias") return TypeRefMask.AnyType.WithRefFlag;
                        if (t.Name == "PhpNumber") return ctx.GetNumberTypeMask();
                        if (t.Name == "PhpString") return ctx.GetWritableStringTypeMask();
                        if (t.Name == "PhpArray") return ctx.GetArrayTypeMask();
                        if (t.Name == "IPhpCallable") return ctx.GetCallableTypeMask();
                    }

                    break;
            }

            return CreateMask(ctx, CreateTypeRef(ctx, t));
        }
示例#4
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);
        }