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(); } }
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; }
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(); }
private static DeclarationParameter ToDeclarationParameter(FormalParam p) { return(new DeclarationParameter( ToNameOfVariable(p.Name), Parse(p.InitValue), p.PassedByRef, p.IsOut, p.IsVariadic )); }
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; }
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; }
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; }
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()); } }
/// <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); }
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); } }
public static void EmitTypeHintTest(this FormalParam /*!*/ node, CodeGenerator /*!*/ codeGenerator) { node.NodeCompiler <IFormalParamCompiler>().EmitTypeHintTest(node, codeGenerator); }
public CustomAttributeProvider(FormalParam node) { this.node = node; }
/// <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); }
/// <summary> /// Visit formal parameter initializer expression. /// </summary> /// <param name="x"></param> virtual public void VisitFormalParam(FormalParam x) { VisitElement(x.TypeHint); VisitElement(x.InitValue); }
public override void VisitFormalParam(FormalParam x) { AddVar(x.Name, x.Span, VariableKind.Parameter); }