public static SyntaxNode IntroduceFieldFromConstructor(SyntaxNode root, ConstructorDeclarationSyntax constructorStatement, ParameterSyntax parameter)
        {
            var oldClass = constructorStatement.FirstAncestorOrSelf<ClassDeclarationSyntax>();
            var newClass = oldClass;
            var fieldName = parameter.Identifier.ValueText;
            var fieldType = parameter.Type;
            var members = ExtractMembersFromClass(oldClass.Members);

            var addMember = false;
            if (!members.Any(p => p.Key == fieldName && p.Value == fieldType.ToString()))
            {
                var identifierPostFix = 0;
                while (members.Any(p => p.Key == fieldName))
                    fieldName = parameter.Identifier.ValueText + ++identifierPostFix;

                addMember = true;
            }

            var assignmentField = SyntaxFactory.ExpressionStatement(SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
                                               SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.ThisExpression(),
                                               SyntaxFactory.IdentifierName(fieldName)), SyntaxFactory.IdentifierName(parameter.Identifier.ValueText)));
            var newConstructor = constructorStatement.WithBody(constructorStatement.Body.AddStatements(assignmentField));
            newClass = newClass.ReplaceNode(constructorStatement, newConstructor);

            if (addMember)
            {
                var newField = SyntaxFactory.FieldDeclaration(SyntaxFactory.VariableDeclaration(parameter.Type)
                                    .WithVariables(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(fieldName)))))
                                    .WithModifiers(SyntaxFactory.TokenList(new[] { SyntaxFactory.Token(SyntaxKind.PrivateKeyword), SyntaxFactory.Token(SyntaxKind.ReadOnlyKeyword) }))
                                    .WithAdditionalAnnotations(Formatter.Annotation);
                newClass = newClass.WithMembers(newClass.Members.Insert(0, newField)).WithoutAnnotations(Formatter.Annotation);
            }
            var newRoot = root.ReplaceNode(oldClass, newClass);
            return newRoot;
        }
        protected IEnumerable<CodeAction> GetActions(Document document, SemanticModel semanticModel, SyntaxNode root, TextSpan span, ParameterSyntax node)
        {
            if (!node.Identifier.Span.Contains(span))
                yield break;

            var parameter = node;
            var bodyStatement = parameter.Parent.Parent.ChildNodes().OfType<BlockSyntax>().FirstOrDefault();
            if (bodyStatement == null)
                yield break;

            var parameterSymbol = semanticModel.GetDeclaredSymbol(node);
            var type = parameterSymbol.Type;
            if (type == null || type.IsValueType || HasNotNullContract(semanticModel, parameterSymbol, bodyStatement))
                yield break;

            yield return CreateAction(
                node.Identifier.Span
                , t2 => {
                    var newBody = bodyStatement.WithStatements(SyntaxFactory.List<StatementSyntax>(new[] { CreateContractRequiresCall(node.Identifier.ToString()) }.Concat(bodyStatement.Statements)));

                    var newRoot = (CompilationUnitSyntax)root.ReplaceNode((SyntaxNode)bodyStatement, newBody);

                    if (UsingStatementNotPresent(newRoot)) newRoot = AddUsingStatement(node, newRoot);

                    return Task.FromResult(document.WithSyntaxRoot(newRoot));
                }
                , "Add contract requiring parameter must not be null"
            );
        }
 public static string GetParameterType(ParameterSyntax parameter)
 {
     return parameter
         .DescendantNodes()
         .First(node => node is PredefinedTypeSyntax || node is IdentifierNameSyntax)
         .GetFirstToken()
         .ValueText;
 }
 public override SyntaxNode VisitParameter(ParameterSyntax node)
 {
     return SimplifyNode(
         node,
         newNode: base.VisitParameter(node),
         parentNode: node.Parent,
         simplifier: SimplifyParameter);
 }
 public ParameterTranslation(ParameterSyntax syntax, SyntaxTranslation parent) : base(syntax, parent)
 {
     Type = syntax.Type.Get<TypeTranslation>(this);
     Identifier = syntax.Identifier.Get(this);
     Modifiers = syntax.Modifiers.Get(this);
     Default = syntax.Default.Get<EqualsValueClauseTranslation>(this);
    
 }
 public static IEnumerable<AttributeSyntaxSymbolMapping> GetAttributesForParameter(ParameterSyntax parameter,
     SemanticModel semanticModel)
 {
     return parameter.AttributeLists
         .SelectMany(al => al.Attributes)
         .Select(attr => new AttributeSyntaxSymbolMapping(attr,
             semanticModel.GetSymbolInfo(attr).Symbol as IMethodSymbol))
         .Where(attr => attr.Symbol != null);
 }
 public override void VisitParameter(ParameterSyntax node)
 {
     // ignore parameters in lambdaexpressions
     if (node.IsWithinLambda())
         return;
     var parameter = new Parameter(
         node.Identifier.ToString(),
         (ITypeSymbol)_semantic.GetSymbolInfo(node.Type).Symbol);
     _parameters.Add(parameter);
 }
示例#8
0
        public static MethodDeclarationSyntax AppendParameterToMethod(MethodDeclarationSyntax method,
            ParameterSyntax parameter)
        {
            if (method.ParameterList.Parameters.Any())
            {
                parameter = parameter.WithLeadingTrivia(SF.Space);
            }

            return method.WithParameterList(method.ParameterList.AddParameters(parameter));
        }
 private async Task<Solution> RemoveHungarianPrefix(Document document, ParameterSyntax token, CancellationToken cancellationToken)
 {
     var newName = DehungarianAnalyzer.SuggestDehungarianName(token.Identifier.Text);
     var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
     var tokenSymbol = semanticModel.GetDeclaredSymbol(token, cancellationToken);
     var originalSolution = document.Project.Solution;
     var optionSet = originalSolution.Workspace.Options;
     var newSolution = await Renamer.RenameSymbolAsync(document.Project.Solution, tokenSymbol, newName, optionSet, cancellationToken).ConfigureAwait(false);
     return newSolution;
 }        
 protected OperatorDeclarationSyntax CreateOperatorDeclaration(SyntaxKind kind, ParameterSyntax[] parameters, StatementSyntax statement)
 {
     return SyntaxFactory.OperatorDeclaration(
         new SyntaxList<AttributeListSyntax>(),
         SyntaxFactory.TokenList(new SyntaxToken[] { SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword) }),
         SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.BoolKeyword)),
         SyntaxFactory.Token(SyntaxKind.OperatorKeyword),
         SyntaxFactory.Token(kind),
         SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList(parameters)),
         SyntaxFactory.Block(statement),
         new SyntaxToken());
 }
 public override void VisitParameter(Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax node)
 {
     base.VisitParameter(node);
     if (parameterDeclarationColor == null)
     {
         if (contextualKeywords.Contains(node.Identifier.Text))
         {
             Colorize(node.Identifier.Span, defaultTextColor);
         }
     }
     else
     {
         Colorize(node.Identifier, parameterDeclarationColor);
     }
 }
        private async Task<Document> ApplyFromODataUriAsync(Document document, ParameterSyntax node,
                         CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync();

            var newParameter = node.WithAttributeLists(node.AttributeLists.Add(SyntaxFactory.AttributeList(
                        SyntaxFactory.SingletonSeparatedList<AttributeSyntax>(
                            SyntaxFactory.Attribute(
                                SyntaxFactory.IdentifierName("FromODataUri"))))));

            var newRoot = root.ReplaceNode(node, newParameter);
            var newDocument = document.WithSyntaxRoot(newRoot);
            return newDocument;

        }
        private async Task<Solution> IntroduceField(Document document, ParameterSyntax paramDecl, CancellationToken cancellationToken)
        {
            var rootNode = await document.GetSyntaxRootAsync();

            var rewriter = new IntroduceFieldRewriter(paramDecl);
            rootNode = rewriter.Visit(rootNode);

            var alterConstructorRewriter = new AlterConstructorRewriter(rewriter.GeneratedField, paramDecl.FirstAncestorOrSelf<ConstructorDeclarationSyntax>(), rewriteParams: false);
            rootNode = alterConstructorRewriter.Visit(rootNode);

            rootNode = Formatter.Format(rootNode, document.Project.Solution.Workspace);

            // Produce a new solution that has all references to that type renamed, including the declaration.
            return document.WithSyntaxRoot(rootNode).Project.Solution;
        }
示例#14
0
        public static SourceParameterSymbol Create(
            Binder context,
            Symbol owner,
            TypeSymbol parameterType,
            ParameterSyntax syntax,
            RefKind refKind,
            SyntaxToken identifier,
            int ordinal,
            bool isParams,
            bool isExtensionMethodThis,
            DiagnosticBag diagnostics)
        {
            var name = identifier.ValueText;
            var locations = ImmutableArray.Create<Location>(new SourceLocation(identifier));

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

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

            var syntaxRef = syntax.GetReference();
            return new SourceComplexParameterSymbol(
                owner,
                ordinal,
                parameterType,
                refKind,
                ImmutableArray<CustomModifier>.Empty,
                false,
                name,
                locations,
                syntaxRef,
                ConstantValue.Unset,
                isParams,
                isExtensionMethodThis);
        }
示例#15
0
        public static string Parameter(ParameterSyntax param)
        {
            if (param.Type == null) return param.Identifier.Text;

            if (param.Type is IdentifierNameSyntax)
            {
                return param.Identifier.Text + ": " + Type(((IdentifierNameSyntax)param.Type).Identifier.Text);
            }

            // TODO: Double check the variadic parameters handling
            if (param.Modifiers.Any(mod => mod.ToString() == "params"))
            {
                return param.Identifier.Text + ": " + SyntaxNode(((ArrayTypeSyntax)param.Type).ElementType) + "...";
            }

            return param.Identifier.Text + ": " + SyntaxNode(param.Type);
        }
        internal SourcePrimaryConstructorParameterSymbolWithBackingField(
            Symbol owner,
            int ordinal,
            TypeSymbol parameterType,
            RefKind refKind,
            string name,
            ImmutableArray<Location> locations,
            ParameterSyntax syntax,
            ConstantValue defaultSyntaxValue,
            bool isParams,
            bool isExtensionMethodThis,
            DiagnosticBag diagnostics
        ) : base(owner, ordinal, parameterType, refKind, ImmutableArray<CustomModifier>.Empty, false, name, locations, syntax.GetReference(), defaultSyntaxValue, isParams, isExtensionMethodThis)
        {
            bool modifierErrors;
            var modifiers = SourceMemberFieldSymbol.MakeModifiers(owner.ContainingType, syntax.Identifier, syntax.Modifiers, diagnostics, out modifierErrors, ignoreParameterModifiers: true);

            backingField = new BackingField(this, modifiers, modifierErrors, diagnostics);
        }
            public override VisualBasicSyntaxNode VisitParameter(CSS.ParameterSyntax node)
            {
                var id = SyntaxFactory.Identifier(node.Identifier.ValueText, SyntaxFacts.IsKeywordKind(node.Identifier.Kind()), node.Identifier.GetIdentifierText(), TypeCharacter.None);
                EqualsValueSyntax @default = null;

                if (node.Default != null)
                {
                    @default = SyntaxFactory.EqualsValue((ExpressionSyntax)node.Default?.Value.Accept(this));
                }
                AttributeListSyntax[] newAttributes;
                var modifiers = ConvertModifiers(node.Modifiers, TokenContext.Member);

                if (modifiers.Count == 0)
                {
                    modifiers     = SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ByValKeyword));
                    newAttributes = new AttributeListSyntax[0];
                }
                else if (node.Modifiers.Any(m => m.IsKind(CS.SyntaxKind.OutKeyword)))
                {
                    newAttributes = new[] {
                        SyntaxFactory.AttributeList(
                            SyntaxFactory.SingletonSeparatedList(
                                SyntaxFactory.Attribute(SyntaxFactory.ParseTypeName("Out"))
                                )
                            )
                    };
                }
                else
                {
                    newAttributes = new AttributeListSyntax[0];
                }
                return(SyntaxFactory.Parameter(
                           SyntaxFactory.List(newAttributes.Concat(node.AttributeLists.Select(a => (AttributeListSyntax)a.Accept(this)))),
                           modifiers,
                           SyntaxFactory.ModifiedIdentifier(id),
                           SyntaxFactory.SimpleAsClause((TypeSyntax)node.Type.Accept(this)),
                           @default
                           ));
            }
		private async Task<Document> CreateFieldAsync(CodeRefactoringContext context, ParameterSyntax parameter,
			string paramName, string fieldName, CancellationToken cancellationToken)
		{
			var oldConstructor = parameter.Ancestors().OfType<ConstructorDeclarationSyntax>().First();
			var newConstructor = oldConstructor.WithBody(oldConstructor.Body.AddStatements(
				 SyntaxFactory.ExpressionStatement(
					 SyntaxFactory.AssignmentExpression(
						 SyntaxKind.SimpleAssignmentExpression,
						 SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.ThisExpression(), SyntaxFactory.IdentifierName(fieldName)),
						 SyntaxFactory.IdentifierName(paramName)))));

			var oldClass = parameter.FirstAncestorOrSelf<ClassDeclarationSyntax>();
			var oldClassWithNewCtor = oldClass.ReplaceNode(oldConstructor, newConstructor);

			var fieldDeclaration = RoslynHelpers.CreateFieldDeclaration(RoslynHelpers.GetParameterType(parameter), fieldName);
			var newClass = oldClassWithNewCtor
				.WithMembers(oldClassWithNewCtor.Members.Insert(0, fieldDeclaration))
				.WithAdditionalAnnotations(Formatter.Annotation);

			var oldRoot = await context.Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
			var newRoot = oldRoot.ReplaceNode(oldClass, newClass);

			return context.Document.WithSyntaxRoot(newRoot);
		}
        private Document Delete(Document document, ParameterSyntax node)
        {
            var parameterList = node.FirstAncestorOrSelf<ParameterListSyntax>();
            var newParameterList = parameterList.RemoveNode(node, SyntaxRemoveOptions.KeepNoTrivia);

            return document.ReplaceNodeAsync(parameterList, newParameterList, CancellationToken.None)
                           .WaitAndGetResult_CodeModel(CancellationToken.None);
        }
            // Checks step one of the user's AnalyzerIfStatement method, returns a SyntaxToken of "" if analysis failed
            private SyntaxToken IfStatementAnalysis1(SyntaxList<StatementSyntax> statements, ParameterSyntax contextParameter)
            {
                var emptyResult = SyntaxFactory.Identifier("");

                var ifStatement = statements[0] as LocalDeclarationStatementSyntax;
                if (ifStatement == null)
                {
                    return emptyResult;
                }

                var statementName = GetIdentifierTokenFromLocalDecl(ifStatement);
                if (statementName.Text == "")
                {
                    return emptyResult;
                }

                var statementEqualsValueClause = GetEqualsValueClauseFromLocalDecl(ifStatement);
                if (statementEqualsValueClause == null)
                {
                    return emptyResult;
                }

                var statementCastExpression = statementEqualsValueClause.Value as CastExpressionSyntax;
                if (statementCastExpression == null)
                {
                    var statementAsExpression = statementEqualsValueClause.Value as BinaryExpressionSyntax;
                    if (statementAsExpression == null)
                    {
                        return emptyResult;
                    }

                    var left = statementAsExpression.Left as MemberAccessExpressionSyntax;
                    if (left == null)
                    {
                        return emptyResult;
                    }

                    var leftName = left.Name as IdentifierNameSyntax;
                    if (leftName == null || leftName.Identifier.Text != "Node")
                    {
                        return emptyResult;
                    }

                    var leftMember = left.Expression as IdentifierNameSyntax;
                    if (leftMember == null || leftMember.Identifier.Text != contextParameter.Identifier.Text)
                    {
                        return emptyResult;
                    }

                    var right = statementAsExpression.Right as IdentifierNameSyntax;
                    if (right == null || right.Identifier.Text != "IfStatementSyntax")
                    {
                        return emptyResult;
                    }

                    return statementName;
                }

                var statementIdentifier = statementCastExpression.Type as IdentifierNameSyntax;
                if (statementIdentifier == null || statementIdentifier.Identifier.Text != "IfStatementSyntax")
                {
                    return emptyResult;
                }

                var statementExpression = statementCastExpression.Expression as MemberAccessExpressionSyntax;
                if (statementExpression == null)
                {
                    return emptyResult;
                }

                var statementExpressionIdentifier = statementExpression.Expression as IdentifierNameSyntax;
                if (statementExpressionIdentifier == null || statementExpressionIdentifier.Identifier.Text != contextParameter.Identifier.Text)
                {
                    return emptyResult;
                }

                var statementExpressionNode = statementExpression.Name as IdentifierNameSyntax;
                if (statementExpressionNode == null || statementExpressionNode.Identifier.Text != "Node")
                {
                    return emptyResult;
                }

                return statementName;
            }
            // Checks the reporting of the diagnostic, returns a bool representing whether or not analysis failed
            private bool DiagnosticReportCheck(CompilationAnalysisContext context, SyntaxToken diagnosticToken, ParameterSyntax contextParameter, SyntaxList<StatementSyntax> statements)
            {
                var statement = statements[9] as ExpressionStatementSyntax;
                if (statement == null)
                {
                    return false;
                }

                var invocationExpression = statement.Expression as InvocationExpressionSyntax;
                if (invocationExpression == null)
                {
                    return false;
                }

                var memberExpression = invocationExpression.Expression as MemberAccessExpressionSyntax;
                if (memberExpression == null)
                {
                    return false;
                }

                var identifier = memberExpression.Expression as IdentifierNameSyntax;
                if (identifier == null || identifier.Identifier.Text != contextParameter.Identifier.Text)
                {
                    return false;
                }

                var name = memberExpression.Name as IdentifierNameSyntax;
                if (name == null || name.Identifier.Text != "ReportDiagnostic")
                {
                    return false;
                }

                var argumentList = invocationExpression.ArgumentList as ArgumentListSyntax;
                if (argumentList == null)
                {
                    return false;
                }

                SeparatedSyntaxList<ArgumentSyntax> args = argumentList.Arguments;
                if (args == null || args.Count != 1)
                {
                    return false;
                }

                var diagnosticArg = args[0] as ArgumentSyntax;
                if (diagnosticArg == null)
                {
                    return false;
                }

                var diagnosticArgIdentifier = diagnosticArg.Expression as IdentifierNameSyntax;
                if (diagnosticArgIdentifier == null || diagnosticArgIdentifier.Identifier.Text != diagnosticToken.Text)
                {
                    return false;
                }

                return true;
            }
            // Checks the buildup steps of creating a diagnostic, returns a bool representing whether or not analysis failed
            private bool CheckDiagnosticCreation(CompilationAnalysisContext context, SyntaxToken statementIdentifierToken, SyntaxToken keywordIdentifierToken, List<string> ruleNames, SyntaxList<StatementSyntax> statements, ParameterSyntax contextParameter)
            {
                int statementCount = statements.Count;

                SyntaxToken openParenToken = OpenParenAnalysis(statementIdentifierToken, statements);
                if (openParenToken.Text == "")
                {
                    IfDiagnostic(context, statements[3], OpenParenIncorrectRule, statementIdentifierToken.Text);
                    return false;
                }

                if (statementCount > 4)
                {
                    SyntaxToken startToken = StartAnalysis(keywordIdentifierToken, statements);
                    if (startToken.Text == "")
                    {
                        IfDiagnostic(context, statements[4], StartSpanIncorrectRule, keywordIdentifierToken.Text);
                        return false;
                    }

                    if (statementCount > 5)
                    {
                        SyntaxToken endToken = EndAnalysis(openParenToken, statements);
                        if (endToken.Text == "")
                        {
                            IfDiagnostic(context, statements[5], EndSpanIncorrectRule, openParenToken.Text);
                            return false;
                        }

                        if (statementCount > 6)
                        {
                            SyntaxToken spanToken = SpanAnalysis(startToken, endToken, statements);
                            if (spanToken.Text == "")
                            {
                                IfDiagnostic(context, statements[6], SpanIncorrectRule, startToken.Text, endToken.Text);
                                return false;
                            }

                            if (statementCount > 7)
                            {
                                SyntaxToken locationToken = LocationAnalysis(statementIdentifierToken, spanToken, statements);
                                if (locationToken.Text == "")
                                {
                                    IfDiagnostic(context, statements[7], LocationIncorrectRule, statementIdentifierToken.Text, spanToken.Text);
                                    return false;
                                }

                                if (statementCount > 8)
                                {
                                    SyntaxToken diagnosticToken = DiagnosticCreationCheck(ruleNames, locationToken, statements);
                                    if (diagnosticToken == null || diagnosticToken.Text == "")
                                    {
                                        IfDiagnostic(context, statements[8], DiagnosticIncorrectRule, ruleNames[0], locationToken.Text);
                                        return false;
                                    }

                                    if (statementCount > 9)
                                    {
                                        bool reportCorrect = DiagnosticReportCheck(context, diagnosticToken, contextParameter, statements);
                                        if (!reportCorrect)
                                        {
                                            IfDiagnostic(context, statements[9], DiagnosticReportIncorrectRule, contextParameter.Identifier.Text, diagnosticToken.Text);
                                            return false;
                                        }
                                    }
                                    else
                                    {
                                        ReportDiagnostic(context, DiagnosticReportMissingRule, statements[8].GetLocation(), contextParameter.Identifier.Text);
                                        return false;
                                    }
                                }
                                else
                                {
                                    ReportDiagnostic(context, DiagnosticMissingRule, statements[7].GetLocation());
                                    return false;
                                }
                            }
                            else
                            {
                                ReportDiagnostic(context, LocationMissingRule, statements[6].GetLocation(), statementIdentifierToken.Text, spanToken.Text);
                                return false;
                            }
                        }
                        else
                        {
                            ReportDiagnostic(context, SpanMissingRule, statements[5].GetLocation(), startToken.Text, endToken.Text);
                            return false;
                        }
                    }
                    else
                    {
                        ReportDiagnostic(context, EndSpanMissingRule, statements[4].GetLocation(), openParenToken.Text);
                        return false;
                    }
                }
                else
                {
                    ReportDiagnostic(context, StartSpanMissingRule, statements[3].GetLocation(), keywordIdentifierToken.Text);
                    return false;
                }

                return true;
            }
            private void ClassifyUpdate(ParameterSyntax oldNode, ParameterSyntax newNode)
            {
                if (!SyntaxFactory.AreEquivalent(oldNode.Identifier, newNode.Identifier))
                {
                    ReportError(RudeEditKind.Renamed);
                    return;
                }

                if (!SyntaxFactory.AreEquivalent(oldNode.Modifiers, newNode.Modifiers))
                {
                    ReportError(RudeEditKind.ModifiersUpdate);
                    return;
                }

                if (!SyntaxFactory.AreEquivalent(oldNode.Type, newNode.Type))
                {
                    ReportError(RudeEditKind.TypeUpdate);
                    return;
                }

                Debug.Assert(!SyntaxFactory.AreEquivalent(oldNode.Default, newNode.Default));
                ReportError(RudeEditKind.InitializerUpdate);
            }
示例#24
0
        internal static bool ReportDefaultParameterErrors(
            Binder binder,
            Symbol owner,
            ParameterSyntax parameterSyntax,
            SourceParameterSymbol parameter,
            BoundExpression defaultExpression,
            DiagnosticBag diagnostics)
        {
            bool hasErrors = false;

            // SPEC VIOLATION: The spec says that the conversion from the initializer to the 
            // parameter type is required to be either an identity or a nullable conversion, but
            // that is not right:
            //
            // void M(short myShort = 10) {}
            // * not an identity or nullable conversion but should be legal
            //
            // void M(object obj = (dynamic)null) {}
            // * an identity conversion, but should be illegal
            //
            // void M(MyStruct? myStruct = default(MyStruct)) {}
            // * a nullable conversion, but must be illegal because we cannot generate metadata for it
            // 
            // Even if the expression is thoroughly illegal, we still want to bind it and 
            // stick it in the parameter because we want to be able to analyze it for
            // IntelliSense purposes.

            TypeSymbol parameterType = parameter.Type;
            HashSet<DiagnosticInfo> useSiteDiagnostics = null;
            Conversion conversion = binder.Conversions.ClassifyImplicitConversionFromExpression(defaultExpression, parameterType, ref useSiteDiagnostics);
            diagnostics.Add(defaultExpression.Syntax, useSiteDiagnostics);

            // SPEC VIOLATION: 
            // By the spec an optional parameter initializer is required to be either:
            // * a constant,
            // * new S() where S is a value type
            // * default(S) where S is a value type.
            // 
            // The native compiler considers default(T) to be a valid
            // initializer regardless of whether T is a value type
            // reference type, type parameter type, and so on.
            // We should consider simply allowing this in the spec.
            //
            // Also when valuetype S has a parameterless constructor, 
            // new S() is clearly not a constant expression and should produce an error

            bool isValidDefaultValue = (defaultExpression.ConstantValue != null) ||
                                        (defaultExpression.Kind == BoundKind.DefaultOperator) ||
                                        (defaultExpression.Kind == BoundKind.ObjectCreationExpression &&
                                                ((BoundObjectCreationExpression)defaultExpression).Constructor.IsDefaultValueTypeConstructor());

            SyntaxToken outKeyword;
            SyntaxToken refKeyword;
            SyntaxToken paramsKeyword;
            SyntaxToken thisKeyword;
            GetModifiers(parameterSyntax.Modifiers, out outKeyword, out refKeyword, out paramsKeyword, out thisKeyword);

            // CONSIDER: We are inconsistent here regarding where the error is reported; is it
            // CONSIDER: reported on the parameter name, or on the value of the initializer?
            // CONSIDER: Consider making this consistent.

            if (outKeyword.Kind() == SyntaxKind.OutKeyword)
            {
                // error CS1741: A ref or out parameter cannot have a default value
                diagnostics.Add(ErrorCode.ERR_RefOutDefaultValue, outKeyword.GetLocation());
                hasErrors = true;
            }
            else if (refKeyword.Kind() == SyntaxKind.RefKeyword)
            {
                // error CS1741: A ref or out parameter cannot have a default value
                diagnostics.Add(ErrorCode.ERR_RefOutDefaultValue, refKeyword.GetLocation());
                hasErrors = true;
            }
            else if (paramsKeyword.Kind() == SyntaxKind.ParamsKeyword)
            {
                // error CS1751: Cannot specify a default value for a parameter array
                diagnostics.Add(ErrorCode.ERR_DefaultValueForParamsParameter, paramsKeyword.GetLocation());
                hasErrors = true;
            }
            else if (thisKeyword.Kind() == SyntaxKind.ThisKeyword)
            {
                // Only need to report CS1743 for the first parameter. The caller will
                // have reported CS1100 if 'this' appeared on another parameter.
                if (parameter.Ordinal == 0)
                {
                    // error CS1743: Cannot specify a default value for the 'this' parameter
                    diagnostics.Add(ErrorCode.ERR_DefaultValueForExtensionParameter, thisKeyword.GetLocation());
                    hasErrors = true;
                }
            }
            else if (!defaultExpression.HasAnyErrors && !isValidDefaultValue)
            {
                // error CS1736: Default parameter value for '{0}' must be a compile-time constant
                diagnostics.Add(ErrorCode.ERR_DefaultValueMustBeConstant, parameterSyntax.Default.Value.Location, parameterSyntax.Identifier.ValueText);
                hasErrors = true;
            }
            else if (!conversion.Exists ||
                conversion.IsUserDefined ||
                conversion.IsIdentity && parameterType.SpecialType == SpecialType.System_Object && defaultExpression.Type.IsDynamic())
            {
                // If we had no implicit conversion, or a user-defined conversion, report an error.
                //
                // Even though "object x = (dynamic)null" is a legal identity conversion, we do not allow it. 
                // CONSIDER: We could. Doesn't hurt anything.

                // error CS1750: A value of type '{0}' cannot be used as a default parameter because there are no standard conversions to type '{1}'
                diagnostics.Add(ErrorCode.ERR_NoConversionForDefaultParam, parameterSyntax.Identifier.GetLocation(),
                    defaultExpression.Type ?? defaultExpression.Display, parameterType);

                hasErrors = true;
            }
            else if (conversion.IsReference &&
                (parameterType.SpecialType == SpecialType.System_Object || parameterType.Kind == SymbolKind.DynamicType) &&
                (object)defaultExpression.Type != null &&
                defaultExpression.Type.SpecialType == SpecialType.System_String ||
                conversion.IsBoxing)
            {
                // We don't allow object x = "hello", object x = 123, dynamic x = "hello", etc.
                // error CS1763: '{0}' is of type '{1}'. A default parameter value of a reference type other than string can only be initialized with null
                diagnostics.Add(ErrorCode.ERR_NotNullRefDefaultParameter, parameterSyntax.Identifier.GetLocation(),
                    parameterSyntax.Identifier.ValueText, parameterType);

                hasErrors = true;
            }
            else if (conversion.IsNullable && defaultExpression.Kind == BoundKind.DefaultOperator && !defaultExpression.Type.IsNullableType() &&
                !(parameterType.GetNullableUnderlyingType().IsEnumType() || parameterType.GetNullableUnderlyingType().IsIntrinsicType()))
            {
                // We can do:
                // M(int? x = default(int)) 
                // M(int? x = default(int?)) 
                // M(MyEnum? e = default(enum))
                // M(MyEnum? e = default(enum?))
                // M(MyStruct? s = default(MyStruct?))
                //
                // but we cannot do:
                //
                // M(MyStruct? s = default(MyStruct))

                // error CS1770: 
                // A value of type '{0}' cannot be used as default parameter for nullable parameter '{1}' because '{0}' is not a simple type
                diagnostics.Add(ErrorCode.ERR_NoConversionForNubDefaultParam, parameterSyntax.Identifier.GetLocation(),
                    defaultExpression.Type, parameterSyntax.Identifier.ValueText);

                hasErrors = true;
            }

            // Certain contexts allow default parameter values syntactically but they are ignored during
            // semantic analysis. They are:

            // 1. Explicitly implemented interface methods; since the method will always be called
            //    via the interface, the defaults declared on the implementation will not 
            //    be seen at the call site.
            //
            // UNDONE: 2. The "actual" side of a partial method; the default values are taken from the
            // UNDONE:    "declaring" side of the method.
            //
            // UNDONE: 3. An indexer with only one formal parameter; it is illegal to omit every argument
            // UNDONE:    to an indexer.
            //
            // 4. A user-defined operator; it is syntactically impossible to omit the argument.

            if (owner.IsExplicitInterfaceImplementation() ||
                owner.IsPartialImplementation() ||
                owner.IsOperator())
            {
                // CS1066: The default value specified for parameter '{0}' will have no effect because it applies to a 
                //         member that is used in contexts that do not allow optional arguments
                diagnostics.Add(ErrorCode.WRN_DefaultValueForUnconsumedLocation,
                    parameterSyntax.Identifier.GetLocation(),
                    parameterSyntax.Identifier.ValueText);
            }

            return hasErrors;
        }
 public override void VisitParameter(Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax node)
 {
     base.VisitParameter(node);
     Colorize(node.Identifier, parameterDeclarationColor);
 }
 private ParameterSymbol GetDeclaredNonLambdaParameterSymbol(ParameterSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken))
 {
     return
         GetMethodParameterSymbol(declarationSyntax, cancellationToken) ??
         GetIndexerParameterSymbol(declarationSyntax, cancellationToken) ??
         GetDelegateParameterSymbol(declarationSyntax, cancellationToken);
 }
        /// <summary>
        /// Given an parameter declaration syntax node, get the corresponding symbol.
        /// </summary>
        /// <param name="declarationSyntax">The syntax node that declares a parameter.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The parameter that was declared.</returns>
        public override IParameterSymbol GetDeclaredSymbol(ParameterSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken))
        {
            CheckSyntaxNode(declarationSyntax);

            MemberSemanticModel memberModel = this.GetMemberModel(declarationSyntax);
            if (memberModel != null)
            {
                // Could be parameter of lambda.
                return memberModel.GetDeclaredSymbol(declarationSyntax, cancellationToken);
            }

            return GetDeclaredNonLambdaParameterSymbol(declarationSyntax, cancellationToken);
        }
        private ParameterSymbol GetDelegateParameterSymbol(
            ParameterSyntax parameter,
            CancellationToken cancellationToken)
        {
            Debug.Assert(parameter != null);

            var paramList = parameter.Parent as ParameterListSyntax;
            if (paramList == null)
            {
                return null;
            }

            var memberDecl = paramList.Parent as DelegateDeclarationSyntax;
            if (memberDecl == null)
            {
                return null;
            }

            var delegateType = GetDeclaredSymbol(memberDecl, cancellationToken) as NamedTypeSymbol;
            if ((object)delegateType == null)
            {
                return null;
            }

            var delegateInvoke = delegateType.DelegateInvokeMethod;
            if ((object)delegateInvoke == null || delegateInvoke.HasUseSiteError)
            {
                return null;
            }

            return GetParameterSymbol(delegateInvoke.Parameters, parameter, cancellationToken);
        }
 public SimpleLambdaExpressionSyntax Update(SyntaxToken asyncKeyword, ParameterSyntax parameter, SyntaxToken arrowToken, CSharpSyntaxNode body)
 => body is BlockSyntax block
 public SimpleLambdaExpressionSyntax Update(SyntaxToken asyncKeyword, ParameterSyntax parameter, SyntaxToken arrowToken, CSharpSyntaxNode body)
 {
     return(Update(asyncKeyword, parameter, arrowToken, this.RefKeyword, body));
 }
        private static bool IdentifierRefersToParam(IdentifierNameSyntax iName, ParameterSyntax param)
        {
            if (iName.Identifier.ToString() != param.Identifier.ToString())
                return false;

            var mae = iName.Parent as MemberAccessExpressionSyntax;
            if (mae == null)
                return true;

            return mae.DescendantNodes().FirstOrDefault() == iName;
        }
 private static SyntaxNodeAnalysisContext ReportDiagnostic(SyntaxNodeAnalysisContext context, ParameterSyntax parameter)
 {
     var props = new Dictionary<string, string> { { "identifier", parameter.Identifier.Text } }.ToImmutableDictionary();
     var diagnostic = Diagnostic.Create(Rule, parameter.GetLocation(), props, parameter.Identifier.ValueText);
     context.ReportDiagnostic(diagnostic);
     return context;
 }
            private bool CompareParameters(ParameterSyntax oldParameter, ParameterSyntax newParameter, SyntaxNode newNodeParent, CodeModelEventQueue eventQueue)
            {
                Debug.Assert(oldParameter != null && newParameter != null);

                bool same = true;

                if (!StringComparer.Ordinal.Equals(CodeModelService.GetName(oldParameter), CodeModelService.GetName(newParameter)))
                {
                    EnqueueChangeEvent(newParameter, newNodeParent, CodeModelEventType.Rename, eventQueue);
                    same = false;
                }

                // If modifiers or the type have changed enqueue a element changed (unknown change) node
                if (!CompareModifiers(oldParameter, newParameter) ||
                    !CompareTypes(oldParameter.Type, newParameter.Type))
                {
                    EnqueueChangeEvent(newParameter, newNodeParent, CodeModelEventType.Unknown, eventQueue);
                    same = false;
                }

                return same;
            }
示例#34
0
        private static void ReportParameterErrors(
            Symbol owner,
            ParameterSyntax parameterSyntax,
            SourceParameterSymbol parameter,
            int firstDefault,
            DiagnosticBag diagnostics)
        {
            TypeSymbol parameterType = parameter.Type;
            int parameterIndex = parameter.Ordinal;
            bool isDefault = parameterSyntax.Default != null;
            SyntaxToken thisKeyword = parameterSyntax.Modifiers.FirstOrDefault(SyntaxKind.ThisKeyword);

            if (thisKeyword.Kind() == SyntaxKind.ThisKeyword && parameterIndex != 0)
            {
                // Report CS1100 on "this". Note that is a change from Dev10
                // which reports the error on the type following "this".

                // error CS1100: Method '{0}' has a parameter modifier 'this' which is not on the first parameter
                diagnostics.Add(ErrorCode.ERR_BadThisParam, thisKeyword.GetLocation(), owner.Name);
            }
            else if (parameter.IsParams && owner.IsOperator())
            {
                // error CS1670: params is not valid in this context
                diagnostics.Add(ErrorCode.ERR_IllegalParams, parameterSyntax.Modifiers.First(t => t.Kind() == SyntaxKind.ParamsKeyword).GetLocation());
            }
            else if (parameter.IsParams && !parameterType.IsSingleDimensionalArray())
            {
                // error CS0225: The params parameter must be a single dimensional array
                diagnostics.Add(ErrorCode.ERR_ParamsMustBeArray, parameterSyntax.Modifiers.First(t => t.Kind() == SyntaxKind.ParamsKeyword).GetLocation());
            }
            else if (parameter.Type.IsStatic && !parameter.ContainingSymbol.ContainingType.IsInterfaceType())
            {
                // error CS0721: '{0}': static types cannot be used as parameters
                diagnostics.Add(ErrorCode.ERR_ParameterIsStaticClass, owner.Locations[0], parameter.Type);
            }
            else if (firstDefault != -1 && parameterIndex > firstDefault && !isDefault && !parameter.IsParams)
            {
                // error CS1737: Optional parameters must appear after all required parameters
                Location loc = parameterSyntax.Identifier.GetNextToken(includeZeroWidth: true).GetLocation(); //could be missing
                diagnostics.Add(ErrorCode.ERR_DefaultValueBeforeRequiredValue, loc);
            }
            else if (parameter.RefKind != RefKind.None && parameter.Type.IsRestrictedType())
            {
                // CS1601: Cannot make reference to variable of type 'System.TypedReference'
                diagnostics.Add(ErrorCode.ERR_MethodArgCantBeRefAny, parameterSyntax.Location, parameter.Type);
            }
        }
 private bool CompareModifiers(ParameterSyntax oldParameter, ParameterSyntax newParameter)
 {
     return oldParameter.GetParameterFlags() == newParameter.GetParameterFlags();
 }