protected override bool TryAnalyzeVariableDeclaration(TypeSyntax typeName, SemanticModel semanticModel, OptionSet optionSet, CancellationToken cancellationToken, out TextSpan issueSpan)
        {
            // If it is already var, return.
            if (typeName.IsTypeInferred(semanticModel))
            {
                issueSpan = default(TextSpan);
                return false;
            }

            var candidateReplacementNode = SyntaxFactory.IdentifierName("var");
            var candidateIssueSpan = typeName.Span;

            // If there exists a type named var, return.
            var conflict = semanticModel.GetSpeculativeSymbolInfo(typeName.SpanStart, candidateReplacementNode, SpeculativeBindingOption.BindAsTypeOrNamespace).Symbol;
            if (conflict?.IsKind(SymbolKind.NamedType) == true)
            {
                issueSpan = default(TextSpan);
                return false;
            }

            if (typeName.Parent.IsKind(SyntaxKind.VariableDeclaration) &&
                typeName.Parent.IsParentKind(SyntaxKind.LocalDeclarationStatement, SyntaxKind.ForStatement, SyntaxKind.UsingStatement))
            {
                var variableDeclaration = (VariableDeclarationSyntax)typeName.Parent;

                // implicitly typed variables cannot be constants.
                if ((variableDeclaration.Parent as LocalDeclarationStatementSyntax)?.IsConst == true)
                {
                    issueSpan = default(TextSpan);
                    return false;
                }

                var variable = variableDeclaration.Variables.Single();
                if (AssignmentSupportsStylePreference(
                        variable.Identifier, typeName, variable.Initializer.Value,
                        semanticModel, optionSet, cancellationToken))
                {
                    issueSpan = candidateIssueSpan;
                    return true;
                }
            }
            else if (typeName.IsParentKind(SyntaxKind.ForEachStatement))
            {
                issueSpan = candidateIssueSpan;
                return true;
            }

            issueSpan = default(TextSpan);
            return false;
        }
 private static DiagnosticDescriptor GetCorrespondingDiagnostic(SemanticModel semanticModel, InvocationExpressionSyntax invocation)
 {
     var methodName = (invocation?.Expression as MemberAccessExpressionSyntax)?.Name?.ToString();
     var nameToCheck = methodName == "Any" ? allName : methodName == "All" ? anyName : null;
     if (nameToCheck == null) return null;
     var invocationSymbol = semanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;
     if (invocationSymbol?.Parameters.Length != 1) return null;
     if (!IsLambdaWithoutBody(invocation)) return null;
     var otherInvocation = invocation.WithExpression(((MemberAccessExpressionSyntax)invocation.Expression).WithName(nameToCheck));
     var otherInvocationSymbol = semanticModel.GetSpeculativeSymbolInfo(invocation.SpanStart, otherInvocation, SpeculativeBindingOption.BindAsExpression);
     if (otherInvocationSymbol.Symbol == null) return null;
     if (methodName == "Any")
         return RuleAny;
     return RuleAll;
 }
예제 #3
0
 /// <summary>
 /// Binds the node in the context of the specified location and get semantic information
 /// such as type, symbols and diagnostics. This method is used to get semantic information
 /// about an expression that did not actually appear in the source code.
 /// </summary>
 /// <param name="semanticModel"></param>
 /// <param name="position">A character position used to identify a declaration scope and
 /// accessibility. This character position must be within the FullSpan of the Root syntax
 /// node in this SemanticModel.
 /// </param>
 /// <param name="expression">A syntax node that represents a parsed expression. This syntax
 /// node need not and typically does not appear in the source code referred to  SemanticModel
 /// instance.</param>
 /// <param name="bindingOption">Indicates whether to binding the expression as a full expressions,
 /// or as a type or namespace. If SpeculativeBindingOption.BindAsTypeOrNamespace is supplied, then
 /// expression should derive from TypeSyntax.</param>
 /// <returns>The semantic information for the topmost node of the expression.</returns>
 /// <remarks>The passed in expression is interpreted as a stand-alone expression, as if it
 /// appeared by itself somewhere within the scope that encloses "position".</remarks>
 public static SymbolInfo GetSpeculativeSymbolInfo(this SemanticModel semanticModel, int position, SyntaxNode expression, SpeculativeBindingOption bindingOption)
 {
     return(semanticModel.GetSpeculativeSymbolInfo(position, expression, bindingOption));
 }
예제 #4
0
		public static bool TryReduceOrSimplifyExplicitName(
			this CrefSyntax crefSyntax,
			SemanticModel semanticModel,
			out CrefSyntax replacementNode,
			out TextSpan issueSpan,
			OptionSet optionSet,
			CancellationToken cancellationToken)
		{
			replacementNode = null;
			issueSpan = default(TextSpan);

			// Currently Qualified Cref is the only CrefSyntax We are handling separately
			if (crefSyntax.Kind() != SyntaxKind.QualifiedCref)
			{
				return false;
			}

			var qualifiedCrefSyntax = (QualifiedCrefSyntax)crefSyntax;
			var memberCref = qualifiedCrefSyntax.Member;

			// Currently we are dealing with only the NameMemberCrefs
			if (optionSet.GetOption(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, LanguageNames.CSharp) &&
				(memberCref.Kind() == SyntaxKind.NameMemberCref))
			{
				var nameMemberCref = ((NameMemberCrefSyntax)memberCref).Name;
				var symbolInfo = semanticModel.GetSymbolInfo(nameMemberCref, cancellationToken);
				var symbol = symbolInfo.Symbol;

				if (symbol == null)
				{
					return false;
				}

				if (symbol is INamespaceOrTypeSymbol)
				{
					//var namespaceOrTypeSymbol = (INamespaceOrTypeSymbol)symbol;

					// 1. Check for Predefined Types
					if (symbol is INamedTypeSymbol)
					{
						var namedSymbol = (INamedTypeSymbol)symbol;
						var keywordKind = ExpressionSyntaxExtensions.GetPredefinedKeywordKind(namedSymbol.SpecialType);

						if (keywordKind != SyntaxKind.None)
						{
							replacementNode = SyntaxFactory.TypeCref(
								SyntaxFactory.PredefinedType(
									SyntaxFactory.Token(crefSyntax.GetLeadingTrivia(), keywordKind, crefSyntax.GetTrailingTrivia())));
							replacementNode = crefSyntax.CopyAnnotationsTo(replacementNode);

							// we want to show the whole name expression as unnecessary
							issueSpan = crefSyntax.Span;

							return true;
						}
					}
				}
			}

			var oldSymbol = semanticModel.GetSymbolInfo(crefSyntax, cancellationToken).Symbol;
			if (oldSymbol != null)
			{
				var speculativeBindingOption = SpeculativeBindingOption.BindAsExpression;
				if (oldSymbol is INamespaceOrTypeSymbol)
				{
					speculativeBindingOption = SpeculativeBindingOption.BindAsTypeOrNamespace;
				}

				var newSymbol = semanticModel.GetSpeculativeSymbolInfo(crefSyntax.SpanStart, memberCref, speculativeBindingOption).Symbol;

				if (newSymbol == oldSymbol)
				{
					// Copy Trivia and Annotations
					memberCref = memberCref.WithLeadingTrivia(crefSyntax.GetLeadingTrivia());
					memberCref = crefSyntax.CopyAnnotationsTo(memberCref);
					issueSpan = qualifiedCrefSyntax.Container.Span;
					replacementNode = memberCref;
					return true;
				}
			}

			return false;
		}
        //		private static bool IsThisOrTypeOrNamespace(MemberAccessExpressionSyntax memberAccess, SemanticModel semanticModel)
        //		{
        //			if (memberAccess.Expression.Kind() == SyntaxKind.ThisExpression)
        //			{
        //				var previousToken = memberAccess.Expression.GetFirstToken().GetPreviousToken();
        //
        //				var symbol = semanticModel.GetSymbolInfo(memberAccess.Name).Symbol;
        //
        //				if (previousToken.Kind() == SyntaxKind.OpenParenToken &&
        //					previousToken.Parent.IsKind(SyntaxKind.ParenthesizedExpression) &&
        //					!previousToken.Parent.IsParentKind(SyntaxKind.ParenthesizedExpression) &&
        //					((ParenthesizedExpressionSyntax)previousToken.Parent).Expression.Kind() == SyntaxKind.SimpleMemberAccessExpression &&
        //					symbol != null && symbol.Kind == SymbolKind.Method)
        //				{
        //					return false;
        //				}
        //
        //				return true;
        //			}
        //
        //			var expressionInfo = semanticModel.GetSymbolInfo(memberAccess.Expression);
        //			if (SimplificationHelpers.IsValidSymbolInfo(expressionInfo.Symbol))
        //			{
        //				if (expressionInfo.Symbol is INamespaceOrTypeSymbol)
        //				{
        //					return true;
        //				}
        //
        //				if (expressionInfo.Symbol.IsThisParameter())
        //				{
        //					return true;
        //				}
        //			}
        //
        //			return false;
        //		}

        private static bool IsReplacableByVar(
            this TypeSyntax simpleName,
            SemanticModel semanticModel,
            out TypeSyntax replacementNode,
            out TextSpan issueSpan,
            OptionSet optionSet,
            CancellationToken cancellationToken)
        {
            replacementNode = null;
            issueSpan = default(TextSpan);

            if (!optionSet.GetOption(SimplificationOptions.PreferImplicitTypeInLocalDeclaration))
            {
                return false;
            }

            // If it is already var
            if (simpleName.IsVar)
            {
                return false;
            }

            var candidateReplacementNode = SyntaxFactory.IdentifierName("var")
                .WithLeadingTrivia(simpleName.GetLeadingTrivia())
                .WithTrailingTrivia(simpleName.GetTrailingTrivia());
            var candidateIssueSpan = simpleName.Span;

            // If there exists a Type called var , fail.
            var checkSymbol = semanticModel.GetSpeculativeSymbolInfo(simpleName.SpanStart, candidateReplacementNode, SpeculativeBindingOption.BindAsTypeOrNamespace).Symbol;
            if (checkSymbol != null && checkSymbol.IsKind(SymbolKind.NamedType) && ((INamedTypeSymbol)checkSymbol).TypeKind == TypeKind.Class && checkSymbol.Name == "var")
            {
                return false;
            }

            // If the simpleName is the type of the Variable Declaration Syntax belonging to LocalDeclaration, For Statement or Using statement
            if (simpleName.IsParentKind(SyntaxKind.VariableDeclaration) &&
                ((VariableDeclarationSyntax)simpleName.Parent).Type == simpleName &&
                simpleName.Parent.Parent.IsKind(SyntaxKind.LocalDeclarationStatement, SyntaxKind.ForStatement, SyntaxKind.UsingStatement))
            {
                if (simpleName.Parent.IsParentKind(SyntaxKind.LocalDeclarationStatement) &&
                    ((LocalDeclarationStatementSyntax)simpleName.Parent.Parent).Modifiers.Any(n => n.Kind() == SyntaxKind.ConstKeyword))
                {
                    return false;
                }

                var variableDeclaration = (VariableDeclarationSyntax)simpleName.Parent;

                // Check the Initialized Value to see if it is allowed to be in the Var initialization
                if (variableDeclaration.Variables.Count != 1 ||
                    !variableDeclaration.Variables.Single().Initializer.IsKind(SyntaxKind.EqualsValueClause))
                {
                    return false;
                }

                var variable = variableDeclaration.Variables.Single();
                var initializer = (EqualsValueClauseSyntax)variable.Initializer;
                var identifier = variable.Identifier;

                if (EqualsValueClauseNotSuitableForVar(identifier, simpleName, initializer, semanticModel, cancellationToken))
                {
                    return false;
                }

                replacementNode = candidateReplacementNode;
                issueSpan = candidateIssueSpan;
                return true;
            }

            if (simpleName.IsParentKind(SyntaxKind.ForEachStatement) &&
                ((ForEachStatementSyntax)simpleName.Parent).Type == simpleName)
            {
                replacementNode = candidateReplacementNode;
                issueSpan = candidateIssueSpan;
                return true;
            }

            return false;
        }
예제 #6
0
        static JToken GetTokenInfo(SemanticModel model, SyntaxToken token)
        {
            var symbol = model.GetDeclaredSymbol(token.Parent);
            if (symbol == null)
            {
                var symbolInfo = model.GetSymbolInfo(token.Parent);

                if (symbolInfo.Symbol == null)
                {
                    symbolInfo = model.GetSpeculativeSymbolInfo(0, token.Parent, SpeculativeBindingOption.BindAsTypeOrNamespace);
                    if (symbolInfo.Symbol == null)
                    {
                        symbolInfo = model.GetSpeculativeSymbolInfo(0, token.Parent, SpeculativeBindingOption.BindAsExpression);
                        if (symbolInfo.Symbol == null)
                            return null;
                    }
                }

                symbol = symbolInfo.Symbol;
            }

            if (!symbol.IsDefinition)
                symbol = symbol.OriginalDefinition;

            string info = null;
            var displayPoarts = symbol.ToDisplayParts(format);
            var xml = symbol.GetDocumentationCommentXml(CultureInfo.InvariantCulture, true);
            if(!string.IsNullOrEmpty(xml))
            {
                try
                {
                    XDocument doc = XDocument.Parse(xml);

                    var summary = doc.Root.Element("summary");
                    if (summary != null)
                        info = summary.Value;
                }
                catch
                { }
            }

            return new JObject(
                new JProperty("summary", info == null ? null : new JValue(info)),
                new JProperty("name", new JArray(
                    displayPoarts.Select(part => Categorize(part))
                ))
            );
        }
 private static SyntaxNode CreatRootWithUsingFromMemberAccessedNode(SyntaxNode root, SemanticModel semanticModel, ref string newVariableName, ExpressionSyntax accessedNode)
 {
     SyntaxNode newRoot;
     var memberAccessStatement = accessedNode.Parent;
     var newVariableNameParts = newVariableName.Split('.');
     newVariableName = newVariableNameParts[newVariableNameParts.Length - 1].ToLowerCaseFirstLetter();
     var parentStatement = memberAccessStatement.FirstAncestorOrSelfThatIsAStatement();
     var originalName = newVariableName;
     for (int nameIncrement = 1; ; nameIncrement++)
     {
         var speculativeSymbol = semanticModel.GetSpeculativeSymbolInfo(parentStatement.GetLocation().SourceSpan.Start, SyntaxFactory.IdentifierName(newVariableName), SpeculativeBindingOption.BindAsExpression);
         if (speculativeSymbol.Symbol == null) break;
         newVariableName = originalName + nameIncrement;
     }
     var newVariable = SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.VariableDeclaration(SyntaxFactory.ParseTypeName("var"),
         SyntaxFactory.SeparatedList(new[] {
                 SyntaxFactory.VariableDeclarator(newVariableName).WithInitializer(SyntaxFactory.EqualsValueClause(accessedNode))
         })));
     newRoot = root.TrackNodes(parentStatement, accessedNode);
     newRoot = newRoot.ReplaceNode(newRoot.GetCurrentNode(accessedNode), SyntaxFactory.IdentifierName(newVariableName));
     var newTrackedParentStatement = newRoot.GetCurrentNode(parentStatement);
     newRoot = newRoot.InsertNodesBefore(newTrackedParentStatement, new[] { newVariable });
     var statement = (LocalDeclarationStatementSyntax)newRoot.GetCurrentNode(parentStatement).GetPreviousStatement();
     var variableDeclaration = statement.Declaration;
     var variableDeclarator = variableDeclaration.Variables.First();
     newRoot = CreateRootWithUsing(newRoot, statement, u => u.WithDeclaration(variableDeclaration.WithoutLeadingTrivia()));
     return newRoot;
 }
        public static SyntaxNode CreateUsing(SyntaxNode root, ObjectCreationExpressionSyntax objectCreation, SemanticModel semanticModel)
        {
            SyntaxNode newRoot;
            if (objectCreation.Parent.IsKind(SyntaxKind.SimpleAssignmentExpression))
            {
                var assignmentExpression = (AssignmentExpressionSyntax)objectCreation.Parent;
                var statement = assignmentExpression.Parent as ExpressionStatementSyntax;
                var identitySymbol = (ILocalSymbol)semanticModel.GetSymbolInfo(assignmentExpression.Left).Symbol;
                newRoot = UsedOutsideParentBlock(semanticModel, statement, identitySymbol)
                    ? CreateRootAddingDisposeToEndOfMethod(root, statement, identitySymbol)
                    : CreateRootWithUsing(root, statement, u => u.WithExpression(assignmentExpression));
            }
            else if (objectCreation.Parent.IsKind(SyntaxKind.EqualsValueClause) && objectCreation.Parent.Parent.IsKind(SyntaxKind.VariableDeclarator))
            {
                var variableDeclarator = (VariableDeclaratorSyntax)objectCreation.Parent.Parent;
                var variableDeclaration = (VariableDeclarationSyntax)variableDeclarator.Parent;
                var statement = (LocalDeclarationStatementSyntax)variableDeclaration.Parent;
                newRoot = CreateRootWithUsing(root, statement, u => u.WithDeclaration(variableDeclaration.WithoutLeadingTrivia()));
            }
            else if (objectCreation.Parent.IsKind(SyntaxKind.Argument))
            {
                var identifierName = GetIdentifierName(objectCreation, semanticModel);

                var variableDeclaration = SyntaxFactory.VariableDeclaration(SyntaxFactory.IdentifierName(@"var"))
                    .WithVariables(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(identifierName))
                    .WithInitializer(SyntaxFactory.EqualsValueClause(SyntaxFactory.Token(SyntaxKind.EqualsToken), objectCreation))));

                var arg = objectCreation.Parent as ArgumentSyntax;
                var args = objectCreation.Parent.Parent as ArgumentListSyntax;
                var newArgs = args.ReplaceNode(arg, arg.WithExpression(SyntaxFactory.IdentifierName(identifierName)));

                StatementSyntax statement = objectCreation.FirstAncestorOfType<ExpressionStatementSyntax>();
                if (statement != null)
                {
                    var exprStatement = statement.ReplaceNode(args, newArgs);
                    var newUsingStatment = CreateUsingStatement(exprStatement, SyntaxFactory.Block(exprStatement))
                        .WithDeclaration(variableDeclaration);
                    return root.ReplaceNode(statement, newUsingStatment);
                }

                statement = (StatementSyntax)objectCreation.Ancestors().First(node => node is StatementSyntax);
                var newStatement = statement.ReplaceNode(args, newArgs);
                var statementsForUsing = new[] { newStatement }.Concat(GetChildStatementsAfter(statement));
                var usingBlock = SyntaxFactory.Block(statementsForUsing);
                var usingStatement = CreateUsingStatement(newStatement, usingBlock)
                    .WithDeclaration(variableDeclaration);
                var statementsToReplace = new List<StatementSyntax> { statement };
                statementsToReplace.AddRange(statementsForUsing.Skip(1));
                newRoot = root.ReplaceNodes(statementsToReplace, (node, _) => node.Equals(statement) ? usingStatement : null);
            }
            else if (objectCreation.Parent.IsKind(SyntaxKind.SimpleMemberAccessExpression))
            {
                var newVariableName = objectCreation.Type.ToString();
                var newVariableNameParts = newVariableName.Split('.');
                newVariableName = newVariableNameParts[newVariableNameParts.Length - 1].ToLowerCaseFirstLetter();
                var parentStatement = objectCreation.Parent.FirstAncestorOrSelfThatIsAStatement();
                var originalName = newVariableName;
                for (int nameIncrement = 1; ; nameIncrement++)
                {
                    var speculativeSymbol = semanticModel.GetSpeculativeSymbolInfo(parentStatement.GetLocation().SourceSpan.Start, SyntaxFactory.IdentifierName(newVariableName), SpeculativeBindingOption.BindAsExpression);
                    if (speculativeSymbol.Symbol == null) break;
                    newVariableName = originalName + nameIncrement;
                }
                var newVariable = SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.VariableDeclaration(SyntaxFactory.ParseTypeName("var"),
                    SyntaxFactory.SeparatedList(new[] {
                        SyntaxFactory.VariableDeclarator(newVariableName).WithInitializer(SyntaxFactory.EqualsValueClause(objectCreation))
                    })));
                newRoot = root.TrackNodes(parentStatement, objectCreation);
                newRoot = newRoot.ReplaceNode(newRoot.GetCurrentNode(objectCreation), SyntaxFactory.IdentifierName(newVariableName));
                var newTrackedParentStatement = newRoot.GetCurrentNode(parentStatement);
                newRoot = newRoot.InsertNodesBefore(newTrackedParentStatement, new[] { newVariable });
                var statement = (LocalDeclarationStatementSyntax)newRoot.GetCurrentNode(parentStatement).GetPreviousStatement();
                var variableDeclaration = statement.Declaration;
                var variableDeclarator = variableDeclaration.Variables.First();
                newRoot = CreateRootWithUsing(newRoot, statement, u => u.WithDeclaration(variableDeclaration.WithoutLeadingTrivia()));
            }
            else
            {
                newRoot = CreateRootWithUsing(root, (ExpressionStatementSyntax)objectCreation.Parent, u => u.WithExpression(objectCreation));
            }
            return newRoot;
        }