private static bool TryReduce( this MemberAccessExpressionSyntax memberAccess, SemanticModel semanticModel, out TypeSyntax replacementNode, out TextSpan issueSpan, OptionSet optionSet, CancellationToken cancellationToken) { replacementNode = null; issueSpan = default(TextSpan); if (memberAccess.Name == null || memberAccess.Expression == null) { return false; } if (memberAccess.Expression.IsKind(SyntaxKind.ThisExpression) && !SimplificationHelpers.ShouldSimplifyMemberAccessExpression(semanticModel, memberAccess.Name, optionSet)) { return false; } // if this node is annotated as being a specialtype, let's use this information. if (memberAccess.HasAnnotations(SpecialTypeAnnotation.Kind)) { replacementNode = SyntaxFactory.PredefinedType( SyntaxFactory.Token( memberAccess.GetLeadingTrivia(), GetPredefinedKeywordKind(SpecialTypeAnnotation.GetSpecialType(memberAccess.GetAnnotations(SpecialTypeAnnotation.Kind).First())), memberAccess.GetTrailingTrivia())); issueSpan = memberAccess.Span; return true; } // if this node is on the left side, we could simplify to aliases if (!memberAccess.IsRightSideOfDot()) { // Check if we need to replace this syntax with an alias identifier if (memberAccess.TryReplaceWithAlias(semanticModel, optionSet.GetOption(SimplificationOptions.PreferAliasToQualification), cancellationToken, out var aliasReplacement)) { // get the token text as it appears in source code to preserve e.g. unicode character escaping var text = aliasReplacement.Name; var syntaxRef = aliasReplacement.DeclaringSyntaxReferences.FirstOrDefault(); if (syntaxRef != null) { var declIdentifier = ((UsingDirectiveSyntax)syntaxRef.GetSyntax(cancellationToken)).Alias.Name.Identifier; text = declIdentifier.IsVerbatimIdentifier() ? declIdentifier.ToString().Substring(1) : declIdentifier.ToString(); } replacementNode = SyntaxFactory.IdentifierName( memberAccess.Name.Identifier.CopyAnnotationsTo(SyntaxFactory.Identifier( memberAccess.GetLeadingTrivia(), SyntaxKind.IdentifierToken, text, aliasReplacement.Name, memberAccess.GetTrailingTrivia()))); replacementNode = memberAccess.CopyAnnotationsTo(replacementNode); replacementNode = memberAccess.Name.CopyAnnotationsTo(replacementNode); issueSpan = memberAccess.Span; // In case the alias name is the same as the last name of the alias target, we only include // the left part of the name in the unnecessary span to Not confuse uses. if (memberAccess.Name.Identifier.ValueText == ((IdentifierNameSyntax)replacementNode).Identifier.ValueText) { issueSpan = memberAccess.Expression.Span; } return true; } // Check if the Expression can be replaced by Predefined Type keyword if (PreferPredefinedTypeKeywordInMemberAccess(memberAccess, optionSet, semanticModel)) { var symbol = semanticModel.GetSymbolInfo(memberAccess, cancellationToken).Symbol; if (symbol != null && symbol.IsKind(SymbolKind.NamedType)) { var keywordKind = GetPredefinedKeywordKind(((INamedTypeSymbol)symbol).SpecialType); if (keywordKind != SyntaxKind.None) { replacementNode = CreatePredefinedTypeSyntax(memberAccess, keywordKind); replacementNode = replacementNode .WithAdditionalAnnotations(new SyntaxAnnotation( nameof(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess))); issueSpan = memberAccess.Span; // we want to show the whole expression as unnecessary return true; } } } } replacementNode = memberAccess.Name .WithLeadingTrivia(memberAccess.GetLeadingTriviaForSimplifiedMemberAccess()) .WithTrailingTrivia(memberAccess.GetTrailingTrivia()); issueSpan = memberAccess.Expression.Span; if (replacementNode == null) { return false; } return memberAccess.CanReplaceWithReducedName(replacementNode, semanticModel, cancellationToken); }
private static bool CanReplaceWithPredefinedTypeKeywordInContext( NameSyntax name, SemanticModel semanticModel, out TypeSyntax replacementNode, ref TextSpan issueSpan, SyntaxKind keywordKind, string codeStyleOptionName, CancellationToken cancellationToken) { replacementNode = CreatePredefinedTypeSyntax(name, keywordKind); issueSpan = name.Span; // we want to show the whole name expression as unnecessary var canReduce = name.CanReplaceWithReducedNameInContext(replacementNode, semanticModel, cancellationToken); if (canReduce) { replacementNode = replacementNode.WithAdditionalAnnotations(new SyntaxAnnotation(codeStyleOptionName)); } return canReduce; }