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:
Diffstat (limited to 'main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.InitializerRewriter.cs')
-rw-r--r--main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.InitializerRewriter.cs107
1 files changed, 107 insertions, 0 deletions
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.InitializerRewriter.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.InitializerRewriter.cs
new file mode 100644
index 0000000000..e6866a9f25
--- /dev/null
+++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.InitializerRewriter.cs
@@ -0,0 +1,107 @@
+// 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 Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Extensions;
+using Microsoft.CodeAnalysis.CSharp.Symbols;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Shared.Extensions;
+using Microsoft.CodeAnalysis.Simplification;
+using Microsoft.CodeAnalysis.CSharp;
+using ICSharpCode.NRefactory6.CSharp;
+
+namespace MonoDevelop.CSharp.CodeRefactorings.InlineTemporary
+{
+ internal partial class InlineTemporaryCodeRefactoringProvider
+ {
+ /// <summary>
+ /// This class handles rewriting initializer expressions that refer to the variable
+ /// being initialized into a simpler form. For example, in "int x = x = 1", we want to
+ /// get just "1" back as the initializer.
+ /// </summary>
+ private class InitializerRewriter : CSharpSyntaxRewriter
+ {
+ private readonly SemanticModel _semanticModel;
+ private readonly ILocalSymbol _localSymbol;
+ private readonly ExpressionSyntax _initializer;
+
+ private InitializerRewriter(ExpressionSyntax initializer, ILocalSymbol localSymbol, SemanticModel semanticModel)
+ {
+ _semanticModel = semanticModel;
+ _localSymbol = localSymbol;
+ _initializer = initializer;
+ }
+
+ private bool IsReference(SimpleNameSyntax name)
+ {
+ if (name.Identifier.ValueText != _localSymbol.Name)
+ {
+ return false;
+ }
+
+ var symbol = _semanticModel.GetSymbolInfo(name).Symbol;
+ return symbol != null
+ && symbol.Equals(_localSymbol);
+ }
+
+ public override SyntaxNode VisitAssignmentExpression(AssignmentExpressionSyntax node)
+ {
+ // Note - leave this as SyntaxNode for now, we might have already re-written it
+ var newNode = base.VisitAssignmentExpression(node);
+
+ if (newNode.Kind() == SyntaxKind.SimpleAssignmentExpression)
+ {
+ // It's okay to just look at the text, since we're explicitly looking for an
+ // identifier standing alone, and we know we're in a local's initializer.
+ // The text can only bind to the initializer.
+ var assignment = (AssignmentExpressionSyntax)newNode;
+ var name = assignment.Left.Kind() == SyntaxKind.IdentifierName
+ ? (IdentifierNameSyntax)assignment.Left
+ : null;
+
+ if (name != null && IsReference(name))
+ {
+ return assignment.Right;
+ }
+ }
+
+ return newNode;
+ }
+
+ public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node)
+ {
+ if (IsReference(node))
+ {
+ var assignmentExpression = node.Parent as AssignmentExpressionSyntax;
+ if (assignmentExpression != null)
+ {
+ if (assignmentExpression.IsCompoundAssignExpression() &&
+ assignmentExpression.Left == node)
+ {
+ return node.Update(node.Identifier.WithAdditionalAnnotations(CreateConflictAnnotation()));
+ }
+ }
+ }
+
+ return base.VisitIdentifierName(node);
+ }
+
+ public override SyntaxNode VisitParenthesizedExpression(ParenthesizedExpressionSyntax node)
+ {
+ var newNode = base.VisitParenthesizedExpression(node);
+
+ if (node != newNode && newNode.Kind() == SyntaxKind.ParenthesizedExpression)
+ {
+ return newNode.WithAdditionalAnnotations(Simplifier.Annotation);
+ }
+
+ return newNode;
+ }
+
+ public static ExpressionSyntax Visit(ExpressionSyntax initializer, ILocalSymbol local, SemanticModel semanticModel)
+ {
+ var simplifier = new InitializerRewriter(initializer, local, semanticModel);
+ return (ExpressionSyntax)simplifier.Visit(initializer);
+ }
+ }
+ }
+}