Exemple #1
0
        private static ImmutableArray <ParameterSymbol> GetParameters(
            PEModuleSymbol moduleSymbol,
            PEPropertySymbol property,
            ParamInfo <TypeSymbol>[] propertyParams,
            ParamInfo <TypeSymbol>[] accessorParams,
            bool isPropertyVirtual,
            out bool anyParameterIsBad)
        {
            anyParameterIsBad = false;

            // First parameter is the property type.
            if (propertyParams.Length < 2)
            {
                return(ImmutableArray <ParameterSymbol> .Empty);
            }

            var numAccessorParams = accessorParams.Length;

            var parameters = new ParameterSymbol[propertyParams.Length - 1];

            for (int i = 1; i < propertyParams.Length; i++) // from 1 to skip property/return type
            {
                // NOTE: this is a best guess at the Dev10 behavior.  The actual behavior is
                // in the unmanaged helper code that Dev10 uses to load the metadata.
                var  propertyParam = propertyParams[i];
                var  paramHandle   = i < numAccessorParams ? accessorParams[i].Handle : propertyParam.Handle;
                var  ordinal       = i - 1;
                bool isBad;

                // https://github.com/dotnet/roslyn/issues/29821: handle extra annotations
                parameters[ordinal] = PEParameterSymbol.Create(moduleSymbol, property, isPropertyVirtual, ordinal, paramHandle, propertyParam, extraAnnotations: default, out isBad);
        private static PEParameterSymbol Create(
            PEModuleSymbol moduleSymbol,
            Symbol containingSymbol,
            bool isContainingSymbolVirtual,
            int ordinal,
            bool isByRef,
            ImmutableArray <ModifierInfo <TypeSymbol> > refCustomModifiers,
            TypeSymbol type,
            ImmutableArray <byte> extraAnnotations,
            ParameterHandle handle,
            ImmutableArray <ModifierInfo <TypeSymbol> > customModifiers,
            bool isReturn,
            out bool isBad)
        {
            // We start without annotation (they will be decoded below)
            var typeWithModifiers = TypeSymbolWithAnnotations.Create(type, customModifiers: CSharpCustomModifier.Convert(customModifiers));

            PEParameterSymbol parameter = customModifiers.IsDefaultOrEmpty && refCustomModifiers.IsDefaultOrEmpty
                ? new PEParameterSymbol(moduleSymbol, containingSymbol, ordinal, isByRef, typeWithModifiers, extraAnnotations, handle, 0, out isBad)
                : new PEParameterSymbolWithCustomModifiers(moduleSymbol, containingSymbol, ordinal, isByRef, refCustomModifiers, typeWithModifiers, extraAnnotations, handle, out isBad);

            bool hasInAttributeModifier = parameter.RefCustomModifiers.HasInAttributeModifier();

            if (isReturn)
            {
                // A RefReadOnly return parameter should always have this modreq, and vice versa.
                isBad |= (parameter.RefKind == RefKind.RefReadOnly) != hasInAttributeModifier;
            }
            else if (parameter.RefKind == RefKind.In)
            {
                // An in parameter should not have this modreq, unless the containing symbol was virtual or abstract.
                isBad |= isContainingSymbolVirtual != hasInAttributeModifier;
            }
            else if (hasInAttributeModifier)
            {
                // This modreq should not exist on non-in parameters.
                isBad = true;
            }

            return(parameter);
        }