internal sealed override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            // Check constraints on return type and parameters. Note: Dev10 uses the
            // method name location for any such errors. We'll do the same for return
            // type errors but for parameter errors, we'll use the parameter location.

            var compilation = DeclaringCompilation;

            this.ReturnType.CheckAllConstraints(compilation, conversions, this.Locations[0], diagnostics);

            foreach (var parameter in this.Parameters)
            {
                parameter.Type.CheckAllConstraints(compilation, conversions, parameter.Locations[0], diagnostics);
            }

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(compilation, Parameters, diagnostics, modifyCompilation: true);

            if (ReturnType.ContainsNativeInteger())
            {
                compilation.EnsureNativeIntegerAttributeExists(diagnostics, ReturnTypeSyntax.Location, modifyCompilation: true);
            }

            ParameterHelpers.EnsureNativeIntegerAttributeExists(compilation, Parameters, diagnostics, modifyCompilation: true);

            if (compilation.ShouldEmitNullableAttributes(this) &&
                ReturnTypeWithAnnotations.NeedsNullableAttribute())
            {
                compilation.EnsureNullableAttributeExists(diagnostics, ReturnTypeSyntax.Location, modifyCompilation: true);
            }

            ParameterHelpers.EnsureNullableAttributeExists(compilation, this, Parameters, diagnostics, modifyCompilation: true);
        }
Example #2
0
            internal InvokeMethod(
                SourceMemberContainerTypeSymbol delegateType,
                RefKind refKind,
                TypeSymbol returnType,
                DelegateDeclarationSyntax syntax,
                Binder binder,
                DiagnosticBag 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,
                    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));
                }

                InitializeParameters(parameters);
            }
        protected override void MethodChecks(DiagnosticBag diagnostics)
        {
            var syntax        = GetSyntax();
            var binderFactory = this.DeclaringCompilation.GetBinderFactory(syntax.SyntaxTree);
            ParameterListSyntax parameterList = syntax.ParameterList;

            // NOTE: if we asked for the binder for the body of the constructor, we'd risk a stack overflow because
            // we might still be constructing the member list of the containing type.  However, getting the binder
            // for the parameters should be safe.
            var bodyBinder = binderFactory.GetBinder(parameterList).WithContainingMemberOrLambda(this);

            SyntaxToken arglistToken;

            _lazyParameters = ParameterHelpers.MakeParameters(bodyBinder, this, parameterList, true, out arglistToken, diagnostics);
            _lazyIsVararg   = (arglistToken.Kind() == SyntaxKind.ArgListKeyword);
            _lazyReturnType = bodyBinder.GetSpecialType(SpecialType.System_Void, diagnostics, syntax);

            var location = this.Locations[0];

            if (MethodKind == MethodKind.StaticConstructor && (_lazyParameters.Length != 0))
            {
                diagnostics.Add(ErrorCode.ERR_StaticConstParam, location, this);
            }

            this.CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics);

            if (_lazyIsVararg && (IsGenericMethod || ContainingType.IsGenericType || _lazyParameters.Length > 0 && _lazyParameters[_lazyParameters.Length - 1].IsParams))
            {
                diagnostics.Add(ErrorCode.ERR_BadVarargs, location);
            }
        }
        internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            // Check constraints on return type and parameters. Note: Dev10 uses the
            // method name location for any such errors. We'll do the same for return
            // type errors but for parameter errors, we'll use the parameter location.

            if ((object)_explicitInterfaceType != null)
            {
                var syntax = this.GetSyntax();
                Debug.Assert(syntax.ExplicitInterfaceSpecifier != null);
                _explicitInterfaceType.CheckAllConstraints(conversions, new SourceLocation(syntax.ExplicitInterfaceSpecifier.Name), diagnostics);
            }

            this.ReturnType.CheckAllConstraints(conversions, this.Locations[0], diagnostics);

            foreach (var parameter in this.Parameters)
            {
                parameter.Type.CheckAllConstraints(conversions, parameter.Locations[0], diagnostics);
            }

            var implementingPart = this.SourcePartialImplementation;

            if ((object)implementingPart != null)
            {
                PartialMethodChecks(this, implementingPart, diagnostics);
            }

            if (_refKind == RefKind.RefReadOnly)
            {
                this.DeclaringCompilation.EnsureIsReadOnlyAttributeExists(diagnostics, GetSyntax().ReturnType.Location, modifyCompilationForRefReadOnly: true);
            }

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilationForRefReadOnly: true);
        }
Example #5
0
        internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            base.AfterAddingTypeMembersChecks(conversions, diagnostics);

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilation: true);
            ParameterHelpers.EnsureNullableAttributeExists(Parameters, diagnostics, modifyCompilation: true);
        }
Example #6
0
        private void ComputeParameters()
        {
            if (_lazyParametersAndDiagnostics != null)
            {
                return;
            }

            var         diagnostics = DiagnosticBag.GetInstance();
            SyntaxToken arglistToken;

            foreach (var param in _syntax.ParameterList.Parameters)
            {
                ReportAnyAttributes(diagnostics, param.AttributeLists);
            }

            var parameters = ParameterHelpers.MakeParameters(
                _binder,
                this,
                _syntax.ParameterList,
                arglistToken: out arglistToken,
                diagnostics: diagnostics,
                allowRefOrOut: true,
                allowThis: true,
                beStrict: true);

            var isVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword);

            if (IsAsync && diagnostics.IsEmptyWithoutResolution)
            {
                SourceMemberMethodSymbol.ReportAsyncParameterErrors(parameters, diagnostics, this.Locations[0]);
            }
            var value = new ParametersAndDiagnostics(parameters, isVararg, diagnostics.ToReadOnlyAndFree());

            Interlocked.CompareExchange(ref _lazyParametersAndDiagnostics, value, null);
        }
        protected override void MethodChecks(DiagnosticBag diagnostics)
        {
            var binder = this.DeclaringCompilation.
                         GetBinderFactory(syntaxReferenceOpt.SyntaxTree).GetBinder(ReturnTypeSyntax, GetSyntax(), this);

            SyntaxToken arglistToken;

            var signatureBinder = binder.WithAdditionalFlags(BinderFlags.SuppressConstraintChecks);

            _lazyParameters = ParameterHelpers.MakeParameters(
                signatureBinder,
                this,
                ParameterListSyntax,
                out arglistToken,
                diagnostics,
                allowRefOrOut: true,
                allowThis: false,
                beStrict: false);

            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));

                // Regardless of whether __arglist appears in the source code, we do not mark
                // the operator method as being a varargs method.
            }

            _lazyReturnType = signatureBinder.BindType(ReturnTypeSyntax, diagnostics);

            if (_lazyReturnType.IsRestrictedType())
            {
                // Method or delegate cannot return type '{0}'
                diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, ReturnTypeSyntax.Location, _lazyReturnType);
            }

            if (_lazyReturnType.IsStatic)
            {
                // '{0}': static types cannot be used as return types
                diagnostics.Add(ErrorCode.ERR_ReturnTypeIsStaticClass, ReturnTypeSyntax.Location, _lazyReturnType);
            }

            this.SetReturnsVoid(_lazyReturnType.SpecialType == SpecialType.System_Void);

            // If we have an operator in an interface or static class then we already
            // have reported that fact as  an error. No need to cascade the error further.
            if (this.ContainingType.IsInterfaceType() || this.ContainingType.IsStatic)
            {
                return;
            }

            // SPEC: All types referenced in an operator declaration must be at least as accessible
            // SPEC: as the operator itself.

            CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics);
            CheckValueParameters(diagnostics);
            CheckOperatorSignatures(diagnostics);
        }
Example #8
0
            internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
            {
                var syntax      = (DelegateDeclarationSyntax)SyntaxRef.GetSyntax();
                var location    = syntax.ReturnType.GetLocation();
                var compilation = DeclaringCompilation;

                Debug.Assert(location != null);

                base.AfterAddingTypeMembersChecks(conversions, diagnostics);

                if (_refKind == RefKind.RefReadOnly)
                {
                    compilation.EnsureIsReadOnlyAttributeExists(diagnostics, location, modifyCompilation: true);
                }

                ParameterHelpers.EnsureIsReadOnlyAttributeExists(compilation, Parameters, diagnostics, modifyCompilation: true);

                if (ReturnType.ContainsNativeInteger())
                {
                    compilation.EnsureNativeIntegerAttributeExists(diagnostics, location, modifyCompilation: true);
                }

                ParameterHelpers.EnsureNativeIntegerAttributeExists(compilation, Parameters, diagnostics, modifyCompilation: true);

                if (compilation.ShouldEmitNullableAttributes(this) &&
                    ReturnTypeWithAnnotations.NeedsNullableAttribute())
                {
                    compilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true);
                }

                ParameterHelpers.EnsureNullableAttributeExists(compilation, this, Parameters, diagnostics, modifyCompilation: true);
            }
        // If binder is null, then get it from the compilation. Otherwise use the provided binder.
        // Don't always get it from the compilation because we might be in a speculative context (local function parameter),
        // in which case the declaring compilation is the wrong one.
        protected ConstantValue MakeDefaultExpression(DiagnosticBag diagnostics, Binder binder)
        {
            var parameterSyntax = this.CSharpSyntaxNode;

            if (parameterSyntax == null)
            {
                return(ConstantValue.NotAvailable);
            }

            var defaultSyntax = parameterSyntax.Default;

            if (defaultSyntax == null)
            {
                return(ConstantValue.NotAvailable);
            }

            if (binder == null)
            {
                var syntaxTree    = _syntaxRef.SyntaxTree;
                var compilation   = this.DeclaringCompilation;
                var binderFactory = compilation.GetBinderFactory(syntaxTree);
                binder = binderFactory.GetBinder(defaultSyntax);
            }

            Debug.Assert(binder.GetBinder(defaultSyntax) == null);

            Binder binderForDefault = binder.CreateBinderForParameterDefaultValue(this, defaultSyntax);

            Debug.Assert(binderForDefault.InParameterDefaultValue);
            Debug.Assert(binderForDefault.ContainingMemberOrLambda == ContainingSymbol);

            BoundExpression valueBeforeConversion;
            var             convertedExpression = binderForDefault.BindParameterDefaultValue(defaultSyntax, parameterType, diagnostics, out valueBeforeConversion);

            bool hasErrors = ParameterHelpers.ReportDefaultParameterErrors(binder, ContainingSymbol, parameterSyntax, this, valueBeforeConversion, diagnostics);

            if (hasErrors)
            {
                return(ConstantValue.Bad);
            }

            // If we have something like M(double? x = 1) then the expression we'll get is (double?)1, which
            // does not have a constant value. The constant value we want is (double)1.

            if (convertedExpression.ConstantValue == null && convertedExpression.Kind == BoundKind.Conversion)
            {
                if (parameterType.IsNullableType())
                {
                    convertedExpression = binder.GenerateConversionForAssignment(parameterType.GetNullableUnderlyingType(),
                                                                                 valueBeforeConversion, diagnostics, isDefaultParameter: true);
                }
            }

            // represent default(struct) by a Null constant:
            var value = convertedExpression.ConstantValue ?? ConstantValue.Null;

            VerifyParamDefaultValueMatchesAttributeIfAny(value, defaultSyntax.Value, diagnostics);
            return(value);
        }
            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);
            }
Example #11
0
        internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes)
        {
            base.AddSynthesizedAttributes(moduleBuilder, ref attributes);

            var compilation = this.DeclaringCompilation;

            if (this.IsParams)
            {
                AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(WellKnownMember.System_ParamArrayAttribute__ctor));
            }

            // Synthesize DecimalConstantAttribute if we don't have an explicit custom attribute already:
            var defaultValue = this.ExplicitDefaultConstantValue;

            if (defaultValue != ConstantValue.NotAvailable &&
                defaultValue.SpecialType == SpecialType.System_Decimal &&
                DefaultValueFromAttributes == ConstantValue.NotAvailable)
            {
                AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDecimalConstantAttribute(defaultValue.DecimalValue));
            }

            var type = this.TypeWithAnnotations;

            if (type.Type.ContainsDynamic())
            {
                AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(type.Type, type.CustomModifiers.Length + this.RefCustomModifiers.Length, this.RefKind));
            }

            if (compilation.ShouldEmitNativeIntegerAttributes(type.Type))
            {
                AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNativeIntegerAttribute(this, type.Type));
            }

            if (ParameterHelpers.RequiresLifetimeAnnotationAttribute(this))
            {
                AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeLifetimeAnnotationAttribute(this, Scope));
            }

            if (type.Type.ContainsTupleNames())
            {
                AddSynthesizedAttribute(ref attributes,
                                        compilation.SynthesizeTupleNamesAttribute(type.Type));
            }

            if (this.RefKind == RefKind.RefReadOnly)
            {
                AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsReadOnlyAttribute(this));
            }

            if (compilation.ShouldEmitNullableAttributes(this))
            {
                AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttributeIfNecessary(this, GetNullableContextValue(), type));
            }
        }
            internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
            {
                base.AfterAddingTypeMembersChecks(conversions, diagnostics);

                if (_refKind == RefKind.RefReadOnly)
                {
                    var syntax = (DelegateDeclarationSyntax)SyntaxRef.GetSyntax();
                    DeclaringCompilation.EnsureIsReadOnlyAttributeExists(diagnostics, syntax.ReturnType.GetLocation(), modifyCompilationForRefReadOnly: true);
                }

                ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilationForRefReadOnly: true);
            }
Example #13
0
        internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            base.AfterAddingTypeMembersChecks(conversions, diagnostics);

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilation: true);
            ParameterHelpers.EnsureNullableAttributeExists(Parameters, diagnostics, modifyCompilation: true);

            foreach (var parameter in this.Parameters)
            {
                parameter.Type.CheckAllConstraints(DeclaringCompilation, conversions, parameter.Locations[0], diagnostics);
            }
        }
        protected override void MethodChecks(DiagnosticBag diagnostics)
        {
            var syntax        = (CSharpSyntaxNode)syntaxReference.GetSyntax();
            var binderFactory = this.DeclaringCompilation.GetBinderFactory(syntaxReference.SyntaxTree);
            ParameterListSyntax parameterList;

            if (syntax.Kind == SyntaxKind.ParameterList)
            {
                // Primary constructor case
                parameterList = (ParameterListSyntax)syntax;
            }
            else
            {
                parameterList = ((ConstructorDeclarationSyntax)syntax).ParameterList;
            }

            // NOTE: if we asked for the binder for the body of the constructor, we'd risk a stack overflow because
            // we might still be constructing the member list of the containing type.  However, getting the binder
            // for the parameters should be safe.
            var bodyBinder = binderFactory.GetBinder(parameterList).WithContainingMemberOrLambda(this);

            SyntaxToken arglistToken;

            this.lazyParameters = ParameterHelpers.MakeParameters(bodyBinder, this, parameterList, true, out arglistToken, diagnostics);
            this.lazyIsVararg   = (arglistToken.CSharpKind() == SyntaxKind.ArgListKeyword);
            this.lazyReturnType = bodyBinder.GetSpecialType(SpecialType.System_Void, diagnostics, syntax);

            if (MethodKind == MethodKind.StaticConstructor && (lazyParameters.Length != 0))
            {
                diagnostics.Add(ErrorCode.ERR_StaticConstParam, Locations[0], this);
            }

            this.CheckEffectiveAccessibility(lazyReturnType, lazyParameters, diagnostics);

            if (this.lazyIsVararg && (IsGenericMethod || ContainingType.IsGenericType || this.lazyParameters.Length > 0 && this.lazyParameters[this.lazyParameters.Length - 1].IsParams))
            {
                diagnostics.Add(ErrorCode.ERR_BadVarargs, Locations[0]);
            }

            if (this.IsPrimaryCtor)
            {
                string typeName = ContainingType.Name;

                foreach (var p in this.lazyParameters)
                {
                    if (typeName.Equals(p.Name))
                    {
                        diagnostics.Add(ErrorCode.ERR_PrimaryCtorParameterSameNameAsContainingType, p.Locations[0], ContainingType);
                        break;
                    }
                }
            }
        }
Example #15
0
        protected (TypeWithAnnotations ReturnType, ImmutableArray <ParameterSymbol> Parameters) MakeParametersAndBindReturnType(BaseMethodDeclarationSyntax declarationSyntax, TypeSyntax returnTypeSyntax, DiagnosticBag diagnostics)
        {
            TypeWithAnnotations returnType;
            ImmutableArray <ParameterSymbol> parameters;

            var binder = this.DeclaringCompilation.
                         GetBinderFactory(declarationSyntax.SyntaxTree).GetBinder(returnTypeSyntax, declarationSyntax, this);

            SyntaxToken arglistToken;

            var signatureBinder = binder.WithAdditionalFlags(BinderFlags.SuppressConstraintChecks);

            parameters = ParameterHelpers.MakeParameters(
                signatureBinder,
                this,
                declarationSyntax.ParameterList,
                out arglistToken,
                allowRefOrOut: true,
                allowThis: false,
                addRefReadOnlyModifier: false,
                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));

                // Regardless of whether __arglist appears in the source code, we do not mark
                // the operator method as being a varargs method.
            }

            returnType = signatureBinder.BindType(returnTypeSyntax, diagnostics);

            // restricted types cannot be returned.
            // NOTE: Span-like types can be returned (if expression is returnable).
            if (returnType.IsRestrictedType(ignoreSpanLikeTypes: true))
            {
                // The return type of a method, delegate, or function pointer cannot be '{0}'
                diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, returnTypeSyntax.Location, returnType.Type);
            }

            if (returnType.Type.IsStatic)
            {
                // Operators in interfaces was introduced in C# 8, so there's no need to be specially concerned about
                // maintaining backcompat with the native compiler bug around interfaces.
                // '{0}': static types cannot be used as return types
                diagnostics.Add(ErrorFacts.GetStaticClassReturnCode(useWarning: false), returnTypeSyntax.Location, returnType.Type);
            }

            return(returnType, parameters);
        }
Example #16
0
        private void ComputeParameters()
        {
            if (_lazyParameters != null)
            {
                return;
            }

            SyntaxToken arglistToken;
            var         diagnostics = DiagnosticBag.GetInstance();

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

            var compilation = DeclaringCompilation;

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(compilation, parameters, diagnostics, modifyCompilation: false);
            ParameterHelpers.EnsureNullableAttributeExists(compilation, this, parameters, diagnostics, modifyCompilation: false);
            // Note: we don't need to warn on annotations used in #nullable disable context for local functions, as this is handled in binding already

            var isVararg = arglistToken.Kind() == SyntaxKind.ArgListKeyword;

            if (isVararg)
            {
                diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, arglistToken.GetLocation());
            }

            if (IsAsync)
            {
                SourceOrdinaryMethodSymbol.ReportAsyncParameterErrors(parameters, diagnostics, this.Locations[0]);
            }

            lock (_declarationDiagnostics)
            {
                if (_lazyParameters != null)
                {
                    diagnostics.Free();
                    return;
                }

                _declarationDiagnostics.AddRangeAndFree(diagnostics);
                _lazyIsVarArg   = isVararg;
                _lazyParameters = parameters;
            }
        }
Example #17
0
        protected sealed override void MethodChecks(BindingDiagnosticBag diagnostics)
        {
            var syntax        = (CSharpSyntaxNode)syntaxReferenceOpt.GetSyntax();
            var binderFactory = this.DeclaringCompilation.GetBinderFactory(syntax.SyntaxTree);
            ParameterListSyntax parameterList = GetParameterList();

            // NOTE: if we asked for the binder for the body of the constructor, we'd risk a stack overflow because
            // we might still be constructing the member list of the containing type.  However, getting the binder
            // for the parameters should be safe.
            var bodyBinder = binderFactory.GetBinder(parameterList, syntax, this).WithContainingMemberOrLambda(this);

            // 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 = bodyBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this);

            SyntaxToken arglistToken;

            _lazyParameters = ParameterHelpers.MakeParameters(
                signatureBinder, this, parameterList, out arglistToken,
                allowRefOrOut: AllowRefOrOut,
                allowThis: false,
                addRefReadOnlyModifier: false,
                diagnostics: diagnostics);

            _lazyIsVararg   = (arglistToken.Kind() == SyntaxKind.ArgListKeyword);
            _lazyReturnType = TypeWithAnnotations.Create(bodyBinder.GetSpecialType(SpecialType.System_Void, diagnostics, syntax));

            var location = this.Locations[0];

            // Don't report ERR_StaticConstParam if the ctor symbol name doesn't match the containing type name.
            // This avoids extra unnecessary errors.
            // There will already be a diagnostic saying Method must have a return type.
            if (MethodKind == MethodKind.StaticConstructor && (_lazyParameters.Length != 0) &&
                ContainingType.Name == ((ConstructorDeclarationSyntax)this.SyntaxNode).Identifier.ValueText)
            {
                diagnostics.Add(ErrorCode.ERR_StaticConstParam, location, this);
            }

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

            if (_lazyIsVararg && (IsGenericMethod || ContainingType.IsGenericType || _lazyParameters.Length > 0 && _lazyParameters[_lazyParameters.Length - 1].IsParams))
            {
                diagnostics.Add(ErrorCode.ERR_BadVarargs, location);
            }
        }
        internal sealed override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            // Check constraints on return type and parameters. Note: Dev10 uses the
            // method name location for any such errors. We'll do the same for return
            // type errors but for parameter errors, we'll use the parameter location.

            this.ReturnType.CheckAllConstraints(conversions, this.Locations[0], diagnostics);

            foreach (var parameter in this.Parameters)
            {
                parameter.Type.CheckAllConstraints(conversions, parameter.Locations[0], diagnostics);
            }

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilationForRefReadOnly: true);
        }
Example #19
0
        private void ComputeParameters()
        {
            if (_lazyParameters != null)
            {
                return;
            }

            SyntaxToken arglistToken;
            var         diagnostics = DiagnosticBag.GetInstance();

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

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(parameters, diagnostics, modifyCompilationForRefReadOnly: false);

            var isVararg = arglistToken.Kind() == SyntaxKind.ArgListKeyword;

            if (isVararg)
            {
                diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, arglistToken.GetLocation());
            }

            if (IsAsync)
            {
                SourceOrdinaryMethodSymbol.ReportAsyncParameterErrors(parameters, diagnostics, this.Locations[0]);
            }

            lock (_declarationDiagnostics)
            {
                if (_lazyParameters != null)
                {
                    diagnostics.Free();
                    return;
                }

                _declarationDiagnostics.AddRangeAndFree(diagnostics);
                _lazyIsVarArg   = isVararg;
                _lazyParameters = parameters;
            }
        }
        internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, BindingDiagnosticBag diagnostics)
        {
            base.AfterAddingTypeMembersChecks(conversions, diagnostics);

            var location    = ReturnTypeLocation;
            var compilation = DeclaringCompilation;

            Debug.Assert(location != null);

            // Check constraints on return type and parameters. Note: Dev10 uses the
            // method name location for any such errors. We'll do the same for return
            // type errors but for parameter errors, we'll use the parameter location.
            CheckConstraintsForExplicitInterfaceType(conversions, diagnostics);

            this.ReturnType.CheckAllConstraints(compilation, conversions, this.Locations[0], diagnostics);

            foreach (var parameter in this.Parameters)
            {
                parameter.Type.CheckAllConstraints(compilation, conversions, parameter.Locations[0], diagnostics);
            }

            PartialMethodChecks(diagnostics);

            if (RefKind == RefKind.RefReadOnly)
            {
                compilation.EnsureIsReadOnlyAttributeExists(diagnostics, location, modifyCompilation: true);
            }

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(compilation, Parameters, diagnostics, modifyCompilation: true);

            if (compilation.ShouldEmitNativeIntegerAttributes(ReturnType))
            {
                compilation.EnsureNativeIntegerAttributeExists(diagnostics, location, modifyCompilation: true);
            }

            ParameterHelpers.EnsureNativeIntegerAttributeExists(compilation, Parameters, diagnostics, modifyCompilation: true);

            ParameterHelpers.EnsureLifetimeAnnotationAttributeExists(compilation, Parameters, diagnostics, modifyCompilation: true);

            if (compilation.ShouldEmitNullableAttributes(this) && ReturnTypeWithAnnotations.NeedsNullableAttribute())
            {
                compilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true);
            }

            ParameterHelpers.EnsureNullableAttributeExists(compilation, this, Parameters, diagnostics, modifyCompilation: true);
        }
Example #21
0
        private void ComputeParameters()
        {
            if (!_parameters.IsDefault)
            {
                return;
            }
            var         diagnostics = DiagnosticBag.GetInstance();
            SyntaxToken arglistToken;

            _parameters = ParameterHelpers.MakeParameters(_binder, this, _syntax.ParameterList, true, out arglistToken, diagnostics, true);
            _isVararg   = (arglistToken.Kind() == SyntaxKind.ArgListKeyword);
            if (diagnostics.IsEmptyWithoutResolution)
            {
                SourceMemberMethodSymbol.ReportAsyncParameterErrors(this, diagnostics, this.Locations[0]);
            }
            AddDiagnostics(diagnostics.ToReadOnlyAndFree());
        }
Example #22
0
        internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, 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;
            var type        = this.TypeWithAnnotations;

            if (type.Type.ContainsDynamic() && compilation.HasDynamicEmitAttributes(BindingDiagnosticBag.Discarded, Location.None) && compilation.CanEmitBoolean())
            {
                AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(type.Type, type.CustomModifiers.Length + this.RefCustomModifiers.Length, this.RefKind));
            }

            if (compilation.ShouldEmitNativeIntegerAttributes(type.Type))
            {
                AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNativeIntegerAttribute(this, type.Type));
            }

            if (ParameterHelpers.RequiresLifetimeAnnotationAttribute(this))
            {
                AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeLifetimeAnnotationAttribute(this, Scope));
            }

            if (type.Type.ContainsTupleNames() &&
                compilation.HasTupleNamesAttributes(BindingDiagnosticBag.Discarded, Location.None) &&
                compilation.CanEmitSpecialType(SpecialType.System_String))
            {
                AddSynthesizedAttribute(ref attributes,
                                        compilation.SynthesizeTupleNamesAttribute(type.Type));
            }

            if (compilation.ShouldEmitNullableAttributes(this))
            {
                AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttributeIfNecessary(this, GetNullableContextValue(), type));
            }

            if (this.RefKind == RefKind.RefReadOnly)
            {
                AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsReadOnlyAttribute(this));
            }
        }
Example #23
0
            internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
            {
                var syntax   = (DelegateDeclarationSyntax)SyntaxRef.GetSyntax();
                var location = syntax.ReturnType.GetLocation();

                Debug.Assert(location != null);

                base.AfterAddingTypeMembersChecks(conversions, diagnostics);

                if (_refKind == RefKind.RefReadOnly)
                {
                    DeclaringCompilation.EnsureIsReadOnlyAttributeExists(diagnostics, location, modifyCompilation: true);
                }

                ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilation: true);

                if (ReturnType.NeedsNullableAttribute())
                {
                    this.DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true);
                }

                ParameterHelpers.EnsureNullableAttributeExists(Parameters, diagnostics, modifyCompilation: true);
            }
Example #24
0
        private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsBinder, DiagnosticBag diagnostics)
        {
            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, true, out arglistToken, diagnostics, false);
            _lazyIsVararg   = (arglistToken.Kind() == SyntaxKind.ArgListKeyword);
            RefKind refKind;
            var     returnTypeSyntax = syntax.ReturnType.SkipRef(out refKind);

            _lazyReturnType = signatureBinder.BindType(returnTypeSyntax, diagnostics);

            if (_lazyReturnType.IsRestrictedType())
            {
                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;
                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 ((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 (this.MethodKind == MethodKind.UserDefinedOperator)
            {
                foreach (var p in this.Parameters)
                {
                    if (p.RefKind != RefKind.None)
                    {
                        diagnostics.Add(ErrorCode.ERR_IllegalRefParam, location);
                        break;
                    }
                }
            }
            else 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).

            // 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;

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

                // 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 _lazyReturnTypeCustomModifiers, out _lazyCountOfCustomModifiersPrecedingByRef,
                                                                      out _lazyParameters, alsoCopyParamsModifier: true);
                    }
                }
            }
            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 _lazyReturnTypeCustomModifiers, out _lazyCountOfCustomModifiersPrecedingByRef,
                                                                  out _lazyParameters, alsoCopyParamsModifier: false);
                }
                else
                {
                    Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
                    _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty;

                    Debug.Assert(_lazyReturnTypeCustomModifiers.IsDefault);
                    Debug.Assert(_lazyCountOfCustomModifiersPrecedingByRef == 0);
                    _lazyReturnTypeCustomModifiers            = ImmutableArray <CustomModifier> .Empty;
                    _lazyCountOfCustomModifiersPrecedingByRef = 0;
                }
            }

            CheckModifiers(location, diagnostics);
        }
Example #25
0
        protected override void MethodChecks(DiagnosticBag diagnostics)
        {
            var binder = this.DeclaringCompilation.
                         GetBinderFactory(syntaxReferenceOpt.SyntaxTree).GetBinder(ReturnTypeSyntax, GetSyntax(), this);

            SyntaxToken arglistToken;

            var signatureBinder = binder.WithAdditionalFlags(BinderFlags.SuppressConstraintChecks);

            _lazyParameters = ParameterHelpers.MakeParameters(
                signatureBinder,
                this,
                ParameterListSyntax,
                out arglistToken,
                allowRefOrOut: true,
                allowThis: false,
                addRefReadOnlyModifier: false,
                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));

                // Regardless of whether __arglist appears in the source code, we do not mark
                // the operator method as being a varargs method.
            }

            _lazyReturnType = signatureBinder.BindType(ReturnTypeSyntax, diagnostics);

            // restricted types cannot be returned.
            // NOTE: Span-like types can be returned (if expression is returnable).
            if (_lazyReturnType.IsRestrictedType(ignoreSpanLikeTypes: true))
            {
                // The return type of a method, delegate, or function pointer cannot be '{0}'
                diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, ReturnTypeSyntax.Location, _lazyReturnType.Type);
            }

            if (_lazyReturnType.Type.IsStatic)
            {
                // '{0}': static types cannot be used as return types
                diagnostics.Add(ErrorCode.ERR_ReturnTypeIsStaticClass, ReturnTypeSyntax.Location, _lazyReturnType.Type);
            }

            this.SetReturnsVoid(_lazyReturnType.IsVoidType());

            // If we have a conversion/equality/inequality operator in an interface or static class then we already
            // have reported that fact as an error. No need to cascade the error further.
            if ((this.ContainingType.IsInterfaceType() &&
                 (MethodKind == MethodKind.Conversion || Name == WellKnownMemberNames.EqualityOperatorName || Name == WellKnownMemberNames.InequalityOperatorName)) ||
                this.ContainingType.IsStatic)
            {
                return;
            }

            // SPEC: All types referenced in an operator declaration must be at least as accessible
            // SPEC: as the operator itself.

            CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics);
            CheckValueParameters(diagnostics);
            CheckOperatorSignatures(diagnostics);
        }
        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());
            }

            ImmutableArray <CustomModifier> inModifiers = ParameterHelpers.ConditionallyCreateInModifiers(refKind, addRefReadOnlyModifier, context, declarationDiagnostics, syntax);

            if (!inModifiers.IsDefaultOrEmpty)
            {
                return(new SourceComplexParameterSymbolWithCustomModifiersPrecedingByRef(
                           owner,
                           ordinal,
                           parameterType,
                           refKind,
                           inModifiers,
                           name,
                           locations,
                           syntax.GetReference(),
                           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(),
                       isParams,
                       isExtensionMethodThis));
        }