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,
|
secondaryDocument,
|
||||||
secondarySpan,
|
secondarySpan,
|
||||||
cancellationToken);
|
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.
|
// Now we have to translate back to the primary document's coordinates.
|
||||||
var offset = primarySpan.Start - secondarySpan.Start;
|
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);
|
var updated = new TextSpan(classifiedSecondarySpan.TextSpan.Start + offset, classifiedSecondarySpan.TextSpan.Length);
|
||||||
Debug.Assert(primarySpan.Contains(updated));
|
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));
|
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
|
// Deal with residue
|
||||||
|
|
|
||||||
|
|
@ -70,22 +70,42 @@ namespace Microsoft.CodeAnalysis.Razor
|
||||||
Assert.Equal(@" var foo = ""Hello, World!"";", result.Value.Content.ToString(), ignoreLineEndingDifferences: true);
|
Assert.Equal(@" var foo = ""Hello, World!"";", result.Value.Content.ToString(), ignoreLineEndingDifferences: true);
|
||||||
Assert.Collection(
|
Assert.Collection(
|
||||||
result.Value.ClassifiedSpans,
|
result.Value.ClassifiedSpans,
|
||||||
|
c =>
|
||||||
|
{
|
||||||
|
Assert.Equal(ClassificationTypeNames.Text, c.ClassificationType);
|
||||||
|
Assert.Equal(" ", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
|
},
|
||||||
c =>
|
c =>
|
||||||
{
|
{
|
||||||
Assert.Equal(ClassificationTypeNames.Keyword, c.ClassificationType);
|
Assert.Equal(ClassificationTypeNames.Keyword, c.ClassificationType);
|
||||||
Assert.Equal("var", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
Assert.Equal("var", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.LocalName, c.ClassificationType);
|
||||||
Assert.Equal("foo", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
Assert.Equal("foo", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.Operator, c.ClassificationType);
|
||||||
Assert.Equal("=", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
Assert.Equal("=", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.StringLiteral, c.ClassificationType);
|
||||||
Assert.Equal("\"Hello, World!\"", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
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());
|
Assert.Equal("3", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.Operator, c.ClassificationType);
|
||||||
Assert.Equal("+", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
Assert.Equal("+", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.NumericLiteral, c.ClassificationType);
|
||||||
Assert.Equal("4", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
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());
|
Assert.Equal("foo", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.Operator, c.ClassificationType);
|
||||||
Assert.Equal("+", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
Assert.Equal("+", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.LocalName, c.ClassificationType);
|
||||||
Assert.Equal("foo", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
Assert.Equal("foo", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
|
|
@ -292,21 +332,41 @@ namespace Microsoft.CodeAnalysis.Razor
|
||||||
ignoreLineEndingDifferences: true);
|
ignoreLineEndingDifferences: true);
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.Keyword, c.ClassificationType);
|
||||||
Assert.Equal("var", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
Assert.Equal("var", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.LocalName, c.ClassificationType);
|
||||||
Assert.Equal("foo", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
Assert.Equal("foo", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.Operator, c.ClassificationType);
|
||||||
Assert.Equal("=", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
Assert.Equal("=", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.StringLiteral, c.ClassificationType);
|
||||||
Assert.Equal("\"Hello, World!\"", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
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());
|
Assert.Equal(";", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.Text, c.ClassificationType);
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
|
|
@ -365,21 +430,41 @@ namespace Microsoft.CodeAnalysis.Razor
|
||||||
Assert.Equal("@{", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
Assert.Equal("@{", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.Keyword, c.ClassificationType);
|
||||||
Assert.Equal("var", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
Assert.Equal("var", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.LocalName, c.ClassificationType);
|
||||||
Assert.Equal("foo", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
Assert.Equal("foo", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.Operator, c.ClassificationType);
|
||||||
Assert.Equal("=", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
Assert.Equal("=", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.StringLiteral, c.ClassificationType);
|
||||||
Assert.Equal("\"Hello, World!\"", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
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());
|
Assert.Equal(";", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
},
|
},
|
||||||
c =>
|
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(ClassificationTypeNames.Text, c.ClassificationType);
|
||||||
Assert.Equal("}", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
Assert.Equal("}", result.Value.Content.GetSubText(c.TextSpan).ToString());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue