示例#1
0
            internal void Analyze(FormalParam /*!*/ node, Analyzer /*!*/ analyzer)
            {
                var attributes = node.Attributes;

                if (attributes != null)
                {
                    node.Attributes.Analyze(analyzer, new CustomAttributeProvider(node));
                }

                if (node.InitValue != null)
                {
                    node.InitValue = node.InitValue.Analyze(analyzer, ExInfoFromParent.DefaultExInfo).Literalize();
                }

                // adds arguments to local variables table:
                if (!routine.Builder.LocalVariables.AddParameter(node.Name, node.PassedByRef))
                {
                    // parameter with the same name specified twice
                    analyzer.ErrorSink.Add(Errors.DuplicateParameterName, analyzer.SourceUnit, node.Span, node.Name);
                }

                if (node.IsOut && !node.PassedByRef)
                {
                    // out can be used only on by-ref params:
                    analyzer.ErrorSink.Add(Errors.OutAttributeOnByValueParam, analyzer.SourceUnit, node.Span, node.Name);
                }

                if (node.IsVariadic)
                {
                    throw new NotImplementedException();
                }
            }
示例#2
0
            internal void AnalyzeMembers(FormalParam /*!*/ node, Analyzer /*!*/ analyzer, PhpRoutine /*!*/ routine, int index)
            {
                this.routine = routine;
                this.index   = index;

                PhpType referring_type;
                Scope   referring_scope;

                if (routine.IsMethod)
                {
                    referring_type  = routine.DeclaringPhpType;
                    referring_scope = referring_type.Declaration.Scope;
                }
                else if (routine.IsLambdaFunction)
                {
                    referring_type  = analyzer.CurrentType;
                    referring_scope = analyzer.CurrentScope;
                }
                else
                {
                    referring_type  = null;
                    referring_scope = ((PhpFunction)routine).Declaration.Scope;
                }

                var attributes = node.Attributes;

                if (attributes != null)
                {
                    attributes.AnalyzeMembers(analyzer, referring_scope);
                }

                resolvedTypeHint = analyzer.ResolveType(node.TypeHint, referring_type, routine, node.Span, false);
            }
        public SourceParameterSymbol(SourceRoutineSymbol routine, FormalParam syntax, int relindex, PHPDocBlock.ParamTag ptagOpt)
        {
            Contract.ThrowIfNull(routine);
            Contract.ThrowIfNull(syntax);
            Debug.Assert(relindex >= 0);


            _routine  = routine;
            _syntax   = syntax;
            _relindex = relindex;

            _initializer = (syntax.InitValue != null)
                ? new SemanticsBinder(DeclaringCompilation, routine.ContainingFile.SyntaxTree, locals: null, routine: null, self: routine.ContainingType as SourceTypeSymbol)
                           .BindWholeExpression(syntax.InitValue, BoundAccess.Read)
                           .SingleBoundElement()
                : null;

            var phpattrs = _syntax.GetAttributes();

            _attributes = phpattrs.Count != 0
                ? new SemanticsBinder(DeclaringCompilation, routine.ContainingFile.SyntaxTree, locals: null, routine: routine, self: routine.ContainingType as SourceTypeSymbol)
                          .BindAttributes(phpattrs)
                : ImmutableArray <AttributeData> .Empty;

            PHPDoc = ptagOpt;
        }
示例#4
0
 override public void VisitFormalParam(FormalParam x)
 {
     _serializer.StartSerialize(typeof(FormalParam).Name, SerializeSpan(x.Span), new NodeObj("Name", x.Name.Name.Value),
                                new NodeObj("PassedByRef", x.PassedByRef.ToString()), new NodeObj("IsVariadic", x.IsVariadic.ToString()));
     SerializeOptionalProperty("TypeHint", x.TypeHint);
     SerializeOptionalProperty("InitValue", x.InitValue);
     _serializer.EndSerialize();
 }
示例#5
0
 private static DeclarationParameter ToDeclarationParameter(FormalParam p)
 {
     return(new DeclarationParameter(
                ToNameOfVariable(p.Name),
                Parse(p.InitValue),
                p.PassedByRef,
                p.IsOut,
                p.IsVariadic
                ));
 }
示例#6
0
        public SourceParameterSymbol(SourceRoutineSymbol routine, FormalParam syntax, int index, PHPDocBlock.ParamTag ptagOpt)
        {
            Contract.ThrowIfNull(routine);
            Contract.ThrowIfNull(syntax);
            Debug.Assert(index >= 0);

            _routine = routine;
            _syntax  = syntax;
            _index   = index;
            _ptagOpt = ptagOpt;
        }
示例#7
0
            public override void VisitFormalParam(FormalParam x)
            {
                VisitSpecificElementProlog();

                SerializeToken(nameof(x.Name), x.Name.ToString(), null);
                SerializeToken(nameof(x.PassedByRef), x.PassedByRef.ToString(), null);
                SerializeToken(nameof(x.IsOut), x.IsOut.ToString(), null);
                SerializeToken(nameof(x.IsVariadic), x.IsVariadic.ToString(), null);

                base.VisitFormalParam(x);
            }
        public SourceParameterSymbol(SourceRoutineSymbol routine, FormalParam syntax, int index, PHPDocBlock.ParamTag ptagOpt)
        {
            Contract.ThrowIfNull(routine);
            Contract.ThrowIfNull(syntax);
            Debug.Assert(index >= 0);

            _routine     = routine;
            _syntax      = syntax;
            _index       = index;
            _ptagOpt     = ptagOpt;
            _initializer = (syntax.InitValue != null)
                ? new SemanticsBinder(null).BindExpression(syntax.InitValue, BoundAccess.Read)
                : null;
        }
        public SourceParameterSymbol(SourceRoutineSymbol routine, FormalParam syntax, int relindex, PHPDocBlock.ParamTag ptagOpt)
        {
            Contract.ThrowIfNull(routine);
            Contract.ThrowIfNull(syntax);
            Debug.Assert(relindex >= 0);

            _routine     = routine;
            _syntax      = syntax;
            _relindex    = relindex;
            _ptagOpt     = ptagOpt;
            _initializer = (syntax.InitValue != null)
                ? new SemanticsBinder(locals: null, diagnostics: DeclaringCompilation.DeclarationDiagnostics).BindWholeExpression(syntax.InitValue, BoundAccess.Read).GetOnlyBoundElement()
                : null;
        }
示例#10
0
        public SourceParameterSymbol(SourceRoutineSymbol routine, FormalParam syntax, int index, PHPDocBlock.ParamTag ptagOpt)
        {
            Contract.ThrowIfNull(routine);
            Contract.ThrowIfNull(syntax);
            Debug.Assert(index >= 0);

            _routine = routine;
            _syntax = syntax;
            _index = index;
            _ptagOpt = ptagOpt;
            _initializer = (syntax.InitValue != null)
                ? new SemanticsBinder(null).BindExpression(syntax.InitValue, BoundAccess.Read)
                : null;
        }
示例#11
0
        public SourceParameterSymbol(SourceRoutineSymbol routine, FormalParam syntax, int relindex, PHPDocBlock.ParamTag ptagOpt)
        {
            Contract.ThrowIfNull(routine);
            Contract.ThrowIfNull(syntax);
            Debug.Assert(relindex >= 0);

            _routine     = routine;
            _syntax      = syntax;
            _relindex    = relindex;
            _ptagOpt     = ptagOpt;
            _initializer = (syntax.InitValue != null)
                ? new SemanticsBinder(DeclaringCompilation, locals: null, routine: routine, self: routine.ContainingType as SourceTypeSymbol)
                           .BindWholeExpression(syntax.InitValue, BoundAccess.Read)
                           .SingleBoundElement()
                : null;
        }
示例#12
0
            internal void Emit(FormalParam /*!*/ node, CodeGenerator /*!*/ codeGenerator)
            {
                var attributes = node.Attributes;

                if (attributes != null)
                {
                    attributes.Emit(codeGenerator, new CustomAttributeProvider(node));
                }

                // persists type hint to the [TypeHint] attribute:
                if (resolvedTypeHint != null)
                {
                    ParameterBuilder param_builder = routine.Builder.ParameterBuilders[routine.FirstPhpParameterIndex + index];
                    DTypeSpec        spec          = resolvedTypeHint.GetTypeSpec(codeGenerator.SourceUnit);
                    param_builder.SetCustomAttribute(spec.ToCustomAttributeBuilder());
                }
            }
示例#13
0
            /// <summary>
            /// Emits type hint test on the argument if specified.
            /// </summary>
            public void EmitTypeHintTest(FormalParam /*!*/ node, CodeGenerator /*!*/ codeGenerator)
            {
                int real_index = routine.FirstPhpParameterIndex + index;

                // not type hint specified:
                if (node.TypeHint == null)
                {
                    return;
                }

                Debug.Assert(resolvedTypeHint != null);

                ILEmitter il          = codeGenerator.IL;
                Label     endif_label = il.DefineLabel();

                // IF (DEREF(ARG[argIdx]) is not of hint type) THEN
                il.Ldarg(real_index);
                if (node.PassedByRef)
                {
                    il.Emit(OpCodes.Ldfld, Fields.PhpReference_Value);
                }

                resolvedTypeHint.EmitInstanceOf(codeGenerator, null);
                il.Emit(OpCodes.Brtrue, endif_label);

                // add a branch allowing null values if the argument is optional with null default value (since PHP 5.1.0);
                if (node.InitValue != null && node.InitValue.HasValue() && node.InitValue.GetValue() == null)
                {
                    // IF (DEREF(ARG[argIdx]) != null) THEN
                    il.Ldarg(real_index);
                    if (node.PassedByRef)
                    {
                        il.Emit(OpCodes.Ldfld, Fields.PhpReference_Value);
                    }
                    il.Emit(OpCodes.Brfalse, endif_label);
                }

                // CALL PhpException.InvalidArgumentType(<param_name>, <class_name>);
                il.Emit(OpCodes.Ldstr, node.Name.ToString());
                il.Emit(OpCodes.Ldstr, resolvedTypeHint.FullName);
                codeGenerator.EmitPhpException(Methods.PhpException.InvalidArgumentType);

                // END IF;
                // END IF;
                il.MarkLabel(endif_label);
            }
示例#14
0
        public override void VisitFormalParam(FormalParam x)
        {
            VisitElement(x.TypeHint);
            if (x.PassedByRef)
            {
                ConsumeToken(Tokens.T_AMP, "&");
            }
            if (x.IsVariadic)
            {
                ConsumeToken(Tokens.T_ELLIPSIS, "...");
            }

            VisitVariableName(x.Name.Name, x.Name.Span, true);
            if (x.InitValue != null)
            {
                ConsumeToken(Tokens.T_EQ, "=");
                VisitElement(x.InitValue);
            }
        }
示例#15
0
 public static void EmitTypeHintTest(this FormalParam /*!*/ node, CodeGenerator /*!*/ codeGenerator)
 {
     node.NodeCompiler <IFormalParamCompiler>().EmitTypeHintTest(node, codeGenerator);
 }
示例#16
0
 public CustomAttributeProvider(FormalParam node)
 {
     this.node = node;
 }
示例#17
0
        /// <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);
        }
示例#18
0
 /// <summary>
 /// Visit formal parameter initializer expression.
 /// </summary>
 /// <param name="x"></param>
 virtual public void VisitFormalParam(FormalParam x)
 {
     VisitElement(x.TypeHint);
     VisitElement(x.InitValue);
 }
示例#19
0
 public override void VisitFormalParam(FormalParam x)
 {
     AddVar(x.Name, x.Span, VariableKind.Parameter);
 }