Skip to content

Commit

Permalink
[FUSE] Add source and line mappings for usings (#9949)
Browse files Browse the repository at this point in the history
* Track if a using statement has an explicit semicolon
Using statements can have an optional semicolon, which is added automatically if the user doesn't write one.
Track if the user explicitly wrote the semicolon so we know where the user written code starts and ends.

* Add missing source mappings for runtime usings
Write out the semicolon if the user didn't explicitly provide it

* Correctly emit enhanced line directives when there is no offset
An offset of 0 is represented by the absence of an offset, not a literal 0. Don't write an offset at all if zero is requested.

* Update baselines and add tests
  • Loading branch information
chsienki authored Feb 28, 2024
1 parent ff30fd4 commit d4236bb
Show file tree
Hide file tree
Showing 235 changed files with 1,688 additions and 645 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ namespace AspNetCore
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml"
using Microsoft.AspNetCore.Mvc.RazorPages;
#line (4,2)-(5,1) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml"
using Microsoft.AspNetCore.Mvc.RazorPages

#line default
#line hidden
;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("RouteTemplate",
// language=Route
#line (1,7)-(1,15) 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml"
#line (1,7)-(1,15) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml"
"/About"

#line default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ namespace AspNetCore
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml"
using Microsoft.AspNetCore.Mvc.RazorPages;
#line (4,2)-(5,1) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml"
using Microsoft.AspNetCore.Mvc.RazorPages

#line default
#line hidden
;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"Sha256", @"4d4352438ec54cff935ed10c73f4fb4ce0ea8ffc7c46b467007618dead77f960", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml")]
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel : global::Microsoft.AspNetCore.Mvc.RazorPages.Page
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ namespace AspNetCore
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml"
using Microsoft.AspNetCore.Mvc.RazorPages;
#line (5,2)-(6,1) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml"
using Microsoft.AspNetCore.Mvc.RazorPages

#line default
#line hidden
;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"Sha256", @"676265931c358e22efce0fe9ebd76cc3a7d2a5c12d37384e13aec92aa7667663", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml")]
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages : global::Microsoft.AspNetCore.Mvc.RazorPages.Page
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,30 @@ namespace AspNetCore
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System.ComponentModel;
#line (1,2)-(2,1) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System.ComponentModel

#line default
#line hidden
#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System.Collections;
;
#line (2,2)-(3,1) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System.Collections

#line default
#line hidden
#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System;
;
#line (3,2)-(4,1) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System

#line default
#line hidden
#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System;
;
#line (4,2)-(4,14) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System

#line default
#line hidden
;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"Sha256", @"9194971d2fb7908a02b02841f18655ccc0908a204c2fa948e8dc7e947269da86", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml")]
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UsingDirectives : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ namespace AspNetCore
using global::Microsoft.AspNetCore.Mvc.Rendering;
using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 1 "TestFiles\IntegrationTests\CodeGenerationIntegrationTest\_ViewImports.cshtml"
using System;
#line (1,2)-(2,1) "TestFiles\IntegrationTests\CodeGenerationIntegrationTest\_ViewImports.cshtml"
using System

#line default
#line hidden
#nullable disable
;
#nullable restore
#line 2 "TestFiles\IntegrationTests\CodeGenerationIntegrationTest\_ViewImports.cshtml"
[Serializable]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ namespace AspNetCore
using global::Microsoft.AspNetCore.Mvc.Rendering;
using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml"
using Microsoft.AspNetCore.Mvc.RazorPages;
#line (4,2)-(5,1) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml"
using Microsoft.AspNetCore.Mvc.RazorPages

#line default
#line hidden
#nullable disable
;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("RouteTemplate",
// language=Route
#nullable restore
#line (1,7)-(1,15) 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml"
#line (1,7)-(1,15) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithRouteTemplate.cshtml"
"/About"

#line default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ namespace AspNetCore
using global::Microsoft.AspNetCore.Mvc.Rendering;
using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml"
using Microsoft.AspNetCore.Mvc.RazorPages;
#line (4,2)-(5,1) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml"
using Microsoft.AspNetCore.Mvc.RazorPages

#line default
#line hidden
#nullable disable
;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"Sha256", @"4d4352438ec54cff935ed10c73f4fb4ce0ea8ffc7c46b467007618dead77f960", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml")]
[global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml")]
[global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ namespace AspNetCore
using global::Microsoft.AspNetCore.Mvc.Rendering;
using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml"
using Microsoft.AspNetCore.Mvc.RazorPages;
#line (5,2)-(6,1) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml"
using Microsoft.AspNetCore.Mvc.RazorPages

#line default
#line hidden
#nullable disable
;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"Sha256", @"676265931c358e22efce0fe9ebd76cc3a7d2a5c12d37384e13aec92aa7667663", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml")]
[global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml")]
[global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ namespace AspNetCore
using global::Microsoft.AspNetCore.Mvc.Rendering;
using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 2 "TestFiles\IntegrationTests\CodeGenerationIntegrationTest\test.cshtml"
using TestNamespace;
#line (2,2)-(3,1) "TestFiles\IntegrationTests\CodeGenerationIntegrationTest\test.cshtml"
using TestNamespace

#line default
#line hidden
#nullable disable
;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"Sha256", @"d0420b910fa2a6f0119a96ffb534fee225ca66e96b3b1741cf04c7ebd9525f62", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/test.cshtml")]
[global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/test.cshtml")]
[global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ namespace AspNetCore
using global::Microsoft.AspNetCore.Mvc.Rendering;
using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 2 "TestFiles\IntegrationTests\CodeGenerationIntegrationTest\test.cshtml"
using TestNamespace;
#line (2,2)-(3,1) "TestFiles\IntegrationTests\CodeGenerationIntegrationTest\test.cshtml"
using TestNamespace

#line default
#line hidden
#nullable disable
;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"Sha256", @"714936b16425e1b5a49883c3e910ed43c30422ebc564f54651880695133a3b4b", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/test.cshtml")]
[global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/test.cshtml")]
[global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ namespace AspNetCore
using global::Microsoft.AspNetCore.Mvc.Rendering;
using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 2 "TestFiles\IntegrationTests\CodeGenerationIntegrationTest\test.cshtml"
using TestNamespace;
#line (2,2)-(3,1) "TestFiles\IntegrationTests\CodeGenerationIntegrationTest\test.cshtml"
using TestNamespace

#line default
#line hidden
#nullable disable
;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"Sha256", @"b354ee3595811e9701f9c464ddf35ccb31360a3799b7bb4279192f084591a4fe", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/test.cshtml")]
[global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/test.cshtml")]
[global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ namespace AspNetCore
using global::Microsoft.AspNetCore.Mvc.Rendering;
using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 2 "TestFiles\IntegrationTests\CodeGenerationIntegrationTest\test.cshtml"
using TestNamespace;
#line (2,2)-(3,1) "TestFiles\IntegrationTests\CodeGenerationIntegrationTest\test.cshtml"
using TestNamespace

#line default
#line hidden
#nullable disable
;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"Sha256", @"b354ee3595811e9701f9c464ddf35ccb31360a3799b7bb4279192f084591a4fe", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/test.cshtml")]
[global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/test.cshtml")]
[global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,37 @@ namespace AspNetCore
using global::Microsoft.AspNetCore.Mvc.Rendering;
using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System.ComponentModel;
#line (1,2)-(2,1) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System.ComponentModel

#line default
#line hidden
#nullable disable
;
#nullable restore
#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System.Collections;
#line (2,2)-(3,1) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System.Collections

#line default
#line hidden
#nullable disable
;
#nullable restore
#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System;
#line (3,2)-(4,1) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System

#line default
#line hidden
#nullable disable
;
#nullable restore
#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System;
#line (4,2)-(4,14) "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml"
using System

#line default
#line hidden
#nullable disable
;
[global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"Sha256", @"9194971d2fb7908a02b02841f18655ccc0908a204c2fa948e8dc7e947269da86", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml")]
[global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UsingDirectives.cshtml")]
[global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,25 +152,31 @@ public static CodeWriter WriteUsing(this CodeWriter writer, string name, bool en
return writer;
}

public static CodeWriter WriteEnhancedLineNumberDirective(this CodeWriter writer, SourceSpan span, int characterOffset)
public static CodeWriter WriteEnhancedLineNumberDirective(this CodeWriter writer, SourceSpan span, int characterOffset = 0)
{
// All values here need to be offset by 1 since #line uses a 1-indexed numbering system.
var lineNumberAsString = (span.LineIndex + 1).ToString(CultureInfo.InvariantCulture);
var characterStartAsString = (span.CharacterIndex + 1).ToString(CultureInfo.InvariantCulture);
var lineEndAsString = (span.LineIndex + 1 + span.LineCount).ToString(CultureInfo.InvariantCulture);
var characterEndAsString = (span.EndCharacterIndex + 1).ToString(CultureInfo.InvariantCulture);
var characterOffsetAsString = characterOffset.ToString(CultureInfo.InvariantCulture);
return writer.Write("#line (")
writer.Write("#line (")
.Write(lineNumberAsString)
.Write(",")
.Write(characterStartAsString)
.Write(")-(")
.Write(lineEndAsString)
.Write(",")
.Write(characterEndAsString)
.Write(") ")
.Write(characterOffsetAsString)
.Write(" \"").Write(span.FilePath).WriteLine("\"");
.Write(") ");

// an offset of zero is indicated by its absence.
if (characterOffset != 0)
{
var characterOffsetAsString = characterOffset.ToString(CultureInfo.InvariantCulture);
writer.Write(characterOffsetAsString).Write(" ");
}

return writer.Write("\"").Write(span.FilePath).WriteLine("\"");
}

public static CodeWriter WriteLineNumberDirective(this CodeWriter writer, SourceSpan span)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#nullable disable

using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -34,9 +33,14 @@ public override void WriteUsingDirective(CodeRenderingContext context, UsingDire
{
if (node.Source.HasValue)
{
using (context.CodeWriter.BuildLinePragma(node.Source.Value, context))
using (context.CodeWriter.BuildEnhancedLinePragma(node.Source.Value, context))
{
context.CodeWriter.WriteUsing(node.Content);
context.AddSourceMappingFor(node);
context.CodeWriter.WriteUsing(node.Content, endLine: node.HasExplicitSemicolon);
}
if (!node.HasExplicitSemicolon)
{
context.CodeWriter.WriteLine(";");
}
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,14 @@ public override void WriteUsingDirective(CodeRenderingContext context, UsingDire

if (node.Source.HasValue)
{
using (context.CodeWriter.BuildLinePragma(node.Source.Value, context))
using (context.CodeWriter.BuildEnhancedLinePragma(node.Source.Value, context))
{
context.CodeWriter.WriteUsing(node.Content);
context.AddSourceMappingFor(node);
context.CodeWriter.WriteUsing(node.Content, endLine: node.HasExplicitSemicolon);
}
if (!node.HasExplicitSemicolon)
{
context.CodeWriter.WriteLine(";");
}
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public override void WriteNode(CodeTarget target, CodeRenderingContext context)
{
context.CodeWriter.WriteLine("(");
context.CodeWriter.WriteLine("// language=Route,Component");
using (context.CodeWriter.BuildEnhancedLinePragma(Source, context, characterOffset: 1))
using (context.CodeWriter.BuildEnhancedLinePragma(Source, context))
{
context.CodeWriter.WritePadding(0, Source, context);
context.AddSourceMappingFor(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ protected override void ExecuteCore(RazorCodeDocument codeDocument)
{
Content = reference.Namespace,
Source = reference.Source,
HasExplicitSemicolon = reference.HasExplicitSemicolon
};

builder.Insert(index++, @using);
Expand Down Expand Up @@ -236,15 +237,18 @@ private static void PostProcessImportedDirectives(DocumentIntermediateNode docum

private struct UsingReference : IEquatable<UsingReference>
{
public UsingReference(string @namespace, SourceSpan? source)
public UsingReference(string @namespace, SourceSpan? source, bool hasExplicitSemicolon)
{
Namespace = @namespace;
Source = source;
HasExplicitSemicolon = hasExplicitSemicolon;
}
public string Namespace { get; }

public SourceSpan? Source { get; }

public bool HasExplicitSemicolon { get; }

public override bool Equals(object other)
{
if (other is UsingReference reference)
Expand Down Expand Up @@ -349,7 +353,7 @@ public override void VisitCSharpStatementLiteral(CSharpStatementLiteralSyntax no
case AddImportChunkGenerator importChunkGenerator:
var namespaceImport = importChunkGenerator.Namespace.Trim();
var namespaceSpan = BuildSourceSpanFromNode(node);
_usings.Add(new UsingReference(namespaceImport, namespaceSpan));
_usings.Add(new UsingReference(namespaceImport, namespaceSpan, importChunkGenerator.HasExplicitSemicolon));
break;
case AddTagHelperChunkGenerator addTagHelperChunkGenerator:
{
Expand Down
Loading

0 comments on commit d4236bb

Please sign in to comment.