Represents a method or method-like symbol (including constructor, destructor, operator, or property/event accessor).
Наследование: Symbol, IMethodSymbol, IPhpRoutineSymbol
Пример #1
0
            public void Construct(NamedTypeSymbol functype, Action<CodeGenerator> binder_builder)
            {
                var callsitetype = _factory.CallSite_T.Construct(functype);

                // TODO: check if it wasn't constructed already

                _target.SetContainingType((SubstitutedNamedTypeSymbol)callsitetype);
                _fld.SetFieldType(callsitetype);
                _callsite_create = (MethodSymbol)_factory.CallSite_T_Create.SymbolAsMember(callsitetype);

                // create callsite

                // static .cctor {
                var cctor = _factory.CctorBuilder;

                // fld = CallSite<T>.Create( <BINDER> )
                var fldPlace = this.Place;
                fldPlace.EmitStorePrepare(cctor);

                var cctor_cg = new CodeGenerator(cctor, _factory._cg.Module, _factory._cg.Diagnostics, _factory._cg.DeclaringCompilation.Options.OptimizationLevel, false, _factory._container, null, null);
                binder_builder(cctor_cg);
                cctor.EmitCall(_factory._cg.Module, _factory._cg.Diagnostics, ILOpCode.Call, this.CallSite_Create);

                fldPlace.EmitStore(cctor);

                // }
            }
Пример #2
0
        internal SourceAttributeData(
            SyntaxReference applicationNode,
            NamedTypeSymbol attributeClass,
            MethodSymbol attributeConstructor,
            ImmutableArray<TypedConstant> constructorArguments,
            ImmutableArray<int> constructorArgumentsSourceIndices,
            ImmutableArray<KeyValuePair<string, TypedConstant>> namedArguments,
            bool hasErrors,
            bool isConditionallyOmitted)
        {
            Debug.Assert(!isConditionallyOmitted || (object)attributeClass != null && attributeClass.IsConditional);
            Debug.Assert(!constructorArguments.IsDefault);
            Debug.Assert(!namedArguments.IsDefault);
            Debug.Assert(constructorArgumentsSourceIndices.IsDefault ||
                constructorArgumentsSourceIndices.Any() && constructorArgumentsSourceIndices.Length == constructorArguments.Length);

            _attributeClass = attributeClass;
            _attributeConstructor = attributeConstructor;
            _constructorArguments = constructorArguments;
            _constructorArgumentsSourceIndices = constructorArgumentsSourceIndices;
            _namedArguments = namedArguments;
            _isConditionallyOmitted = isConditionallyOmitted;
            _hasErrors = hasErrors;
            _applicationNode = applicationNode;
        }
Пример #3
0
        void EmitInvoke(MethodSymbol invoke, Emit.PEModuleBuilder module)
        {
            if (invoke == null)
            {
                return;
            }

            module.SetMethodBody(invoke, MethodGenerator.GenerateMethodBody(module, invoke, il =>
            {
                var cg = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), OptimizationLevel.Release, false, this, new ParamPlace(invoke.Parameters[0]), new ArgPlace(this, 0));
                //var __invoke = (MethodSymbol)GetMembers(Pchp.Syntax.Name.SpecialMethodNames.Invoke.Value).Single(s => s is MethodSymbol);

                // TODO: call __invoke() directly

                // context.Call<T>(T, TypeMethods.MagicMethods, params PhpValue[])
                var call_t = cg.CoreTypes.Context.Symbol.GetMembers("Call")
                    .OfType<MethodSymbol>()
                    .Where(s => s.Arity == 1 && s.ParameterCount == 3 && s.Parameters[2].IsParams)
                    .Single()
                    .Construct(this);

                // return context.Call<T>(this, __invoke, args)
                cg.EmitLoadContext();
                cg.EmitThis();
                cg.Builder.EmitIntConstant((int)Core.Reflection.TypeMethods.MagicMethods.__invoke);
                cg.Builder.EmitLoadArgumentOpcode(2);
                cg.EmitCall(ILOpCode.Call, call_t);
                cg.EmitRet(invoke.ReturnType);

            }, null, DiagnosticBag.GetInstance(), false));
        }
Пример #4
0
 internal ConstructedMethodSymbol(MethodSymbol constructedFrom, ImmutableArray<TypeSymbol> typeArguments)
     : base(containingSymbol: constructedFrom.ContainingType,
            map: new TypeMap(constructedFrom.ContainingType, ((MethodSymbol)constructedFrom.OriginalDefinition).TypeParameters, typeArguments.SelectAsArray(TypeMap.TypeSymbolAsTypeWithModifiers)),
            originalDefinition: (MethodSymbol)constructedFrom.OriginalDefinition,
            constructedFrom: constructedFrom)
 {
     _typeArguments = typeArguments;
 }
Пример #5
0
        protected SynthesizedContainer(string name, MethodSymbol topLevelMethod)
        {
            Debug.Assert(name != null);
            Debug.Assert(topLevelMethod != null);

            _name = name;
            _typeMap = TypeMap.Empty.WithAlphaRename(topLevelMethod, this, out _typeParameters);
        }
Пример #6
0
 public SynthesizedPropertySymbol(NamedTypeSymbol containing, string name, bool isStatic, TypeSymbol type, Accessibility accessibility, MethodSymbol getter, MethodSymbol setter)
 {
     _containing = containing;
     _name = name;
     _accessibility = accessibility;
     _setMethod = setter;
     _getMethod = getter;
     _type = type;
     _isStatic = isStatic;
 }
Пример #7
0
        public SpecialParameterSymbol(MethodSymbol symbol, object type, string name, int index)
        {
            Debug.Assert(type is TypeSymbol || type is CoreType);
            Contract.ThrowIfNull(symbol);
            Contract.ThrowIfNull(type);

            _symbol = symbol;
            _type = type;
            _name = name;
            _index = index;
        }
Пример #8
0
 internal RetargetingAttributeData(
     SyntaxReference applicationNode,
     NamedTypeSymbol attributeClass,
     MethodSymbol attributeConstructor,
     ImmutableArray<TypedConstant> constructorArguments,
     ImmutableArray<int> constructorArgumentsSourceIndices,
     ImmutableArray<KeyValuePair<string, TypedConstant>> namedArguments,
     bool hasErrors,
     bool isConditionallyOmitted)
     : base(applicationNode, attributeClass, attributeConstructor, constructorArguments, constructorArgumentsSourceIndices, namedArguments, hasErrors, isConditionallyOmitted)
 {
 }
Пример #9
0
 internal SourceAttributeData(SyntaxReference applicationNode, NamedTypeSymbol attributeClass, MethodSymbol attributeConstructor, bool hasErrors)
     : this(
     applicationNode,
     attributeClass,
     attributeConstructor,
     constructorArguments: ImmutableArray<TypedConstant>.Empty,
     constructorArgumentsSourceIndices: default(ImmutableArray<int>),
     namedArguments: ImmutableArray<KeyValuePair<string, TypedConstant>>.Empty,
     hasErrors: hasErrors,
     isConditionallyOmitted: false)
 {
 }
Пример #10
0
 // constructor for dynamic call-site delegate:
 public SynthesizedDelegateSymbol(
     NamespaceOrTypeSymbol containingSymbol,
     string name,
     TypeSymbol objectType,
     TypeSymbol intPtrType,
     TypeSymbol voidReturnTypeOpt,
     int parameterCount,
     BitVector byRefParameters)
     : base(name, parameterCount, returnsVoid: (object)voidReturnTypeOpt != null)
 {
     _containingSymbol = containingSymbol;
     _constructor = new DelegateConstructor(this, objectType, intPtrType);
     _invoke = new InvokeMethod(this, byRefParameters, voidReturnTypeOpt);
 }
Пример #11
0
        static bool IsAccessible(MethodSymbol method, TypeSymbol classCtx)
        {
            if (method.DeclaredAccessibility == Accessibility.Private)
            {
                return (method.ContainingType == classCtx);
            }
            else if (method.DeclaredAccessibility == Accessibility.Protected)
            {
                return classCtx != null && (
                    method.ContainingType.IsEqualToOrDerivedFrom(classCtx) ||
                    classCtx.IsEqualToOrDerivedFrom(method.ContainingType));
            }

            return true;
        }
Пример #12
0
 internal SynthesizedAttributeData(MethodSymbol ctor, ImmutableArray<TypedConstant> arguments, ImmutableArray<KeyValuePair<String, TypedConstant>> namedArguments)
     : base(
     applicationNode: null,
     attributeClass: (NamedTypeSymbol)ctor.ContainingType,
     attributeConstructor: ctor,
     constructorArguments: arguments,
     constructorArgumentsSourceIndices: default(ImmutableArray<int>),
     namedArguments: namedArguments,
     hasErrors: false,
     isConditionallyOmitted: false)
 {
     Debug.Assert((object)ctor != null);
     Debug.Assert(!arguments.IsDefault);
     Debug.Assert(!namedArguments.IsDefault); // Frequently empty though.
 }
Пример #13
0
 protected SubstitutedMethodSymbol(NamedTypeSymbol containingSymbol, TypeMap map, MethodSymbol originalDefinition, MethodSymbol constructedFrom)
 {
     Debug.Assert(originalDefinition.IsDefinition);
     _containingType = containingSymbol;
     this.originalDefinition = originalDefinition;
     _inputMap = map;
     if ((object)constructedFrom != null)
     {
         _constructedFrom = constructedFrom;
         Debug.Assert(ReferenceEquals(constructedFrom.ConstructedFrom, constructedFrom));
         _lazyTypeParameters = constructedFrom.TypeParameters;
         _lazyMap = map;
     }
     else
     {
         _constructedFrom = this;
     }
 }
Пример #14
0
        /// <summary>
        /// Creates ghost stub that calls current method.
        /// </summary>
        protected void CreateGhostOverload(PEModuleBuilder module, DiagnosticBag diagnostic,
            TypeSymbol ghostreturn, IEnumerable<ParameterSymbol> ghostparams,
            MethodSymbol explicitOverride = null)
        {
            var ghost = new SynthesizedMethodSymbol(
                this.ContainingType, this.Name, this.IsStatic, explicitOverride != null, ghostreturn, this.DeclaredAccessibility)
            {
                ExplicitOverride = explicitOverride,
            };

            ghost.SetParameters(ghostparams.Select(p =>
                new SynthesizedParameterSymbol(ghost, p.Type, p.Ordinal, p.RefKind, p.Name)).ToArray());

            // save method symbol to module
            module.SynthesizedManager.AddMethod(this.ContainingType, ghost);

            // generate method body
            GenerateGhostBody(module, diagnostic, ghost);
        }
Пример #15
0
        public SynthesizedParameterSymbol(
            MethodSymbol container,
            TypeSymbol type,
            int ordinal,
            RefKind refKind,
            string name = "",
            ImmutableArray<CustomModifier> customModifiers = default(ImmutableArray<CustomModifier>),
            ushort countOfCustomModifiersPrecedingByRef = 0,
            ConstantValue explicitDefaultConstantValue = null)
        {
            Debug.Assert((object)type != null);
            Debug.Assert(name != null);
            Debug.Assert(ordinal >= 0);

            _container = container;
            _type = type;
            _ordinal = ordinal;
            _refKind = refKind;
            _name = name;
            _customModifiers = customModifiers.NullToEmpty();
            _countOfCustomModifiersPrecedingByRef = countOfCustomModifiersPrecedingByRef;
            _explicitDefaultConstantValue = explicitDefaultConstantValue;
        }
Пример #16
0
        private int _hashCode; // computed on demand

        internal SubstitutedMethodSymbol(SubstitutedNamedTypeSymbol containingSymbol, MethodSymbol originalDefinition)
            : this(containingSymbol, containingSymbol.TypeSubstitution, originalDefinition, constructedFrom: null)
        {
        }
Пример #17
0
 public static bool IsParams(this MethodSymbol method)
 {
     return(method.ParameterCount != 0 && method.Parameters[method.ParameterCount - 1].IsParams);
 }
Пример #18
0
 public static bool IsErrorMethod(this MethodSymbol method) => method == null || method is IErrorMethodSymbol;
Пример #19
0
        public MethodReference(MethodSymbol underlyingMethod)
        {
            Debug.Assert((object)underlyingMethod != null);

            this.UnderlyingMethod = underlyingMethod;
        }
Пример #20
0
 public static TypeSymbol[] ParametersType(this MethodSymbol method)
 {
     return(method.Parameters.Select(p => p.Type).ToArray());
 }
Пример #21
0
        internal override void Generate(CodeGenerator cg)
        {
            Debug.Assert(this.Enumeree != null);

            // get the enumerator,
            // bind actual MoveNext() and CurrentValue and CurrentKey

            // Template: using(
            // a) enumerator = enumeree.GetEnumerator()
            // b) enumerator = Operators.GetEnumerator(enumeree)
            // ) ...

            cg.EmitSequencePoint(this.Enumeree.PhpSyntax);

            var enumereeType = cg.Emit(this.Enumeree);
            Debug.Assert(enumereeType.SpecialType != SpecialType.System_Void);

            var getEnumeratorMethod = enumereeType.LookupMember<MethodSymbol>(WellKnownMemberNames.GetEnumeratorMethodName);

            TypeSymbol enumeratorType;

            if (enumereeType.IsOfType(cg.CoreTypes.PhpArray))
            {
                cg.Builder.EmitBoolConstant(_aliasedValues);
                
                // PhpArray.GetForeachtEnumerator(bool)
                enumeratorType = cg.EmitCall(ILOpCode.Callvirt, cg.CoreMethods.PhpArray.GetForeachEnumerator_Boolean);  // TODO: IPhpArray
            }
            // TODO: IPhpEnumerable
            // TODO: IPhpArray
            // TODO: Iterator
            else if (getEnumeratorMethod != null && getEnumeratorMethod.ParameterCount == 0 && enumereeType.IsReferenceType)
            {
                // enumeree.GetEnumerator()
                enumeratorType = cg.EmitCall(getEnumeratorMethod.IsVirtual ? ILOpCode.Callvirt : ILOpCode.Call, getEnumeratorMethod);
            }
            else
            {
                cg.EmitConvertToPhpValue(enumereeType, 0);
                cg.Builder.EmitBoolConstant(_aliasedValues);
                cg.EmitCallerRuntimeTypeHandle();

                // Operators.GetForeachEnumerator(PhpValue, bool, RuntimeTypeHandle)
                enumeratorType = cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.GetForeachEnumerator_PhpValue_Bool_RuntimeTypeHandle);
            }

            //
            _current = enumeratorType.LookupMember<PropertySymbol>(WellKnownMemberNames.CurrentPropertyName);   // TODO: Err if no Current
            _currentValue = enumeratorType.LookupMember<PropertySymbol>(_aliasedValues ? "CurrentValueAliased" : "CurrentValue");
            _currentKey = enumeratorType.LookupMember<PropertySymbol>("CurrentKey");
            _disposeMethod = enumeratorType.LookupMember<MethodSymbol>("Dispose", m => m.ParameterCount == 0 && !m.IsStatic);

            //
            _enumeratorLoc = cg.GetTemporaryLocal(enumeratorType);
            cg.Builder.EmitLocalStore(_enumeratorLoc);

            // bind methods
            _moveNextMethod = enumeratorType.LookupMember<MethodSymbol>(WellKnownMemberNames.MoveNextMethodName);    // TODO: Err if there is no MoveNext()
            Debug.Assert(_moveNextMethod.ReturnType.SpecialType == SpecialType.System_Boolean);
            Debug.Assert(_moveNextMethod.IsStatic == false);

            if (_disposeMethod != null)
            {
                /* Template: try { body } finally { enumerator.Dispose }
                 */

                // try {
                cg.Builder.AssertStackEmpty();
                cg.Builder.OpenLocalScope(ScopeType.TryCatchFinally);
                cg.Builder.OpenLocalScope(ScopeType.Try);

                //
                EmitBody(cg);

                // }
                cg.Builder.CloseLocalScope();   // /Try

                // finally {
                cg.Builder.OpenLocalScope(ScopeType.Finally);

                // enumerator.Dispose() & cleanup
                EmitDisposeAndClean(cg);

                // }
                cg.Builder.CloseLocalScope();   // /Finally
                cg.Builder.CloseLocalScope();   // /TryCatchFinally
            }
            else
            {
                EmitBody(cg);
                EmitDisposeAndClean(cg);
            }
        }
Пример #22
0
        //internal static ImmutableArray<TypeParameterSymbol> GetMemberTypeParameters(this Symbol symbol)
        //{
        //    switch (symbol.Kind)
        //    {
        //        case SymbolKind.Method:
        //            return ((MethodSymbol)symbol).TypeParameters;
        //        case SymbolKind.NamedType:
        //        case SymbolKind.ErrorType:
        //            return ((NamedTypeSymbol)symbol).TypeParameters;
        //        case SymbolKind.Field:
        //        case SymbolKind.Property:
        //        case SymbolKind.Event:
        //            return ImmutableArray<TypeParameterSymbol>.Empty;
        //        default:
        //            throw ExceptionUtilities.UnexpectedValue(symbol.Kind);
        //    }
        //}

        //internal static ImmutableArray<TypeSymbol> GetMemberTypeArgumentsNoUseSiteDiagnostics(this Symbol symbol)
        //{
        //    switch (symbol.Kind)
        //    {
        //        case SymbolKind.Method:
        //            return ((MethodSymbol)symbol).TypeArguments;
        //        case SymbolKind.NamedType:
        //        case SymbolKind.ErrorType:
        //            return ((NamedTypeSymbol)symbol).TypeArgumentsNoUseSiteDiagnostics;
        //        case SymbolKind.Field:
        //        case SymbolKind.Property:
        //        case SymbolKind.Event:
        //            return ImmutableArray<TypeSymbol>.Empty;
        //        default:
        //            throw ExceptionUtilities.UnexpectedValue(symbol.Kind);
        //    }
        //}

        /// <summary>
        /// NOTE: every struct has a public parameterless constructor either used-defined or default one
        /// </summary>
        internal static bool IsParameterlessConstructor(this MethodSymbol method)
        {
            return(method.MethodKind == MethodKind.Constructor && method.ParameterCount == 0);
        }
Пример #23
0
 /// <summary>
 /// Determines whether <paramref name="method"/> can override <paramref name="basemethod"/>.
 /// </summary>
 /// <param name="method">Source method.</param>
 /// <param name="basemethod">Overriden method.</param>
 public static bool CanBeOverride(SourceMethodSymbol method, MethodSymbol basemethod)
 {
     return IsAllowedCost(OverrideCost(method, basemethod));
 }
 public SpecializedGenericMethodInstanceReference(MethodSymbol underlyingMethod)
     : base(underlyingMethod)
 {
     Debug.Assert(PEModuleBuilder.IsGenericType(underlyingMethod.ContainingType) && underlyingMethod.ContainingType.IsDefinition);
     _genericMethod = new SpecializedMethodReference(underlyingMethod);
 }
Пример #25
0
        //internal static ISet<PropertySymbol> GetPropertiesForExplicitlyImplementedAccessor(MethodSymbol accessor)
        //{
        //    return GetSymbolsForExplicitlyImplementedAccessor<PropertySymbol>(accessor);
        //}

        //internal static ISet<EventSymbol> GetEventsForExplicitlyImplementedAccessor(MethodSymbol accessor)
        //{
        //    return GetSymbolsForExplicitlyImplementedAccessor<EventSymbol>(accessor);
        //}

        //// CONSIDER: the 99% case is a very small set.  A list might be more efficient in such cases.
        //private static ISet<T> GetSymbolsForExplicitlyImplementedAccessor<T>(MethodSymbol accessor) where T : Symbol
        //{
        //    if ((object)accessor == null)
        //    {
        //        return SpecializedCollections.EmptySet<T>();
        //    }

        //    ImmutableArray<MethodSymbol> implementedAccessors = accessor.ExplicitInterfaceImplementations;
        //    if (implementedAccessors.Length == 0)
        //    {
        //        return SpecializedCollections.EmptySet<T>();
        //    }

        //    var symbolsForExplicitlyImplementedAccessors = new HashSet<T>();
        //    foreach (var implementedAccessor in implementedAccessors)
        //    {
        //        var associatedProperty = implementedAccessor.AssociatedSymbol as T;
        //        if ((object)associatedProperty != null)
        //        {
        //            symbolsForExplicitlyImplementedAccessors.Add(associatedProperty);
        //        }
        //    }
        //    return symbolsForExplicitlyImplementedAccessors;
        //}

        // Properties and events from metadata do not have explicit accessibility. Instead,
        // the accessibility reported for the PEPropertySymbol or PEEventSymbol is the most
        // restrictive level that is no more restrictive than the getter/adder and setter/remover.
        internal static Accessibility GetDeclaredAccessibilityFromAccessors(MethodSymbol accessor1, MethodSymbol accessor2)
        {
            if ((object)accessor1 == null)
            {
                return(((object)accessor2 == null) ? Accessibility.NotApplicable : accessor2.DeclaredAccessibility);
            }
            else if ((object)accessor2 == null)
            {
                return(accessor1.DeclaredAccessibility);
            }

            return(GetDeclaredAccessibilityFromAccessors(accessor1.DeclaredAccessibility, accessor2.DeclaredAccessibility));
        }
Пример #26
0
 internal TypeMap WithAlphaRename(MethodSymbol oldOwner, Symbol newOwner, out ImmutableArray<TypeParameterSymbol> newTypeParameters)
 {
     Debug.Assert(object.ReferenceEquals(oldOwner.ConstructedFrom, oldOwner));
     return WithAlphaRename(oldOwner.OriginalDefinition.TypeParameters, newOwner, out newTypeParameters);
 }
Пример #27
0
        //internal override void AddSynthesizedAttributes(ModuleCompilationState compilationState, ref ArrayBuilder<SynthesizedAttributeData> attributes)
        //{
        //    // Emit [Dynamic] on synthesized parameter symbols when the original parameter was dynamic 
        //    // in order to facilitate debugging.  In the case the necessary attributes are missing 
        //    // this is a no-op.  Emitting an error here, or when the original parameter was bound, would
        //    // adversely effect the compilation or potentially change overload resolution.  
        //    var compilation = this.DeclaringCompilation;
        //    if (Type.ContainsDynamic() && compilation.HasDynamicEmitAttributes())
        //    {
        //        var boolType = compilation.GetSpecialType(SpecialType.System_Boolean);
        //        var diagnostic = boolType.GetUseSiteDiagnostic();
        //        if ((diagnostic == null) || (diagnostic.Severity != DiagnosticSeverity.Error))
        //        {
        //            AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.Type, this.CustomModifiers.Length, this.RefKind));
        //        }
        //    }
        //}

        /// <summary>
        /// For each parameter of a source method, construct a corresponding synthesized parameter
        /// for a destination method.
        /// </summary>
        /// <param name="sourceMethod">Has parameters.</param>
        /// <param name="destinationMethod">Needs parameters.</param>
        /// <returns>Synthesized parameters to add to destination method.</returns>
        internal static ImmutableArray<ParameterSymbol> DeriveParameters(MethodSymbol sourceMethod, MethodSymbol destinationMethod)
        {
            var builder = ArrayBuilder<ParameterSymbol>.GetInstance();

            foreach (var oldParam in sourceMethod.Parameters)
            {
                //same properties as the old one, just change the owner
                builder.Add(new SynthesizedParameterSymbol(destinationMethod, oldParam.Type, oldParam.Ordinal,
                    oldParam.RefKind, oldParam.Name, oldParam.CustomModifiers, oldParam.CountOfCustomModifiersPrecedingByRef));
            }

            return builder.ToImmutableAndFree();
        }
Пример #28
0
 public static bool IsMissingMethod(this MethodSymbol method) =>
 (method == null) ||
 (method is IErrorMethodSymbol && ((IErrorMethodSymbol)method).ErrorKind == ErrorMethodKind.Missing);
Пример #29
0
        //public static bool IsIndexedPropertyAccessor(this MethodSymbol methodSymbol)
        //{
        //    var propertyOrEvent = methodSymbol.AssociatedSymbol;
        //    return ((object)propertyOrEvent != null) && propertyOrEvent.IsIndexedProperty();
        //}

        public static bool IsOperator(this MethodSymbol methodSymbol)
        {
            return(methodSymbol.MethodKind == MethodKind.UserDefinedOperator || methodSymbol.MethodKind == MethodKind.Conversion);
        }
 public GenericMethodInstanceReference(MethodSymbol underlyingMethod)
     : base(underlyingMethod)
 {
 }
Пример #31
0
        //internal static bool HasUnsafeParameter(this Symbol member)
        //{
        //    foreach (TypeSymbol parameterType in member.GetParameterTypes())
        //    {
        //        if (parameterType.IsUnsafe())
        //        {
        //            return true;
        //        }
        //    }

        //    return false;
        //}

        public static bool IsAccessor(this MethodSymbol methodSymbol)
        {
            return((object)methodSymbol.AssociatedSymbol != null);
        }
Пример #32
0
        /// <summary>
        /// Checks whether signatures of two methods match exactly so one can override the second.
        /// </summary>
        public static bool SignaturesMatch(this MethodSymbol a, MethodSymbol b)
        {
            Contract.ThrowIfNull(a);
            Contract.ThrowIfNull(b);

            if (a.ReturnType != b.ReturnType)
            {
                return false;
            }

            var ps1 = a.Parameters;
            var ps2 = b.Parameters;

            if (ps1.Length != ps2.Length)
            {
                return false;
            }

            for (int i = 0; i < ps1.Length; i++)
            {
                var p1 = ps1[i];
                var p2 = ps2[i];

                if (p1.Type != p2.Type || p1.RefKind != p2.RefKind)
                {
                    return false;
                }
            }

            //
            return true;
        }
Пример #33
0
        void EmitDisposeAndClean(CodeGenerator cg)
        {
            // enumerator.Dispose()
            if (_disposeMethod != null)
            {
                // TODO: if (enumerator != null)

                if (_enumeratorLoc.Type.IsValueType)
                    cg.Builder.EmitLocalAddress(_enumeratorLoc);
                else
                    cg.Builder.EmitLocalLoad(_enumeratorLoc);

                cg.EmitCall(_disposeMethod.IsVirtual ? ILOpCode.Callvirt : ILOpCode.Call, _disposeMethod)
                    .Expect(SpecialType.System_Void);
            }

            //// enumerator = null;
            //if (!_enumeratorLoc.Type.IsValueType)
            //{
            //    cg.Builder.EmitNullConstant();
            //    cg.Builder.EmitLocalStore(_enumeratorLoc);
            //}

            //
            cg.ReturnTemporaryLocal(_enumeratorLoc);
            _enumeratorLoc = null;

            // unbind
            _moveNextMethod = null;
            _disposeMethod = null;
            _currentValue = null;
            _currentKey = null;
            _current = null;
        }
Пример #34
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));
        }
Пример #35
0
        /// <summary>
        /// Calculates override cost, i.e. whether the override is possible and its value.
        /// In case of more possible overrides, the one with better cost is selected.
        /// </summary>
        /// <param name="method">Source method.</param>
        /// <param name="basemethod">A hypothetical base method.</param>
        /// <returns></returns>
        public static ConversionCost OverrideCost(SourceMethodSymbol method, MethodSymbol basemethod)
        {
            Contract.ThrowIfNull(method);
            Contract.ThrowIfNull(basemethod);

            //
            if (method.IsStatic || basemethod.IsStatic || basemethod.IsSealed ||
                (!basemethod.IsVirtual && !basemethod.IsAbstract) ||    // not abstract or virtual
                method.Name.EqualsOrdinalIgnoreCase(basemethod.Name) == false ||
                method.DeclaredAccessibility == Accessibility.Private || basemethod.DeclaredAccessibility == Accessibility.Private)
            {
                return ConversionCost.NoConversion;
            }

            if (method.ReturnType != basemethod.ReturnType)
            {
                return ConversionCost.ImplicitCast;
            }

            //
            var ps = method.Parameters;
            var psbase = basemethod.Parameters;

            //
            var result = ConversionCost.Pass;

            // NOTE: there shouldn't be any implicit parameters (Context and LateBoundType are known from this instance)

            for (int i = 0; i < ps.Length; i++)
            {
                if (i < psbase.Length)
                {
                    var p = ps[i];
                    var pbase = psbase[i];

                    if (p.Type != pbase.Type)
                    {
                        if (p.Type.IsOfType(pbase.Type))
                        {
                            result |= ConversionCost.ImplicitCast;
                        }
                        else
                        {
                            result |= ConversionCost.NoConversion;
                        }
                    }
                }
                else
                {
                    result |= ConversionCost.TooManyArgs;
                }
            }

            //
            if (ps.Length < psbase.Length)
            {
                result |= ConversionCost.MissingArgs;
            }

            //
            return result;
        }
Пример #36
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 as IPhpTypeSymbol)?.InitializeInstanceMethod;   // 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();
        }
Пример #37
0
 internal SubstitutedParameterSymbol(MethodSymbol containingSymbol, TypeMap map, ParameterSymbol originalParameter) :
     this((Symbol)containingSymbol, map, originalParameter)
 {
 }
Пример #38
0
        internal virtual TypeSymbol EmitDirectCall(CodeGenerator cg, ILOpCode opcode, MethodSymbol method)
        {
            // TODO: emit check the routine is declared
            // <ctx>.AssertFunctionDeclared

            var arguments = _arguments.Select(a => a.Value).ToImmutableArray();

            return cg.EmitCall(opcode, method, this.Instance, arguments);
        }
        //internal override void AddSynthesizedAttributes(ModuleCompilationState compilationState, ref ArrayBuilder<SynthesizedAttributeData> attributes)
        //{
        //    // Emit [Dynamic] on synthesized parameter symbols when the original parameter was dynamic
        //    // in order to facilitate debugging.  In the case the necessary attributes are missing
        //    // this is a no-op.  Emitting an error here, or when the original parameter was bound, would
        //    // adversely effect the compilation or potentially change overload resolution.
        //    var compilation = this.DeclaringCompilation;
        //    if (Type.ContainsDynamic() && compilation.HasDynamicEmitAttributes())
        //    {
        //        var boolType = compilation.GetSpecialType(SpecialType.System_Boolean);
        //        var diagnostic = boolType.GetUseSiteDiagnostic();
        //        if ((diagnostic == null) || (diagnostic.Severity != DiagnosticSeverity.Error))
        //        {
        //            AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.Type, this.CustomModifiers.Length, this.RefKind));
        //        }
        //    }
        //}

        /// <summary>
        /// For each parameter of a source method, construct a corresponding synthesized parameter
        /// for a destination method.
        /// </summary>
        /// <param name="sourceMethod">Has parameters.</param>
        /// <param name="destinationMethod">Needs parameters.</param>
        /// <returns>Synthesized parameters to add to destination method.</returns>
        internal static ImmutableArray <ParameterSymbol> DeriveParameters(MethodSymbol sourceMethod, MethodSymbol destinationMethod)
        {
            var builder = ArrayBuilder <ParameterSymbol> .GetInstance();

            foreach (var oldParam in sourceMethod.Parameters)
            {
                //same properties as the old one, just change the owner
                builder.Add(new SynthesizedParameterSymbol(destinationMethod, oldParam.Type, oldParam.Ordinal,
                                                           oldParam.RefKind, oldParam.Name, false, oldParam.CustomModifiers, oldParam.CountOfCustomModifiersPrecedingByRef));
            }

            return(builder.ToImmutableAndFree());
        }