Exemplo n.º 1
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument)
        {
            var options    = codeDocument.GetParserOptions() ?? _optionsFeature.GetOptions();
            var syntaxTree = RazorSyntaxTree.Parse(codeDocument.Source, options);

            codeDocument.SetSyntaxTree(syntaxTree);

            var importSyntaxTrees = new RazorSyntaxTree[codeDocument.Imports.Count];

            for (var i = 0; i < codeDocument.Imports.Count; i++)
            {
                importSyntaxTrees[i] = RazorSyntaxTree.Parse(codeDocument.Imports[i], options);
            }
            codeDocument.SetImportSyntaxTrees(importSyntaxTrees);
        }
Exemplo n.º 2
0
    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);
    }
Exemplo n.º 3
0
        /// <inheritdoc />
        protected override void OnDocumentStructureCreated(
            RazorCodeDocument codeDocument,
            NamespaceDeclarationIntermediateNode @namespace,
            ClassDeclarationIntermediateNode @class,
            MethodDeclarationIntermediateNode method)
        {
            if (!codeDocument.TryComputeNamespace(fallbackToRootNamespace: true, out var computedNamespace) ||
                !TryComputeClassName(codeDocument, out var computedClass))
            {
                // If we can't compute a nice namespace (no relative path) then just generate something
                // mangled.
                computedNamespace = FallbackRootNamespace;
                var checksum = Checksum.BytesToString(codeDocument.Source.GetChecksum());
                computedClass = $"AspNetCore_{checksum}";
            }

            var documentNode = codeDocument.GetDocumentIntermediateNode();

            if (char.IsLower(computedClass, 0))
            {
                // We don't allow component names to start with a lowercase character.
                documentNode.Diagnostics.Add(
                    ComponentDiagnosticFactory.Create_ComponentNamesCannotStartWithLowerCase(computedClass, documentNode.Source));
            }

            if (MangleClassNames)
            {
                computedClass = ComponentMetadata.MangleClassName(computedClass);
            }

            @namespace.Content = computedNamespace;
            @class.ClassName   = computedClass;
            @class.Modifiers.Clear();
            @class.Modifiers.Add("public");
            @class.Modifiers.Add("partial");

            if (FileKinds.IsComponentImport(codeDocument.GetFileKind()))
            {
                // We don't want component imports to be considered as real component.
                // But we still want to generate code for it so we can get diagnostics.
                @class.BaseType = typeof(object).FullName;

                method.ReturnType = "void";
                method.MethodName = "Execute";
                method.Modifiers.Clear();
                method.Modifiers.Add("protected");

                method.Parameters.Clear();
            }
            else
            {
                @class.BaseType = ComponentsApi.ComponentBase.FullTypeName;

                // Constrained type parameters are only supported in Razor language versions v6.0
                var razorLanguageVersion = codeDocument.GetParserOptions()?.Version ?? RazorLanguageVersion.Latest;
                var directiveType        = razorLanguageVersion.CompareTo(RazorLanguageVersion.Version_6_0) >= 0
                    ? ComponentConstrainedTypeParamDirective.Directive
                    : ComponentTypeParamDirective.Directive;
                var typeParamReferences = documentNode.FindDirectiveReferences(directiveType);
                for (var i = 0; i < typeParamReferences.Count; i++)
                {
                    var typeParamNode = (DirectiveIntermediateNode)typeParamReferences[i].Node;
                    if (typeParamNode.HasDiagnostics)
                    {
                        continue;
                    }

                    @class.TypeParameters.Add(new TypeParameter()
                    {
                        ParameterName = typeParamNode.Tokens.First().Content,
                        Constraints   = typeParamNode.Tokens.Skip(1).FirstOrDefault()?.Content
                    });
                }

                method.ReturnType = "void";
                method.MethodName = ComponentsApi.ComponentBase.BuildRenderTree;
                method.Modifiers.Clear();
                method.Modifiers.Add("protected");
                method.Modifiers.Add("override");

                method.Parameters.Clear();
                method.Parameters.Add(new MethodParameter()
                {
                    ParameterName = ComponentsApi.RenderTreeBuilder.BuilderParameter,
                    TypeName      = ComponentsApi.RenderTreeBuilder.FullTypeName,
                });
            }
        }
Exemplo n.º 4
0
        protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
        {
            if (codeDocument == null)
            {
                throw new ArgumentNullException(nameof(codeDocument));
            }

            if (documentNode == null)
            {
                throw new ArgumentNullException(nameof(documentNode));
            }

            if (!IsComponentDocument(documentNode))
            {
                return;
            }

            if (documentNode.Options.SuppressPrimaryMethodBody)
            {
                // There's no benefit running the whitespace trimmer if we're not emitting
                // the method bodies.
                return;
            }

            // There's no benefit running the whitespace trimmer during design-time builds
            if (documentNode.Options.DesignTime)
            {
                return;
            }

            var razorLanguageVersion = codeDocument.GetParserOptions().Version;
            var useLegacyBehavior    = razorLanguageVersion.CompareTo(RazorLanguageVersion.Version_5_0) < 0;

            if (useLegacyBehavior)
            {
                // Prior to 5.0, the whitespace pass only applied to the BuildRenderTree method, and
                // only removed the top-level leading and trailing whitespace

                var method = documentNode.FindPrimaryMethod();
                if (method != null)
                {
                    RemoveContiguousWhitespace(method.Children, TraversalDirection.Forwards);
                    RemoveContiguousWhitespace(method.Children, TraversalDirection.Backwards);
                }
            }
            else
            {
                // From 5.0 onwards, the whitespace pass applies as broadly as possible. It removes leading
                // and trailing whitespace from all methods, elements, and child component blocks. There's
                // also a directive that can disable it.

                // Respect @preservewhitespace directives
                if (PreserveWhitespaceIsEnabled(documentNode))
                {
                    return;
                }

                var @class = documentNode.FindPrimaryClass();
                if (@class != null)
                {
                    var visitor = new Visitor();
                    visitor.Visit(@class);
                }
            }
        }