Beispiel #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);
        }
Beispiel #2
0
 /// <summary>
 /// Gets <c>parent</c> type for this context.
 /// </summary>
 public TypeRefMask GetParentTypeMask()
 {
     if (_selfType != null && _selfType.Syntax.BaseClass != null)
     {
         return(GetTypeMask(BoundTypeRefFactory.Create(_selfType.BaseType), false));
     }
     else
     {
         return(GetSystemObjectTypeMask());
     }
 }
Beispiel #3
0
 /// <summary>
 /// Gets type of <c>$this</c> in current context.
 /// </summary>
 public TypeRefMask GetThisTypeMask()
 {
     if (_thisType != null)
     {
         return(GetTypeMask(BoundTypeRefFactory.Create(_thisType), includesSubclasses: !_thisType.IsSealed));
     }
     else
     {
         return(GetSystemObjectTypeMask());
     }
 }
Beispiel #4
0
        /// <summary>
        /// Gets <c>self</c> type for this context.
        /// </summary>
        public TypeRefMask GetSelfTypeMask()
        {
            TypeRefMask result;

            if (_selfType != null && !_selfType.IsTrait)
            {
                result = GetTypeMask(BoundTypeRefFactory.Create(_selfType), includesSubclasses: false);
            }
            else
            {
                result = GetSystemObjectTypeMask();
            }

            return(result);
        }
Beispiel #5
0
        /// <summary>
        /// Binds <see cref="AST.TypeRef"/> to a type symbol.
        /// </summary>
        /// <param name="tref">Type reference.</param>
        /// <param name="selfHint">Optional.
        /// Current type scope for better <paramref name="tref"/> resolution since <paramref name="tref"/> might be ambiguous</param>
        /// <param name="nullable">Whether the resulting type must be able to contain NULL. Default is <c>false</c>.</param>
        /// <returns>Resolved symbol.</returns>
        internal TypeSymbol GetTypeFromTypeRef(AST.TypeRef tref, SourceTypeSymbol selfHint = null, bool nullable = false)
        {
            if (tref == null)
            {
                return(null);
            }

            var t = BoundTypeRefFactory.CreateFromTypeRef(tref, null, selfHint);

            var symbol = t.ResolveRuntimeType(this);

            if (t.IsNullable || nullable)
            {
                // TODO: for value types -> Nullable<T>
                symbol = MergeNull(symbol);
            }

            return(symbol);
        }
Beispiel #6
0
        public static TypeRefMask CreateMask(TypeRefContext ctx, TypeSymbol t)
        {
            // shortcuts:
            if (t.Is_PhpValue())
            {
                return(TypeRefMask.AnyType);
            }
            if (t.Is_PhpAlias())
            {
                return(TypeRefMask.AnyType.WithRefFlag);
            }
            if (t.IsNullableType(out var ttype))
            {
                return(CreateMask(ctx, ttype) | ctx.GetNullTypeMask());
            }

            //
            return(BoundTypeRefFactory.Create(t).GetTypeRefMask(ctx));
        }
Beispiel #7
0
 public static TypeRefMask CreateMask(TypeRefContext ctx, TypeSymbol t) => BoundTypeRefFactory.Create(t).GetTypeRefMask(ctx);