Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLluis Sanchez Gual <lluis@xamarin.com>2015-04-20 19:07:51 +0300
committerLluis Sanchez Gual <lluis@xamarin.com>2015-04-20 19:07:51 +0300
commit95408b1a41b31b645f3a8c3323ab7d3ca4bff26b (patch)
treef8f137cddcb9a40499d303be95722fd2c6081bce /main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeFixes/SimplifyTypeNames/SimplifyTypeNamesCodeFixProvider.cs
parentb70e4e04b4e41b8ec28d7e4b220b401ecf467e7a (diff)
parentde043d330a8bf5855d4d983c804cd36727cb2406 (diff)
Merge remote-tracking branch 'origin/roslyn' into new-project-model
Diffstat (limited to 'main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeFixes/SimplifyTypeNames/SimplifyTypeNamesCodeFixProvider.cs')
-rw-r--r--main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeFixes/SimplifyTypeNames/SimplifyTypeNamesCodeFixProvider.cs143
1 files changed, 143 insertions, 0 deletions
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeFixes/SimplifyTypeNames/SimplifyTypeNamesCodeFixProvider.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeFixes/SimplifyTypeNames/SimplifyTypeNamesCodeFixProvider.cs
new file mode 100644
index 0000000000..be3ccc4cd3
--- /dev/null
+++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeFixes/SimplifyTypeNames/SimplifyTypeNamesCodeFixProvider.cs
@@ -0,0 +1,143 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Immutable;
+using System.Composition;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis.Formatting;
+using Microsoft.CodeAnalysis.Options;
+using Microsoft.CodeAnalysis.Shared.Extensions;
+using Microsoft.CodeAnalysis.Simplification;
+using Microsoft.CodeAnalysis.Text;
+using Roslyn.Utilities;
+using Microsoft.CodeAnalysis;
+using MonoDevelop.CSharp.Diagnostics;
+using ICSharpCode.NRefactory6.CSharp;
+using MonoDevelop.Core;
+using System;
+using Microsoft.CodeAnalysis.CSharp;
+using ICSharpCode.NRefactory6.CSharp.Refactoring;
+using MonoDevelop.CSharp.Diagnostics.SimplifyTypeNames;
+
+namespace MonoDevelop.CSharp.CodeFixes.SimplifyTypeNames
+{
+ [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.SimplifyNames), Shared]
+ [ExtensionOrder(After = PredefinedCodeFixProviderNames.RemoveUnnecessaryCast)]
+ internal partial class SimplifyTypeNamesCodeFixProvider : CodeFixProvider
+ {
+ public sealed override ImmutableArray<string> FixableDiagnosticIds
+ {
+ get
+ {
+ return ImmutableArray.Create(
+ IDEDiagnosticIds.SimplifyNamesDiagnosticId,
+ IDEDiagnosticIds.SimplifyMemberAccessDiagnosticId,
+ IDEDiagnosticIds.SimplifyThisOrMeDiagnosticId);
+ }
+ }
+
+// public sealed override FixAllProvider GetFixAllProvider()
+// {
+// return SimplifyTypeNamesFixAllProvider.Instance;
+// }
+
+ internal static SyntaxNode GetNodeToSimplify(SyntaxNode root, SemanticModel model, TextSpan span, OptionSet optionSet, out string diagnosticId, CancellationToken cancellationToken)
+ {
+ diagnosticId = null;
+ var token = root.FindToken(span.Start, findInsideTrivia: true);
+ if (!token.Span.IntersectsWith(span))
+ {
+ return null;
+ }
+
+ foreach (var n in token.GetAncestors<SyntaxNode>())
+ {
+ if (n.Span.IntersectsWith(span) && CanSimplifyTypeNameExpression(model, n, optionSet, span, out diagnosticId, cancellationToken))
+ {
+ return n;
+ }
+ }
+
+ return null;
+ }
+
+ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
+ {
+ var document = context.Document;
+ var span = context.Span;
+ var cancellationToken = context.CancellationToken;
+
+ var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
+ var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+ var optionSet = document.Project.Solution.Workspace.Options;
+ string diagnosticId;
+ var node = GetNodeToSimplify(root, model, span, optionSet, out diagnosticId, cancellationToken);
+ if (node == null)
+ {
+ return;
+ }
+
+ var id = GetCodeActionId(diagnosticId, node.ToString());
+ var title = id;
+ var codeAction = new DocumentChangeAction(node.Span, DiagnosticSeverity.Warning, title,
+ (c) => SimplifyTypeNameAsync(document, node, c));
+
+ context.RegisterCodeFix(codeAction, context.Diagnostics);
+ }
+
+ // internal for testing purpose
+ internal static string GetCodeActionId(string diagnosticId, string nodeText)
+ {
+ switch (diagnosticId)
+ {
+ case IDEDiagnosticIds.SimplifyNamesDiagnosticId:
+ return string.Format(GettextCatalog.GetString ("Simplify name '{0}'"), nodeText);
+
+ case IDEDiagnosticIds.SimplifyMemberAccessDiagnosticId:
+ return string.Format(GettextCatalog.GetString ("Simplify member access '{0}'"), nodeText);
+
+ case IDEDiagnosticIds.SimplifyThisOrMeDiagnosticId:
+ return GettextCatalog.GetString ("Remove 'this' qualification");
+
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+
+ private static bool CanSimplifyTypeNameExpression(SemanticModel model, SyntaxNode node, OptionSet optionSet, TextSpan span, out string diagnosticId, CancellationToken cancellationToken)
+ {
+ diagnosticId = null;
+ TextSpan issueSpan;
+ if (!CSharpSimplifyTypeNamesDiagnosticAnalyzer.IsCandidate(node) ||
+ !CSharpSimplifyTypeNamesDiagnosticAnalyzer.CanSimplifyTypeNameExpression(model, node, optionSet, out issueSpan, out diagnosticId, cancellationToken))
+ {
+ return false;
+ }
+
+ return issueSpan.Equals(span);
+ }
+
+ private async Task<Document> SimplifyTypeNameAsync(Document document, SyntaxNode node, CancellationToken cancellationToken)
+ {
+ var expressionSyntax = node;
+ var annotatedexpressionSyntax = expressionSyntax.WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation);
+
+ if (annotatedexpressionSyntax.Kind() == SyntaxKind.IsExpression || annotatedexpressionSyntax.Kind() == SyntaxKind.AsExpression)
+ {
+ var right = ((BinaryExpressionSyntax)annotatedexpressionSyntax).Right;
+ annotatedexpressionSyntax = annotatedexpressionSyntax.ReplaceNode(right, right.WithAdditionalAnnotations(Simplifier.Annotation));
+ }
+
+ SyntaxNode oldNode = expressionSyntax;
+ SyntaxNode newNode = annotatedexpressionSyntax;
+
+ var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
+ var newRoot = root.ReplaceNode(oldNode, newNode);
+
+ return document.WithSyntaxRoot(newRoot);
+ }
+ }
+}