Esempio n. 1
0
 void CheckMissusedPrimitiveType(IBoundTypeRef tref)
 {
     if (tref.IsPrimitiveType)
     {
         // error: use of primitive type {0} is misused // primitive type does not make any sense in this context
         _diagnostics.Add(_routine, tref.PhpSyntax, ErrorCode.ERR_PrimitiveTypeNameMisused, tref);
     }
 }
Esempio n. 2
0
        public SourceCustomAttribute(PhpCompilation compilation, SourceTypeSymbol containingType, IBoundTypeRef tref, ImmutableArray <BoundArgument> arguments)
        {
            _compilation = compilation;
            _tref        = tref;
            _arguments   = arguments;

            TypeCtx = new FlowAnalysis.TypeRefContext(compilation, containingType);
        }
Esempio n. 3
0
        private TypeRefMask GetPrimitiveTypeRefMask(IBoundTypeRef /*!*/ typeref)
        {
            Debug.Assert(typeref.IsPrimitiveType);

            // primitive type cannot include subclasses
            var index = AddToContext(typeref);

            return(TypeRefMask.CreateFromTypeIndex(index));
        }
Esempio n. 4
0
        /// <summary>
        /// Does not lookup existing types whether there is typeref already.
        /// </summary>
        private TypeRefMask GetPrimitiveTypeRefMaskNoCheck(IBoundTypeRef /*!*/ typeref)
        {
            Debug.Assert(typeref.IsPrimitiveType);

            if (this.Types.Count < TypeRefMask.IndicesCount)
            {
                var index = AddToContextNoCheck(typeref);
                return(TypeRefMask.CreateFromTypeIndex(index));
            }
            else
            {
                return(TypeRefMask.AnyType);
            }
        }
Esempio n. 5
0
            /// <summary>Template: new LateStaticTypeParam(PhpTypeInfo)</summary>
            public TypeSymbol EmitLateStaticTypeParam(IBoundTypeRef tref)
            {
                if (tref != null && (tref.IsSelf() || tref.IsParent()) &&
                    _cg.Routine != null &&
                    _cg.Routine.IsStatic &&
                    _cg.Routine.HasLateStaticBoundParam())
                {
                    // pass current <static> to the callsite:
                    return(EmitWrapParam(_cg.CoreTypes.Dynamic_LateStaticTypeParam, _cg.EmitLoadStaticPhpTypeInfo()));
                }

                // not needed
                return(null);
            }
Esempio n. 6
0
        private int AddToContextNoCheck(IBoundTypeRef /*!*/ typeRef)
        {
            Contract.ThrowIfNull(typeRef);
            Debug.Assert(_typeRefs.IndexOf(typeRef) == -1);

            int index = _typeRefs.Count;

            this.UpdateMasks(typeRef, index);

            _typeRefs.Add(typeRef);

            //
            return(index);
        }
Esempio n. 7
0
        /// <summary>
        /// Updates internal masks for newly added type.
        /// </summary>
        /// <param name="typeRef">Type.</param>
        /// <param name="index">Type index.</param>
        private void UpdateMasks(IBoundTypeRef /*!*/ typeRef, int index)
        {
            Debug.Assert(index >= 0 && index < TypeRefMask.IndicesCount);

            ulong mask = (ulong)1 << index;

            if (typeRef.IsObject)
            {
                _isObjectMask |= mask;
            }
            if (typeRef.IsArray)
            {
                _isArrayMask |= mask;
            }
            if (typeRef.IsLambda)
            {
                _isLambdaMask |= mask;
            }

            if (typeRef is BoundPrimitiveTypeRef pt)
            {
                switch (pt.TypeCode)
                {
                case PhpTypeCode.Boolean:
                    _isBoolMask = mask;
                    break;

                case PhpTypeCode.Long:
                    _isLongMask = mask;
                    break;

                case PhpTypeCode.Double:
                    _isDoubleMask = mask;
                    break;

                case PhpTypeCode.String:
                    _isStringMask = mask;
                    break;

                case PhpTypeCode.Null:
                    _isNullMask = mask;
                    break;

                case PhpTypeCode.WritableString:
                    _isWritableStringMask = mask;
                    break;
                }
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Ensures given type is in the context.
        /// </summary>
        /// <param name="typeRef">Type reference to be in the context.</param>
        /// <returns>Index of the type within the context. Can return <c>-1</c> if there is too many types in the context already.</returns>
        public int AddToContext(IBoundTypeRef /*!*/ typeRef)
        {
            Contract.ThrowIfNull(typeRef);

            var types = _typeRefs;
            var index = this.GetTypeIndex(typeRef);

            if (index < 0 && this.Types.Count < TypeRefMask.IndicesCount)
            {
                index = this.AddToContextNoCheck(typeRef);
            }

            //
            return(index);
        }
Esempio n. 9
0
        /// <summary>
        /// Helper method that builds <see cref="TypeRefMask"/> for given type in this context.
        /// </summary>
        public TypeRefMask GetTypeMask(IBoundTypeRef /*!*/ typeref, bool includesSubclasses)
        {
            var index = AddToContext(typeref);
            var mask  = TypeRefMask.CreateFromTypeIndex(index);

            if (includesSubclasses && typeref.IsObject)
            {
                mask.SetIncludesSubclasses();
            }

            if (typeref.IsNullable)
            {
                mask |= GetNullTypeMask();
            }

            return(mask);
        }
Esempio n. 10
0
        /// <summary>
        /// Returns whether the given type can be used as an array key.
        /// </summary>
        public static bool IsValidKeyType(IBoundTypeRef type)
        {
            if (type is BoundPrimitiveTypeRef pt)
            {
                switch (pt.TypeCode)
                {
                case PhpTypeCode.Boolean:
                case PhpTypeCode.Long:
                case PhpTypeCode.Double:
                case PhpTypeCode.String:
                case PhpTypeCode.WritableString:
                case PhpTypeCode.Null:
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 11
0
 public static void EmitClassName(this IBoundTypeRef tref, CodeGenerator cg)
 {
     if (tref is BoundIndirectTypeRef it)
     {
         it.EmitClassName(cg);
     }
     else if (tref is BoundClassTypeRef ct)
     {
         cg.Builder.EmitStringConstant(ct.ClassName.ToString());
     }
     else
     {
         // Template: {LOAD PhpTypeInfo}.Name
         tref.EmitLoadTypeInfo(cg, true);
         cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.GetName_PhpTypeInfo.Getter)
         .Expect(SpecialType.System_String);
     }
 }
Esempio n. 12
0
        public override bool Equals(IBoundTypeRef other)
        {
            if (ReferenceEquals(this, other))
            {
                return(true);
            }

            if (other is BoundGenericClassTypeRef gt && gt._targetType.Equals(_targetType) && gt._typeArguments.Length == _typeArguments.Length)
            {
                for (int i = 0; i < _typeArguments.Length; i++)
                {
                    if (!other.TypeArguments[i].Equals(this.TypeArguments[i]))
                    {
                        return(false);
                    }
                }

                return(true);
            }

            return(false);
        }
Esempio n. 13
0
        /// <summary>
        /// Gets <see cref="TypeSymbol"/> suitable to be used for the runtime operations.
        /// Does not return <c>null</c> nor <see cref="ErrorTypeSymbol"/>.
        /// </summary>
        public static TypeSymbol ResolveRuntimeType(this IBoundTypeRef tref, PhpCompilation compilation)
        {
            var boundType = (BoundTypeRef)tref;

            var t = boundType.ResolvedType ?? (TypeSymbol)boundType.ResolveTypeSymbol(compilation);

            if (t.IsErrorTypeOrNull()) // error type => class could not be found
            {
                if (t is AmbiguousErrorTypeSymbol ambiguous)
                {
                    // ambiguity -> try to find a common base
                    var common = compilation.FindCommonBase(ambiguous._candidates);
                    if (common.IsValidType())
                    {
                        return(common);
                    }
                }

                t = compilation.CoreTypes.Object.Symbol;
            }

            return(t);
        }
Esempio n. 14
0
        /// <summary>
        /// Gets string representation of types contained in given type mask.
        /// </summary>
        public string ToString(TypeRefMask mask)
        {
            if (!mask.IsVoid)
            {
                if (mask.IsAnyType)
                {
                    return(TypeRefMask.MixedTypeName);
                }

                //
                var types = new List <string>(1);

                // handle arrays separately
                var arrmask = mask & _isArrayMask;
                if (arrmask != 0)
                {
                    mask &= ~_isArrayMask;
                    IBoundTypeRef elementtype = null;
                    var           elementmask = GetElementType(arrmask);
                    if (elementmask.IsSingleType)
                    {
                        elementtype = GetTypes(elementmask).FirstOrDefault();
                    }

                    if (elementtype != null)
                    {
                        types.Add(elementtype.ToString() + "[]");
                    }
                    else
                    {
                        types.Add(QualifiedName.Array.ToString());
                    }
                }

                //// int|double => number
                //var isNumber = (_isIntMask != 0 && _isDoubleMask != 0 && (mask & IsNumberMask) == IsNumberMask);
                //if (isNumber)
                //    mask &= ~IsNumberMask;

                //if (IsNull(mask))
                //{
                //    mask &= ~_isNullMask;
                //    types.Add(QualifiedName.Null.ToString());
                //}

                //
                types.AddRange(GetTypes(mask).Select(t => t.ToString()));

                //if (isNumber)
                //    types.Add("number");

                //
                if (types.Count != 0)
                {
                    types.Sort();
                    return(string.Join(PHPDocBlock.TypeVarDescTag.TypeNamesSeparator.ToString(), types.Distinct()));
                }
            }

            return(TypeRefMask.VoidTypeName);
        }
Esempio n. 15
0
 public BoundGenericClassTypeRef(IBoundTypeRef targetType, ImmutableArray <BoundTypeRef> typeArguments)
 {
     _targetType    = targetType ?? throw ExceptionUtilities.ArgumentNull(nameof(targetType));
     _typeArguments = typeArguments;
 }
Esempio n. 16
0
 public override bool Equals(IBoundTypeRef other) => base.Equals(other) || (other is BoundClassTypeRef ct && ct.ClassName == this.ClassName && ct.TypeArguments.IsDefaultOrEmpty);
Esempio n. 17
0
 public override bool Equals(IBoundTypeRef other) => base.Equals(other) || (other is BoundLambdaTypeRef lt && lt._returnType == this._returnType);
Esempio n. 18
0
 public override bool Equals(IBoundTypeRef other) => base.Equals(other) || (other is BoundArrayTypeRef at && at.ElementType == this.ElementType);
Esempio n. 19
0
 public override bool Equals(IBoundTypeRef other) => base.Equals(other) || (other is BoundPrimitiveTypeRef pt && pt._type == this._type);
Esempio n. 20
0
 private CatchBlock(IBoundTypeRef typeRef, BoundVariableRef variable, List <BoundStatement> statements)
     : base(statements)
 {
     _typeRef  = typeRef;
     _variable = variable;
 }
Esempio n. 21
0
 public CatchBlock(IBoundTypeRef typeRef, BoundVariableRef variable)
     : this(typeRef, variable, new List <BoundStatement>())
 {
 }
Esempio n. 22
0
 /// <summary>
 /// Determines if given <see cref="IBoundTypeRef"/> represents a number (integral or real).
 /// </summary>
 public static bool IsNumber(this IBoundTypeRef tref) => tref is BoundPrimitiveTypeRef pt && pt.IsNumber;
Esempio n. 23
0
 /// <summary>Template: new TargetTypeParam(PhpTypeInfo)</summary>
 public TypeSymbol EmitTargetTypeParam(IBoundTypeRef tref)
 => tref != null?EmitWrapParam(_cg.CoreTypes.Dynamic_TargetTypeParam, tref.EmitLoadTypeInfo(_cg, true)) : null;
Esempio n. 24
0
 public override bool Equals(IBoundTypeRef other) => base.Equals(other) || (other is BoundIndirectTypeRef it && it._typeExpression == _typeExpression);
Esempio n. 25
0
 /// <summary>
 /// Gets value indicating the <paramref name="tref"/> represents <c>self</c> keyword.
 /// </summary>
 public static bool IsSelf(this IBoundTypeRef tref) => tref is BoundReservedTypeRef reserved && reserved.ReservedType == Devsense.PHP.Syntax.Ast.ReservedTypeRef.ReservedType.self;
Esempio n. 26
0
 public static ITypeSymbol EmitLoadTypeInfo(this IBoundTypeRef tref, CodeGenerator cg, bool throwOnError = false) => ((BoundTypeRef)tref).EmitLoadTypeInfo(cg, throwOnError);
Esempio n. 27
0
 public override bool Equals(IBoundTypeRef other) => base.Equals(other) || (other is BoundTypeRefFromPlace pt && pt._place == _place);
Esempio n. 28
0
 void CannotInstantiate(IPhpOperation op, string kind, IBoundTypeRef t)
 {
     _diagnostics.Add(_routine, op.PhpSyntax, ErrorCode.ERR_CannotInstantiateType, kind, t.Type);
 }
Esempio n. 29
0
 public virtual bool Equals(IBoundTypeRef other) => ReferenceEquals(this, other);
Esempio n. 30
0
 /// <summary>
 /// Gets index of the given type within the context. Returns <c>-1</c> if such type is not present.
 /// </summary>
 int GetTypeIndex(IBoundTypeRef /*!*/ typeref)
 {
     return(_typeRefs.IndexOf(typeref));
 }