Classify non-C# inside C#
Fixes a bug with preview formatting for FAR.
So when we ask the Roslyn API to classify C# for us, it will only
classify the actual C# tokens. We are responsible for filling in the
gaps and whitespace.
The bug is that the following text would have all of its whitespace
removed in the VS FAR preview window.
```
@{ var foo = "Hello, world!"; }
```
Would look like:
```
@{varfoo="Hello, world!";}
```
This fixes the issue and makes it look like what one would expect.
This commit is contained in:
parent
a3d0c8f634
commit
6c1bee1940
|
|
@ -176,6 +176,10 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
secondaryDocument,
|
||||
secondarySpan,
|
||||
cancellationToken);
|
||||
|
||||
// NOTE: The Classifier will only returns spans for things that it understands. That means
|
||||
// that whitespace is not classified. The preview expects us to provide contiguous spans,
|
||||
// so we are going to have to fill in the gaps.
|
||||
|
||||
// Now we have to translate back to the primary document's coordinates.
|
||||
var offset = primarySpan.Start - secondarySpan.Start;
|
||||
|
|
@ -185,11 +189,29 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
|
||||
var updated = new TextSpan(classifiedSecondarySpan.TextSpan.Start + offset, classifiedSecondarySpan.TextSpan.Length);
|
||||
Debug.Assert(primarySpan.Contains(updated));
|
||||
|
||||
// Make sure that we're not introducing a gap. Remember, we need to fill in the whitespace.
|
||||
if (remainingSpan.Start < updated.Start)
|
||||
{
|
||||
builder.Add(new ClassifiedSpan(
|
||||
ClassificationTypeNames.Text,
|
||||
new TextSpan(remainingSpan.Start, updated.Start - remainingSpan.Start)));
|
||||
remainingSpan = new TextSpan(updated.Start, remainingSpan.Length - (updated.Start - remainingSpan.Start));
|
||||
}
|
||||
|
||||
builder.Add(new ClassifiedSpan(classifiedSecondarySpan.ClassificationType, updated));
|
||||
remainingSpan = new TextSpan(updated.End, remainingSpan.Length - (updated.End - remainingSpan.Start));
|
||||
}
|
||||
|
||||
// Make sure that we're not introducing a gap. Remember, we need to fill in the whitespace.
|
||||
if (remainingSpan.Start < primarySpan.End)
|
||||
{
|
||||
builder.Add(new ClassifiedSpan(
|
||||
ClassificationTypeNames.Text,
|
||||
new TextSpan(remainingSpan.Start, primarySpan.End - remainingSpan.Start)));
|
||||
remainingSpan = new TextSpan(primarySpan.End, remainingSpan.Length - (primarySpan.End - remainingSpan.Start));
|
||||
}
|
||||
|
||||
remainingSpan = new TextSpan(primarySpan.End, remainingSpan.Length - primarySpan.Length);
|
||||
}
|
||||
|
||||
// Deal with residue
|
||||
|
|
|
|||
|
|
@ -70,22 +70,42 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
Assert.Equal(@" var foo = ""Hello, World!"";", result.Value.Content.ToString(), ignoreLineEndingDifferences: true);
|
||||
Assert.Collection(
|
||||
result.Value.ClassifiedSpans,
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Keyword, c.ClassificationType);
|
||||
Assert.Equal("var", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.LocalName, c.ClassificationType);
|
||||
Assert.Equal("foo", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Operator, c.ClassificationType);
|
||||
Assert.Equal("=", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.StringLiteral, c.ClassificationType);
|
||||
Assert.Equal("\"Hello, World!\"", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
|
|
@ -199,11 +219,21 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
Assert.Equal("3", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Operator, c.ClassificationType);
|
||||
Assert.Equal("+", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.NumericLiteral, c.ClassificationType);
|
||||
Assert.Equal("4", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
|
|
@ -219,11 +249,21 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
Assert.Equal("foo", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Operator, c.ClassificationType);
|
||||
Assert.Equal("+", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.LocalName, c.ClassificationType);
|
||||
Assert.Equal("foo", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
|
|
@ -292,21 +332,41 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
ignoreLineEndingDifferences: true);
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal("\r\n ", result.Value.Content.GetSubText(c.TextSpan).ToString(), ignoreLineEndingDifferences: true);
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Keyword, c.ClassificationType);
|
||||
Assert.Equal("var", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.LocalName, c.ClassificationType);
|
||||
Assert.Equal("foo", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Operator, c.ClassificationType);
|
||||
Assert.Equal("=", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.StringLiteral, c.ClassificationType);
|
||||
Assert.Equal("\"Hello, World!\"", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
|
|
@ -317,6 +377,11 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
Assert.Equal(";", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal("\r\n", result.Value.Content.GetSubText(c.TextSpan).ToString(), ignoreLineEndingDifferences: true);
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(
|
||||
|
|
@ -365,21 +430,41 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
Assert.Equal("@{", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Keyword, c.ClassificationType);
|
||||
Assert.Equal("var", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.LocalName, c.ClassificationType);
|
||||
Assert.Equal("foo", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Operator, c.ClassificationType);
|
||||
Assert.Equal("=", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.StringLiteral, c.ClassificationType);
|
||||
Assert.Equal("\"Hello, World!\"", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
|
|
@ -390,6 +475,11 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
Assert.Equal(";", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||
Assert.Equal("}", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||
|
|
|
|||
Loading…
Reference in New Issue