/// <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); }
/// <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()); } }
/// <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()); } }
/// <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); }
/// <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); }
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)); }
public static TypeRefMask CreateMask(TypeRefContext ctx, TypeSymbol t) => BoundTypeRefFactory.Create(t).GetTypeRefMask(ctx);