array
/// <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 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; }
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)); }
/// <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); }