提交 3dbe614e 编写于 作者: D Dustin Campbell

Merge pull request #5583 from DustinCampbell/issue-2638

Fix indentation when pressing ENTER in a partially completed from clause of a query expression
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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.Linq; using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Editor.UnitTests;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Formatting.Rules; using Microsoft.CodeAnalysis.Formatting.Rules;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text;
using Roslyn.Test.Utilities; using Roslyn.Test.Utilities;
using Xunit; using Xunit;
...@@ -2531,6 +2528,29 @@ class UserViewModel ...@@ -2531,6 +2528,29 @@ class UserViewModel
expectedIndentation: 25); expectedIndentation: 25);
} }
[WorkItem(5495, "https://github.com/dotnet/roslyn/issues/5495")]
[Fact, Trait(Traits.Feature, Traits.Features.SmartIndent)]
public void AfterPartialFromClause()
{
var code = @"
using System.Linq;
class C
{
void M()
{
var q = from x
}
}
";
AssertSmartIndent(
code,
indentationLine: 8,
expectedIndentation: 16);
}
private static void AssertSmartIndentInProjection(string markup, int expectedIndentation, CSharpParseOptions options = null) private static void AssertSmartIndentInProjection(string markup, int expectedIndentation, CSharpParseOptions options = null)
{ {
var optionsSet = options != null var optionsSet = options != null
......
...@@ -26,6 +26,36 @@ public override void AddSuppressOperations(List<SuppressOperation> list, SyntaxN ...@@ -26,6 +26,36 @@ public override void AddSuppressOperations(List<SuppressOperation> list, SyntaxN
} }
} }
private void AddIndentBlockOperationsForFromClause(List<IndentBlockOperation> list, FromClauseSyntax fromClause)
{
// Only add the indent block operation if the 'in' keyword is present. Otherwise, we'll get the following:
//
// from x
// in args
//
// Rather than:
//
// from x
// in args
//
// However, we want to get the following result if the 'in' keyword is present to allow nested queries
// to be formatted properly.
//
// from x in
// args
if (fromClause.InKeyword.IsMissing)
{
return;
}
var baseToken = fromClause.FromKeyword;
var startToken = fromClause.Expression.GetFirstToken(includeZeroWidth: true);
var endToken = fromClause.Expression.GetLastToken(includeZeroWidth: true);
AddIndentBlockOperation(list, baseToken, startToken, endToken);
}
public override void AddIndentBlockOperations(List<IndentBlockOperation> list, SyntaxNode node, OptionSet optionSet, NextAction<IndentBlockOperation> nextOperation) public override void AddIndentBlockOperations(List<IndentBlockOperation> list, SyntaxNode node, OptionSet optionSet, NextAction<IndentBlockOperation> nextOperation)
{ {
nextOperation.Invoke(list); nextOperation.Invoke(list);
...@@ -33,19 +63,15 @@ public override void AddIndentBlockOperations(List<IndentBlockOperation> list, S ...@@ -33,19 +63,15 @@ public override void AddIndentBlockOperations(List<IndentBlockOperation> list, S
var queryExpression = node as QueryExpressionSyntax; var queryExpression = node as QueryExpressionSyntax;
if (queryExpression != null) if (queryExpression != null)
{ {
var firstToken = queryExpression.FromClause.Expression.GetFirstToken(includeZeroWidth: true); AddIndentBlockOperationsForFromClause(list, queryExpression.FromClause);
var lastToken = queryExpression.FromClause.Expression.GetLastToken(includeZeroWidth: true);
AddIndentBlockOperation(list, queryExpression.FromClause.FromKeyword, firstToken, lastToken);
for (int i = 0; i < queryExpression.Body.Clauses.Count; i++) foreach (var queryClause in queryExpression.Body.Clauses)
{ {
// if it is nested query expression // if it is nested query expression
var fromClause = queryExpression.Body.Clauses[i] as FromClauseSyntax; var fromClause = queryClause as FromClauseSyntax;
if (fromClause != null) if (fromClause != null)
{ {
firstToken = fromClause.Expression.GetFirstToken(includeZeroWidth: true); AddIndentBlockOperationsForFromClause(list, fromClause);
lastToken = fromClause.Expression.GetLastToken(includeZeroWidth: true);
AddIndentBlockOperation(list, fromClause.FromKeyword, firstToken, lastToken);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册