diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/NamespaceDirective.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/NamespaceDirective.cs index 188b60f6ca..946788eb77 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/NamespaceDirective.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/NamespaceDirective.cs @@ -85,7 +85,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions { var directiveSource = NormalizeDirectory(directive.Source?.FilePath); - var baseNamespace = directive.Tokens.First().Content; + var baseNamespace = directive.Tokens.FirstOrDefault()?.Content; + if (string.IsNullOrEmpty(baseNamespace)) + { + // The namespace directive was incomplete. + @namespace = string.Empty; + return false; + } + if (string.IsNullOrEmpty(source) || directiveSource == null) { // No sources, can't compute a suffix. diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/NamespaceDirectiveTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/NamespaceDirectiveTest.cs index 292afbd945..688517e8cb 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/NamespaceDirectiveTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/NamespaceDirectiveTest.cs @@ -9,6 +9,48 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions { public class NamespaceDirectiveTest { + [Fact] + public void TryComputeNamespace_IncompleteDirective_UsesEmptyNamespace() + { + // Arrange + var source = "c:\\foo\\bar\\bleh.cshtml"; + var imports = "c:\\foo\\baz\\bleh.cshtml"; + var node = new DirectiveIRNode() + { + Descriptor = NamespaceDirective.Directive, + Source = new SourceSpan(imports, 0, 0, 0, 0), + }; + + // Act + var computed = NamespaceDirective.TryComputeNamespace(source, node, out var @namespace); + + // Assert + Assert.False(computed); + Assert.Equal(string.Empty, @namespace); + } + + [Fact] + public void TryComputeNamespace_EmptyDirective_UsesEmptyNamespace() + { + // Arrange + var source = "c:\\foo\\bar\\bleh.cshtml"; + var imports = "c:\\foo\\baz\\bleh.cshtml"; + var node = new DirectiveIRNode() + { + Descriptor = NamespaceDirective.Directive, + Source = new SourceSpan(imports, 0, 0, 0, 0), + }; + node.Children.Add(new DirectiveTokenIRNode() { Content = string.Empty }); + node.Children[0].Parent = node; + + // Act + var computed = NamespaceDirective.TryComputeNamespace(source, node, out var @namespace); + + // Assert + Assert.False(computed); + Assert.Equal(string.Empty, @namespace); + } + // When we don't have a relationship between the source file and the imports file // we will just use the namespace on the node directly. [Theory]