コード例 #1
0
        private TypeWithAnnotations ComputeReturnType(DiagnosticBag diagnostics)
        {
            if (this.MethodKind == MethodKind.PropertyGet)
            {
                var type = _property.TypeWithAnnotations;
                if (!ContainingType.IsInterfaceType() && type.Type.IsStatic)
                {
                    // '{0}': static types cannot be used as return types
                    diagnostics.Add(ErrorCode.ERR_ReturnTypeIsStaticClass, this.locations[0], type.Type);
                }

                return(type);
            }
            else
            {
                var binder = GetBinder();
                var type   = TypeWithAnnotations.Create(binder.GetSpecialType(SpecialType.System_Void, diagnostics, this.GetSyntax()));

                if (IsInitOnly)
                {
                    var isInitOnlyType = Binder.GetWellKnownType(this.DeclaringCompilation,
                                                                 WellKnownType.System_Runtime_CompilerServices_IsExternalInit, diagnostics, this.locations[0]);

                    var modifiers = ImmutableArray.Create <CustomModifier>(
                        CSharpCustomModifier.CreateRequired(isInitOnlyType));
                    type = type.WithModifiers(modifiers);
                }

                return(type);
            }
        }
コード例 #2
0
        internal virtual ImmutableArray <CustomModifier> SubstituteCustomModifiers(
            ImmutableArray <CustomModifier> customModifiers
            )
        {
            if (customModifiers.IsDefaultOrEmpty)
            {
                return(customModifiers);
            }

            for (int i = 0; i < customModifiers.Length; i++)
            {
                NamedTypeSymbol modifier =
                    ((CSharpCustomModifier)customModifiers[i]).ModifierSymbol;
                var substituted = SubstituteNamedType(modifier);

                if (!TypeSymbol.Equals(modifier, substituted, TypeCompareKind.ConsiderEverything2))
                {
                    var builder = ArrayBuilder <CustomModifier> .GetInstance(customModifiers.Length);

                    builder.AddRange(customModifiers, i);

                    builder.Add(
                        customModifiers[i].IsOptional
                          ? CSharpCustomModifier.CreateOptional(substituted)
                          : CSharpCustomModifier.CreateRequired(substituted)
                        );
                    for (i++; i < customModifiers.Length; i++)
                    {
                        modifier    = ((CSharpCustomModifier)customModifiers[i]).ModifierSymbol;
                        substituted = SubstituteNamedType(modifier);

                        if (
                            !TypeSymbol.Equals(
                                modifier,
                                substituted,
                                TypeCompareKind.ConsiderEverything2
                                )
                            )
                        {
                            builder.Add(
                                customModifiers[i].IsOptional
                                  ? CSharpCustomModifier.CreateOptional(substituted)
                                  : CSharpCustomModifier.CreateRequired(substituted)
                                );
                        }
                        else
                        {
                            builder.Add(customModifiers[i]);
                        }
                    }

                    Debug.Assert(builder.Count == customModifiers.Length);
                    return(builder.ToImmutableAndFree());
                }
            }

            return(customModifiers);
        }
コード例 #3
0
            internal InvokeMethod(
                SourceMemberContainerTypeSymbol delegateType,
                RefKind refKind,
                TypeWithAnnotations returnType,
                DelegateDeclarationSyntax syntax,
                Binder binder,
                BindingDiagnosticBag diagnostics
            )
                : base(
                    delegateType,
                    returnType,
                    syntax,
                    MethodKind.DelegateInvoke,
                    DeclarationModifiers.Virtual | DeclarationModifiers.Public
                )
            {
                this._refKind = refKind;

                SyntaxToken arglistToken;
                var parameters = ParameterHelpers.MakeParameters(
                    binder,
                    this,
                    syntax.ParameterList,
                    out arglistToken,
                    allowRefOrOut: true,
                    allowThis: false,
                    addRefReadOnlyModifier: true,
                    diagnostics: diagnostics
                );

                if (arglistToken.Kind() == SyntaxKind.ArgListKeyword)
                {
                    // This is a parse-time error in the native compiler; it is a semantic analysis error in Roslyn.

                    // error CS1669: __arglist is not valid in this context
                    diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, new SourceLocation(arglistToken));
                }

                if (_refKind == RefKind.RefReadOnly)
                {
                    var modifierType = binder.GetWellKnownType(
                        WellKnownType.System_Runtime_InteropServices_InAttribute,
                        diagnostics,
                        syntax.ReturnType
                    );
                    _refCustomModifiers = ImmutableArray.Create(
                        CSharpCustomModifier.CreateRequired(modifierType)
                    );
                }
                else
                {
                    _refCustomModifiers = ImmutableArray<CustomModifier>.Empty;
                }

                InitializeParameters(parameters);
            }
コード例 #4
0
        IEnumerable <Cci.TypeReferenceWithAttributes> Cci.IGenericParameter.GetConstraints(EmitContext context)
        {
            var moduleBeingBuilt = (PEModuleBuilder)context.Module;

            var seenValueType = false;

            if (this.HasUnmanagedTypeConstraint)
            {
                var typeRef = moduleBeingBuilt.GetSpecialType(
                    SpecialType.System_ValueType,
                    syntaxNodeOpt: (CSharpSyntaxNode)context.SyntaxNodeOpt,
                    diagnostics: context.Diagnostics);

                var modifier = CSharpCustomModifier.CreateRequired(
                    moduleBeingBuilt.Compilation.GetWellKnownType(WellKnownType.System_Runtime_InteropServices_UnmanagedType));

                // emit "(class [mscorlib]System.ValueType modreq([mscorlib]System.Runtime.InteropServices.UnmanagedType" pattern as "unmanaged"
                yield return(new Cci.TypeReferenceWithAttributes(new Cci.ModifiedTypeReference(typeRef, ImmutableArray.Create <Cci.ICustomModifier>(modifier))));

                // do not emit another one for Dev11 similarities
                seenValueType = true;
            }

            foreach (var type in this.ConstraintTypesNoUseSiteDiagnostics)
            {
                switch (type.SpecialType)
                {
                case SpecialType.System_Object:
                    Debug.Assert(!type.NullableAnnotation.IsAnnotated());
                    break;

                case SpecialType.System_ValueType:
                    seenValueType = true;
                    break;
                }
                var typeRef = moduleBeingBuilt.Translate(type.Type,
                                                         syntaxNodeOpt: (CSharpSyntaxNode)context.SyntaxNodeOpt,
                                                         diagnostics: context.Diagnostics);

                yield return(type.GetTypeRefWithAttributes(
                                 moduleBeingBuilt,
                                 declaringSymbol: this,
                                 typeRef));
            }

            if (this.HasValueTypeConstraint && !seenValueType)
            {
                // Add System.ValueType constraint to comply with Dev11 output
                var typeRef = moduleBeingBuilt.GetSpecialType(SpecialType.System_ValueType,
                                                              syntaxNodeOpt: (CSharpSyntaxNode)context.SyntaxNodeOpt,
                                                              diagnostics: context.Diagnostics);

                yield return(new Cci.TypeReferenceWithAttributes(typeRef));
            }
        }
コード例 #5
0
        internal ImmutableArray <CustomModifier> SubstituteCustomModifiers(ImmutableArray <CustomModifier> customModifiers)
        {
            if (customModifiers.IsDefaultOrEmpty)
            {
                return(customModifiers);
            }

            for (int i = 0; i < customModifiers.Length; i++)
            {
                var modifier    = (NamedTypeSymbol)customModifiers[i].Modifier;
                var substituted = SubstituteNamedType(modifier);

                if (modifier != substituted)
                {
                    var builder = ArrayBuilder <CustomModifier> .GetInstance(customModifiers.Length);

                    builder.AddRange(customModifiers, i);

                    builder.Add(customModifiers[i].IsOptional ? CSharpCustomModifier.CreateOptional(substituted) : CSharpCustomModifier.CreateRequired(substituted));
                    for (i++; i < customModifiers.Length; i++)
                    {
                        modifier    = (NamedTypeSymbol)customModifiers[i].Modifier;
                        substituted = SubstituteNamedType(modifier);

                        if (modifier != substituted)
                        {
                            builder.Add(customModifiers[i].IsOptional ? CSharpCustomModifier.CreateOptional(substituted) : CSharpCustomModifier.CreateRequired(substituted));
                        }
                        else
                        {
                            builder.Add(customModifiers[i]);
                        }
                    }

                    Debug.Assert(builder.Count == customModifiers.Length);
                    return(builder.ToImmutableAndFree());
                }
            }

            return(customModifiers);
        }
コード例 #6
0
            public InitAccessorSymbol(
                SynthesizedRecordPropertySymbol property,
                string paramName,
                DiagnosticBag diagnostics)
            {
                _property = property;
                Name      = SourcePropertyAccessorSymbol.GetAccessorName(
                    paramName,
                    getNotSet: false,
                    // https://github.com/dotnet/roslyn/issues/44684
                    isWinMdOutput: false);

                var comp         = property.DeclaringCompilation;
                var type         = TypeWithAnnotations.Create(comp.GetSpecialType(SpecialType.System_Void));
                var initOnlyType = Binder.GetWellKnownType(
                    comp,
                    WellKnownType.System_Runtime_CompilerServices_IsExternalInit,
                    diagnostics,
                    property.Location);
                var modifiers = ImmutableArray.Create <CustomModifier>(CSharpCustomModifier.CreateRequired(initOnlyType));

                ReturnTypeWithAnnotations = type.WithModifiers(modifiers);
            }
コード例 #7
0
ファイル: SourceParameterSymbol.cs プロジェクト: zuvys/roslyn
        public static SourceParameterSymbol Create(
            Binder context,
            Symbol owner,
            TypeWithAnnotations parameterType,
            ParameterSyntax syntax,
            RefKind refKind,
            SyntaxToken identifier,
            int ordinal,
            bool isParams,
            bool isExtensionMethodThis,
            bool addRefReadOnlyModifier,
            DiagnosticBag declarationDiagnostics)
        {
            Debug.Assert(!(owner is LambdaSymbol)); // therefore we don't need to deal with discard parameters

            var name      = identifier.ValueText;
            var locations = ImmutableArray.Create <Location>(new SourceLocation(identifier));

            if (isParams)
            {
                // touch the constructor in order to generate proper use-site diagnostics
                Binder.ReportUseSiteDiagnosticForSynthesizedAttribute(context.Compilation,
                                                                      WellKnownMember.System_ParamArrayAttribute__ctor,
                                                                      declarationDiagnostics,
                                                                      identifier.Parent.GetLocation());
            }

            if (addRefReadOnlyModifier && refKind == RefKind.In)
            {
                var modifierType = context.GetWellKnownType(WellKnownType.System_Runtime_InteropServices_InAttribute, declarationDiagnostics, syntax);

                return(new SourceComplexParameterSymbolWithCustomModifiersPrecedingByRef(
                           owner,
                           ordinal,
                           parameterType,
                           refKind,
                           ImmutableArray.Create(CSharpCustomModifier.CreateRequired(modifierType)),
                           name,
                           locations,
                           syntax.GetReference(),
                           ConstantValue.Unset,
                           isParams,
                           isExtensionMethodThis));
            }

            if (!isParams &&
                !isExtensionMethodThis &&
                (syntax.Default == null) &&
                (syntax.AttributeLists.Count == 0) &&
                !owner.IsPartialMethod())
            {
                return(new SourceSimpleParameterSymbol(owner, parameterType, ordinal, refKind, name, isDiscard: false, locations));
            }

            return(new SourceComplexParameterSymbol(
                       owner,
                       ordinal,
                       parameterType,
                       refKind,
                       name,
                       locations,
                       syntax.GetReference(),
                       ConstantValue.Unset,
                       isParams,
                       isExtensionMethodThis));
        }
コード例 #8
0
        protected MethodSymbol?MethodChecks(TypeWithAnnotations returnType, ImmutableArray <ParameterSymbol> parameters, BindingDiagnosticBag diagnostics)
        {
            _lazyReturnType = returnType;
            _lazyParameters = parameters;

            // set ReturnsVoid flag
            this.SetReturnsVoid(_lazyReturnType.IsVoidType());

            this.CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics);
            this.CheckFileTypeUsage(_lazyReturnType, _lazyParameters, diagnostics);

            var location = locations[0];

            // Checks taken from MemberDefiner::defineMethod
            if (this.Name == WellKnownMemberNames.DestructorName && this.ParameterCount == 0 && this.Arity == 0 && this.ReturnsVoid)
            {
                diagnostics.Add(ErrorCode.WRN_FinalizeMethod, location);
            }

            ExtensionMethodChecks(diagnostics);

            if (IsPartial)
            {
                if (MethodKind == MethodKind.ExplicitInterfaceImplementation)
                {
                    diagnostics.Add(ErrorCode.ERR_PartialMethodNotExplicit, location);
                }

                if (!ContainingType.IsPartial())
                {
                    diagnostics.Add(ErrorCode.ERR_PartialMethodOnlyInPartialClass, location);
                }
            }

            if (!IsPartial)
            {
                LazyAsyncMethodChecks(CancellationToken.None);
                Debug.Assert(state.HasComplete(CompletionPart.FinishAsyncMethodChecks));
            }

            // The runtime will not treat this method as an override or implementation of another
            // method unless both the signatures and the custom modifiers match.  Hence, in the
            // case of overrides and *explicit* implementations, we need to copy the custom modifiers
            // that are in the signature of the overridden/implemented method.  (From source, we know
            // that there can only be one such method, so there are no conflicts.)  This is
            // unnecessary for implicit implementations because, if the custom modifiers don't match,
            // we'll insert a bridge method (an explicit implementation that delegates to the implicit
            // implementation) with the correct custom modifiers
            // (see SourceMemberContainerTypeSymbol.SynthesizeInterfaceMemberImplementation).

            // This value may not be correct, but we need something while we compute this.OverriddenMethod.
            // May be re-assigned below.
            Debug.Assert(_lazyReturnType.CustomModifiers.IsEmpty);
            _lazyRefCustomModifiers = ImmutableArray <CustomModifier> .Empty;

            MethodSymbol?overriddenOrExplicitlyImplementedMethod = null;

            // Note: we're checking if the syntax indicates explicit implementation rather,
            // than if explicitInterfaceType is null because we don't want to look for an
            // overridden property if this is supposed to be an explicit implementation.
            if (MethodKind != MethodKind.ExplicitInterfaceImplementation)
            {
                Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;

                // If this method is an override, we may need to copy custom modifiers from
                // the overridden method (so that the runtime will recognize it as an override).
                // We check for this case here, while we can still modify the parameters and
                // return type without losing the appearance of immutability.
                if (this.IsOverride)
                {
                    // This computation will necessarily be performed with partially incomplete
                    // information.  There is no way we can determine the complete signature
                    // (i.e. including custom modifiers) until we have found the method that
                    // this method overrides.  To accommodate this, MethodSymbol.OverriddenOrHiddenMembers
                    // is written to allow relaxed matching of custom modifiers for source methods,
                    // on the assumption that they will be updated appropriately.
                    overriddenOrExplicitlyImplementedMethod = this.OverriddenMethod;

                    if ((object)overriddenOrExplicitlyImplementedMethod != null)
                    {
                        CustomModifierUtils.CopyMethodCustomModifiers(overriddenOrExplicitlyImplementedMethod, this, out _lazyReturnType,
                                                                      out _lazyRefCustomModifiers,
                                                                      out _lazyParameters, alsoCopyParamsModifier: true);
                    }
                }
                else if (RefKind == RefKind.RefReadOnly)
                {
                    var modifierType = Binder.GetWellKnownType(DeclaringCompilation, WellKnownType.System_Runtime_InteropServices_InAttribute, diagnostics, ReturnTypeLocation);

                    _lazyRefCustomModifiers = ImmutableArray.Create(CSharpCustomModifier.CreateRequired(modifierType));
                }
            }
            else if (ExplicitInterfaceType is not null)
            {
                //do this last so that it can assume the method symbol is constructed (except for ExplicitInterfaceImplementation)
                overriddenOrExplicitlyImplementedMethod = FindExplicitlyImplementedMethod(diagnostics);

                if (overriddenOrExplicitlyImplementedMethod is not null)
                {
                    Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                    _lazyExplicitInterfaceImplementations = ImmutableArray.Create <MethodSymbol>(overriddenOrExplicitlyImplementedMethod);

                    CustomModifierUtils.CopyMethodCustomModifiers(overriddenOrExplicitlyImplementedMethod, this, out _lazyReturnType,
                                                                  out _lazyRefCustomModifiers,
                                                                  out _lazyParameters, alsoCopyParamsModifier: false);
                    this.FindExplicitlyImplementedMemberVerification(overriddenOrExplicitlyImplementedMethod, diagnostics);
                    TypeSymbol.CheckNullableReferenceTypeAndScopedMismatchOnImplementingMember(this.ContainingType, this, overriddenOrExplicitlyImplementedMethod, isExplicit: true, diagnostics);
                }
                else
                {
                    Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                    _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;

                    Debug.Assert(_lazyReturnType.CustomModifiers.IsEmpty);
                }
            }

            return(overriddenOrExplicitlyImplementedMethod);
        }
コード例 #9
0
        private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsBinder, DiagnosticBag diagnostics)
        {
            Debug.Assert(this.MethodKind != MethodKind.UserDefinedOperator, "SourceUserDefinedOperatorSymbolBase overrides this");

            SyntaxToken arglistToken;

            // Constraint checking for parameter and return types must be delayed until
            // the method has been added to the containing type member list since
            // evaluating the constraints may depend on accessing this method from
            // the container (comparing this method to others to find overrides for
            // instance). Constraints are checked in AfterAddingTypeMembersChecks.
            var signatureBinder = withTypeParamsBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this);

            _lazyParameters = ParameterHelpers.MakeParameters(
                signatureBinder, this, syntax.ParameterList, out arglistToken,
                allowRefOrOut: true,
                allowThis: true,
                addRefReadOnlyModifier: IsVirtual || IsAbstract,
                diagnostics: diagnostics);

            _lazyIsVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword);
            RefKind refKind;
            var     returnTypeSyntax = syntax.ReturnType.SkipRef(out refKind);

            _lazyReturnType = signatureBinder.BindType(returnTypeSyntax, diagnostics);

            // span-like types are returnable in general
            if (_lazyReturnType.IsRestrictedType(ignoreSpanLikeTypes: true))
            {
                if (_lazyReturnType.SpecialType == SpecialType.System_TypedReference &&
                    (this.ContainingType.SpecialType == SpecialType.System_TypedReference || this.ContainingType.SpecialType == SpecialType.System_ArgIterator))
                {
                    // Two special cases: methods in the special types TypedReference and ArgIterator are allowed to return TypedReference
                }
                else
                {
                    // Method or delegate cannot return type '{0}'
                    diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, syntax.ReturnType.Location, _lazyReturnType);
                }
            }

            var returnsVoid = _lazyReturnType.SpecialType == SpecialType.System_Void;

            if (this.RefKind != RefKind.None && returnsVoid)
            {
                Debug.Assert(returnTypeSyntax.HasErrors);
            }

            // set ReturnsVoid flag
            this.SetReturnsVoid(returnsVoid);

            var location = this.Locations[0];

            this.CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics);

            // Checks taken from MemberDefiner::defineMethod
            if (this.Name == WellKnownMemberNames.DestructorName && this.ParameterCount == 0 && this.Arity == 0 && this.ReturnsVoid)
            {
                diagnostics.Add(ErrorCode.WRN_FinalizeMethod, location);
            }

            // errors relevant for extension methods
            if (IsExtensionMethod)
            {
                var parameter0Type    = this.Parameters[0].Type;
                var parameter0RefKind = this.Parameters[0].RefKind;
                if (!parameter0Type.IsValidExtensionParameterType())
                {
                    // Duplicate Dev10 behavior by selecting the parameter type.
                    var parameterSyntax = syntax.ParameterList.Parameters[0];
                    Debug.Assert(parameterSyntax.Type != null);
                    var loc = parameterSyntax.Type.Location;
                    diagnostics.Add(ErrorCode.ERR_BadTypeforThis, loc, parameter0Type);
                }
                else if (parameter0RefKind == RefKind.Ref && !parameter0Type.IsValueType)
                {
                    diagnostics.Add(ErrorCode.ERR_RefExtensionMustBeValueTypeOrConstrainedToOne, location, Name);
                }
                else if (parameter0RefKind == RefKind.In && parameter0Type.TypeKind != TypeKind.Struct)
                {
                    diagnostics.Add(ErrorCode.ERR_InExtensionMustBeValueType, location, Name);
                }
                else if ((object)ContainingType.ContainingType != null)
                {
                    diagnostics.Add(ErrorCode.ERR_ExtensionMethodsDecl, location, ContainingType.Name);
                }
                else if (!ContainingType.IsScriptClass && !(ContainingType.IsStatic && ContainingType.Arity == 0))
                {
                    // Duplicate Dev10 behavior by selecting the containing type identifier. However if there
                    // is no containing type (in the interactive case for instance), select the method identifier.
                    var typeDecl   = syntax.Parent as TypeDeclarationSyntax;
                    var identifier = (typeDecl != null) ? typeDecl.Identifier : syntax.Identifier;
                    var loc        = identifier.GetLocation();
                    diagnostics.Add(ErrorCode.ERR_BadExtensionAgg, loc);
                }
                else if (!IsStatic)
                {
                    diagnostics.Add(ErrorCode.ERR_BadExtensionMeth, location);
                }
                else
                {
                    // Verify ExtensionAttribute is available.
                    var attributeConstructor = withTypeParamsBinder.Compilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_ExtensionAttribute__ctor);
                    if ((object)attributeConstructor == null)
                    {
                        var memberDescriptor = WellKnownMembers.GetDescriptor(WellKnownMember.System_Runtime_CompilerServices_ExtensionAttribute__ctor);
                        // do not use Binder.ReportUseSiteErrorForAttributeCtor in this case, because we'll need to report a special error id, not a generic use site error.
                        diagnostics.Add(
                            ErrorCode.ERR_ExtensionAttrNotFound,
                            syntax.ParameterList.Parameters[0].Modifiers.FirstOrDefault(SyntaxKind.ThisKeyword).GetLocation(),
                            memberDescriptor.DeclaringTypeMetadataName);
                    }
                }
            }

            if (IsPartial)
            {
                // check that there are no out parameters in a partial
                foreach (var p in this.Parameters)
                {
                    if (p.RefKind == RefKind.Out)
                    {
                        diagnostics.Add(ErrorCode.ERR_PartialMethodCannotHaveOutParameters, location);
                        break;
                    }
                }

                if (MethodKind == MethodKind.ExplicitInterfaceImplementation)
                {
                    diagnostics.Add(ErrorCode.ERR_PartialMethodNotExplicit, location);
                }

                if (!ContainingType.IsPartial() || ContainingType.IsInterface)
                {
                    diagnostics.Add(ErrorCode.ERR_PartialMethodOnlyInPartialClass, location);
                }
            }

            if (!IsPartial)
            {
                LazyAsyncMethodChecks(CancellationToken.None);
                Debug.Assert(state.HasComplete(CompletionPart.FinishAsyncMethodChecks));
            }

            // The runtime will not treat this method as an override or implementation of another
            // method unless both the signatures and the custom modifiers match.  Hence, in the
            // case of overrides and *explicit* implementations, we need to copy the custom modifiers
            // that are in the signature of the overridden/implemented method.  (From source, we know
            // that there can only be one such method, so there are no conflicts.)  This is
            // unnecessary for implicit implementations because, if the custom modifiers don't match,
            // we'll insert a bridge method (an explicit implementation that delegates to the implicit
            // implementation) with the correct custom modifiers
            // (see SourceNamedTypeSymbol.ImplementInterfaceMember).

            // This value may not be correct, but we need something while we compute overridden/implemented method.
            // May be re-assigned below.
            Debug.Assert(_lazyCustomModifiers == null);
            _lazyCustomModifiers = CustomModifiersTuple.Empty;

            // Note: we're checking if the syntax indicates explicit implementation rather,
            // than if explicitInterfaceType is null because we don't want to look for an
            // overridden property if this is supposed to be an explicit implementation.
            if (syntax.ExplicitInterfaceSpecifier == null)
            {
                Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;

                // If this method is an override, we may need to copy custom modifiers from
                // the overridden method (so that the runtime will recognize it as an override).
                // We check for this case here, while we can still modify the parameters and
                // return type without losing the appearance of immutability.
                if (this.IsOverride)
                {
                    // This computation will necessarily be performed with partially incomplete
                    // information.  There is no way we can determine the complete signature
                    // (i.e. including custom modifiers) until we have found the method that
                    // this method overrides.  To accommodate this, MethodSymbol.OverriddenOrHiddenMembers
                    // is written to allow relaxed matching of custom modifiers for source methods,
                    // on the assumption that they will be updated appropriately.
                    MethodSymbol overriddenMethod = this.OverriddenMethod;

                    if ((object)overriddenMethod != null)
                    {
                        CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType,
                                                                      out _lazyCustomModifiers,
                                                                      out _lazyParameters, alsoCopyParamsModifier: true);
                    }
                }
                else if (_refKind == RefKind.RefReadOnly)
                {
                    var modifierType = withTypeParamsBinder.GetWellKnownType(WellKnownType.System_Runtime_InteropServices_InAttribute, diagnostics, syntax.ReturnType);

                    _lazyCustomModifiers = CustomModifiersTuple.Create(
                        typeCustomModifiers: ImmutableArray <CustomModifier> .Empty,
                        refCustomModifiers: ImmutableArray.Create(CSharpCustomModifier.CreateRequired(modifierType)));
                }
            }
            else if ((object)_explicitInterfaceType != null)
            {
                //do this last so that it can assume the method symbol is constructed (except for ExplicitInterfaceImplementation)
                MethodSymbol implementedMethod = this.FindExplicitlyImplementedMethod(_explicitInterfaceType, syntax.Identifier.ValueText, syntax.ExplicitInterfaceSpecifier, diagnostics);

                if ((object)implementedMethod != null)
                {
                    Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                    _lazyExplicitInterfaceImplementations = ImmutableArray.Create <MethodSymbol>(implementedMethod);

                    CustomModifierUtils.CopyMethodCustomModifiers(implementedMethod, this, out _lazyReturnType,
                                                                  out _lazyCustomModifiers,
                                                                  out _lazyParameters, alsoCopyParamsModifier: false);
                }
                else
                {
                    Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                    _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;
                }
            }

            CheckModifiers(_hasAnyBody, location, diagnostics);

            foreach (var typeParameter in _typeParameters)
            {
                if (typeParameter.HasUnmanagedTypeConstraint)
                {
                    DeclaringCompilation.EnsureIsUnmanagedAttributeExists(diagnostics, typeParameter.GetNonNullSyntaxNode().Location, modifyCompilationForIsUnmanaged: true);
                }
            }
        }
コード例 #10
0
 internal CodeblockEvalMethod(NamedTypeSymbol container)
     : base(container, "Eval")
 {
     if (this.Manager.Compilation.Options.XSharpRuntime)
     {
         _parameters = ImmutableArray.Create <ParameterSymbol>(
             new SynthesizedParamsParameterSymbol(this, this.Manager.Compilation.CreateArrayTypeSymbol(this.Manager.UsualType), 0, RefKind.None, "args")
             );
     }
     else
     {
         _parameters = ImmutableArray.Create <ParameterSymbol>(
             new SynthesizedParamsParameterSymbol(this, this.Manager.Compilation.CreateArrayTypeSymbol(this.Manager.UsualType), 0, RefKind.None, "args",
                                                  customModifiers: new[] { CSharpCustomModifier.CreateOptional(this.Manager.Compilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IsConst)) }.ToImmutableArray())
             );
     }
 }