IsContextParameter() public static method

Determines whether given parameter is treated as a special Context parameter which is always first and of type Pchp.Core.Context.
public static IsContextParameter ( ParameterSymbol p ) : bool
p ParameterSymbol
return bool
コード例 #1
0
        private SynthesizedPhpCtorSymbol(SourceTypeSymbol containingType, Accessibility accessibility,
                                         bool isInitFieldsOnly,
                                         MethodSymbol basector, MethodSymbol __construct, int paramsLimit = int.MaxValue)
            : base(containingType, WellKnownMemberNames.InstanceConstructorName, false, false, containingType.DeclaringCompilation.CoreTypes.Void, accessibility)
        {
            if (basector == null)
            {
                throw new ArgumentNullException(nameof(basector));
            }

            _basector     = basector;
            _phpconstruct = __construct;

            this.IsInitFieldsOnly = isInitFieldsOnly;

            // clone parameters from __construct ?? basector
            var template = (__construct ?? basector).Parameters;
            var ps       = new List <ParameterSymbol>(template.Length)
            {
                new SpecialParameterSymbol(this, DeclaringCompilation.CoreTypes.Context, SpecialParameterSymbol.ContextName, 0) // Context <ctx>
            };

            // same parameters as PHP constructor
            for (int i = 0; i < template.Length && i < paramsLimit; i++)
            {
                var p = template[i];
                if (!SpecialParameterSymbol.IsContextParameter(p))
                {
                    ps.Add(new SynthesizedParameterSymbol(this, p.Type, ps.Count, p.RefKind, p.Name, p.IsParams,
                                                          explicitDefaultConstantValue: p.ExplicitDefaultConstantValue));
                }
            }

            _parameters = ps.ToImmutableArray();
        }
コード例 #2
0
        protected virtual IEnumerable <ParameterSymbol> CreateParameters(IEnumerable <ParameterSymbol> baseparams)
        {
            int index = 0;

            // Context <ctx>
            yield return(new SpecialParameterSymbol(this, DeclaringCompilation.CoreTypes.Context, SpecialParameterSymbol.ContextName, index++));

            if (IsInitFieldsOnly)
            {
                // DummyFieldsOnlyCtor _
                yield return(new SpecialParameterSymbol(this, DeclaringCompilation.CoreTypes.DummyFieldsOnlyCtor, "_", index++));
            }

            // same parameters as PHP constructor
            foreach (var p in baseparams)
            {
                if (SpecialParameterSymbol.IsContextParameter(p))
                {
                    continue;
                }
                if (SpecialParameterSymbol.IsDummyFieldsOnlyCtorParameter(p))
                {
                    continue;
                }

                yield return(SynthesizedParameterSymbol.Create(this, p, index++));
            }
        }
コード例 #3
0
        void EmitPhpCtor(MethodSymbol ctor, Emit.PEModuleBuilder module)
        {
            if (ctor == null)
            {
                return;                 // static class
            }
            Debug.Assert(ctor.MethodKind == MethodKind.Constructor);

            module.SetMethodBody(ctor, MethodGenerator.GenerateMethodBody(module, ctor, il =>
            {
                Debug.Assert(SpecialParameterSymbol.IsContextParameter(ctor.Parameters[0]));

                var cg = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), OptimizationLevel.Release, false, this, new ParamPlace(ctor.Parameters[0]), new ArgPlace(this, 0));

                // call .phpnew
                var phpnew = this.InitializeInstanceMethod;
                cg.EmitPop(cg.EmitThisCall(phpnew, ctor));

                // call __construct
                var phpctor = this.ResolvePhpCtor(true);
                cg.EmitPop(cg.EmitThisCall(phpctor, ctor));

                Debug.Assert(ctor.ReturnsVoid);
                cg.EmitRet(ctor.ReturnType);
            }, null, DiagnosticBag.GetInstance(), false));
        }
コード例 #4
0
        protected virtual IEnumerable <ParameterSymbol> CreateParameters(IEnumerable <ParameterSymbol> baseparams)
        {
            int index = 0;

            // Context <ctx>
            yield return(new SpecialParameterSymbol(this, DeclaringCompilation.CoreTypes.Context, SpecialParameterSymbol.ContextName, index++));

            if (IsInitFieldsOnly)
            {
                // QueryValue<DummyFieldsOnlyCtor> _
                var dummy = DeclaringCompilation.CoreTypes.QueryValue_T.Symbol.Construct(DeclaringCompilation.CoreTypes.QueryValue_DummyFieldsOnlyCtor);
                yield return(new SpecialParameterSymbol(this, dummy, "_", index++));
            }

            // same parameters as PHP constructor
            foreach (var p in baseparams)
            {
                if (SpecialParameterSymbol.IsContextParameter(p))
                {
                    continue;
                }
                if (SpecialParameterSymbol.IsQueryValueParameter(p, out var _, out var t) && t == SpecialParameterSymbol.QueryValueTypes.DummyFieldsOnlyCtor)
                {
                    continue;
                }

                yield return(new SynthesizedParameterSymbol(this, p.Type, index++, p.RefKind, p.Name, p.IsParams,
                                                            explicitDefaultConstantValue: p.ExplicitDefaultConstantValue));
            }
        }
コード例 #5
0
        void EmitTraitImplementations(Emit.PEModuleBuilder module)
        {
            foreach (var t in TraitUses)
            {
                foreach (var m in t.GetMembers().OfType <SynthesizedMethodSymbol>())
                {
                    Debug.Assert(m.ForwardedCall != null);

                    module.SetMethodBody(m, MethodGenerator.GenerateMethodBody(module, m, il =>
                    {
                        IPlace thisPlace          = null;
                        IPlace traitInstancePlace = null;
                        IPlace ctxPlace;

                        if (m.IsStatic)
                        {
                            // Template: return TRAIT.method(...)
                            Debug.Assert(SpecialParameterSymbol.IsContextParameter(m.Parameters[0]));
                            ctxPlace = new ParamPlace(m.Parameters[0]);
                        }
                        else
                        {
                            // Template: return this.<>trait.method(...)
                            thisPlace          = new ArgPlace(this, 0);                                   // this
                            ctxPlace           = new FieldPlace(thisPlace, this.ContextStore, module);    // this.<ctx>
                            traitInstancePlace = new FieldPlace(thisPlace, t.TraitInstanceField, module); // this.<>trait
                        }

                        using (var cg = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), module.Compilation.Options.OptimizationLevel, false, this, ctxPlace, thisPlace)
                        {
                            CallerType = this,
                        })
                        {
                            var forwarded_type = cg.EmitForwardCall(m.ForwardedCall, m, thisPlaceExplicit: traitInstancePlace);
                            var target_type    = m.ReturnType;

                            cg.EmitConvert(forwarded_type, 0, target_type); // always (forwarded_type === target_type)
                            cg.EmitRet(target_type);
                        }
                    }, null, DiagnosticBag.GetInstance(), false));
                    module.SynthesizedManager.AddMethod(this, m);

                    // NOTE: following is not needed anymore:
                    //// ghost stubs: // ... resolve this already in SourceTypeSymbol.GetMembers(), now it does not get overloaded properly
                    //var ps = m.Parameters;
                    //for (int i = 0; i < ps.Length; i++)
                    //{
                    //    if (ps[i].HasUnmappedDefaultValue())  // => ConstantValue couldn't be resolved for optional parameter
                    //    {
                    //        // create ghost stub foo(p0, .. pi-1) => foo(p0, .. , pN)
                    //        GhostMethodBuilder.CreateGhostOverload(m, module, DiagnosticBag.GetInstance(), i);
                    //    }
                    //}
                }
            }
        }
コード例 #6
0
 /// <summary>
 /// Gets place referring to <c>Pchp.Core.Context</c> object.
 /// </summary>
 internal virtual IPlace GetContextPlace()
 {
     if (_params.Length != 0 && SpecialParameterSymbol.IsContextParameter(_params[0]))
     {
         return(new ParamPlace(_params[0]));  // <ctx>
     }
     else
     {
         return(null);
     }
 }
コード例 #7
0
        void EmitPhpCtors(ImmutableArray <MethodSymbol> instancectors, Emit.PEModuleBuilder module, DiagnosticBag diagnostics)
        {
            foreach (SynthesizedPhpCtorSymbol ctor in instancectors)
            {
                module.SetMethodBody(ctor, MethodGenerator.GenerateMethodBody(module, ctor, il =>
                {
                    Debug.Assert(SpecialParameterSymbol.IsContextParameter(ctor.Parameters[0]));

                    var cg = new CodeGenerator(il, module, diagnostics, OptimizationLevel.Release, false, this, new ParamPlace(ctor.Parameters[0]), new ArgPlace(this, 0));

                    Debug.Assert(ctor.BaseCtor != null);

                    // base..ctor or this..ctor
                    cg.EmitPop(cg.EmitThisCall(ctor.BaseCtor, ctor));

                    if (ctor.PhpConstructor == null)
                    {
                        // initialize <ctx> field, if field is declared within this type
                        var ctxField = this.ContextStore;
                        if (ctxField != null && object.ReferenceEquals((object)ctxField.ContainingType, this))
                        {
                            var ctxFieldPlace = new FieldPlace(cg.ThisPlaceOpt, ctxField);

                            // Debug.Assert(<ctx> != null)
                            cg.EmitDebugAssertNotNull(cg.ContextPlaceOpt, "Context cannot be null.");

                            // <this>.<ctx> = <ctx>
                            ctxFieldPlace.EmitStorePrepare(il);
                            cg.EmitLoadContext();
                            ctxFieldPlace.EmitStore(il);
                        }

                        // initialize class fields
                        foreach (var fld in this.EnsureMembers().OfType <SourceFieldSymbol>().Where(fld => !fld.RequiresHolder && !fld.IsStatic && !fld.IsConst))
                        {
                            fld.EmitInit(cg);
                        }
                    }
                    else
                    {
                        Debug.Assert(ctor.BaseCtor.ContainingType == this);

                        // this.__construct
                        cg.EmitPop(cg.EmitThisCall(ctor.PhpConstructor, ctor));
                    }

                    // ret
                    Debug.Assert(ctor.ReturnsVoid);
                    cg.EmitRet(ctor.ReturnType);
                }, null, diagnostics, false));
            }
        }
コード例 #8
0
        /// <summary>
        /// Gets place referring to <c>Pchp.Core.Context</c> object.
        /// </summary>
        internal virtual IPlace GetContextPlace(PEModuleBuilder module)
        {
            var ps = ImplicitParameters;

            if (ps.Length != 0 && SpecialParameterSymbol.IsContextParameter(ps[0]))
            {
                return(new ParamPlace(ps[0]));  // <ctx>
            }
            else
            {
                return(null);
            }
        }
コード例 #9
0
        /// <summary>
        /// Gets place referring to <c>Pchp.Core.Context</c> object.
        /// </summary>
        internal virtual IPlace GetContextPlace()
        {
            var ps = ImplicitParameters;

            if (ps.Count != 0 && SpecialParameterSymbol.IsContextParameter(ps[0]))
            {
                return(new ParamPlace(ps[0]));  // <ctx>
            }
            else
            {
                return(null);
            }
        }
コード例 #10
0
        protected override IEnumerable <ParameterSymbol> CreateParameters(IEnumerable <ParameterSymbol> baseparams)
        {
            int index = 0;

            // same parameters as PHP constructor
            foreach (var p in baseparams)
            {
                if (!SpecialParameterSymbol.IsContextParameter(p))
                {
                    yield return(new SynthesizedParameterSymbol(this, p.Type, index++, p.RefKind, p.Name, p.IsParams,
                                                                explicitDefaultConstantValue: p.ExplicitDefaultConstantValue));
                }
            }
        }
コード例 #11
0
        protected virtual IEnumerable <ParameterSymbol> CreateParameters(IEnumerable <ParameterSymbol> baseparams)
        {
            int index = 0;

            // Context <ctx>
            yield return(new SpecialParameterSymbol(this, DeclaringCompilation.CoreTypes.Context, SpecialParameterSymbol.ContextName, index++));

            // same parameters as PHP constructor
            foreach (var p in baseparams)
            {
                if (!SpecialParameterSymbol.IsContextParameter(p))
                {
                    yield return(new SynthesizedParameterSymbol(this, p.Type, index++, p.RefKind, p.Name, p.IsParams,
                                                                explicitDefaultConstantValue: p.ExplicitDefaultConstantValue));
                }
            }
        }
コード例 #12
0
        void EmitTraitImplementations(Emit.PEModuleBuilder module)
        {
            foreach (var t in TraitUses)
            {
                foreach (var m in t.GetMembers().OfType <SynthesizedMethodSymbol>())
                {
                    Debug.Assert(m.ForwardedCall != null);

                    module.SetMethodBody(m, MethodGenerator.GenerateMethodBody(module, m, il =>
                    {
                        IPlace thisPlace          = null;
                        IPlace traitInstancePlace = null;
                        IPlace ctxPlace;

                        if (m.IsStatic)
                        {
                            // Template: return TRAIT.method(...)
                            Debug.Assert(SpecialParameterSymbol.IsContextParameter(m.Parameters[0]));
                            ctxPlace = new ParamPlace(m.Parameters[0]);
                        }
                        else
                        {
                            // Template: return this.<>trait.method(...)
                            thisPlace          = new ArgPlace(this, 0);                                   // this
                            ctxPlace           = new FieldPlace(thisPlace, this.ContextStore, module);    // this.<ctx>
                            traitInstancePlace = new FieldPlace(thisPlace, t.TraitInstanceField, module); // this.<>trait
                        }

                        using (var cg = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), module.Compilation.Options.OptimizationLevel, false, this, ctxPlace, thisPlace)
                        {
                            CallerType = this,
                        })
                        {
                            var forwarded_type = cg.EmitForwardCall(m.ForwardedCall, m, thisPlaceExplicit: traitInstancePlace);
                            var target_type    = m.ReturnType;

                            cg.EmitConvert(forwarded_type, 0, target_type); // always (forwarded_type === target_type)
                            cg.EmitRet(target_type);
                        }
                    }, null, DiagnosticBag.GetInstance(), false));
                    module.SynthesizedManager.AddMethod(this, m);
                }
            }
        }
コード例 #13
0
        void EmitPhpNew(SynthesizedPhpNewMethodSymbol phpnew, Emit.PEModuleBuilder module)
        {
            if (phpnew == null)
            {
                return;                 // static class
            }
            module.SetMethodBody(phpnew, MethodGenerator.GenerateMethodBody(module, phpnew, il =>
            {
                Debug.Assert(SpecialParameterSymbol.IsContextParameter(phpnew.Parameters[0]));

                var cg = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), OptimizationLevel.Release, false, this, new ParamPlace(phpnew.Parameters[0]), new ArgPlace(this, 0));

                // initialize <ctx> field,
                // if field is declared within this type
                var ctxField = this.ContextField;
                if (ctxField != null && object.ReferenceEquals(ctxField.ContainingType, this))
                {
                    var ctxFieldPlace = new FieldPlace(cg.ThisPlaceOpt, ctxField);

                    // Debug.Assert(<ctx> != null)
                    cg.EmitDebugAssertNotNull(cg.ContextPlaceOpt, "Context cannot be null.");

                    // <this>.<ctx> = <ctx>
                    ctxFieldPlace.EmitStorePrepare(il);
                    cg.EmitLoadContext();
                    ctxFieldPlace.EmitStore(il);
                }

                // initialize class fields,
                // default(PhpValue) is not a valid value, its TypeTable must not be null
                foreach (var fld in this.GetFieldsToEmit().OfType <SourceFieldSymbol>().Where(fld => !fld.IsStatic && !fld.IsConst))
                {
                    fld.EmitInit(cg);
                }

                // base..phpnew ?? base..ctor
                var basenew = phpnew.BasePhpNew;
                Debug.Assert(basenew != null);
                cg.EmitPop(cg.EmitThisCall(basenew, phpnew));

                Debug.Assert(phpnew.ReturnsVoid);
                cg.EmitRet(true);
            }, null, DiagnosticBag.GetInstance(), false));
        }
コード例 #14
0
        void EmitPhpCtors(ImmutableArray <MethodSymbol> instancectors, Emit.PEModuleBuilder module, DiagnosticBag diagnostics)
        {
            foreach (SynthesizedPhpCtorSymbol ctor in instancectors)
            {
                module.SetMethodBody(ctor, MethodGenerator.GenerateMethodBody(module, ctor, il =>
                {
                    if (ctor is SynthesizedParameterlessPhpCtorSymbol)
                    {
                        EmitParameterlessCtor(ctor, il, module, diagnostics);
                        return;
                    }

                    Debug.Assert(SpecialParameterSymbol.IsContextParameter(ctor.Parameters[0]));

                    var cg = new CodeGenerator(il, module, diagnostics, module.Compilation.Options.OptimizationLevel, false, this, new ParamPlace(ctor.Parameters[0]), new ArgPlace(this, 0))
                    {
                        CallerType     = this,
                        ContainingFile = ContainingFile,
                    };

                    Debug.Assert(ctor.BaseCtor != null);

                    // base..ctor or this..ctor
                    cg.EmitPop(cg.EmitForwardCall(ctor.BaseCtor, ctor));

                    if (ctor.PhpConstructor == null)
                    {
                        // initialize <ctx> field, if field is declared within this type
                        var ctxField = this.ContextStore;
                        if (ctxField != null && object.ReferenceEquals((object)ctxField.ContainingType, this))
                        {
                            var ctxFieldPlace = new FieldPlace(cg.ThisPlaceOpt, ctxField, module);

                            // Debug.Assert(<ctx> != null)
                            cg.EmitDebugAssertNotNull(cg.ContextPlaceOpt, "Context cannot be null.");

                            // <this>.<ctx> = <ctx>
                            ctxFieldPlace.EmitStorePrepare(il);
                            cg.EmitLoadContext();
                            ctxFieldPlace.EmitStore(il);
                        }

                        // trait specific:
                        if (ctor is SynthesizedPhpTraitCtorSymbol tctor)
                        {
                            EmitTraitCtorInit(cg, tctor);
                        }

                        // trait instances:
                        foreach (var t in this.TraitUses)
                        {
                            EmitTraitInstanceInit(cg, ctor, t);
                        }

                        // initialize instance fields:
                        foreach (var f in this.GetMembers().OfType <IPhpPropertySymbol>().Where(f => f.FieldKind == PhpPropertyKind.InstanceField))
                        {
                            Debug.Assert(f.ContainingStaticsHolder == null);
                            f.EmitInit(cg);
                        }
                    }
                    else
                    {
                        Debug.Assert(ctor.BaseCtor.ContainingType == this);

                        // this.__construct
                        cg.EmitPop(cg.EmitForwardCall(ctor.PhpConstructor, ctor));
                    }

                    // ret
                    Debug.Assert(ctor.ReturnsVoid);
                    cg.EmitRet(ctor.ReturnType);
                }, null, diagnostics, false));
            }
        }
コード例 #15
0
        void ResolveBaseCtorAndParameters()
        {
            if (!_parameters.IsDefaultOrEmpty)
            {
                return;
            }

            //
            var phpctor    = this.PhpCtor;                                    // this tells us what parameters are provided to resolve base .ctor that can be called
            var basephpnew = this.ContainingType.BaseType.PhpNewMethodSymbol; // base..phpnew() to be called if provided
            var basectors  = (basephpnew != null)
                ? ImmutableArray.Create(basephpnew)
                : this.ContainingType.BaseType.InstanceConstructors
                             .Where(c => c.DeclaredAccessibility != Accessibility.Private)
                             .OrderByDescending(c => c.ParameterCount) // longest ctors first
                             .AsImmutable();

            // Context <ctx>
            var ps = new List <ParameterSymbol>(1)
            {
                new SpecialParameterSymbol(this, DeclaringCompilation.CoreTypes.Context, SpecialParameterSymbol.ContextName, 0) // Context <ctx>
            };

            var givenparams = (phpctor != null)
                ? phpctor.Parameters.Where(p => !p.IsImplicitlyDeclared).ToArray()
                : EmptyArray <ParameterSymbol> .Instance;

            // find best matching basector
            foreach (var c in basectors)
            {
                var calledparams = c.Parameters.Where(p => !p.IsImplicitlyDeclared).ToArray();

                if (CanBePassedTo(givenparams, calledparams))
                {
                    // we have found base constructor with most parameters we can call with given parameters
                    _lazyBaseCtor = c;
                    break;
                }
            }

            if (_lazyBaseCtor == null)
            {
                throw new InvalidOperationException("Base .ctor cannot be resolved with provided constructor.");
            }

            //
            Debug.Assert(SpecialParameterSymbol.IsContextParameter(ps[0]));
            Debug.Assert(_lazyBaseCtor != null && !_lazyBaseCtor.IsStatic);

            foreach (var p in _lazyBaseCtor.Parameters)
            {
                if (SpecialParameterSymbol.IsContextParameter(p))
                {
                    continue;
                }

                ps.Add(new SynthesizedParameterSymbol(this, p.Type, ps.Count, p.RefKind, p.Name,
                                                      explicitDefaultConstantValue: p.ExplicitDefaultConstantValue));
            }

            //
            _parameters = ps.AsImmutable();
        }