| File: Language\Components\ComponentPageDirectivePass.cs | Web Access |
| Project: src\roslyn\src\Razor\src\Compiler\Microsoft.CodeAnalysis.Razor.Compiler\src\Microsoft.CodeAnalysis.Razor.Compiler.csproj (Microsoft.CodeAnalysis.Razor.Compiler) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Linq; using System.Threading; using Microsoft.AspNetCore.Razor.Language.Intermediate; namespace Microsoft.AspNetCore.Razor.Language.Components; internal sealed class ComponentPageDirectivePass : IntermediateNodePassBase, IRazorDirectiveClassifierPass { protected override void ExecuteCore( RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode, CancellationToken cancellationToken) { var @namespace = documentNode.FindPrimaryNamespace(); var @class = documentNode.FindPrimaryClass(); if (@namespace == null || @class == null) { return; } var directives = documentNode.FindDirectiveReferences(ComponentPageDirective.Directive); if (directives.Length == 0) { return; } // We don't allow @page directives in imports foreach (var directive in directives) { if (codeDocument.FileKind.IsComponentImport() || directive.Node.IsImported) { directive.Node.AddDiagnostic(ComponentDiagnosticFactory.CreatePageDirective_CannotBeImported(directive.Node.Source.GetValueOrDefault())); } } // Insert the attributes 'on-top' of the class declaration, since classes don't directly support attributes. var index = 0; for (; index < @namespace.Children.Count; index++) { if (object.ReferenceEquals(@class, @namespace.Children[index])) { break; } } foreach (var directive in directives) { var pageDirective = directive.Node; // The parser also adds errors for invalid syntax, we just need to not crash. var routeToken = pageDirective.Tokens.First(); if (routeToken is not { Content: ['"', '/', .., '"'] }) { pageDirective.AddDiagnostic(ComponentDiagnosticFactory.CreatePageDirective_MustSpecifyRoute(pageDirective.Source)); } @namespace.Children.Insert(index++, new RouteAttributeExtensionNode(routeToken.Content) { Source = routeToken.Source }); } } }