Beispiel #1
0
        protected virtual TypeSymbol BuildReturnType(Signature signature, PHPDocBlock phpdocOpt, TypeRefMask return_tmask)
        {
            if (signature.AliasReturn)
            {
                return(DeclaringCompilation.CoreTypes.PhpAlias);
            }

            // TODO: PHP7 return type
            //signature.ReturnTypeHint

            //
            if (phpdocOpt != null)
            {
                var returnTag = phpdocOpt.Returns;
                if (returnTag != null && returnTag.TypeNames.Length != 0)
                {
                    var typeCtx = this.TypeRefContext;
                    var tmask   = PHPDoc.GetTypeMask(typeCtx, returnTag.TypeNamesArray);
                    if (!tmask.IsVoid && !tmask.IsAnyType)
                    {
                        return(DeclaringCompilation.GetTypeFromTypeRef(typeCtx, tmask));
                    }
                }
            }

            //
            return(DeclaringCompilation.GetTypeFromTypeRef(this.TypeRefContext, return_tmask));
        }
Beispiel #2
0
        protected virtual TypeSymbol BuildReturnType(Signature signature, TypeRef tref, PHPDocBlock phpdocOpt, TypeRefMask rtype)
        {
            if (signature.AliasReturn)
            {
                return(DeclaringCompilation.CoreTypes.PhpAlias);
            }

            // PHP7 return type
            if (tref != null)
            {
                return(DeclaringCompilation.GetTypeFromTypeRef(tref));
            }

            //
            var typeCtx = this.TypeRefContext;

            //
            if (phpdocOpt != null && (DeclaringCompilation.Options.PhpDocTypes & PhpDocTypes.ReturnTypes) != 0)
            {
                var returnTag = phpdocOpt.Returns;
                if (returnTag != null && returnTag.TypeNames.Length != 0)
                {
                    var tmask = PHPDoc.GetTypeMask(typeCtx, returnTag.TypeNamesArray, this.GetNamingContext());
                    if (!tmask.IsVoid && !tmask.IsAnyType)
                    {
                        return(DeclaringCompilation.GetTypeFromTypeRef(typeCtx, tmask));
                    }
                }
            }

            //
            return(DeclaringCompilation.GetTypeFromTypeRef(typeCtx, rtype));
        }
        TypeSymbol ResolveType()
        {
            if (IsThis)
            {
                // <this> parameter
                if (_routine is SourceGlobalMethodSymbol)
                {
                    // "AnyType" in case of $this in global scope
                    return(DeclaringCompilation.CoreTypes.PhpValue);
                }

                return(ContainingType);
            }

            //return DeclaringCompilation.GetTypeFromTypeRef(_routine, _routine.ControlFlowGraph.GetParamTypeMask(this));

            // determine parameter type from the signature:

            // aliased parameter:
            if (_syntax.IsOut || _syntax.PassedByRef)
            {
                return(DeclaringCompilation.CoreTypes.PhpAlias);
            }

            // 1. specified type hint
            var typehint = new Utilities.TypeHintValue(_syntax.TypeHint);
            var result   = typehint.AsTypeSymbol(DeclaringCompilation);

            // 2. optionally type specified in PHPDoc
            if (result == null && _ptagOpt != null && _ptagOpt.TypeNamesArray.Length != 0)
            {
                var typectx = _routine.TypeRefContext;
                var tmask   = FlowAnalysis.PHPDoc.GetTypeMask(typectx, _ptagOpt.TypeNamesArray);
                if (!tmask.IsVoid && !tmask.IsAnyType)
                {
                    result = DeclaringCompilation.GetTypeFromTypeRef(typectx, tmask);
                }
            }

            // 3 default:
            if (result == null)
            {
                // TODO: use type from overriden method

                result = DeclaringCompilation.CoreTypes.PhpValue;
            }

            // variadic (result[])
            if (_syntax.IsVariadic)
            {
                // result = ArraySZSymbol.FromElement(result);
                throw new NotImplementedException();
            }

            //
            return(result);
        }
Beispiel #4
0
        internal override TypeSymbol GetFieldType(ConsList <FieldSymbol> fieldsBeingBound)
        {
            var vartag = _phpdoc?.GetElement <PHPDocBlock.VarTag>();

            if (vartag != null && vartag.TypeNamesArray.Length != 0)
            {
                var typectx = TypeRefFactory.CreateTypeRefContext(_type);
                var tmask   = PHPDoc.GetTypeMask(typectx, vartag.TypeNamesArray);
                var t       = DeclaringCompilation.GetTypeFromTypeRef(typectx, tmask);
                return(t);
            }

            // TODO: analysed PHP type

            return(DeclaringCompilation.CoreTypes.PhpValue);
        }
        internal override TypeSymbol GetFieldType(ConsList <FieldSymbol> fieldsBeingBound)
        {
            // TODO: HHVM TypeHint

            //
            if ((IsConst || IsReadOnly) && Initializer != null)
            {
                // resolved type symbol if possible
                if (Initializer.ResultType != null)
                {
                    return(Initializer.ResultType);
                }

                // resolved value type if possible
                var cvalue = Initializer.ConstantValue;
                if (cvalue.HasValue)
                {
                    var specialType = (cvalue.Value != null)
                        ? cvalue.ToConstantValueOrNull()?.SpecialType
                        : SpecialType.System_Object;    // NULL

                    if (specialType.HasValue && specialType != SpecialType.None)
                    {
                        return(DeclaringCompilation.GetSpecialType(specialType.Value));
                    }
                }

                //
                //return DeclaringCompilation.GetTypeFromTypeRef(typectx, Initializer.TypeRefMask);
            }

            // PHPDoc @var type
            if ((DeclaringCompilation.Options.PhpDocTypes & PhpDocTypes.FieldTypes) != 0)
            {
                var vartag = FindPhpDocVarTag();
                if (vartag != null && vartag.TypeNamesArray.Length != 0)
                {
                    var dummyctx = TypeRefFactory.CreateTypeRefContext(_containingType);
                    var tmask    = PHPDoc.GetTypeMask(dummyctx, vartag.TypeNamesArray, NameUtils.GetNamingContext(_containingType.Syntax));
                    return(DeclaringCompilation.GetTypeFromTypeRef(dummyctx, tmask));
                }
            }

            // default
            return(DeclaringCompilation.CoreTypes.PhpValue);
        }
        TypeSymbol ResolveType()
        {
            if (IsThis)
            {
                // <this> parameter
                if (_routine is SourceGlobalMethodSymbol)
                {
                    // "AnyType" in case of $this in global scope
                    return(DeclaringCompilation.CoreTypes.PhpValue);
                }

                return(ContainingType);
            }

            //return DeclaringCompilation.GetTypeFromTypeRef(_routine, _routine.ControlFlowGraph.GetParamTypeMask(this));

            // determine parameter type from the signature:

            // aliased parameter:
            if (_syntax.IsOut || _syntax.PassedByRef)
            {
                if (_syntax.IsVariadic)
                {
                    // PhpAlias[]
                    return(ArrayTypeSymbol.CreateSZArray(this.ContainingAssembly, DeclaringCompilation.CoreTypes.PhpAlias));
                }
                else
                {
                    // PhpAlias
                    return(DeclaringCompilation.CoreTypes.PhpAlias);
                }
            }

            // 1. specified type hint
            var result = DeclaringCompilation.GetTypeFromTypeRef(_syntax.TypeHint);

            // 2. optionally type specified in PHPDoc
            if (result == null && _ptagOpt != null && _ptagOpt.TypeNamesArray.Length != 0 &&
                (DeclaringCompilation.Options.PhpDocTypes & PhpDocTypes.ParameterTypes) != 0)
            {
                var typectx = _routine.TypeRefContext;
                var tmask   = FlowAnalysis.PHPDoc.GetTypeMask(typectx, _ptagOpt.TypeNamesArray, _routine.GetNamingContext());
                if (!tmask.IsVoid && !tmask.IsAnyType)
                {
                    result = DeclaringCompilation.GetTypeFromTypeRef(typectx, tmask);
                }
            }

            // 3 default:
            if (result == null)
            {
                // TODO: use type from overriden method

                result = DeclaringCompilation.CoreTypes.PhpValue;
            }

            // variadic (result[])
            if (_syntax.IsVariadic)
            {
                result = ArrayTypeSymbol.CreateSZArray(this.ContainingAssembly, result);
            }

            //
            return(result);
        }
        TypeSymbol ResolveType()
        {
            if (IsThis)
            {
                // <this> parameter
                if (_routine is SourceGlobalMethodSymbol)
                {
                    // "AnyType" in case of $this in global scope
                    return(DeclaringCompilation.CoreTypes.PhpValue);
                }

                return(ContainingType);
            }

            //return DeclaringCompilation.GetTypeFromTypeRef(_routine, _routine.ControlFlowGraph.GetParamTypeMask(this));

            // determine parameter type from the signature:

            // aliased parameter:
            if (_syntax.IsOut || _syntax.PassedByRef)
            {
                if (_syntax.IsVariadic)
                {
                    // PhpAlias[]
                    return(ArrayTypeSymbol.CreateSZArray(this.ContainingAssembly, DeclaringCompilation.CoreTypes.PhpAlias));
                }
                else
                {
                    // PhpAlias
                    return(DeclaringCompilation.CoreTypes.PhpAlias);
                }
            }

            // 1. specified type hint
            var typeHint = _syntax.TypeHint;

            if (typeHint is ReservedTypeRef rtref)
            {
                // workaround for https://github.com/peachpiecompiler/peachpie/issues/281
                // remove once it gets updated in parser
                if (rtref.Type == ReservedTypeRef.ReservedType.self)
                {
                    return(_routine.ContainingType);                                                 // self
                }
            }
            var result = DeclaringCompilation.GetTypeFromTypeRef(typeHint, _routine.ContainingType as SourceTypeSymbol, nullable: DefaultsToNull, phpLang: true);

            // 2. optionally type specified in PHPDoc
            if (result == null && PHPDoc != null && PHPDoc.TypeNamesArray.Length != 0 &&
                (DeclaringCompilation.Options.PhpDocTypes & PhpDocTypes.ParameterTypes) != 0)
            {
                var typectx = _routine.TypeRefContext;
                var tmask   = FlowAnalysis.PHPDoc.GetTypeMask(typectx, PHPDoc.TypeNamesArray, _routine.GetNamingContext());
                if (!tmask.IsVoid && !tmask.IsAnyType)
                {
                    result = DeclaringCompilation.GetTypeFromTypeRef(typectx, tmask);
                }
            }

            // 3 default:
            if (result == null)
            {
                // TODO: use type from overriden method

                result = DeclaringCompilation.CoreTypes.PhpValue;
            }

            // variadic (result[])
            if (_syntax.IsVariadic)
            {
                result = ArrayTypeSymbol.CreateSZArray(this.ContainingAssembly, result);
            }

            //
            return(result);
        }