Microsoft.CSharp.RuntimeBinder.SymbolTable.AddPropertyToSymbolTable C# (CSharp) Метод

AddPropertyToSymbolTable() приватный Метод

private AddPropertyToSymbolTable ( PropertyInfo property, AggregateSymbol aggregate ) : Microsoft.CSharp.RuntimeBinder.Semantics.PropertySymbol
property System.Reflection.PropertyInfo
aggregate Microsoft.CSharp.RuntimeBinder.Semantics.AggregateSymbol
Результат Microsoft.CSharp.RuntimeBinder.Semantics.PropertySymbol
        private PropertySymbol AddPropertyToSymbolTable(PropertyInfo property, AggregateSymbol aggregate)
        {
            Name name;
            bool isIndexer = property.GetIndexParameters() != null && property.GetIndexParameters().Length != 0;

            if (isIndexer)
            {
                name = GetName(SpecialNames.Indexer);
            }
            else
            {
                name = GetName(property.Name);
            }
            PropertySymbol prop = _symbolTable.LookupSym(
                name,
                aggregate,
                symbmask_t.MASK_PropertySymbol) as PropertySymbol;

            // If we already had one, see if it matches.
            if (prop != null)
            {
                PropertySymbol prevProp = null;

                // We'll have multiple properties with the same name if we have indexers.
                // In that case, we need to look at every indexer to see if we find one with
                // the matching associated sym that we want.
                while (prop != null)
                {
                    if (prop.AssociatedPropertyInfo.IsEquivalentTo(property))
                    {
                        return prop;
                    }

                    prevProp = prop;
                    prop = _semanticChecker.SymbolLoader.LookupNextSym(prop, prop.parent, symbmask_t.MASK_PropertySymbol).AsPropertySymbol();
                }

                prop = prevProp;
                if (isIndexer)
                {
                    // We have an indexer for a different property info, so 
                    // create a new symbol for it.
                    prop = null;
                }
            }

            // If we already had a property but its associated info doesn't match,
            // then we repurpose the property that we've found. This can happen
            // in the case of generic instantiations. 
            //
            // Note that this is a bit of a hack - the best way to fix this is 
            // by not depending on the instantiated properties at all, but rather depending
            // on their non-instantiated generic form, which can be gotten from the
            // parent's generic type definition's member. From there, we'll also need to 
            // keep track of the instantiation as we move along, so that when we need the
            // associated property, we can instantiate it correctly.
            //
            // This seems far too heavyweight - since we know we will never bind to more
            // than one property per payload, lets just blast it each time.
            if (prop == null)
            {
                if (isIndexer)
                {
                    prop = _semanticChecker.GetSymbolLoader().GetGlobalMiscSymFactory().CreateIndexer(name, aggregate, GetName(property.Name), null);
                    prop.Params = CreateParameterArray(null, property.GetIndexParameters());
                }
                else
                {
                    prop = _symFactory.CreateProperty(GetName(property.Name), aggregate, null);
                    prop.Params = BSYMMGR.EmptyTypeArray();
                }
            }
            prop.AssociatedPropertyInfo = property;

            prop.isStatic = property.GetGetMethod(true) != null ? property.GetGetMethod(true).IsStatic : property.GetSetMethod(true).IsStatic;
            prop.isParamArray = DoesMethodHaveParameterArray(property.GetIndexParameters());
            prop.swtSlot = null;
            prop.RetType = GetCTypeFromType(property.PropertyType);
            prop.isOperator = isIndexer;

            // Determine if its an override. We should always have an accessor, unless
            // the metadata was bogus.
            if (property.GetMethod != null || property.SetMethod != null)
            {
                MethodInfo accessor = property.GetMethod ?? property.SetMethod; // Must have at least one.
                prop.isOverride = accessor.IsVirtual && accessor.IsHideBySig && accessor.GetRuntimeBaseDefinition() != accessor;
                prop.isHideByName = !accessor.IsHideBySig;
            }

            SetParameterDataForMethProp(prop, property.GetIndexParameters());

            // Get and set.
            MethodInfo methGet = property.GetMethod;
            MethodInfo methSet = property.SetMethod;
            ACCESS access = ACCESS.ACC_PRIVATE;
            if (methGet != null)
            {
                prop.methGet = AddMethodToSymbolTable(methGet, aggregate, MethodKindEnum.PropAccessor);

                // If we have an indexed property, leave the method as a method we can call,
                // and mark the property as bogus.
                if (isIndexer || prop.methGet.Params.size == 0)
                {
                    prop.methGet.SetProperty(prop);
                }
                else
                {
                    prop.setBogus(true);
                    prop.methGet.SetMethKind(MethodKindEnum.Actual);
                }

                if (prop.methGet.GetAccess() > access)
                {
                    access = prop.methGet.GetAccess();
                }
            }
            if (methSet != null)
            {
                prop.methSet = AddMethodToSymbolTable(methSet, aggregate, MethodKindEnum.PropAccessor);

                // If we have an indexed property, leave the method as a method we can call,
                // and mark the property as bogus.
                if (isIndexer || prop.methSet.Params.size == 1)
                {
                    prop.methSet.SetProperty(prop);
                }
                else
                {
                    prop.setBogus(true);
                    prop.methSet.SetMethKind(MethodKindEnum.Actual);
                }

                if (prop.methSet.GetAccess() > access)
                {
                    access = prop.methSet.GetAccess();
                }
            }

            // The access of the property is the least restrictive access of its getter/setter.
            prop.SetAccess(access);

            return prop;
        }