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.ReferenceRewriter.cs')
-rw-r--r--main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.ReferenceRewriter.cs106
1 files changed, 106 insertions, 0 deletions
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.ReferenceRewriter.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.ReferenceRewriter.cs
new file mode 100644
index 0000000000..16d712e672
--- /dev/null
+++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.ReferenceRewriter.cs
@@ -0,0 +1,106 @@
+// 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.Threading;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Extensions;
+using Microsoft.CodeAnalysis.CSharp.Symbols;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Formatting;
+using Microsoft.CodeAnalysis.Shared.Extensions;
+using Microsoft.CodeAnalysis.Simplification;
+using ICSharpCode.NRefactory6.CSharp;
+using Microsoft.CodeAnalysis.CSharp;
+
+namespace MonoDevelop.CSharp.CodeRefactorings.InlineTemporary
+{
+ internal partial class InlineTemporaryCodeRefactoringProvider
+ {
+ private class ReferenceRewriter : CSharpSyntaxRewriter
+ {
+ private readonly SemanticModel _semanticModel;
+ private readonly ILocalSymbol _localSymbol;
+ private readonly VariableDeclaratorSyntax _variableDeclarator;
+ private readonly ExpressionSyntax _expressionToInline;
+ private readonly CancellationToken _cancellationToken;
+
+ private ReferenceRewriter(
+ SemanticModel semanticModel,
+ VariableDeclaratorSyntax variableDeclarator,
+ ExpressionSyntax expressionToInline,
+ CancellationToken cancellationToken)
+ {
+ _semanticModel = semanticModel;
+ _localSymbol = (ILocalSymbol)semanticModel.GetDeclaredSymbol(variableDeclarator, cancellationToken);
+ _variableDeclarator = variableDeclarator;
+ _expressionToInline = expressionToInline;
+ _cancellationToken = cancellationToken;
+ }
+
+ private bool IsReference(SimpleNameSyntax name)
+ {
+ if (name.Identifier.ValueText != _variableDeclarator.Identifier.ValueText)
+ {
+ return false;
+ }
+
+ var symbol = _semanticModel.GetSymbolInfo(name).Symbol;
+ return symbol != null
+ && symbol.Equals(_localSymbol);
+ }
+
+ public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node)
+ {
+ _cancellationToken.ThrowIfCancellationRequested();
+
+ if (IsReference(node))
+ {
+ if (HasConflict(node, _variableDeclarator))
+ {
+ return node.Update(node.Identifier.WithAdditionalAnnotations(CreateConflictAnnotation()));
+ }
+
+ return _expressionToInline
+ .Parenthesize()
+ .WithAdditionalAnnotations(Formatter.Annotation, Simplifier.Annotation);
+ }
+
+ return base.VisitIdentifierName(node);
+ }
+
+ public override SyntaxNode VisitAnonymousObjectMemberDeclarator(AnonymousObjectMemberDeclaratorSyntax node)
+ {
+ var nameEquals = node.NameEquals;
+ var expression = node.Expression;
+ var identifier = expression as IdentifierNameSyntax;
+
+ if (nameEquals != null || identifier == null || !IsReference(identifier) || HasConflict(identifier, _variableDeclarator))
+ {
+ return base.VisitAnonymousObjectMemberDeclarator(node);
+ }
+
+ // Special case inlining into anonymous types to ensure that we keep property names:
+ //
+ // E.g.
+ // int x = 42;
+ // var a = new { x; };
+ //
+ // Should become:
+ // var a = new { x = 42; };
+ nameEquals = SyntaxFactory.NameEquals(identifier);
+ expression = (ExpressionSyntax)this.Visit(expression);
+ return node.Update(nameEquals, expression).WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation);
+ }
+
+ public static SyntaxNode Visit(
+ SemanticModel semanticModel,
+ SyntaxNode scope,
+ VariableDeclaratorSyntax variableDeclarator,
+ ExpressionSyntax expressionToInline,
+ CancellationToken cancellationToken)
+ {
+ var rewriter = new ReferenceRewriter(semanticModel, variableDeclarator, expressionToInline, cancellationToken);
+ return rewriter.Visit(scope);
+ }
+ }
+ }
+}