protected override void ExecuteCore(RazorCodeDocument codeDocument) { var syntaxTree = codeDocument.GetSyntaxTree(); ThrowForMissingDocumentDependency(syntaxTree); var descriptors = codeDocument.GetTagHelpers(); if (descriptors == null) { var feature = Engine.GetFeature <ITagHelperFeature>(); if (feature == null) { // No feature, nothing to do. return; } descriptors = feature.GetDescriptors(); } var parserOptions = codeDocument.GetParserOptions(); // We need to find directives in all of the *imports* as well as in the main razor file // // The imports come logically before the main razor file and are in the order they // should be processed. DirectiveVisitor visitor; if (FileKinds.IsComponent(codeDocument.GetFileKind()) && (parserOptions == null || parserOptions.FeatureFlags.AllowComponentFileKind)) { codeDocument.TryComputeNamespace(fallbackToRootNamespace: true, out var currentNamespace); visitor = new ComponentDirectiveVisitor(codeDocument.Source.FilePath, descriptors, currentNamespace); } else { visitor = new TagHelperDirectiveVisitor(descriptors); } var imports = codeDocument.GetImportSyntaxTrees(); if (imports != null) { for (var i = 0; i < imports.Count; i++) { var import = imports[i]; visitor.Visit(import); } } visitor.Visit(syntaxTree); // This will always be null for a component document. var tagHelperPrefix = visitor.TagHelperPrefix; descriptors = visitor.Matches.ToArray(); var context = TagHelperDocumentContext.Create(tagHelperPrefix, descriptors); codeDocument.SetTagHelperContext(context); if (descriptors.Count == 0) { // No descriptors, no-op. return; } var rewrittenSyntaxTree = TagHelperParseTreeRewriter.Rewrite(syntaxTree, tagHelperPrefix, descriptors); codeDocument.SetSyntaxTree(rewrittenSyntaxTree); }